{"version":3,"file":"pullManualEnrichmentIdentifiersToCsv-BwdUNMV5.mjs","names":[],"sources":["../src/lib/manual-enrichment/pullManualEnrichmentIdentifiersToCsv.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n  buildTranscendGraphQLClient,\n  createSombraGotInstance,\n  fetchAllRequestEnrichers,\n  fetchAllRequestIdentifiers,\n  validateSombraVersion,\n  type RequestEnricher,\n  type RequestIdentifier,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport { groupBy, uniq } from 'lodash-es';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { type PrivacyRequest, fetchAllRequests } from '../graphql/index.js';\nimport { writeCsv } from '../helpers/writeCsv.js';\n\nexport interface PrivacyRequestWithIdentifiers extends PrivacyRequest {\n  /** Request Enrichers */\n  requestEnrichers: RequestEnricher[];\n  /** Request Identifiers */\n  requestIdentifiers: RequestIdentifier[];\n}\n\n/**\n * Pull the set of manual enrichment jobs to CSV\n *\n * @param options - Options\n * @returns List of requests with identifiers\n */\nexport async function pullManualEnrichmentIdentifiersToCsv({\n  file,\n  auth,\n  sombraAuth,\n  requestActions = [],\n  concurrency = 100,\n  transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n  /** CSV file path */\n  file: string;\n  /** Transcend API key authentication */\n  auth: string;\n  /** Sombra API key */\n  sombraAuth?: string;\n  /** Concurrency */\n  concurrency?: number;\n  /** The request actions to fetch */\n  requestActions?: RequestAction[];\n  /** API URL for Transcend backend */\n  transcendUrl?: string;\n}): Promise<PrivacyRequestWithIdentifiers[]> {\n  // Find all requests made before createdAt that are in a removing data state\n  const client = buildTranscendGraphQLClient(transcendUrl, auth);\n  const sombra = await createSombraGotInstance(transcendUrl, auth, {\n    logger,\n    sombraApiKey: sombraAuth,\n    sombraUrl: process.env.SOMBRA_URL,\n  });\n\n  logger.info(\n    colors.magenta(\n      `Pulling manual enrichment requests, filtered for actions: ${requestActions.join(',')}`,\n    ),\n  );\n\n  // Pull all privacy requests\n  const allRequests = await fetchAllRequests(client, {\n    actions: requestActions,\n    statuses: [RequestStatus.Enriching],\n  });\n\n  await validateSombraVersion(client, { logger });\n\n  // Requests to save\n  const savedRequests: PrivacyRequestWithIdentifiers[] = [];\n\n  // Filter down requests to what is needed\n  await map(\n    allRequests,\n    async (request) => {\n      // Fetch enrichers\n      const requestEnrichers = await fetchAllRequestEnrichers(client, {\n        filterBy: { requestId: request.id },\n        logger,\n      });\n\n      // Check if manual enrichment exists for that request\n      const hasManualEnrichment = requestEnrichers.filter(\n        ({ status }) => status === 'ACTION_REQUIRED',\n      );\n\n      // Save request to queue\n      if (hasManualEnrichment) {\n        const requestIdentifiers = await fetchAllRequestIdentifiers(client, sombra, {\n          filterBy: { requestId: request.id },\n          skipSombraCheck: true,\n          logger,\n        });\n        savedRequests.push({\n          ...request,\n          requestIdentifiers,\n          requestEnrichers,\n        });\n      }\n    },\n    {\n      concurrency,\n    },\n  );\n\n  const data = savedRequests.map(\n    ({\n      attributeValues,\n      requestIdentifiers,\n      requestEnrichers, // eslint-disable-line @typescript-eslint/no-unused-vars\n      ...request\n    }) => ({\n      ...request,\n      // flatten identifiers\n      ...Object.entries(groupBy(requestIdentifiers, 'name')).reduce(\n        (acc, [key, values]) =>\n          Object.assign(acc, {\n            [key]: values.map(({ value }) => value).join(','),\n          }),\n        {},\n      ),\n      // flatten attributes\n      ...Object.entries(groupBy(attributeValues, 'attributeKey.name')).reduce(\n        (acc, [key, values]) =>\n          Object.assign(acc, {\n            [key]: values.map(({ name }) => name).join(','),\n          }),\n        {},\n      ),\n    }),\n  );\n\n  // Write out to CSV\n  const headers = uniq(data.map((d) => Object.keys(d)).flat());\n  await writeCsv(file, data, headers);\n\n  logger.info(\n    colors.green(`Successfully wrote ${savedRequests.length} requests to file \"${file}\"`),\n  );\n\n  return savedRequests;\n}\n"],"mappings":"khBAgCA,eAAsB,EAAqC,CACzD,OACA,OACA,aACA,iBAAiB,EAAE,CACnB,cAAc,IACd,eAAe,GAc4B,CAE3C,IAAM,EAAS,EAA4B,EAAc,EAAK,CACxD,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAEF,EAAO,KACL,EAAO,QACL,6DAA6D,EAAe,KAAK,IAAI,GACtF,CACF,CAGD,IAAM,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAEF,MAAM,EAAsB,EAAQ,CAAE,SAAQ,CAAC,CAG/C,IAAM,EAAiD,EAAE,CAGzD,MAAM,EACJ,EACA,KAAO,IAAY,CAEjB,IAAM,EAAmB,MAAM,EAAyB,EAAQ,CAC9D,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,SACD,CAAC,CAQF,GAL4B,EAAiB,QAC1C,CAAE,YAAa,IAAW,kBAIN,CAAE,CACvB,IAAM,EAAqB,MAAM,EAA2B,EAAQ,EAAQ,CAC1E,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,gBAAiB,GACjB,SACD,CAAC,CACF,EAAc,KAAK,CACjB,GAAG,EACH,qBACA,mBACD,CAAC,GAGN,CACE,cACD,CACF,CAED,IAAM,EAAO,EAAc,KACxB,CACC,kBACA,qBACA,mBACA,GAAG,MACE,CACL,GAAG,EAEH,GAAG,OAAO,QAAQ,EAAQ,EAAoB,OAAO,CAAC,CAAC,QACpD,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,GAAM,EAAO,KAAK,CAAE,WAAY,EAAM,CAAC,KAAK,IAAI,CAClD,CAAC,CACJ,EAAE,CACH,CAED,GAAG,OAAO,QAAQ,EAAQ,EAAiB,oBAAoB,CAAC,CAAC,QAC9D,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,GAAM,EAAO,KAAK,CAAE,UAAW,EAAK,CAAC,KAAK,IAAI,CAChD,CAAC,CACJ,EAAE,CACH,CACF,EACF,CAUD,OANA,MAAM,EAAS,EAAM,EADL,EAAK,EAAK,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACzB,CAAC,CAEnC,EAAO,KACL,EAAO,MAAM,sBAAsB,EAAc,OAAO,qBAAqB,EAAK,GAAG,CACtF,CAEM"}