@transcend-io/cli 10.5.4 → 10.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-DzXC3o66.mjs +131 -0
- package/dist/{app-CGrl8jGp.mjs.map → app-DzXC3o66.mjs.map} +1 -1
- package/dist/{approvePrivacyRequests-B-pGYZ3B.mjs → approvePrivacyRequests-CiJJar6N.mjs} +2 -2
- package/dist/{approvePrivacyRequests-B-pGYZ3B.mjs.map → approvePrivacyRequests-CiJJar6N.mjs.map} +1 -1
- package/dist/bin/bash-complete.mjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/bin/deprecated-command.mjs +1 -1
- package/dist/bin/deprecated-command.mjs.map +1 -1
- package/dist/{buildXdiSyncEndpoint-3C-ODh2I.mjs → buildXdiSyncEndpoint-CSOGLrEh.mjs} +2 -2
- package/dist/{buildXdiSyncEndpoint-3C-ODh2I.mjs.map → buildXdiSyncEndpoint-CSOGLrEh.mjs.map} +1 -1
- package/dist/{bulkRestartRequests-DTBSNfe1.mjs → bulkRestartRequests-BFYgQddg.mjs} +2 -2
- package/dist/{bulkRestartRequests-DTBSNfe1.mjs.map → bulkRestartRequests-BFYgQddg.mjs.map} +1 -1
- package/dist/{bulkRetryEnrichers-DP8sSSyj.mjs → bulkRetryEnrichers-C1TsWVFy.mjs} +2 -2
- package/dist/{bulkRetryEnrichers-DP8sSSyj.mjs.map → bulkRetryEnrichers-C1TsWVFy.mjs.map} +1 -1
- package/dist/{cancelPrivacyRequests-B96uHF1A.mjs → cancelPrivacyRequests-CpECjTPR.mjs} +2 -2
- package/dist/{cancelPrivacyRequests-B96uHF1A.mjs.map → cancelPrivacyRequests-CpECjTPR.mjs.map} +1 -1
- package/dist/codecs-Dnq-rEcB.mjs +2 -0
- package/dist/codecs-Dnq-rEcB.mjs.map +1 -0
- package/dist/collectCsvFilesOrExit-CbtyKAzu.mjs.map +1 -1
- package/dist/collectParquetFilesOrExit-BJiAyaQ5.mjs.map +1 -1
- package/dist/{command-CNHVi3X1.mjs → command-BVxNkJEw.mjs} +2 -2
- package/dist/{command-CNHVi3X1.mjs.map → command-BVxNkJEw.mjs.map} +1 -1
- package/dist/constants-BmwXDQu9.mjs.map +1 -1
- package/dist/constants-CLxPXlJM.mjs +2 -0
- package/dist/{constants-ClkQQhJs.mjs.map → constants-CLxPXlJM.mjs.map} +1 -1
- package/dist/constants-zytGRR9s.mjs +2 -0
- package/dist/{constants-BOycJ_AQ.mjs.map → constants-zytGRR9s.mjs.map} +1 -1
- package/dist/{createExtraKeyHandler-Dz15OUvs.mjs → createExtraKeyHandler-2BcgOSo8.mjs} +3 -3
- package/dist/{createExtraKeyHandler-Dz15OUvs.mjs.map → createExtraKeyHandler-2BcgOSo8.mjs.map} +1 -1
- package/dist/dataFlowsToDataSilos-Ca2DtTsd.mjs.map +1 -1
- package/dist/{downloadPrivacyRequestFiles-Aneyb8TU.mjs → downloadPrivacyRequestFiles-B1rI73ok.mjs} +2 -2
- package/dist/{downloadPrivacyRequestFiles-Aneyb8TU.mjs.map → downloadPrivacyRequestFiles-B1rI73ok.mjs.map} +1 -1
- package/dist/fetchAllRequests-CHHdyb4Q.mjs.map +1 -1
- package/dist/{generateCrossAccountApiKeys-wIS5jh1i.mjs → generateCrossAccountApiKeys-FUo_wsSM.mjs} +2 -2
- package/dist/{generateCrossAccountApiKeys-wIS5jh1i.mjs.map → generateCrossAccountApiKeys-FUo_wsSM.mjs.map} +1 -1
- package/dist/{impl-8WdsvXOc.mjs → impl-AgujmepV.mjs} +2 -2
- package/dist/{impl-8WdsvXOc.mjs.map → impl-AgujmepV.mjs.map} +1 -1
- package/dist/{impl-CzUXWrgQ.mjs → impl-B3-wUMSZ.mjs} +2 -2
- package/dist/{impl-CzUXWrgQ.mjs.map → impl-B3-wUMSZ.mjs.map} +1 -1
- package/dist/{impl-zTKleu53.mjs → impl-B78f1YnE.mjs} +2 -2
- package/dist/{impl-zTKleu53.mjs.map → impl-B78f1YnE.mjs.map} +1 -1
- package/dist/{impl-HSoEoM66.mjs → impl-BTTzSg7k.mjs} +2 -2
- package/dist/{impl-HSoEoM66.mjs.map → impl-BTTzSg7k.mjs.map} +1 -1
- package/dist/{impl-Ph9niRN-.mjs → impl-BUjfG4eC.mjs} +2 -2
- package/dist/{impl-Ph9niRN-.mjs.map → impl-BUjfG4eC.mjs.map} +1 -1
- package/dist/{impl-piZKrouV.mjs → impl-BW0nZQcf.mjs} +2 -2
- package/dist/{impl-piZKrouV.mjs.map → impl-BW0nZQcf.mjs.map} +1 -1
- package/dist/{impl-CFYxHmDT.mjs → impl-BhNnDVWM.mjs} +2 -2
- package/dist/{impl-CFYxHmDT.mjs.map → impl-BhNnDVWM.mjs.map} +1 -1
- package/dist/impl-BjCQSRLu.mjs.map +1 -1
- package/dist/{impl-Cg9TvlD0.mjs → impl-Bjf36di3.mjs} +2 -2
- package/dist/{impl-Cg9TvlD0.mjs.map → impl-Bjf36di3.mjs.map} +1 -1
- package/dist/{impl-C3B_DbVl.mjs → impl-BnME6ASm.mjs} +2 -2
- package/dist/{impl-C3B_DbVl.mjs.map → impl-BnME6ASm.mjs.map} +1 -1
- package/dist/{impl-D0_1vCyS.mjs → impl-BwKFPCHn.mjs} +2 -2
- package/dist/{impl-D0_1vCyS.mjs.map → impl-BwKFPCHn.mjs.map} +1 -1
- package/dist/{impl-DCC9QQh4.mjs → impl-C08anQRz.mjs} +2 -2
- package/dist/{impl-DCC9QQh4.mjs.map → impl-C08anQRz.mjs.map} +1 -1
- package/dist/{impl-CPPvCxrg.mjs → impl-C2to-OHX.mjs} +2 -2
- package/dist/{impl-CPPvCxrg.mjs.map → impl-C2to-OHX.mjs.map} +1 -1
- package/dist/{impl-v4FNox3W.mjs → impl-C9By5dWV.mjs} +2 -2
- package/dist/{impl-v4FNox3W.mjs.map → impl-C9By5dWV.mjs.map} +1 -1
- package/dist/{impl-E3r8gzm6.mjs → impl-CA4HCgZH.mjs} +2 -2
- package/dist/{impl-E3r8gzm6.mjs.map → impl-CA4HCgZH.mjs.map} +1 -1
- package/dist/{impl-y6OJgoDw.mjs → impl-CCw9Nk9s.mjs} +2 -2
- package/dist/{impl-y6OJgoDw.mjs.map → impl-CCw9Nk9s.mjs.map} +1 -1
- package/dist/{impl-uxQT5IZV.mjs → impl-CEhKFcOU.mjs} +2 -2
- package/dist/{impl-uxQT5IZV.mjs.map → impl-CEhKFcOU.mjs.map} +1 -1
- package/dist/{impl-DfKBJwNF.mjs → impl-CH0jeBtq.mjs} +2 -2
- package/dist/{impl-DfKBJwNF.mjs.map → impl-CH0jeBtq.mjs.map} +1 -1
- package/dist/{impl-Ca9jo1uf.mjs → impl-CTre0PAy.mjs} +2 -2
- package/dist/{impl-Ca9jo1uf.mjs.map → impl-CTre0PAy.mjs.map} +1 -1
- package/dist/{impl-CldmgMzS.mjs → impl-CWGE0wkZ.mjs} +2 -2
- package/dist/{impl-CldmgMzS.mjs.map → impl-CWGE0wkZ.mjs.map} +1 -1
- package/dist/{impl-B0XDaW-q.mjs → impl-CWIKNmbA.mjs} +2 -2
- package/dist/{impl-B0XDaW-q.mjs.map → impl-CWIKNmbA.mjs.map} +1 -1
- package/dist/{impl-8BvKYax5.mjs → impl-CWxFcw0g.mjs} +2 -2
- package/dist/{impl-8BvKYax5.mjs.map → impl-CWxFcw0g.mjs.map} +1 -1
- package/dist/{impl-CN7qqr0l.mjs → impl-CXOR_MZL.mjs} +2 -2
- package/dist/{impl-CN7qqr0l.mjs.map → impl-CXOR_MZL.mjs.map} +1 -1
- package/dist/{impl-DHW1Tt2p.mjs → impl-CkCbsgWr.mjs} +2 -2
- package/dist/{impl-DHW1Tt2p.mjs.map → impl-CkCbsgWr.mjs.map} +1 -1
- package/dist/impl-Cw3_0zqC.mjs.map +1 -1
- package/dist/{impl-CUly8WpU.mjs → impl-CyNmrj6z.mjs} +2 -2
- package/dist/{impl-CUly8WpU.mjs.map → impl-CyNmrj6z.mjs.map} +1 -1
- package/dist/{impl-DVpGoSQ9.mjs → impl-D2TC7ZOH.mjs} +2 -2
- package/dist/{impl-DVpGoSQ9.mjs.map → impl-D2TC7ZOH.mjs.map} +1 -1
- package/dist/{impl-BZIZuD4O.mjs → impl-D5kcMRqr.mjs} +2 -2
- package/dist/{impl-BZIZuD4O.mjs.map → impl-D5kcMRqr.mjs.map} +1 -1
- package/dist/impl-DKIBerx4.mjs +4 -0
- package/dist/{impl-BjIylEKQ.mjs.map → impl-DKIBerx4.mjs.map} +1 -1
- package/dist/impl-DQQ_nI25.mjs.map +1 -1
- package/dist/{impl-DmFYqMyc.mjs → impl-DT3pE3Ze.mjs} +2 -2
- package/dist/{impl-DmFYqMyc.mjs.map → impl-DT3pE3Ze.mjs.map} +1 -1
- package/dist/{impl-DXHqqWJb.mjs → impl-DiHeNVFr.mjs} +2 -2
- package/dist/{impl-DXHqqWJb.mjs.map → impl-DiHeNVFr.mjs.map} +1 -1
- package/dist/{impl-BZQ0KiYZ.mjs → impl-Dk94fgeK.mjs} +2 -2
- package/dist/{impl-BZQ0KiYZ.mjs.map → impl-Dk94fgeK.mjs.map} +1 -1
- package/dist/{impl-BuxT4Cx2.mjs → impl-Dm6ITkBn.mjs} +2 -2
- package/dist/{impl-BuxT4Cx2.mjs.map → impl-Dm6ITkBn.mjs.map} +1 -1
- package/dist/{impl-j0jL7UnC.mjs → impl-EgoVUcWR.mjs} +2 -2
- package/dist/{impl-j0jL7UnC.mjs.map → impl-EgoVUcWR.mjs.map} +1 -1
- package/dist/{impl-Clog0IsW.mjs → impl-WDt81-Vk.mjs} +2 -2
- package/dist/{impl-Clog0IsW.mjs.map → impl-WDt81-Vk.mjs.map} +1 -1
- package/dist/{impl-BW3HCdPO.mjs → impl-Xona8YN1.mjs} +2 -2
- package/dist/{impl-BW3HCdPO.mjs.map → impl-Xona8YN1.mjs.map} +1 -1
- package/dist/{impl-DgRkDJIM.mjs → impl-dQg1-ZW6.mjs} +2 -2
- package/dist/{impl-DgRkDJIM.mjs.map → impl-dQg1-ZW6.mjs.map} +1 -1
- package/dist/{impl-DxAtF6i2.mjs → impl-qO0ED4q4.mjs} +2 -2
- package/dist/{impl-DxAtF6i2.mjs.map → impl-qO0ED4q4.mjs.map} +1 -1
- package/dist/{impl-CFuzHw_V.mjs → impl-qemxdloz.mjs} +2 -2
- package/dist/{impl-CFuzHw_V.mjs.map → impl-qemxdloz.mjs.map} +1 -1
- package/dist/{impl-CetnLzsu.mjs → impl-s0EM9fea.mjs} +2 -2
- package/dist/{impl-CetnLzsu.mjs.map → impl-s0EM9fea.mjs.map} +1 -1
- package/dist/{impl-tJanHDLi.mjs → impl-uxbaFgZT.mjs} +2 -2
- package/dist/{impl-tJanHDLi.mjs.map → impl-uxbaFgZT.mjs.map} +1 -1
- package/dist/impl-xtlx25UP.mjs.map +1 -1
- package/dist/index.d.mts +462 -15
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/{inquirer-BqZXFEt1.mjs → inquirer-B4iEodLy.mjs} +2 -2
- package/dist/{inquirer-BqZXFEt1.mjs.map → inquirer-B4iEodLy.mjs.map} +1 -1
- package/dist/{markRequestDataSiloIdsCompleted-hvdftA2o.mjs → markRequestDataSiloIdsCompleted-_VvJoVTL.mjs} +2 -2
- package/dist/{markRequestDataSiloIdsCompleted-hvdftA2o.mjs.map → markRequestDataSiloIdsCompleted-_VvJoVTL.mjs.map} +1 -1
- package/dist/{markSilentPrivacyRequests-DZKKnSo0.mjs → markSilentPrivacyRequests-KYqGzjta.mjs} +2 -2
- package/dist/{markSilentPrivacyRequests-DZKKnSo0.mjs.map → markSilentPrivacyRequests-KYqGzjta.mjs.map} +1 -1
- package/dist/{notifyPrivacyRequestsAdditionalTime-BG0X2G1i.mjs → notifyPrivacyRequestsAdditionalTime-CygA3uum.mjs} +2 -2
- package/dist/{notifyPrivacyRequestsAdditionalTime-BG0X2G1i.mjs.map → notifyPrivacyRequestsAdditionalTime-CygA3uum.mjs.map} +1 -1
- package/dist/parquetToCsvOneFile-B84XXInh.mjs.map +1 -1
- package/dist/{parseAttributesFromString-D1Yl0xwT.mjs → parseAttributesFromString-q4-59nEN.mjs} +2 -2
- package/dist/{parseAttributesFromString-D1Yl0xwT.mjs.map → parseAttributesFromString-q4-59nEN.mjs.map} +1 -1
- package/dist/parseVariablesFromString-BeKOGw5n.mjs.map +1 -1
- package/dist/pullAllDatapoints-Bbmky50p.mjs.map +1 -1
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-D2oMDSTM.mjs → pullChunkedCustomSiloOutstandingIdentifiers-Bz1EGQOW.mjs} +2 -2
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-D2oMDSTM.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-Bz1EGQOW.mjs.map} +1 -1
- package/dist/pullConsentManagerMetrics-zKgjc3Ap.mjs.map +1 -1
- package/dist/{pullManualEnrichmentIdentifiersToCsv-CuMrsy2E.mjs → pullManualEnrichmentIdentifiersToCsv-BWxxJ2Qi.mjs} +2 -2
- package/dist/{pullManualEnrichmentIdentifiersToCsv-CuMrsy2E.mjs.map → pullManualEnrichmentIdentifiersToCsv-BWxxJ2Qi.mjs.map} +1 -1
- package/dist/pullTranscendConfiguration-BHP6t_Nq.mjs +58 -0
- package/dist/pullTranscendConfiguration-BHP6t_Nq.mjs.map +1 -0
- package/dist/pullUnstructuredSubDataPointRecommendations-D0z-vPgq.mjs.map +1 -1
- package/dist/{pushCronIdentifiersFromCsv-Diqe_40J.mjs → pushCronIdentifiersFromCsv-DUZv9xss.mjs} +2 -2
- package/dist/{pushCronIdentifiersFromCsv-Diqe_40J.mjs.map → pushCronIdentifiersFromCsv-DUZv9xss.mjs.map} +1 -1
- package/dist/{pushManualEnrichmentIdentifiersFromCsv-DTc5tZta.mjs → pushManualEnrichmentIdentifiersFromCsv-QnSf70JE.mjs} +2 -2
- package/dist/{pushManualEnrichmentIdentifiersFromCsv-DTc5tZta.mjs.map → pushManualEnrichmentIdentifiersFromCsv-QnSf70JE.mjs.map} +1 -1
- package/dist/readCsv-C4TyEs-r.mjs.map +1 -1
- package/dist/{readTranscendYaml-BbnEGgVD.mjs → readTranscendYaml-CGb2UUyM.mjs} +2 -2
- package/dist/{readTranscendYaml-BbnEGgVD.mjs.map → readTranscendYaml-CGb2UUyM.mjs.map} +1 -1
- package/dist/{removeUnverifiedRequestIdentifiers-CjXqxX3q.mjs → removeUnverifiedRequestIdentifiers-Bh8EQEts.mjs} +2 -2
- package/dist/{removeUnverifiedRequestIdentifiers-CjXqxX3q.mjs.map → removeUnverifiedRequestIdentifiers-Bh8EQEts.mjs.map} +1 -1
- package/dist/{retryRequestDataSilos-B-dCsMNC.mjs → retryRequestDataSilos-BPORd8Q4.mjs} +2 -2
- package/dist/{retryRequestDataSilos-B-dCsMNC.mjs.map → retryRequestDataSilos-BPORd8Q4.mjs.map} +1 -1
- package/dist/{skipPreflightJobs-CoTI1wuB.mjs → skipPreflightJobs-DFDwnE32.mjs} +2 -2
- package/dist/{skipPreflightJobs-CoTI1wuB.mjs.map → skipPreflightJobs-DFDwnE32.mjs.map} +1 -1
- package/dist/{skipRequestDataSilos-CbdhNiBV.mjs → skipRequestDataSilos-DQkZn9Wx.mjs} +2 -2
- package/dist/{skipRequestDataSilos-CbdhNiBV.mjs.map → skipRequestDataSilos-DQkZn9Wx.mjs.map} +1 -1
- package/dist/{streamPrivacyRequestsToCsv-B6-4KjP_.mjs → streamPrivacyRequestsToCsv-B0GqwHNz.mjs} +2 -2
- package/dist/{streamPrivacyRequestsToCsv-B6-4KjP_.mjs.map → streamPrivacyRequestsToCsv-B0GqwHNz.mjs.map} +1 -1
- package/dist/syncCodePackages-CAk_Hjyl.mjs.map +1 -1
- package/dist/{updateConsentManagerVersionToLatest-Bo0g8BLm.mjs → updateConsentManagerVersionToLatest-D3ms_fBZ.mjs} +2 -2
- package/dist/{updateConsentManagerVersionToLatest-Bo0g8BLm.mjs.map → updateConsentManagerVersionToLatest-D3ms_fBZ.mjs.map} +1 -1
- package/dist/{uploadConsents-GNPBOA3B.mjs → uploadConsents-DA8DR8pb.mjs} +2 -2
- package/dist/{uploadConsents-GNPBOA3B.mjs.map → uploadConsents-DA8DR8pb.mjs.map} +1 -1
- package/dist/{uploadCookiesFromCsv-C5n0dIZs.mjs → uploadCookiesFromCsv-dHTagDcv.mjs} +2 -2
- package/dist/{uploadCookiesFromCsv-C5n0dIZs.mjs.map → uploadCookiesFromCsv-dHTagDcv.mjs.map} +1 -1
- package/dist/{uploadDataFlowsFromCsv-Dnh7n6R0.mjs → uploadDataFlowsFromCsv-Db7cxXcH.mjs} +2 -2
- package/dist/{uploadDataFlowsFromCsv-Dnh7n6R0.mjs.map → uploadDataFlowsFromCsv-Db7cxXcH.mjs.map} +1 -1
- package/dist/uploadPrivacyRequestsFromCsv-Cs9e4fgB.mjs +2 -0
- package/dist/{uploadPrivacyRequestsFromCsv-7KNlE6Et.mjs.map → uploadPrivacyRequestsFromCsv-Cs9e4fgB.mjs.map} +1 -1
- package/dist/{validateTranscendAuth-BHw0WQu1.mjs → validateTranscendAuth-DJ8qHb9B.mjs} +2 -2
- package/dist/{validateTranscendAuth-BHw0WQu1.mjs.map → validateTranscendAuth-DJ8qHb9B.mjs.map} +1 -1
- package/dist/writeCsv-C4pjXGsD.mjs.map +1 -1
- package/package.json +9 -9
- package/dist/app-CGrl8jGp.mjs +0 -131
- package/dist/codecs-B2mV72Wn.mjs +0 -2
- package/dist/codecs-B2mV72Wn.mjs.map +0 -1
- package/dist/constants-BOycJ_AQ.mjs +0 -2
- package/dist/constants-ClkQQhJs.mjs +0 -2
- package/dist/impl-BjIylEKQ.mjs +0 -4
- package/dist/pullTranscendConfiguration-CofsMdIn.mjs +0 -58
- package/dist/pullTranscendConfiguration-CofsMdIn.mjs.map +0 -1
- package/dist/uploadPrivacyRequestsFromCsv-7KNlE6Et.mjs +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateCrossAccountApiKeys-
|
|
1
|
+
{"version":3,"file":"generateCrossAccountApiKeys-FUo_wsSM.mjs","names":[],"sources":["../src/lib/api-keys/generateCrossAccountApiKeys.ts"],"sourcesContent":["import { ScopeName } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClientGeneric,\n loginUser,\n createApiKey,\n fetchAllApiKeys,\n deleteApiKey,\n assumeRole,\n} from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { StoredApiKey } from '../../codecs.js';\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\n\nexport interface ApiKeyGenerateError {\n /** Name of instance */\n organizationName: string;\n /** Error */\n error: string;\n /** Organization ID API key is for */\n organizationId: string;\n}\n\n/**\n * Generate API keys across multiple transcend accounts\n *\n * @param options - Options\n * @returns Number of API keys created\n */\nexport async function generateCrossAccountApiKeys({\n email,\n password,\n scopes,\n apiKeyTitle,\n parentOrganizationId,\n deleteExistingApiKey = true,\n createNewApiKey = true,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** Email address of user generating API keys */\n email: string;\n /** Password of user generating API keys */\n password: string;\n /** Filter for organizations that match this parent organization ID */\n parentOrganizationId?: string;\n /** Title of the API create to create */\n apiKeyTitle: string;\n /** Title of the API create to create */\n scopes: ScopeName[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** When true delete existing API keys with that title, if set to false an API key exists with that title, an error is thrown */\n deleteExistingApiKey?: boolean;\n /** When true, generate new API keys, otherwise only will delete past API keys */\n createNewApiKey?: boolean;\n}): Promise<{\n /** Successfully generated */\n apiKeys: StoredApiKey[];\n /** Error results */\n errors: ApiKeyGenerateError[];\n}> {\n // Create GraphQL client\n const client = await buildTranscendGraphQLClientGeneric(transcendUrl, {});\n\n // Login the user\n logger.info(colors.magenta('Logging in using email and password.'));\n const { roles, loginCookie } = await loginUser(client, { email, password, logger });\n logger.info(\n colors.green(\n `Successfully logged in and found ${roles.length} role${roles.length === 1 ? '' : 's'}!`,\n ),\n );\n\n // Filter down by parentOrganizationId\n const filteredRoles = parentOrganizationId\n ? roles.filter(\n (role) =>\n role.organization.id === parentOrganizationId ||\n role.organization.parentOrganizationId === parentOrganizationId,\n )\n : roles;\n\n // Save cookie to call route subsequent times\n client.setHeaders({\n Cookie: loginCookie,\n });\n\n // Save the resulting API keys\n const results: StoredApiKey[] = [];\n const errors: ApiKeyGenerateError[] = [];\n\n // Generate API keys\n logger.info(\n colors.magenta(`Generating API keys with title: ${apiKeyTitle}, scopes: ${scopes.join(',')}.`),\n );\n\n // Map over each role\n await mapSeries(filteredRoles, async (role) => {\n try {\n // Log into the other instance\n await assumeRole(client, { roleId: role.id, email, logger });\n\n // Grab API keys with that title\n logger.info(\n colors.magenta(\n `Checking if API key already exists in organization \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n\n // Delete existing API key\n const [apiKeyWithTitle] = await fetchAllApiKeys(client, {\n logger,\n filterBy: { titles: [apiKeyTitle] },\n });\n if (apiKeyWithTitle && deleteExistingApiKey) {\n logger.info(\n colors.yellow(\n `Deleting existing API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n await deleteApiKey(client, { id: apiKeyWithTitle.id, logger });\n logger.info(\n colors.green(\n `Successfully deleted API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n } else if (apiKeyWithTitle) {\n // throw error if one exists but not configured to delete\n throw new Error(`API key already exists with title: \"${apiKeyTitle}\"`);\n }\n\n // Create the API key\n if (createNewApiKey) {\n logger.info(\n colors.magenta(\n `Creating API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n const { apiKey } = await createApiKey(client, {\n input: { title: apiKeyTitle, scopes },\n logger,\n });\n results.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n apiKey,\n });\n logger.info(\n colors.green(\n `Successfully created API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n } else {\n // Delete only\n results.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n apiKey: '',\n });\n }\n } catch (err) {\n logger.error(\n colors.red(\n `Failed to create API key in organization \"${role.organization.name}\"! - ${err.message}`,\n ),\n );\n errors.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n error: err.message,\n });\n }\n });\n logger.info(\n colors.green(\n `Successfully created ${results.length} API key${results.length === 1 ? '' : 's'}`,\n ),\n );\n\n if (errors.length > 0) {\n logger.error(\n colors.red(`Failed to create ${errors.length} API key${errors.length === 1 ? '' : 's'}!`),\n );\n }\n\n return { errors, apiKeys: results };\n}\n"],"mappings":"uTA+BA,eAAsB,EAA4B,CAChD,QACA,WACA,SACA,cACA,uBACA,uBAAuB,GACvB,kBAAkB,GAClB,eAAe,GAuBd,CAED,IAAM,EAAS,MAAM,EAAmC,EAAc,EAAE,CAAC,CAGzE,EAAO,KAAK,EAAO,QAAQ,uCAAuC,CAAC,CACnE,GAAM,CAAE,QAAO,eAAgB,MAAM,EAAU,EAAQ,CAAE,QAAO,WAAU,SAAQ,CAAC,CACnF,EAAO,KACL,EAAO,MACL,oCAAoC,EAAM,OAAO,OAAO,EAAM,SAAW,EAAI,GAAK,IAAI,GACvF,CACF,CAGD,IAAM,EAAgB,EAClB,EAAM,OACH,GACC,EAAK,aAAa,KAAO,GACzB,EAAK,aAAa,uBAAyB,EAC9C,CACD,EAGJ,EAAO,WAAW,CAChB,OAAQ,EACT,CAAC,CAGF,IAAM,EAA0B,EAAE,CAC5B,EAAgC,EAAE,CAgGxC,OA7FA,EAAO,KACL,EAAO,QAAQ,mCAAmC,EAAY,YAAY,EAAO,KAAK,IAAI,CAAC,GAAG,CAC/F,CAGD,MAAM,EAAU,EAAe,KAAO,IAAS,CAC7C,GAAI,CAEF,MAAM,EAAW,EAAQ,CAAE,OAAQ,EAAK,GAAI,QAAO,SAAQ,CAAC,CAG5D,EAAO,KACL,EAAO,QACL,uDAAuD,EAAK,aAAa,KAAK,iBAAiB,EAAY,IAC5G,CACF,CAGD,GAAM,CAAC,GAAmB,MAAM,EAAgB,EAAQ,CACtD,SACA,SAAU,CAAE,OAAQ,CAAC,EAAY,CAAE,CACpC,CAAC,CACF,GAAI,GAAmB,EACrB,EAAO,KACL,EAAO,OACL,iCAAiC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACtF,CACF,CACD,MAAM,EAAa,EAAQ,CAAE,GAAI,EAAgB,GAAI,SAAQ,CAAC,CAC9D,EAAO,KACL,EAAO,MACL,oCAAoC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACzF,CACF,SACQ,EAET,MAAU,MAAM,uCAAuC,EAAY,GAAG,CAIxE,GAAI,EAAiB,CACnB,EAAO,KACL,EAAO,QACL,wBAAwB,EAAK,aAAa,KAAK,iBAAiB,EAAY,IAC7E,CACF,CACD,GAAM,CAAE,UAAW,MAAM,EAAa,EAAQ,CAC5C,MAAO,CAAE,MAAO,EAAa,SAAQ,CACrC,SACD,CAAC,CACF,EAAQ,KAAK,CACX,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,SACD,CAAC,CACF,EAAO,KACL,EAAO,MACL,oCAAoC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACzF,CACF,MAGD,EAAQ,KAAK,CACX,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,OAAQ,GACT,CAAC,OAEG,EAAK,CACZ,EAAO,MACL,EAAO,IACL,6CAA6C,EAAK,aAAa,KAAK,OAAO,EAAI,UAChF,CACF,CACD,EAAO,KAAK,CACV,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,MAAO,EAAI,QACZ,CAAC,GAEJ,CACF,EAAO,KACL,EAAO,MACL,wBAAwB,EAAQ,OAAO,UAAU,EAAQ,SAAW,EAAI,GAAK,MAC9E,CACF,CAEG,EAAO,OAAS,GAClB,EAAO,MACL,EAAO,IAAI,oBAAoB,EAAO,OAAO,UAAU,EAAO,SAAW,EAAI,GAAK,IAAI,GAAG,CAC1F,CAGI,CAAE,SAAQ,QAAS,EAAS"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./downloadPrivacyRequestFiles-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./downloadPrivacyRequestFiles-B1rI73ok.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";import{RequestStatus as n}from"@transcend-io/privacy-types";async function r({auth:r,transcendUrl:i,folderPath:a,requestIds:o,statuses:s=[n.Approving,n.Downloadable],concurrency:c,createdAtBefore:l,createdAtAfter:u,updatedAtBefore:d,updatedAtAfter:f,approveAfterDownload:p}){t(this.process.exit),await e({transcendUrl:i,auth:r,folderPath:a,requestIds:o,statuses:s,concurrency:c,createdAtBefore:l,createdAtAfter:u,updatedAtBefore:d,updatedAtAfter:f,approveAfterDownload:p})}export{r as downloadFiles};
|
|
2
|
+
//# sourceMappingURL=impl-AgujmepV.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-AgujmepV.mjs","names":[],"sources":["../src/commands/request/download-files/impl.ts"],"sourcesContent":["import { RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { downloadPrivacyRequestFiles } from '../../../lib/requests/index.js';\n\nexport interface DownloadFilesCommandFlags {\n auth: string;\n sombraAuth?: string;\n concurrency: number;\n requestIds?: string[];\n statuses?: RequestStatus[];\n folderPath: string;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n approveAfterDownload: boolean;\n transcendUrl: string;\n}\n\nexport async function downloadFiles(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n folderPath,\n requestIds,\n statuses = [RequestStatus.Approving, RequestStatus.Downloadable],\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n approveAfterDownload,\n }: DownloadFilesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await downloadPrivacyRequestFiles({\n transcendUrl,\n auth,\n folderPath,\n requestIds,\n statuses,\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n approveAfterDownload,\n });\n}\n"],"mappings":"+KAqBA,eAAsB,EAEpB,CACE,OACA,eACA,aACA,aACA,WAAW,CAAC,EAAc,UAAW,EAAc,aAAa,CAChE,cACA,kBACA,iBACA,kBACA,iBACA,wBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAA4B,CAChC,eACA,OACA,aACA,aACA,WACA,cACA,kBACA,iBACA,kBACA,iBACA,uBACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./retryRequestDataSilos-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./retryRequestDataSilos-BPORd8Q4.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({auth:n,dataSiloId:r,actions:i,transcendUrl:a}){t(this.process.exit),await e({requestActions:i,transcendUrl:a,auth:n,dataSiloId:r})}export{n as retryRequestDataSilos};
|
|
2
|
+
//# sourceMappingURL=impl-B3-wUMSZ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-B3-wUMSZ.mjs","names":["retryRequestDataSilosHelper"],"sources":["../src/commands/request/system/retry-request-data-silos/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { retryRequestDataSilos as retryRequestDataSilosHelper } from '../../../../lib/requests/index.js';\n\nexport interface RetryRequestDataSilosCommandFlags {\n auth: string;\n dataSiloId: string;\n actions: RequestAction[];\n transcendUrl: string;\n}\n\nexport async function retryRequestDataSilos(\n this: LocalContext,\n { auth, dataSiloId, actions, transcendUrl }: RetryRequestDataSilosCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await retryRequestDataSilosHelper({\n requestActions: actions,\n transcendUrl,\n auth,\n dataSiloId,\n });\n}\n"],"mappings":"6GAaA,eAAsB,EAEpB,CAAE,OAAM,aAAY,UAAS,gBACd,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAMA,EAA4B,CAChC,eAAgB,EAChB,eACA,OACA,aACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{c as e}from"./constants-zytGRR9s.mjs";import{t}from"./generateCrossAccountApiKeys-FUo_wsSM.mjs";import{t as n}from"./done-input-validation-BcNBxhEs.mjs";import{writeFileSync as r}from"node:fs";async function i({email:i,password:a,apiKeyTitle:o,file:s,scopes:c,deleteExistingApiKey:l,createNewApiKey:u,parentOrganizationId:d,transcendUrl:f}){n(this.process.exit);let{errors:p,apiKeys:m}=await t({transcendUrl:f,password:a,email:i,parentOrganizationId:d,deleteExistingApiKey:l,createNewApiKey:u,apiKeyTitle:o,scopes:c.map(t=>e[t].name)});r(s,`${JSON.stringify(m,null,2)}\n`),p.length>0&&this.process.exit(1)}export{i as generateApiKeys};
|
|
2
|
+
//# sourceMappingURL=impl-B78f1YnE.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-B78f1YnE.mjs","names":[],"sources":["../src/commands/admin/generate-api-keys/impl.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\n\nimport { ScopeName } from '@transcend-io/privacy-types';\n\nimport { SCOPES_BY_TITLE } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { generateCrossAccountApiKeys } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\n\n// Command flag interface\nexport interface GenerateApiKeysCommandFlags {\n email: string;\n password: string;\n apiKeyTitle: string;\n file: string;\n scopes: string[];\n deleteExistingApiKey: boolean;\n createNewApiKey: boolean;\n parentOrganizationId?: string;\n transcendUrl: string;\n}\n\n// Command implementation\nexport async function generateApiKeys(\n this: LocalContext,\n {\n email,\n password,\n apiKeyTitle,\n file,\n scopes,\n deleteExistingApiKey,\n createNewApiKey,\n parentOrganizationId,\n transcendUrl,\n }: GenerateApiKeysCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const scopeNames = scopes.map((scopeTitle) => SCOPES_BY_TITLE[scopeTitle].name as ScopeName);\n\n // Upload privacy requests\n const { errors, apiKeys } = await generateCrossAccountApiKeys({\n transcendUrl,\n password,\n email,\n parentOrganizationId,\n deleteExistingApiKey,\n createNewApiKey,\n apiKeyTitle,\n scopes: scopeNames,\n });\n\n // Write to disk\n writeFileSync(file, `${JSON.stringify(apiKeys, null, 2)}\\n`);\n if (errors.length > 0) {\n this.process.exit(1);\n }\n}\n"],"mappings":"wMAuBA,eAAsB,EAEpB,CACE,QACA,WACA,cACA,OACA,SACA,uBACA,kBACA,uBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAKtC,GAAM,CAAE,SAAQ,WAAY,MAAM,EAA4B,CAC5D,eACA,WACA,QACA,uBACA,uBACA,kBACA,cACA,OAXiB,EAAO,IAAK,GAAe,EAAgB,GAAY,KAWtD,CACnB,CAAC,CAGF,EAAc,EAAM,GAAG,KAAK,UAAU,EAAS,KAAM,EAAE,CAAC,IAAI,CACxD,EAAO,OAAS,GAClB,KAAK,QAAQ,KAAK,EAAE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./approvePrivacyRequests-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./approvePrivacyRequests-CiJJar6N.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({auth:n,actions:r,origins:i,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l,transcendUrl:u,concurrency:d}){t(this.process.exit),await e({transcendUrl:u,requestActions:r,auth:n,requestOrigins:i,concurrency:d,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l})}export{n as approve};
|
|
2
|
+
//# sourceMappingURL=impl-BTTzSg7k.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BTTzSg7k.mjs","names":[],"sources":["../src/commands/request/approve/impl.ts"],"sourcesContent":["import { RequestAction, RequestOrigin } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { approvePrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface ApproveCommandFlags {\n auth: string;\n actions: RequestAction[];\n origins?: RequestOrigin[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function approve(\n this: LocalContext,\n {\n auth,\n actions,\n origins,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n transcendUrl,\n concurrency,\n }: ApproveCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await approvePrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n requestOrigins: origins,\n concurrency,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"8GAmBA,eAAsB,EAEpB,CACE,OACA,UACA,UACA,mBACA,kBACA,iBACA,kBACA,iBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAuB,CAC3B,eACA,eAAgB,EAChB,OACA,eAAgB,EAChB,cACA,mBACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{n as e}from"./constants-zytGRR9s.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{s as n}from"./writeCsv-C4pjXGsD.mjs";import{t as r}from"./pullAllDatapoints-Bbmky50p.mjs";import{t as i}from"./done-input-validation-BcNBxhEs.mjs";import{groupBy as a,uniq as o}from"lodash-es";import s from"colors";import{buildTranscendGraphQLClient as c}from"@transcend-io/sdk";async function l({auth:l,file:u,transcendUrl:d,dataSiloIds:f,includeAttributes:p,includeGuessedCategories:m,parentCategories:h,subCategories:g=[]}){i(this.process.exit);try{let e=await r(c(d,l),{dataSiloIds:f,includeGuessedCategories:m,parentCategories:h,includeAttributes:p,subCategories:g});t.info(s.magenta(`Writing datapoints to file "${u}"...`));let i=[];await n(u,e.map(e=>{let t={"Property ID":e.id,"Data Silo":e.dataSilo.title,Object:e.dataPoint.name,"Object Path":e.dataPoint.path.join(`.`),Property:e.name,"Property Description":e.description,"Data Categories":e.categories.map(e=>`${e.category}:${e.name}`).join(`, `),"Guessed Category":e.pendingCategoryGuesses?.[0]?`${e.pendingCategoryGuesses[0].category.category}:${e.pendingCategoryGuesses[0].category.name}`:``,"Processing Purposes":e.purposes.map(e=>`${e.purpose}:${e.name}`).join(`, `),...Object.entries(a(e.attributeValues||[],({attributeKey:e})=>e.name)).reduce((e,[t,n])=>(e[t]=n.map(e=>e.name).join(`,`),e),{})};return i=o([...i,...Object.keys(t)]),t}),i)}catch(e){t.error(s.red(`An error occurred syncing the datapoints: ${e.message}`)),this.process.exit(1)}t.info(s.green(`Successfully synced datapoints to disk at ${u}! View at ${e}`))}export{l as pullDatapoints};
|
|
2
|
+
//# sourceMappingURL=impl-BUjfG4eC.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BUjfG4eC.mjs","names":[],"sources":["../src/commands/inventory/pull-datapoints/impl.ts"],"sourcesContent":["import { DataCategoryType } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { uniq, groupBy } from 'lodash-es';\n\nimport { ADMIN_DASH_DATAPOINTS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { pullAllDatapoints } from '../../../lib/data-inventory/index.js';\nimport { writeLargeCsv } from '../../../lib/helpers/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface PullDatapointsCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n dataSiloIds?: string[];\n includeAttributes: boolean;\n includeGuessedCategories: boolean;\n parentCategories?: DataCategoryType[];\n subCategories?: string[];\n}\n\nexport async function pullDatapoints(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n dataSiloIds,\n includeAttributes,\n includeGuessedCategories,\n parentCategories,\n subCategories = [],\n }: PullDatapointsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n try {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const dataPoints = await pullAllDatapoints(client, {\n dataSiloIds,\n includeGuessedCategories,\n parentCategories,\n includeAttributes,\n subCategories, // TODO: https://transcend.height.app/T-40482 - do by name not ID\n });\n\n logger.info(colors.magenta(`Writing datapoints to file \"${file}\"...`));\n let headers: string[] = [];\n const inputs = dataPoints.map((point) => {\n const result = {\n 'Property ID': point.id,\n 'Data Silo': point.dataSilo.title,\n Object: point.dataPoint.name,\n 'Object Path': point.dataPoint.path.join('.'),\n Property: point.name,\n 'Property Description': point.description,\n 'Data Categories': point.categories\n .map((category) => `${category.category}:${category.name}`)\n .join(', '),\n 'Guessed Category': point.pendingCategoryGuesses?.[0]\n ? `${point.pendingCategoryGuesses![0]!.category.category}:${\n point.pendingCategoryGuesses![0]!.category.name\n }`\n : '',\n 'Processing Purposes': point.purposes\n .map((purpose) => `${purpose.purpose}:${purpose.name}`)\n .join(', '),\n ...Object.entries(\n groupBy(point.attributeValues || [], ({ attributeKey }) => attributeKey.name),\n ).reduce(\n (acc, [key, values]) => {\n acc[key] = values.map((value) => value.name).join(',');\n return acc;\n },\n {} as Record<string, string>,\n ),\n };\n headers = uniq([...headers, ...Object.keys(result)]);\n return result;\n });\n await writeLargeCsv(file, inputs, headers);\n } catch (err) {\n logger.error(colors.red(`An error occurred syncing the datapoints: ${err.message}`));\n this.process.exit(1);\n }\n\n // Indicate success\n logger.info(\n colors.green(\n `Successfully synced datapoints to disk at ${file}! View at ${ADMIN_DASH_DATAPOINTS}`,\n ),\n );\n}\n"],"mappings":"gXAuBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,cACA,oBACA,2BACA,mBACA,gBAAgB,EAAE,EAEL,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAI,CAIF,IAAM,EAAa,MAAM,EAFV,EAA4B,EAAc,EAER,CAAE,CACjD,cACA,2BACA,mBACA,oBACA,gBACD,CAAC,CAEF,EAAO,KAAK,EAAO,QAAQ,+BAA+B,EAAK,MAAM,CAAC,CACtE,IAAI,EAAoB,EAAE,CAiC1B,MAAM,EAAc,EAhCL,EAAW,IAAK,GAAU,CACvC,IAAM,EAAS,CACb,cAAe,EAAM,GACrB,YAAa,EAAM,SAAS,MAC5B,OAAQ,EAAM,UAAU,KACxB,cAAe,EAAM,UAAU,KAAK,KAAK,IAAI,CAC7C,SAAU,EAAM,KAChB,uBAAwB,EAAM,YAC9B,kBAAmB,EAAM,WACtB,IAAK,GAAa,GAAG,EAAS,SAAS,GAAG,EAAS,OAAO,CAC1D,KAAK,KAAK,CACb,mBAAoB,EAAM,yBAAyB,GAC/C,GAAG,EAAM,uBAAwB,GAAI,SAAS,SAAS,GACrD,EAAM,uBAAwB,GAAI,SAAS,OAE7C,GACJ,sBAAuB,EAAM,SAC1B,IAAK,GAAY,GAAG,EAAQ,QAAQ,GAAG,EAAQ,OAAO,CACtD,KAAK,KAAK,CACb,GAAG,OAAO,QACR,EAAQ,EAAM,iBAAmB,EAAE,EAAG,CAAE,kBAAmB,EAAa,KAAK,CAC9E,CAAC,QACC,EAAK,CAAC,EAAK,MACV,EAAI,GAAO,EAAO,IAAK,GAAU,EAAM,KAAK,CAAC,KAAK,IAAI,CAC/C,GAET,EAAE,CACH,CACF,CAED,MADA,GAAU,EAAK,CAAC,GAAG,EAAS,GAAG,OAAO,KAAK,EAAO,CAAC,CAAC,CAC7C,GAEuB,CAAE,EAAQ,OACnC,EAAK,CACZ,EAAO,MAAM,EAAO,IAAI,6CAA6C,EAAI,UAAU,CAAC,CACpF,KAAK,QAAQ,KAAK,EAAE,CAItB,EAAO,KACL,EAAO,MACL,6CAA6C,EAAK,YAAY,IAC/D,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./pullChunkedCustomSiloOutstandingIdentifiers-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./pullChunkedCustomSiloOutstandingIdentifiers-Bz1EGQOW.mjs";import{i as n,s as r}from"./writeCsv-C4pjXGsD.mjs";import{t as i}from"./done-input-validation-BcNBxhEs.mjs";import{uniq as a}from"lodash-es";import o from"colors";async function s({file:s,transcendUrl:c,auth:l,sombraAuth:u,dataSiloId:d,actions:f,pageLimit:p,skipRequestCount:m,chunkSize:h}){m&&e.info(o.yellow(`Skipping request count as requested. This may help speed up the call.`)),(Number.isNaN(h)||h<=0||h%p!==0)&&(e.error(o.red(`Invalid chunk size: "${h}". Must be a positive integer that is a multiple of ${p}.`)),this.process.exit(1)),i(this.process.exit);let{baseName:g,extension:_}=n(s),v=0;await t({transcendUrl:c,apiPageSize:p,savePageSize:h,onSave:async t=>{let n=`${g}-${v}${_}`;return e.info(o.blue(`Saving ${t.length} identifiers to file "${n}"`)),await r(n,t,a(t.map(e=>Object.keys(e)).flat())),e.info(o.green(`Successfully wrote ${t.length} identifiers to file "${n}"`)),v+=1,Promise.resolve()},actions:f,auth:l,sombraAuth:u,dataSiloId:d,skipRequestCount:m})}export{s as pullIdentifiers};
|
|
2
|
+
//# sourceMappingURL=impl-BW0nZQcf.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BW0nZQcf.mjs","names":[],"sources":["../src/commands/request/cron/pull-identifiers/impl.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport colors from 'colors';\nimport { uniq } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n CsvFormattedIdentifier,\n pullChunkedCustomSiloOutstandingIdentifiers,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\nimport { logger } from '../../../../logger.js';\n\nexport interface PullIdentifiersCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n actions: RequestAction[];\n pageLimit: number;\n skipRequestCount: boolean;\n chunkSize: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n {\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n actions,\n pageLimit,\n skipRequestCount,\n chunkSize,\n }: PullIdentifiersCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process.exit);\n\n const { baseName, extension } = parseFilePath(file);\n let fileCount = 0;\n\n const onSave = async (chunk: CsvFormattedIdentifier[]): Promise<void> => {\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n logger.info(colors.blue(`Saving ${chunk.length} identifiers to file \"${numberedFileName}\"`));\n\n const headers = uniq(chunk.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileName, chunk, headers);\n logger.info(\n colors.green(`Successfully wrote ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n fileCount += 1;\n return Promise.resolve();\n };\n\n // Pull down outstanding identifiers\n await pullChunkedCustomSiloOutstandingIdentifiers({\n transcendUrl,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n actions,\n auth,\n sombraAuth,\n dataSiloId,\n skipRequestCount,\n });\n}\n"],"mappings":"uRAyBA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,aACA,aACA,UACA,YACA,mBACA,aAEa,CACX,GACF,EAAO,KACL,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,EAAO,MACL,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,WAAU,aAAc,EAAc,EAAK,CAC/C,EAAY,EAgBhB,MAAM,EAA4C,CAChD,eACA,YAAa,EACb,aAAc,EACd,YAlBoB,IAAmD,CACvE,IAAM,EAAmB,GAAG,EAAS,GAAG,IAAY,IASpD,OARA,EAAO,KAAK,EAAO,KAAK,UAAU,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAAC,CAG5F,MAAM,EAAc,EAAkB,EADtB,EAAK,EAAM,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACR,CAAC,CACrD,EAAO,KACL,EAAO,MAAM,sBAAsB,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAC7F,CACD,GAAa,EACN,QAAQ,SAAS,EASxB,UACA,OACA,aACA,aACA,mBACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./logger-Bj782ZYD.mjs";import{a as t,r as n}from"./readTranscendYaml-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./logger-Bj782ZYD.mjs";import{a as t,r as n}from"./readTranscendYaml-CGb2UUyM.mjs";import{t as r}from"./listFiles-D2wMHnEr.mjs";import{t as i}from"./done-input-validation-BcNBxhEs.mjs";import{t as a}from"./dataFlowsToDataSilos-Ca2DtTsd.mjs";import{existsSync as o,lstatSync as s}from"node:fs";import{join as c}from"node:path";import l from"colors";import{buildTranscendGraphQLClient as u,fetchAndIndexCatalogs as d}from"@transcend-io/sdk";async function f({auth:f,dataFlowsYmlFolder:p,dataSilosYmlFolder:m,ignoreYmls:h=[],transcendUrl:g}){i(this.process.exit),(!o(p)||!s(p).isDirectory())&&(e.error(l.red(`Folder does not exist: "${p}"`)),this.process.exit(1)),(!o(m)||!s(m).isDirectory())&&(e.error(l.red(`Folder does not exist: "${m}"`)),this.process.exit(1));let{serviceToTitle:_,serviceToSupportedIntegration:v}=await d(u(g,f),{logger:e});r(p).forEach(r=>{let{"data-flows":i=[]}=n(c(p,r)),{adTechDataSilos:o,siteTechDataSilos:s}=a(i,{serviceToSupportedIntegration:v,serviceToTitle:_}),l=[...o,...s];e.log(`Total Services: ${l.length}`),e.log(`Ad Tech Services: ${o.length}`),e.log(`Site Tech Services: ${s.length}`),t(c(m,r),{"data-silos":h.includes(r)?[]:l})})}export{f as deriveDataSilosFromDataFlows};
|
|
2
|
+
//# sourceMappingURL=impl-BhNnDVWM.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BhNnDVWM.mjs","names":[],"sources":["../src/commands/inventory/derive-data-silos-from-data-flows/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';\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 DeriveDataSilosFromDataFlowsCommandFlags {\n auth: string;\n dataFlowsYmlFolder: string;\n dataSilosYmlFolder: string;\n ignoreYmls?: string[];\n transcendUrl: string;\n}\n\nexport async function deriveDataSilosFromDataFlows(\n this: LocalContext,\n {\n auth,\n dataFlowsYmlFolder,\n dataSilosYmlFolder,\n ignoreYmls = [],\n transcendUrl,\n }: DeriveDataSilosFromDataFlowsCommandFlags,\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 // Ensure folder is passed\n if (!existsSync(dataSilosYmlFolder) || !lstatSync(dataSilosYmlFolder).isDirectory()) {\n logger.error(colors.red(`Folder does not exist: \"${dataSilosYmlFolder}\"`));\n this.process.exit(1);\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 // List of each data flow yml file\n listFiles(dataFlowsYmlFolder).forEach((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 // combine and write to yml file\n const dataSilos = [...adTechDataSilos, ...siteTechDataSilos];\n logger.log(`Total Services: ${dataSilos.length}`);\n logger.log(`Ad Tech Services: ${adTechDataSilos.length}`);\n logger.log(`Site Tech Services: ${siteTechDataSilos.length}`);\n writeTranscendYaml(join(dataSilosYmlFolder, directory), {\n 'data-silos': ignoreYmls.includes(directory) ? [] : dataSilos,\n });\n });\n}\n"],"mappings":"0cAsBA,eAAsB,EAEpB,CACE,OACA,qBACA,qBACA,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,GAIlB,CAAC,EAAW,EAAmB,EAAI,CAAC,EAAU,EAAmB,CAAC,aAAa,IACjF,EAAO,MAAM,EAAO,IAAI,2BAA2B,EAAmB,GAAG,CAAC,CAC1E,KAAK,QAAQ,KAAK,EAAE,EAKtB,GAAM,CAAE,iBAAgB,iCAAkC,MAAM,EADjD,EAA4B,EAAc,EACmC,CAAE,CAC5F,SACD,CAAC,CAGF,EAAU,EAAmB,CAAC,QAAS,GAAc,CAEnD,GAAM,CAAE,aAAc,EAAY,EAAE,EAAK,EAAkB,EAAK,EAAoB,EAAU,CAAC,CAGzF,CAAE,kBAAiB,qBAAsB,EAC7C,EACA,CACE,gCACA,iBACD,CACF,CAGK,EAAY,CAAC,GAAG,EAAiB,GAAG,EAAkB,CAC5D,EAAO,IAAI,mBAAmB,EAAU,SAAS,CACjD,EAAO,IAAI,qBAAqB,EAAgB,SAAS,CACzD,EAAO,IAAI,uBAAuB,EAAkB,SAAS,CAC7D,EAAmB,EAAK,EAAoB,EAAU,CAAE,CACtD,aAAc,EAAW,SAAS,EAAU,CAAG,EAAE,CAAG,EACrD,CAAC,EACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BjCQSRLu.mjs","names":["fg"],"sources":["../src/commands/admin/find-text-in-folder/impl.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport colors from 'colors';\nimport fg from 'fast-glob';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { logger } from '../../../logger.js';\n\n/** CLI flags accepted by the `find-text-in-folder` command. */\nexport type FindTextInFolderCommandFlags = {\n /** The text string to search for */\n needle: string;\n /** Root directory to search */\n root: string;\n /** Comma-separated file extensions */\n exts: string;\n /** Skip parquet file scanning */\n noParquet: boolean;\n /** Max concurrent file scans */\n concurrency: number;\n /** Stop scanning each file after N bytes */\n maxBytes?: number;\n};\n\n/**\n * Streams through a file checking if it contains the needle (case-insensitive).\n *\n * @param filePath - Absolute path to the file to scan\n * @param needle - Lowercased needle as a Buffer\n * @param maxBytes - Optional byte limit per file\n * @returns Whether the file contains the needle\n */\nexport function fileContainsExactBytes(\n filePath: string,\n needle: Buffer,\n maxBytes?: number,\n): Promise<boolean> {\n return new Promise<boolean>((resolve, reject) => {\n const stream = fs.createReadStream(filePath);\n let carry = Buffer.alloc(0);\n const n = needle.length;\n let seen = 0;\n\n stream.on('data', (raw) => {\n let chunk = typeof raw === 'string' ? Buffer.from(raw) : raw;\n\n if (maxBytes) {\n const remaining = maxBytes - seen;\n if (remaining <= 0) {\n stream.destroy();\n resolve(false);\n return;\n }\n if (chunk.length > remaining) {\n chunk = chunk.subarray(0, remaining);\n }\n seen += chunk.length;\n }\n\n const buf = carry.length ? Buffer.concat([carry, chunk]) : chunk;\n const haystack = buf.toString('utf8').toLowerCase();\n if (haystack.includes(needle.toString('utf8'))) {\n stream.destroy();\n resolve(true);\n return;\n }\n\n // Keep last n-1 bytes to catch boundary matches\n if (n > 1) {\n carry = Buffer.from(buf.subarray(Math.max(0, buf.length - (n - 1))));\n } else {\n carry = Buffer.alloc(0);\n }\n });\n\n stream.on('error', reject);\n stream.on('close', () => resolve(false));\n stream.on('end', () => resolve(false));\n });\n}\n\n/**\n * Run async workers over items with bounded concurrency.\n *\n * @param items - Array of items to process\n * @param limit - Maximum concurrent workers\n * @param worker - Async function to run per item\n * @returns Resolves when all items are processed\n */\nasync function runWithConcurrency<T>(\n items: T[],\n limit: number,\n worker: (item: T) => Promise<void>,\n): Promise<void> {\n let idx = 0;\n const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const current = idx;\n idx += 1;\n if (current >= items.length) return;\n await worker(items[current]);\n }\n });\n await Promise.all(runners);\n}\n\n/**\n * Execute a DuckDB query and return stdout.\n *\n * @param duckdbPath - Path to the duckdb binary\n * @param sql - SQL query to execute\n * @returns The stdout output from duckdb\n */\nfunction duckdbQuery(duckdbPath: string, sql: string): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const child = spawn(duckdbPath, ['-noheader', '-batch', '-cmd', sql], {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (d) => {\n stdout += String(d);\n });\n child.stderr.on('data', (d) => {\n stderr += String(d);\n });\n\n child.on('error', reject);\n child.on('close', (code) => {\n if (code === 0) resolve(stdout);\n else reject(new Error(`duckdb exited ${code}: ${stderr}`));\n });\n });\n}\n\n/**\n * Get all VARCHAR/STRING column names from a parquet file.\n *\n * @param duckdbPath - Path to the duckdb binary\n * @param filePath - Absolute path to the parquet file\n * @returns Array of string column names\n */\nasync function duckdbGetParquetStringColumns(\n duckdbPath: string,\n filePath: string,\n): Promise<string[]> {\n const escaped = filePath.replace(/'/g, \"''\");\n const sql = [\n 'SELECT column_name',\n `FROM parquet_schema('${escaped}')`,\n \"WHERE lower(column_type) LIKE '%varchar%'\",\n \" OR lower(column_type) LIKE '%string%';\",\n ].join('\\n');\n\n const out = await duckdbQuery(duckdbPath, sql);\n return out\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n}\n\n/**\n * Check if any string column in a parquet file contains the needle value.\n *\n * @param duckdbPath - Path to the duckdb binary\n * @param filePath - Absolute path to the parquet file\n * @param needle - The string to search for (exact equality per column)\n * @returns Whether any row/column matches\n */\nasync function parquetFileHasExactString(\n duckdbPath: string,\n filePath: string,\n needle: string,\n): Promise<boolean> {\n const cols = await duckdbGetParquetStringColumns(duckdbPath, filePath);\n if (cols.length === 0) return false;\n\n const escaped = filePath.replace(/'/g, \"''\");\n const orChain = cols\n .map((c) => `\"${c.replace(/\"/g, '\"\"')}\" = '${needle.replace(/'/g, \"''\")}'`)\n .join(' OR ');\n\n const sql = [\n `SELECT 1 AS hit FROM read_parquet('${escaped}')`,\n `WHERE ${orChain}`,\n 'LIMIT 1;',\n ].join('\\n');\n\n const out = await duckdbQuery(duckdbPath, sql);\n return out.trim().length > 0;\n}\n\n/**\n * Entrypoint for the `admin find-text-in-folder` command.\n *\n * Searches a folder of files for a given text string. Useful for finding\n * a needle in a haystack across many large files (multi-GB CSVs, JSON\n * dumps, log archives). Files are streamed so memory stays flat.\n *\n * @param this - Bound CLI context\n * @param flags - CLI flags for the run\n */\nexport async function findTextInFolder(\n this: LocalContext,\n flags: FindTextInFolderCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { needle, root, exts, noParquet, concurrency, maxBytes } = flags;\n const rootAbs = path.resolve(root);\n\n const extSet = new Set(\n exts\n .split(',')\n .map((x) => x.trim().replace(/^\\./, '').toLowerCase())\n .filter(Boolean),\n );\n const patterns = Array.from(extSet).map((e) => `**/*.${e}`);\n\n logger.info(\n colors.green(`Searching for \"${needle}\" in ${rootAbs} (exts: ${[...extSet].join(', ')})`),\n );\n\n const normalFiles = await fg(patterns, {\n cwd: rootAbs,\n absolute: true,\n onlyFiles: true,\n followSymbolicLinks: false,\n suppressErrors: true,\n });\n\n const needleBuf = Buffer.from(needle.toLowerCase(), 'utf8');\n const hits: string[] = [];\n\n await runWithConcurrency(normalFiles, concurrency, async (file) => {\n try {\n const ok = await fileContainsExactBytes(file, needleBuf, maxBytes);\n if (ok) {\n hits.push(file);\n this.process.stdout.write(`${file}\\n`);\n }\n } catch {\n // ignore unreadable files\n }\n });\n\n if (!noParquet) {\n const parquetFiles = await fg(['**/*.parquet'], {\n cwd: rootAbs,\n absolute: true,\n onlyFiles: true,\n followSymbolicLinks: false,\n suppressErrors: true,\n });\n\n if (parquetFiles.length > 0) {\n logger.info(colors.green(`Scanning ${parquetFiles.length} parquet file(s) via DuckDB...`));\n\n await runWithConcurrency(\n parquetFiles,\n Math.max(2, Math.floor(concurrency / 4)),\n async (file) => {\n try {\n const ok = await parquetFileHasExactString('duckdb', file, needle);\n if (ok) {\n hits.push(file);\n this.process.stdout.write(`${file}\\n`);\n }\n } catch {\n // ignore parquet read issues\n }\n },\n );\n }\n }\n\n logger.info(colors.green(`Done. Found ${hits.length} matching file(s).`));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"impl-BjCQSRLu.mjs","names":["fg"],"sources":["../src/commands/admin/find-text-in-folder/impl.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport colors from 'colors';\nimport fg from 'fast-glob';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { logger } from '../../../logger.js';\n\n/** CLI flags accepted by the `find-text-in-folder` command. */\nexport type FindTextInFolderCommandFlags = {\n /** The text string to search for */\n needle: string;\n /** Root directory to search */\n root: string;\n /** Comma-separated file extensions */\n exts: string;\n /** Skip parquet file scanning */\n noParquet: boolean;\n /** Max concurrent file scans */\n concurrency: number;\n /** Stop scanning each file after N bytes */\n maxBytes?: number;\n};\n\n/**\n * Streams through a file checking if it contains the needle (case-insensitive).\n *\n * @param filePath - Absolute path to the file to scan\n * @param needle - Lowercased needle as a Buffer\n * @param maxBytes - Optional byte limit per file\n * @returns Whether the file contains the needle\n */\nexport function fileContainsExactBytes(\n filePath: string,\n needle: Buffer,\n maxBytes?: number,\n): Promise<boolean> {\n return new Promise<boolean>((resolve, reject) => {\n const stream = fs.createReadStream(filePath);\n let carry = Buffer.alloc(0);\n const n = needle.length;\n let seen = 0;\n\n stream.on('data', (raw) => {\n let chunk = typeof raw === 'string' ? Buffer.from(raw) : raw;\n\n if (maxBytes) {\n const remaining = maxBytes - seen;\n if (remaining <= 0) {\n stream.destroy();\n resolve(false);\n return;\n }\n if (chunk.length > remaining) {\n chunk = chunk.subarray(0, remaining);\n }\n seen += chunk.length;\n }\n\n const buf = carry.length ? Buffer.concat([carry, chunk]) : chunk;\n const haystack = buf.toString('utf8').toLowerCase();\n if (haystack.includes(needle.toString('utf8'))) {\n stream.destroy();\n resolve(true);\n return;\n }\n\n // Keep last n-1 bytes to catch boundary matches\n if (n > 1) {\n carry = Buffer.from(buf.subarray(Math.max(0, buf.length - (n - 1))));\n } else {\n carry = Buffer.alloc(0);\n }\n });\n\n stream.on('error', reject);\n stream.on('close', () => resolve(false));\n stream.on('end', () => resolve(false));\n });\n}\n\n/**\n * Run async workers over items with bounded concurrency.\n *\n * @param items - Array of items to process\n * @param limit - Maximum concurrent workers\n * @param worker - Async function to run per item\n * @returns Resolves when all items are processed\n */\nasync function runWithConcurrency<T>(\n items: T[],\n limit: number,\n worker: (item: T) => Promise<void>,\n): Promise<void> {\n let idx = 0;\n const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const current = idx;\n idx += 1;\n if (current >= items.length) return;\n await worker(items[current]);\n }\n });\n await Promise.all(runners);\n}\n\n/**\n * Execute a DuckDB query and return stdout.\n *\n * @param duckdbPath - Path to the duckdb binary\n * @param sql - SQL query to execute\n * @returns The stdout output from duckdb\n */\nfunction duckdbQuery(duckdbPath: string, sql: string): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const child = spawn(duckdbPath, ['-noheader', '-batch', '-cmd', sql], {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (d) => {\n stdout += String(d);\n });\n child.stderr.on('data', (d) => {\n stderr += String(d);\n });\n\n child.on('error', reject);\n child.on('close', (code) => {\n if (code === 0) resolve(stdout);\n else reject(new Error(`duckdb exited ${code}: ${stderr}`));\n });\n });\n}\n\n/**\n * Get all VARCHAR/STRING column names from a parquet file.\n *\n * @param duckdbPath - Path to the duckdb binary\n * @param filePath - Absolute path to the parquet file\n * @returns Array of string column names\n */\nasync function duckdbGetParquetStringColumns(\n duckdbPath: string,\n filePath: string,\n): Promise<string[]> {\n const escaped = filePath.replace(/'/g, \"''\");\n const sql = [\n 'SELECT column_name',\n `FROM parquet_schema('${escaped}')`,\n \"WHERE lower(column_type) LIKE '%varchar%'\",\n \" OR lower(column_type) LIKE '%string%';\",\n ].join('\\n');\n\n const out = await duckdbQuery(duckdbPath, sql);\n return out\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n}\n\n/**\n * Check if any string column in a parquet file contains the needle value.\n *\n * @param duckdbPath - Path to the duckdb binary\n * @param filePath - Absolute path to the parquet file\n * @param needle - The string to search for (exact equality per column)\n * @returns Whether any row/column matches\n */\nasync function parquetFileHasExactString(\n duckdbPath: string,\n filePath: string,\n needle: string,\n): Promise<boolean> {\n const cols = await duckdbGetParquetStringColumns(duckdbPath, filePath);\n if (cols.length === 0) return false;\n\n const escaped = filePath.replace(/'/g, \"''\");\n const orChain = cols\n .map((c) => `\"${c.replace(/\"/g, '\"\"')}\" = '${needle.replace(/'/g, \"''\")}'`)\n .join(' OR ');\n\n const sql = [\n `SELECT 1 AS hit FROM read_parquet('${escaped}')`,\n `WHERE ${orChain}`,\n 'LIMIT 1;',\n ].join('\\n');\n\n const out = await duckdbQuery(duckdbPath, sql);\n return out.trim().length > 0;\n}\n\n/**\n * Entrypoint for the `admin find-text-in-folder` command.\n *\n * Searches a folder of files for a given text string. Useful for finding\n * a needle in a haystack across many large files (multi-GB CSVs, JSON\n * dumps, log archives). Files are streamed so memory stays flat.\n *\n * @param this - Bound CLI context\n * @param flags - CLI flags for the run\n */\nexport async function findTextInFolder(\n this: LocalContext,\n flags: FindTextInFolderCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { needle, root, exts, noParquet, concurrency, maxBytes } = flags;\n const rootAbs = path.resolve(root);\n\n const extSet = new Set(\n exts\n .split(',')\n .map((x) => x.trim().replace(/^\\./, '').toLowerCase())\n .filter(Boolean),\n );\n const patterns = Array.from(extSet).map((e) => `**/*.${e}`);\n\n logger.info(\n colors.green(`Searching for \"${needle}\" in ${rootAbs} (exts: ${[...extSet].join(', ')})`),\n );\n\n const normalFiles = await fg(patterns, {\n cwd: rootAbs,\n absolute: true,\n onlyFiles: true,\n followSymbolicLinks: false,\n suppressErrors: true,\n });\n\n const needleBuf = Buffer.from(needle.toLowerCase(), 'utf8');\n const hits: string[] = [];\n\n await runWithConcurrency(normalFiles, concurrency, async (file) => {\n try {\n const ok = await fileContainsExactBytes(file, needleBuf, maxBytes);\n if (ok) {\n hits.push(file);\n this.process.stdout.write(`${file}\\n`);\n }\n } catch {\n // ignore unreadable files\n }\n });\n\n if (!noParquet) {\n const parquetFiles = await fg(['**/*.parquet'], {\n cwd: rootAbs,\n absolute: true,\n onlyFiles: true,\n followSymbolicLinks: false,\n suppressErrors: true,\n });\n\n if (parquetFiles.length > 0) {\n logger.info(colors.green(`Scanning ${parquetFiles.length} parquet file(s) via DuckDB...`));\n\n await runWithConcurrency(\n parquetFiles,\n Math.max(2, Math.floor(concurrency / 4)),\n async (file) => {\n try {\n const ok = await parquetFileHasExactString('duckdb', file, needle);\n if (ok) {\n hits.push(file);\n this.process.stdout.write(`${file}\\n`);\n }\n } catch {\n // ignore parquet read issues\n }\n },\n );\n }\n }\n\n logger.info(colors.green(`Done. Found ${hits.length} matching file(s).`));\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./streamPrivacyRequestsToCsv-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./streamPrivacyRequestsToCsv-B0GqwHNz.mjs";import{t as n}from"./done-input-validation-BcNBxhEs.mjs";import r from"colors";async function i({auth:i,transcendUrl:a,file:o,pageLimit:s,concurrency:c,actions:l,sombraAuth:u,skipRequestIdentifiers:d,statuses:f,createdAtBefore:p,createdAtAfter:m,updatedAtBefore:h,updatedAtAfter:g,showTests:_}){n(this.process.exit);let{filePaths:v,totalCount:y}=await t({transcendUrl:a,concurrency:c,pageLimit:s,actions:l,statuses:f,auth:i,sombraAuth:u,skipRequestIdentifiers:d,createdAtBefore:p,createdAtAfter:m,updatedAtBefore:h,updatedAtAfter:g,isTest:_,file:o});e.info(r.green(`Successfully wrote ${y} requests to ${v.length} file(s): ${v.join(`, `)}`))}export{i as _export};
|
|
2
|
+
//# sourceMappingURL=impl-Bjf36di3.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-Bjf36di3.mjs","names":[],"sources":["../src/commands/request/export/impl.ts"],"sourcesContent":["import type { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { streamPrivacyRequestsToCsv } from '../../../lib/requests/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface ExportCommandFlags {\n auth: string;\n sombraAuth?: string;\n actions?: RequestAction[];\n statuses?: RequestStatus[];\n transcendUrl: string;\n file: string;\n concurrency: number;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n showTests?: boolean;\n skipRequestIdentifiers?: boolean;\n pageLimit: number;\n}\n\n// `export` is a reserved keyword, so we need to prefix it with an underscore\n// eslint-disable-next-line no-underscore-dangle\nexport async function _export(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n file,\n pageLimit,\n concurrency,\n actions,\n sombraAuth,\n skipRequestIdentifiers,\n statuses,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n showTests,\n }: ExportCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { filePaths, totalCount } = await streamPrivacyRequestsToCsv({\n transcendUrl,\n concurrency,\n pageLimit,\n actions,\n statuses,\n auth,\n sombraAuth,\n skipRequestIdentifiers,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isTest: showTests,\n file,\n });\n\n logger.info(\n colors.green(\n `Successfully wrote ${totalCount} requests to ` +\n `${filePaths.length} file(s): ${filePaths.join(', ')}`,\n ),\n );\n}\n"],"mappings":"kLA2BA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,YACA,cACA,UACA,aACA,yBACA,WACA,kBACA,iBACA,kBACA,iBACA,aAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,cAAe,MAAM,EAA2B,CACjE,eACA,cACA,YACA,UACA,WACA,OACA,aACA,yBACA,kBACA,iBACA,kBACA,iBACA,OAAQ,EACR,OACD,CAAC,CAEF,EAAO,KACL,EAAO,MACL,sBAAsB,EAAW,eAC5B,EAAU,OAAO,YAAY,EAAU,KAAK,KAAK,GACvD,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./pushCronIdentifiersFromCsv-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./pushCronIdentifiersFromCsv-DUZv9xss.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o}){t(this.process.exit),await e({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o})}export{n as markIdentifiersCompleted};
|
|
2
|
+
//# sourceMappingURL=impl-BnME6ASm.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BnME6ASm.mjs","names":[],"sources":["../src/commands/request/cron/mark-identifiers-completed/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushCronIdentifiersFromCsv } from '../../../../lib/cron/index.js';\n\nexport interface MarkIdentifiersCompletedCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n}\n\nexport async function markIdentifiersCompleted(\n this: LocalContext,\n { file, transcendUrl, auth, sombraAuth, dataSiloId }: MarkIdentifiersCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pushCronIdentifiersFromCsv({\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n });\n}\n"],"mappings":"kHAYA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,aAAY,cACzB,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAA2B,CAC/B,OACA,eACA,OACA,aACA,aACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./readCsv-C4TyEs-r.mjs";import{t as n}from"./markRequestDataSiloIdsCompleted-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./readCsv-C4TyEs-r.mjs";import{t as n}from"./markRequestDataSiloIdsCompleted-_VvJoVTL.mjs";import{t as r}from"./done-input-validation-BcNBxhEs.mjs";import i from"colors";import*as a from"io-ts";const o=a.type({"Request Id":a.string});async function s({auth:a,dataSiloId:s,file:c,transcendUrl:l}){r(this.process.exit),e.info(i.magenta(`Reading "${c}" from disk`)),await n({requestIds:t(c,o).map(e=>e[`Request Id`]),transcendUrl:l,auth:a,dataSiloId:s})}export{s as markRequestDataSilosCompleted};
|
|
2
|
+
//# sourceMappingURL=impl-BwKFPCHn.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BwKFPCHn.mjs","names":[],"sources":["../src/commands/request/system/mark-request-data-silos-completed/impl.ts"],"sourcesContent":["import colors from 'colors';\nimport * as t from 'io-ts';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { markRequestDataSiloIdsCompleted } from '../../../../lib/cron/index.js';\nimport { readCsv } from '../../../../lib/requests/index.js';\nimport { logger } from '../../../../logger.js';\n\nconst RequestIdRow = t.type({\n 'Request Id': t.string,\n});\n\nexport interface MarkRequestDataSilosCompletedCommandFlags {\n auth: string;\n dataSiloId: string;\n file: string;\n transcendUrl: string;\n}\n\nexport async function markRequestDataSilosCompleted(\n this: LocalContext,\n { auth, dataSiloId, file, transcendUrl }: MarkRequestDataSilosCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, RequestIdRow);\n\n await markRequestDataSiloIdsCompleted({\n requestIds: activeResults.map((request) => request['Request Id']),\n transcendUrl,\n auth,\n dataSiloId,\n });\n}\n"],"mappings":"0PASA,MAAM,EAAe,EAAE,KAAK,CAC1B,aAAc,EAAE,OACjB,CAAC,CASF,eAAsB,EAEpB,CAAE,OAAM,aAAY,OAAM,gBACX,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAG1D,MAAM,EAAgC,CACpC,WAHoB,EAAQ,EAAM,EAGT,CAAC,IAAK,GAAY,EAAQ,cAAc,CACjE,eACA,OACA,aACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./logger-Bj782ZYD.mjs";import{E as t}from"./codecs-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./logger-Bj782ZYD.mjs";import{E as t}from"./codecs-Dnq-rEcB.mjs";import{a as n}from"./readTranscendYaml-CGb2UUyM.mjs";import{t as r}from"./done-input-validation-BcNBxhEs.mjs";import{ConsentTrackerStatus as i,DataFlowScope as a}from"@transcend-io/privacy-types";import{decodeCodec as o}from"@transcend-io/type-utils";import{existsSync as s,readFileSync as c}from"node:fs";import l from"colors";import*as u from"io-ts";function d({file:d,output:f}){r(this.process.exit),s(d)||(e.error(l.red(`File does not exist: --file="${d}"`)),this.process.exit(1));let p=o(u.array(t),c(d,`utf-8`)),m=[],h=[];p.forEach(e=>{e.dataFlows.filter(({type:e})=>e!==a.CSP).forEach(e=>{m.push({value:e.value,type:e.type,status:i.Live,trackingPurposes:e.trackingPurposes})}),e.cookies.forEach(e=>{h.push({name:e.name,status:i.Live,trackingPurposes:e.trackingPurposes})})}),n(f,{"data-flows":m,cookies:h}),e.info(l.green(`Successfully wrote ${m.length} data flows and ${h.length} cookies to file "${f}"`))}export{d as consentManagerServiceJsonToYml};
|
|
2
|
+
//# sourceMappingURL=impl-C08anQRz.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-C08anQRz.mjs","names":[],"sources":["../src/commands/inventory/consent-manager-service-json-to-yml/impl.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\n\nimport { ConsentTrackerStatus, DataFlowScope } from '@transcend-io/privacy-types';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport colors from 'colors';\nimport * as t from 'io-ts';\n\nimport { ConsentManagerServiceMetadata, CookieInput, DataFlowInput } from '../../../codecs.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { writeTranscendYaml } from '../../../lib/readTranscendYaml.js';\nimport { logger } from '../../../logger.js';\n\nexport interface ConsentManagerServiceJsonToYmlCommandFlags {\n file: string;\n output: string;\n}\n\nexport function consentManagerServiceJsonToYml(\n this: LocalContext,\n { file, output }: ConsentManagerServiceJsonToYmlCommandFlags,\n): void {\n doneInputValidation(this.process.exit);\n\n // Ensure files exist\n if (!existsSync(file)) {\n logger.error(colors.red(`File does not exist: --file=\"${file}\"`));\n this.process.exit(1);\n }\n\n // Read in each consent manager configuration\n const services = decodeCodec(t.array(ConsentManagerServiceMetadata), readFileSync(file, 'utf-8'));\n\n // Create data flows and cookie configurations\n const dataFlows: DataFlowInput[] = [];\n const cookies: CookieInput[] = [];\n services.forEach((service) => {\n service.dataFlows\n .filter(({ type }) => type !== DataFlowScope.CSP)\n .forEach((dataFlow) => {\n dataFlows.push({\n value: dataFlow.value,\n type: dataFlow.type,\n status: ConsentTrackerStatus.Live,\n trackingPurposes: dataFlow.trackingPurposes,\n });\n });\n\n service.cookies.forEach((cookie) => {\n cookies.push({\n name: cookie.name,\n status: ConsentTrackerStatus.Live,\n trackingPurposes: cookie.trackingPurposes,\n });\n });\n });\n\n // write to disk\n writeTranscendYaml(output, {\n 'data-flows': dataFlows,\n cookies,\n });\n\n logger.info(\n colors.green(\n `Successfully wrote ${dataFlows.length} data flows and ${cookies.length} cookies to file \"${output}\"`,\n ),\n );\n}\n"],"mappings":"obAkBA,SAAgB,EAEd,CAAE,OAAM,UACF,CACN,EAAoB,KAAK,QAAQ,KAAK,CAGjC,EAAW,EAAK,GACnB,EAAO,MAAM,EAAO,IAAI,gCAAgC,EAAK,GAAG,CAAC,CACjE,KAAK,QAAQ,KAAK,EAAE,EAItB,IAAM,EAAW,EAAY,EAAE,MAAM,EAA8B,CAAE,EAAa,EAAM,QAAQ,CAAC,CAG3F,EAA6B,EAAE,CAC/B,EAAyB,EAAE,CACjC,EAAS,QAAS,GAAY,CAC5B,EAAQ,UACL,QAAQ,CAAE,UAAW,IAAS,EAAc,IAAI,CAChD,QAAS,GAAa,CACrB,EAAU,KAAK,CACb,MAAO,EAAS,MAChB,KAAM,EAAS,KACf,OAAQ,EAAqB,KAC7B,iBAAkB,EAAS,iBAC5B,CAAC,EACF,CAEJ,EAAQ,QAAQ,QAAS,GAAW,CAClC,EAAQ,KAAK,CACX,KAAM,EAAO,KACb,OAAQ,EAAqB,KAC7B,iBAAkB,EAAO,iBAC1B,CAAC,EACF,EACF,CAGF,EAAmB,EAAQ,CACzB,aAAc,EACd,UACD,CAAC,CAEF,EAAO,KACL,EAAO,MACL,sBAAsB,EAAU,OAAO,kBAAkB,EAAQ,OAAO,oBAAoB,EAAO,GACpG,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./bulkRetryEnrichers-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./bulkRetryEnrichers-C1TsWVFy.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({auth:n,enricherId:r,actions:i,requestEnricherStatuses:a,requestIds:o,createdAtBefore:s,createdAtAfter:c,updatedAtBefore:l,updatedAtAfter:u,concurrency:d,transcendUrl:f}){t(this.process.exit),await e({auth:n,enricherId:r,requestActions:i,requestEnricherStatuses:a,requestIds:o,createdAtBefore:s?new Date(s):void 0,createdAtAfter:c?new Date(c):void 0,updatedAtBefore:l?new Date(l):void 0,updatedAtAfter:u?new Date(u):void 0,concurrency:d,transcendUrl:f})}export{n as enricherRestart};
|
|
2
|
+
//# sourceMappingURL=impl-C2to-OHX.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-C2to-OHX.mjs","names":[],"sources":["../src/commands/request/enricher-restart/impl.ts"],"sourcesContent":["import type { RequestAction, RequestEnricherStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { bulkRetryEnrichers } from '../../../lib/requests/index.js';\n\nexport interface EnricherRestartCommandFlags {\n auth: string;\n enricherId: string;\n actions?: RequestAction[];\n requestEnricherStatuses?: RequestEnricherStatus[];\n transcendUrl: string;\n concurrency: number;\n requestIds?: string[];\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n}\n\nexport async function enricherRestart(\n this: LocalContext,\n {\n auth,\n enricherId,\n actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n }: EnricherRestartCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await bulkRetryEnrichers({\n auth,\n enricherId,\n requestActions: actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n updatedAtBefore: updatedAtBefore ? new Date(updatedAtBefore) : undefined,\n updatedAtAfter: updatedAtAfter ? new Date(updatedAtAfter) : undefined,\n concurrency,\n transcendUrl,\n });\n}\n"],"mappings":"0GAoBA,eAAsB,EAEpB,CACE,OACA,aACA,UACA,0BACA,aACA,kBACA,iBACA,kBACA,iBACA,cACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAmB,CACvB,OACA,aACA,eAAgB,EAChB,0BACA,aACA,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,cACA,eACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./pushManualEnrichmentIdentifiersFromCsv-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./pushManualEnrichmentIdentifiersFromCsv-QnSf70JE.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({auth:n,transcendUrl:r,file:i,enricherId:a,concurrency:o,markSilent:s,sombraAuth:c}){t(this.process.exit),await e({file:i,transcendUrl:r,enricherId:a,concurrency:o,markSilent:s,auth:n,sombraAuth:c})}export{n as pushIdentifiers};
|
|
2
|
+
//# sourceMappingURL=impl-C9By5dWV.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-C9By5dWV.mjs","names":[],"sources":["../src/commands/request/preflight/push-identifiers/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushManualEnrichmentIdentifiersFromCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PushIdentifiersCommandFlags {\n auth: string;\n enricherId: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n markSilent: boolean;\n concurrency: number;\n}\n\nexport async function pushIdentifiers(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n file,\n enricherId,\n concurrency,\n markSilent,\n sombraAuth,\n }: PushIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pushManualEnrichmentIdentifiersFromCsv({\n file,\n transcendUrl,\n enricherId,\n concurrency,\n markSilent,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"8HAcA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,aACA,cACA,aACA,cAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAuC,CAC3C,OACA,eACA,aACA,cACA,aACA,OACA,aACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./readCsv-C4TyEs-r.mjs";import{r as t}from"./uploadConsents-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./readCsv-C4TyEs-r.mjs";import{r as t}from"./uploadConsents-DA8DR8pb.mjs";import{t as n}from"./done-input-validation-BcNBxhEs.mjs";import*as r from"io-ts";const i=r.intersection([r.type({userId:r.string,timestamp:r.string}),r.partial({confirmed:r.union([r.literal(`true`),r.literal(`false`)]),updated:r.union([r.literal(`true`),r.literal(`false`)]),prompted:r.union([r.literal(`true`),r.literal(`false`)]),metadata:r.string,usp:r.union([r.string,r.null]),gpp:r.union([r.string,r.null]),purposes:r.string})]);async function a({base64EncryptionKey:r,base64SigningKey:a,partition:o,file:s,consentUrl:c,concurrency:l}){n(this.process.exit),await t({base64EncryptionKey:r,base64SigningKey:a,preferences:e(s,i),partition:o,concurrency:l,transcendUrl:c})}export{a as uploadConsentPreferences};
|
|
2
|
+
//# sourceMappingURL=impl-CA4HCgZH.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-CA4HCgZH.mjs","names":[],"sources":["../src/lib/consent-manager/types.ts","../src/commands/consent/upload-consent-preferences/impl.ts"],"sourcesContent":["import * as t from 'io-ts';\n\nexport const ConsentPreferenceUpload = t.intersection([\n t.type({\n /** User ID */\n userId: t.string,\n /** Has the consent been updated (including no-change confirmation) since default resolution */\n timestamp: t.string,\n }),\n t.partial({\n /** Was tracking consent confirmed by the user? If this is false, the consent was resolved from defaults & is not yet confirmed */\n confirmed: t.union([t.literal('true'), t.literal('false')]),\n /**\n * Has the consent been updated (including no-change confirmation) since default resolution\n */\n updated: t.union([t.literal('true'), t.literal('false')]),\n /**\n * Whether or not the UI has been shown to the end-user (undefined in older versions of airgap.js)\n */\n prompted: t.union([t.literal('true'), t.literal('false')]),\n /** Consent metadata */\n metadata: t.string,\n /** US Privacy (USP) String */\n usp: t.union([t.string, t.null]),\n /** IAB GPP String */\n gpp: t.union([t.string, t.null]),\n /**\n * Purpose map\n * This is a stringified JSON object with keys as purpose names and values as booleans or 'Auto'\n */\n purposes: t.string,\n }),\n]);\n\n/** Type override */\nexport type ConsentPreferenceUpload = t.TypeOf<typeof ConsentPreferenceUpload>;\n","import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { ConsentPreferenceUpload } from '../../../lib/consent-manager/types.js';\nimport { uploadConsents } from '../../../lib/consent-manager/uploadConsents.js';\nimport { readCsv } from '../../../lib/requests/index.js';\n\nexport interface UploadConsentPreferencesCommandFlags {\n base64EncryptionKey: string;\n base64SigningKey: string;\n partition: string;\n file: string;\n consentUrl: string;\n concurrency: number;\n}\n\nexport async function uploadConsentPreferences(\n this: LocalContext,\n {\n base64EncryptionKey,\n base64SigningKey,\n partition,\n file,\n consentUrl,\n concurrency,\n }: UploadConsentPreferencesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Load in preferences from csv\n const preferences = readCsv(file, ConsentPreferenceUpload);\n\n // Upload cookies\n await uploadConsents({\n base64EncryptionKey,\n base64SigningKey,\n preferences,\n partition,\n concurrency,\n transcendUrl: consentUrl,\n });\n}\n"],"mappings":"8KAEA,MAAa,EAA0B,EAAE,aAAa,CACpD,EAAE,KAAK,CAEL,OAAQ,EAAE,OAEV,UAAW,EAAE,OACd,CAAC,CACF,EAAE,QAAQ,CAER,UAAW,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAI3D,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAIzD,SAAU,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAE1D,SAAU,EAAE,OAEZ,IAAK,EAAE,MAAM,CAAC,EAAE,OAAQ,EAAE,KAAK,CAAC,CAEhC,IAAK,EAAE,MAAM,CAAC,EAAE,OAAQ,EAAE,KAAK,CAAC,CAKhC,SAAU,EAAE,OACb,CAAC,CACH,CAAC,CCjBF,eAAsB,EAEpB,CACE,sBACA,mBACA,YACA,OACA,aACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAMtC,MAAM,EAAe,CACnB,sBACA,mBACA,YANkB,EAAQ,EAAM,EAMrB,CACX,YACA,cACA,aAAc,EACf,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./pullManualEnrichmentIdentifiersToCsv-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./pullManualEnrichmentIdentifiersToCsv-BWxxJ2Qi.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({auth:n,transcendUrl:r,file:i,concurrency:a,actions:o,sombraAuth:s}){t(this.process.exit),await e({file:i,transcendUrl:r,concurrency:a,requestActions:o,auth:n,sombraAuth:s})}export{n as pullIdentifiers};
|
|
2
|
+
//# sourceMappingURL=impl-CCw9Nk9s.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-CCw9Nk9s.mjs","names":[],"sources":["../src/commands/request/preflight/pull-identifiers/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pullManualEnrichmentIdentifiersToCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n auth: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n actions?: RequestAction[];\n concurrency: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n { auth, transcendUrl, file, concurrency, actions, sombraAuth }: PullIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pullManualEnrichmentIdentifiersToCsv({\n file,\n transcendUrl,\n concurrency,\n requestActions: actions,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"4HAeA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,cAAa,UAAS,cACnC,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAqC,CACzC,OACA,eACA,cACA,eAAgB,EAChB,OACA,aACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./pullChunkedCustomSiloOutstandingIdentifiers-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./logger-Bj782ZYD.mjs";import{t}from"./pullChunkedCustomSiloOutstandingIdentifiers-Bz1EGQOW.mjs";import{i as n,s as r}from"./writeCsv-C4pjXGsD.mjs";import{t as i}from"./done-input-validation-BcNBxhEs.mjs";import{chunk as a,uniq as o}from"lodash-es";import s from"colors";import{buildTranscendGraphQLClient as c,fetchRequestFilesForRequest as l}from"@transcend-io/sdk";import{map as u}from"@transcend-io/utils";async function d({file:d,fileTarget:f,transcendUrl:p,auth:m,sombraAuth:h,cronDataSiloId:g,targetDataSiloId:_,actions:v,skipRequestCount:y,pageLimit:b,chunkSize:x}){y&&e.info(s.yellow(`Skipping request count as requested. This may help speed up the call.`)),(Number.isNaN(x)||x<=0||x%b!==0)&&(e.error(s.red(`Invalid chunk size: "${x}". Must be a positive integer that is a multiple of ${b}.`)),this.process.exit(1)),i(this.process.exit);let S=c(p,m),{baseName:C,extension:w}=n(d),{baseName:T,extension:E}=n(f),D=0,O=0,k=0;await t({dataSiloId:g,auth:m,sombraAuth:h,actions:v,apiPageSize:b,savePageSize:x,onSave:async t=>{D+=t.length;let n=await u(a(o(t.map(e=>e.requestId)),b),async t=>(e.info(s.magenta(`Fetching target identifiers for ${t.length} requests`)),(await l(S,{logger:e,pageSize:b*2,filterBy:{requestIds:t,dataSiloIds:[_]}})).map(({fileName:e,remoteId:t})=>{if(!t)throw Error(`Failed to find remoteId for ${e}`);return{RecordId:t,Object:e.replace(`.json`,``).split(`/`).pop()?.replace(` Information`,``),Comment:`Customer data deletion request submitted via transcend.io`}})),{concurrency:1});O+=n.flat().length;let i=o(t.map(e=>Object.keys(e)).flat()),c=`${C}-${k}${w}`,p=`${T}-${k}${E}`;await r(c,t,i),e.info(s.green(`Successfully wrote ${t.length} identifiers to file "${d}"`));let m=n.flat();await r(p,m,o(m.map(e=>Object.keys(e)).flat())),e.info(s.green(`Successfully wrote ${m.length} identifiers to file "${f}"`)),e.info(s.blue(`Processed chunk of ${a.length} identifiers, found ${m.length} target identifiers`)),k+=1},transcendUrl:p,skipRequestCount:y}),e.info(s.green(`Successfully wrote ${D} identifiers to file "${d}"`)),e.info(s.green(`Successfully wrote ${O} identifiers to file "${f}"`))}export{d as pullProfiles};
|
|
2
|
+
//# sourceMappingURL=impl-CEhKFcOU.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-CEhKFcOU.mjs","names":[],"sources":["../src/commands/request/cron/pull-profiles/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, fetchRequestFilesForRequest } from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport { uniq, chunk } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n pullChunkedCustomSiloOutstandingIdentifiers,\n type CsvFormattedIdentifier,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\nimport { logger } from '../../../../logger.js';\n\nexport interface PullProfilesCommandFlags {\n file: string;\n fileTarget: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n cronDataSiloId: string;\n targetDataSiloId: string;\n actions: RequestAction[];\n skipRequestCount: boolean;\n pageLimit: number;\n chunkSize: number;\n}\n\nexport async function pullProfiles(\n this: LocalContext,\n {\n file,\n fileTarget,\n transcendUrl,\n auth,\n sombraAuth,\n cronDataSiloId,\n targetDataSiloId,\n actions,\n skipRequestCount,\n pageLimit,\n chunkSize,\n }: PullProfilesCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process.exit);\n\n // Create GraphQL client to connect to Transcend backend\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n const { baseName, extension } = parseFilePath(file);\n const { baseName: baseNameTarget, extension: extensionTarget } = parseFilePath(fileTarget);\n\n let allIdentifiersCount = 0;\n let allTargetIdentifiersCount = 0;\n let fileCount = 0;\n // Create onSave callback to handle chunked processing\n const onSave = async (chunkToSave: CsvFormattedIdentifier[]): Promise<void> => {\n // Add to all identifiers\n allIdentifiersCount += chunkToSave.length;\n\n // Get unique request IDs from this chunk\n const requestIds = chunkToSave.map((d) => d.requestId as string);\n const uniqueRequestIds = uniq(requestIds);\n\n // Pull down target identifiers for this chunk\n const chunkedRequestIds = chunk(uniqueRequestIds, pageLimit);\n const results = await map(\n chunkedRequestIds,\n async (requestIds) => {\n logger.info(\n colors.magenta(`Fetching target identifiers for ${requestIds.length} requests`),\n );\n const results = await fetchRequestFilesForRequest(client, {\n logger,\n pageSize: pageLimit * 2,\n filterBy: {\n requestIds,\n dataSiloIds: [targetDataSiloId],\n },\n });\n return results.map(({ fileName, remoteId }) => {\n if (!remoteId) {\n throw new Error(`Failed to find remoteId for ${fileName}`);\n }\n return {\n RecordId: remoteId,\n Object: fileName.replace('.json', '').split('/').pop()?.replace(' Information', ''),\n Comment: 'Customer data deletion request submitted via transcend.io',\n };\n });\n },\n // We are grabbing all the request files for the 'pageLimit' # of requests at a time\n {\n concurrency: 1,\n },\n );\n\n allTargetIdentifiersCount += results.flat().length;\n\n // Write the identifiers and target identifiers to CSV\n const headers = uniq(chunkToSave.map((d) => Object.keys(d)).flat());\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n const numberedFileNameTarget = `${baseNameTarget}-${fileCount}${extensionTarget}`;\n await writeLargeCsv(numberedFileName, chunkToSave, headers);\n logger.info(\n colors.green(`Successfully wrote ${chunkToSave.length} identifiers to file \"${file}\"`),\n );\n\n const targetIdentifiers = results.flat();\n const headers2 = uniq(targetIdentifiers.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileNameTarget, targetIdentifiers, headers2);\n logger.info(\n colors.green(\n `Successfully wrote ${targetIdentifiers.length} identifiers to file \"${fileTarget}\"`,\n ),\n );\n\n logger.info(\n colors.blue(\n `Processed chunk of ${chunk.length} identifiers, found ${targetIdentifiers.length} target identifiers`,\n ),\n );\n fileCount += 1;\n };\n\n // Pull down outstanding identifiers using the new chunked function\n await pullChunkedCustomSiloOutstandingIdentifiers({\n dataSiloId: cronDataSiloId,\n auth,\n sombraAuth,\n actions,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n transcendUrl,\n skipRequestCount,\n });\n\n logger.info(\n colors.green(`Successfully wrote ${allIdentifiersCount} identifiers to file \"${file}\"`),\n );\n logger.info(\n colors.green(\n `Successfully wrote ${allTargetIdentifiersCount} identifiers to file \"${fileTarget}\"`,\n ),\n );\n}\n"],"mappings":"6aA6BA,eAAsB,EAEpB,CACE,OACA,aACA,eACA,OACA,aACA,iBACA,mBACA,UACA,mBACA,YACA,aAEa,CACX,GACF,EAAO,KACL,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,EAAO,MACL,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,KAAK,CAGtC,IAAM,EAAS,EAA4B,EAAc,EAAK,CACxD,CAAE,WAAU,aAAc,EAAc,EAAK,CAC7C,CAAE,SAAU,EAAgB,UAAW,GAAoB,EAAc,EAAW,CAEtF,EAAsB,EACtB,EAA4B,EAC5B,EAAY,EAwEhB,MAAM,EAA4C,CAChD,WAAY,EACZ,OACA,aACA,UACA,YAAa,EACb,aAAc,EACd,YA7EoB,IAAyD,CAE7E,GAAuB,EAAY,OAQnC,IAAM,EAAU,MAAM,EADI,EAHD,EADN,EAAY,IAAK,GAAM,EAAE,UACJ,CAGQ,CAAE,EAE/B,CACjB,KAAO,KACL,EAAO,KACL,EAAO,QAAQ,mCAAmC,EAAW,OAAO,WAAW,CAChF,EASM,MARe,EAA4B,EAAQ,CACxD,SACA,SAAU,EAAY,EACtB,SAAU,CACR,aACA,YAAa,CAAC,EAAiB,CAChC,CACF,CAAC,EACa,KAAK,CAAE,WAAU,cAAe,CAC7C,GAAI,CAAC,EACH,MAAU,MAAM,+BAA+B,IAAW,CAE5D,MAAO,CACL,SAAU,EACV,OAAQ,EAAS,QAAQ,QAAS,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,QAAQ,eAAgB,GAAG,CACnF,QAAS,4DACV,EACD,EAGJ,CACE,YAAa,EACd,CACF,CAED,GAA6B,EAAQ,MAAM,CAAC,OAG5C,IAAM,EAAU,EAAK,EAAY,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAC7D,EAAmB,GAAG,EAAS,GAAG,IAAY,IAC9C,EAAyB,GAAG,EAAe,GAAG,IAAY,IAChE,MAAM,EAAc,EAAkB,EAAa,EAAQ,CAC3D,EAAO,KACL,EAAO,MAAM,sBAAsB,EAAY,OAAO,wBAAwB,EAAK,GAAG,CACvF,CAED,IAAM,EAAoB,EAAQ,MAAM,CAExC,MAAM,EAAc,EAAwB,EAD3B,EAAK,EAAkB,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACF,CAAC,CACxE,EAAO,KACL,EAAO,MACL,sBAAsB,EAAkB,OAAO,wBAAwB,EAAW,GACnF,CACF,CAED,EAAO,KACL,EAAO,KACL,sBAAsB,EAAM,OAAO,sBAAsB,EAAkB,OAAO,qBACnF,CACF,CACD,GAAa,GAYb,eACA,mBACD,CAAC,CAEF,EAAO,KACL,EAAO,MAAM,sBAAsB,EAAoB,wBAAwB,EAAK,GAAG,CACxF,CACD,EAAO,KACL,EAAO,MACL,sBAAsB,EAA0B,wBAAwB,EAAW,GACpF,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./skipPreflightJobs-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./skipPreflightJobs-DFDwnE32.mjs";import{t}from"./done-input-validation-BcNBxhEs.mjs";async function n({auth:n,transcendUrl:r,enricherIds:i}){t(this.process.exit),await e({transcendUrl:r,auth:n,enricherIds:i})}export{n as skipPreflightJobs};
|
|
2
|
+
//# sourceMappingURL=impl-CH0jeBtq.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-CH0jeBtq.mjs","names":["skipPreflightJobsHelper"],"sources":["../src/commands/request/skip-preflight-jobs/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { skipPreflightJobs as skipPreflightJobsHelper } from '../../../lib/requests/index.js';\n\nexport interface SkipPreflightJobsCommandFlags {\n auth: string;\n enricherIds: string[];\n transcendUrl: string;\n}\n\nexport async function skipPreflightJobs(\n this: LocalContext,\n { auth, transcendUrl, enricherIds }: SkipPreflightJobsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await skipPreflightJobsHelper({\n transcendUrl,\n auth,\n enricherIds,\n });\n}\n"],"mappings":"yGAUA,eAAsB,EAEpB,CAAE,OAAM,eAAc,eACP,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAMA,EAAwB,CAC5B,eACA,OACA,cACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{r as e}from"./constants-zytGRR9s.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./readTranscendYaml-CGb2UUyM.mjs";import{n as r,r as i,t as a}from"./parseVariablesFromString-BeKOGw5n.mjs";import{t as o}from"./validateTranscendAuth-DJ8qHb9B.mjs";import{t as s}from"./listFiles-D2wMHnEr.mjs";import{t as c}from"./done-input-validation-BcNBxhEs.mjs";import{existsSync as l,lstatSync as u}from"node:fs";import{join as d}from"node:path";import f from"colors";import{buildTranscendGraphQLClient as p}from"@transcend-io/sdk";import{mapSeries as m}from"@transcend-io/utils";async function h({transcendUrl:e,auth:n,pageSize:r,publishToPrivacyCenter:a,contents:o,deleteExtraAttributeValues:s=!1,classifyService:c=!1}){let l=p(e,n);try{return!await i(o,l,{pageSize:r,publishToPrivacyCenter:a,classifyService:c,deleteExtraAttributeValues:s})}catch(e){return t.error(f.red(`An unexpected error occurred syncing the schema: ${e.message}`)),!1}}async function g({file:i=`./transcend.yml`,transcendUrl:p,auth:g,variables:_,pageSize:v,publishToPrivacyCenter:y,classifyService:b,deleteExtraAttributeValues:x}){c(this.process.exit);let S=await o(g),C=a(_),w;if(w=Array.isArray(S)&&u(i).isDirectory()?s(i).map(e=>d(i,e)):i.split(`,`),w.length<1)throw Error(`No file specified!`);let T=w.map(e=>{l(e)?t.info(f.magenta(`Reading file "${e}"...`)):(t.error(f.red(`The file path does not exist on disk: ${e}. You can specify the filepath using --file=./examples/transcend.yml`)),this.process.exit(1));try{let r=n(e,C);return t.info(f.green(`Successfully read in "${e}"`)),{content:r,name:e.split(`/`).pop().replace(`.yml`,``)}}catch(e){t.error(f.red(`The shape of your yaml file is invalid with the following errors: ${e.message}`)),this.process.exit(1)}});if(typeof S==`string`){let[n,...i]=T.map(({content:e})=>e);await h({transcendUrl:p,auth:S,contents:r(n,...i),publishToPrivacyCenter:y,deleteExtraAttributeValues:x,pageSize:v,classifyService:!!b})||(t.info(f.red(`Sync encountered errors. View output above for more information, or check out ${e}`)),this.process.exit(1))}else{if(T.length!==1&&T.length!==S.length)throw Error(`Expected list of yml files to be equal to the list of API keys.Got ${T.length} YML file${T.length===1?``:`s`} and ${S.length} API key${S.length===1?``:`s`}`);let n=[];await m(S,async(e,r)=>{let i=`[${r+1}/${S.length}][${e.organizationName}] `;t.info(f.magenta(`~~~\n\n${i}Attempting to push configuration...\n\n~~~`));let a=T.length===1?T[0].content:T.find(t=>t.name===e.organizationName)?.content;if(!a){t.error(f.red(`${i}Failed to find transcend.yml file for organization: "${e.organizationName}".`)),n.push(e.organizationName);return}await h({transcendUrl:p,auth:e.apiKey,contents:a,pageSize:v,publishToPrivacyCenter:y,deleteExtraAttributeValues:x,classifyService:b})?t.info(f.green(`${i}Successfully pushed configuration!`)):(t.error(f.red(`${i}Failed to sync configuration.`)),n.push(e.organizationName))}),n.length>0&&(t.info(f.red(`Sync encountered errors for "${n.join(`,`)}". View output above for more information, or check out ${e}`)),this.process.exit(1))}t.info(f.green(`Successfully synced yaml file to Transcend! View at ${e}`))}export{g as push};
|
|
2
|
+
//# sourceMappingURL=impl-CTre0PAy.mjs.map
|