{"version":3,"file":"impl-B2eZGemA.mjs","names":[],"sources":["../src/commands/inventory/derive-data-silos-from-data-flows-cross-instance/impl.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { buildTranscendGraphQLClient, fetchAndIndexCatalogs } from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { difference } from 'lodash-es';\n\nimport { DataFlowInput } from '../../../codecs.js';\nimport type { LocalContext } from '../../../context.js';\nimport { listFiles } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { dataFlowsToDataSilos } from '../../../lib/consent-manager/dataFlowsToDataSilos.js';\nimport { readTranscendYaml, writeTranscendYaml } from '../../../lib/readTranscendYaml.js';\nimport { logger } from '../../../logger.js';\n\nexport interface DeriveDataSilosFromDataFlowsCrossInstanceCommandFlags {\n  auth: string;\n  dataFlowsYmlFolder: string;\n  output: string;\n  ignoreYmls?: string[];\n  transcendUrl: string;\n}\n\nexport async function deriveDataSilosFromDataFlowsCrossInstance(\n  this: LocalContext,\n  {\n    auth,\n    dataFlowsYmlFolder,\n    output,\n    ignoreYmls = [],\n    transcendUrl,\n  }: DeriveDataSilosFromDataFlowsCrossInstanceCommandFlags,\n): Promise<void> {\n  doneInputValidation(this.process.exit);\n\n  // Ensure folder is passed\n  if (!existsSync(dataFlowsYmlFolder) || !lstatSync(dataFlowsYmlFolder).isDirectory()) {\n    logger.error(colors.red(`Folder does not exist: \"${dataFlowsYmlFolder}\"`));\n    this.process.exit(1);\n  }\n\n  // Ignore the data flows in these yml files\n  const instancesToIgnore = ignoreYmls.map((x) => x.split('.')[0]);\n\n  // Map over each data flow yml file and convert to data silo configurations\n  const dataSiloInputs = listFiles(dataFlowsYmlFolder).map((directory) => {\n    // read in the data flows for a specific instance\n    const { 'data-flows': dataFlows = [] } = readTranscendYaml(join(dataFlowsYmlFolder, directory));\n\n    // map the data flows to data silos\n    const { adTechDataSilos, siteTechDataSilos } = dataFlowsToDataSilos(\n      dataFlows as DataFlowInput[],\n      {\n        serviceToSupportedIntegration,\n        serviceToTitle,\n      },\n    );\n\n    return {\n      adTechDataSilos,\n      siteTechDataSilos,\n      organizationName: directory.split('.')[0],\n    };\n  });\n\n  // Mapping from service name to instances that have that service\n  const serviceToInstance: { [k in string]: string[] } = {};\n  dataSiloInputs.forEach(({ adTechDataSilos, siteTechDataSilos, organizationName }) => {\n    const allDataSilos = [...adTechDataSilos, ...siteTechDataSilos];\n    allDataSilos.forEach((dataSilo) => {\n      const service = dataSilo['outer-type'] || dataSilo.integrationName;\n      // create mapping to instance\n      if (!serviceToInstance[service]) {\n        serviceToInstance[service] = [];\n      }\n      serviceToInstance[service]!.push(organizationName);\n      serviceToInstance[service] = [...new Set(serviceToInstance[service])];\n    });\n  });\n\n  // List of ad tech integrations\n  const adTechIntegrations = [\n    ...new Set(\n      dataSiloInputs\n        .map(({ adTechDataSilos }) =>\n          adTechDataSilos.map((silo) => silo['outer-type'] || silo.integrationName),\n        )\n        .flat(),\n    ),\n  ];\n\n  // List of site tech integrations\n  const siteTechIntegrations = difference(\n    [\n      ...new Set(\n        dataSiloInputs\n          .map(({ siteTechDataSilos }) =>\n            siteTechDataSilos.map((silo) => silo['outer-type'] || silo.integrationName),\n          )\n          .flat(),\n      ),\n    ],\n    adTechIntegrations,\n  );\n\n  // Mapping from service name to list of\n  const serviceToFoundOnDomain: { [k in string]: string[] } = {};\n  dataSiloInputs.forEach(({ adTechDataSilos, siteTechDataSilos }) => {\n    const allDataSilos = [...adTechDataSilos, ...siteTechDataSilos];\n    allDataSilos.forEach((dataSilo) => {\n      const service = dataSilo['outer-type'] || dataSilo.integrationName;\n      const foundOnDomain = dataSilo.attributes?.find((attr) => attr.key === 'Found On Domain');\n      // create mapping to instance\n      if (!serviceToFoundOnDomain[service]) {\n        serviceToFoundOnDomain[service] = [];\n      }\n      serviceToFoundOnDomain[service]!.push(...(foundOnDomain?.values || []));\n      serviceToFoundOnDomain[service] = [...new Set(serviceToFoundOnDomain[service])];\n    });\n  });\n\n  // Fetch all integrations in the catalog\n  const client = buildTranscendGraphQLClient(transcendUrl, auth);\n  const { serviceToTitle, serviceToSupportedIntegration } = await fetchAndIndexCatalogs(client, {\n    logger,\n  });\n\n  // construct the aggregated data silo inputs\n  const dataSilos = [...adTechIntegrations, ...siteTechIntegrations].map((service) => ({\n    title: serviceToTitle[service],\n    ...(serviceToSupportedIntegration[service]\n      ? { integrationName: service }\n      : { integrationName: 'promptAPerson', 'outer-type': service }),\n    attributes: [\n      {\n        key: 'Tech Type',\n        values: ['Ad Tech'],\n      },\n      {\n        key: 'Business Units',\n        values: difference(serviceToInstance[service] || [], instancesToIgnore),\n      },\n      {\n        key: 'Found On Domain',\n        values: serviceToFoundOnDomain[service] || [],\n      },\n    ],\n  }));\n\n  // Log output\n  logger.log(`Total Services: ${dataSilos.length}`);\n  logger.log(`Ad Tech Services: ${adTechIntegrations.length}`);\n  logger.log(`Site Tech Services: ${siteTechIntegrations.length}`);\n\n  // Write to yaml\n  writeTranscendYaml(output, {\n    'data-silos': dataSilos,\n  });\n}\n"],"mappings":"ifAuBA,eAAsB,EAEpB,CACE,OACA,qBACA,SACA,aAAa,EAAE,CACf,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,EAGlC,CAAC,EAAW,EAAmB,EAAI,CAAC,EAAU,EAAmB,CAAC,aAAa,IACjF,EAAO,MAAM,EAAO,IAAI,2BAA2B,EAAmB,GAAG,CAAC,CAC1E,KAAK,QAAQ,KAAK,EAAE,EAItB,IAAM,EAAoB,EAAW,IAAK,GAAM,EAAE,MAAM,IAAI,CAAC,GAAG,CAG1D,EAAiB,EAAU,EAAmB,CAAC,IAAK,GAAc,CAEtE,GAAM,CAAE,aAAc,EAAY,EAAE,EAAK,EAAkB,EAAK,EAAoB,EAAU,CAAC,CAGzF,CAAE,kBAAiB,qBAAsB,EAC7C,EACA,CACE,gCACA,iBACD,CACF,CAED,MAAO,CACL,kBACA,oBACA,iBAAkB,EAAU,MAAM,IAAI,CAAC,GACxC,EACD,CAGI,EAAiD,EAAE,CACzD,EAAe,SAAS,CAAE,kBAAiB,oBAAmB,sBAAuB,CAEnF,CADsB,GAAG,EAAiB,GAAG,EACjC,CAAC,QAAS,GAAa,CACjC,IAAM,EAAU,EAAS,eAAiB,EAAS,gBAE9C,EAAkB,KACrB,EAAkB,GAAW,EAAE,EAEjC,EAAkB,GAAU,KAAK,EAAiB,CAClD,EAAkB,GAAW,CAAC,GAAG,IAAI,IAAI,EAAkB,GAAS,CAAC,EACrE,EACF,CAGF,IAAM,EAAqB,CACzB,GAAG,IAAI,IACL,EACG,KAAK,CAAE,qBACN,EAAgB,IAAK,GAAS,EAAK,eAAiB,EAAK,gBAAgB,CAC1E,CACA,MAAM,CACV,CACF,CAGK,EAAuB,EAC3B,CACE,GAAG,IAAI,IACL,EACG,KAAK,CAAE,uBACN,EAAkB,IAAK,GAAS,EAAK,eAAiB,EAAK,gBAAgB,CAC5E,CACA,MAAM,CACV,CACF,CACD,EACD,CAGK,EAAsD,EAAE,CAC9D,EAAe,SAAS,CAAE,kBAAiB,uBAAwB,CAEjE,CADsB,GAAG,EAAiB,GAAG,EACjC,CAAC,QAAS,GAAa,CACjC,IAAM,EAAU,EAAS,eAAiB,EAAS,gBAC7C,EAAgB,EAAS,YAAY,KAAM,GAAS,EAAK,MAAQ,kBAAkB,CAEpF,EAAuB,KAC1B,EAAuB,GAAW,EAAE,EAEtC,EAAuB,GAAU,KAAK,GAAI,GAAe,QAAU,EAAE,CAAE,CACvE,EAAuB,GAAW,CAAC,GAAG,IAAI,IAAI,EAAuB,GAAS,CAAC,EAC/E,EACF,CAIF,GAAM,CAAE,iBAAgB,iCAAkC,MAAM,EADjD,EAA4B,EAAc,EACmC,CAAE,CAC5F,SACD,CAAC,CAGI,EAAY,CAAC,GAAG,EAAoB,GAAG,EAAqB,CAAC,IAAK,IAAa,CACnF,MAAO,EAAe,GACtB,GAAI,EAA8B,GAC9B,CAAE,gBAAiB,EAAS,CAC5B,CAAE,gBAAiB,gBAAiB,aAAc,EAAS,CAC/D,WAAY,CACV,CACE,IAAK,YACL,OAAQ,CAAC,UAAU,CACpB,CACD,CACE,IAAK,iBACL,OAAQ,EAAW,EAAkB,IAAY,EAAE,CAAE,EAAkB,CACxE,CACD,CACE,IAAK,kBACL,OAAQ,EAAuB,IAAY,EAAE,CAC9C,CACF,CACF,EAAE,CAGH,EAAO,IAAI,mBAAmB,EAAU,SAAS,CACjD,EAAO,IAAI,qBAAqB,EAAmB,SAAS,CAC5D,EAAO,IAAI,uBAAuB,EAAqB,SAAS,CAGhE,EAAmB,EAAQ,CACzB,aAAc,EACf,CAAC"}