@transcend-io/cli 10.27.3 → 10.27.5
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-CWTAiJKB.mjs → app-dIu3pdTM.mjs} +21 -21
- package/dist/{app-CWTAiJKB.mjs.map → app-dIu3pdTM.mjs.map} +1 -1
- package/dist/{approvePrivacyRequests-DYW20j6q.mjs → approvePrivacyRequests-B842tXn4.mjs} +2 -2
- package/dist/{approvePrivacyRequests-DYW20j6q.mjs.map → approvePrivacyRequests-B842tXn4.mjs.map} +1 -1
- package/dist/bin/bash-complete.mjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/bin/deprecated-command.mjs +3 -3
- package/dist/bin/deprecated-command.mjs.map +1 -1
- package/dist/{buildExamples-9cTRehd1.mjs → buildExamples-CRrUU89C.mjs} +2 -2
- package/dist/{buildExamples-9cTRehd1.mjs.map → buildExamples-CRrUU89C.mjs.map} +1 -1
- package/dist/{buildXdiSyncEndpoint-DPAOTaDK.mjs → buildXdiSyncEndpoint-B9seJTxP.mjs} +2 -2
- package/dist/{buildXdiSyncEndpoint-DPAOTaDK.mjs.map → buildXdiSyncEndpoint-B9seJTxP.mjs.map} +1 -1
- package/dist/{bulkRestartRequests-BNsFqq1U.mjs → bulkRestartRequests-CE7cDUMd.mjs} +2 -2
- package/dist/{bulkRestartRequests-BNsFqq1U.mjs.map → bulkRestartRequests-CE7cDUMd.mjs.map} +1 -1
- package/dist/{bulkRetryEnrichers-DzbsrAL3.mjs → bulkRetryEnrichers-BcSANZPC.mjs} +2 -2
- package/dist/{bulkRetryEnrichers-DzbsrAL3.mjs.map → bulkRetryEnrichers-BcSANZPC.mjs.map} +1 -1
- package/dist/{cancelPrivacyRequests-DIfhHbQn.mjs → cancelPrivacyRequests-BKibbagv.mjs} +2 -2
- package/dist/{cancelPrivacyRequests-DIfhHbQn.mjs.map → cancelPrivacyRequests-BKibbagv.mjs.map} +1 -1
- package/dist/{codecs-DJFlZLGT.mjs → codecs-zRkskjaJ.mjs} +1 -1
- package/dist/{codecs-DJFlZLGT.mjs.map → codecs-zRkskjaJ.mjs.map} +1 -1
- package/dist/collectCsvFilesOrExit-Dg5U3Qx_.mjs +2 -0
- package/dist/collectCsvFilesOrExit-Dg5U3Qx_.mjs.map +1 -0
- package/dist/collectParquetFilesOrExit-BlG2RRSC.mjs +2 -0
- package/dist/collectParquetFilesOrExit-BlG2RRSC.mjs.map +1 -0
- package/dist/{command-3eoWijOv.mjs → command-DKNKpgUB.mjs} +2 -2
- package/dist/{command-3eoWijOv.mjs.map → command-DKNKpgUB.mjs.map} +1 -1
- package/dist/commands/admin/chunk-csv/worker.mjs +1 -1
- package/dist/commands/admin/parquet-to-csv/worker.mjs +1 -1
- package/dist/consentManagersToBusinessEntities-Rv-ajWya.mjs +2 -0
- package/dist/consentManagersToBusinessEntities-Rv-ajWya.mjs.map +1 -0
- package/dist/{constants-BgCEW975.mjs → constants-B6wESCW2.mjs} +2 -2
- package/dist/{constants-BgCEW975.mjs.map → constants-B6wESCW2.mjs.map} +1 -1
- package/dist/{constants-C9xZJ9YW.mjs → constants-BuoISmXP.mjs} +1 -1
- package/dist/{constants-C9xZJ9YW.mjs.map → constants-BuoISmXP.mjs.map} +1 -1
- package/dist/{constants-DKKXqoSr.mjs → constants-CdgK1myP.mjs} +2 -2
- package/dist/{constants-DKKXqoSr.mjs.map → constants-CdgK1myP.mjs.map} +1 -1
- package/dist/context-4GAUnhTE.mjs +2 -0
- package/dist/context-4GAUnhTE.mjs.map +1 -0
- package/dist/createPoolingCommandUi-vTsGgYZT.mjs +14 -0
- package/dist/createPoolingCommandUi-vTsGgYZT.mjs.map +1 -0
- package/dist/done-input-validation-BFgMCQWH.mjs +2 -0
- package/dist/done-input-validation-BFgMCQWH.mjs.map +1 -0
- package/dist/{downloadPrivacyRequestFiles-cSB4B_30.mjs → downloadPrivacyRequestFiles-Dn3VexN2.mjs} +2 -2
- package/dist/{downloadPrivacyRequestFiles-cSB4B_30.mjs.map → downloadPrivacyRequestFiles-Dn3VexN2.mjs.map} +1 -1
- package/dist/{extractClientError-X9wJVqGq.mjs → extractClientError-DeS63kje.mjs} +1 -1
- package/dist/{extractClientError-X9wJVqGq.mjs.map → extractClientError-DeS63kje.mjs.map} +1 -1
- package/dist/{fetchAllRequests-DP24WqrP.mjs → fetchAllRequests-DUQGTJjx.mjs} +2 -2
- package/dist/{fetchAllRequests-DP24WqrP.mjs.map → fetchAllRequests-DUQGTJjx.mjs.map} +1 -1
- package/dist/{fuzzyMatchColumns-C1STZ_T1.mjs → fuzzyMatchColumns-BDD4a2W0.mjs} +2 -2
- package/dist/{fuzzyMatchColumns-C1STZ_T1.mjs.map → fuzzyMatchColumns-BDD4a2W0.mjs.map} +1 -1
- package/dist/{generateCrossAccountApiKeys-B1nowja2.mjs → generateCrossAccountApiKeys-QhnLqtUN.mjs} +2 -2
- package/dist/{generateCrossAccountApiKeys-B1nowja2.mjs.map → generateCrossAccountApiKeys-QhnLqtUN.mjs.map} +1 -1
- package/dist/impl-3IyENr9T.mjs +2 -0
- package/dist/impl-3IyENr9T.mjs.map +1 -0
- package/dist/impl-4rLX5Wah2.mjs +2 -0
- package/dist/impl-4rLX5Wah2.mjs.map +1 -0
- package/dist/impl-9TDsbGfF2.mjs +2 -0
- package/dist/impl-9TDsbGfF2.mjs.map +1 -0
- package/dist/impl-BPjGRqOL2.mjs +3 -0
- package/dist/{impl-eW9ZxuVu2.mjs.map → impl-BPjGRqOL2.mjs.map} +1 -1
- package/dist/impl-BPn_YPIq2.mjs +2 -0
- package/dist/{impl-hGwy9khM2.mjs.map → impl-BPn_YPIq2.mjs.map} +1 -1
- package/dist/impl-BQTw6jpw.mjs +2 -0
- package/dist/impl-BQTw6jpw.mjs.map +1 -0
- package/dist/impl-Ba8naMzu.mjs +2 -0
- package/dist/impl-Ba8naMzu.mjs.map +1 -0
- package/dist/impl-BbWzTCSd2.mjs +2 -0
- package/dist/{impl-C3S5iupW2.mjs.map → impl-BbWzTCSd2.mjs.map} +1 -1
- package/dist/impl-BddyFp_q.mjs +3 -0
- package/dist/impl-BddyFp_q.mjs.map +1 -0
- package/dist/impl-BgxjEv88.mjs +3 -0
- package/dist/impl-BgxjEv88.mjs.map +1 -0
- package/dist/impl-BiBNqcob.mjs +2 -0
- package/dist/impl-BiBNqcob.mjs.map +1 -0
- package/dist/{impl-QK9-ui6X.mjs → impl-BkyqCY72.mjs} +2 -2
- package/dist/impl-BkyqCY72.mjs.map +1 -0
- package/dist/{impl-Ca064LmU.mjs → impl-BlFBTc6f.mjs} +3 -3
- package/dist/{impl-Ca064LmU.mjs.map → impl-BlFBTc6f.mjs.map} +1 -1
- package/dist/impl-BoCD0t4j.mjs +3 -0
- package/dist/impl-BoCD0t4j.mjs.map +1 -0
- package/dist/impl-BqiclSRZ.mjs +2 -0
- package/dist/impl-BqiclSRZ.mjs.map +1 -0
- package/dist/impl-BsEYMBx2.mjs +7 -0
- package/dist/{impl-DvSnW_IA.mjs.map → impl-BsEYMBx2.mjs.map} +1 -1
- package/dist/impl-CBC5K-IH.mjs +2 -0
- package/dist/impl-CBC5K-IH.mjs.map +1 -0
- package/dist/impl-CH40t5qf.mjs +2 -0
- package/dist/impl-CH40t5qf.mjs.map +1 -0
- package/dist/impl-CLVMZXJo.mjs +2 -0
- package/dist/impl-CLVMZXJo.mjs.map +1 -0
- package/dist/{impl-Bccyro7t.mjs → impl-CMYYX3Kz.mjs} +2 -2
- package/dist/{impl-Bccyro7t.mjs.map → impl-CMYYX3Kz.mjs.map} +1 -1
- package/dist/impl-CVChVd63.mjs +2 -0
- package/dist/impl-CVChVd63.mjs.map +1 -0
- package/dist/impl-CXdy0YMX.mjs +2 -0
- package/dist/impl-CXdy0YMX.mjs.map +1 -0
- package/dist/impl-CZ-KvZE02.mjs +2 -0
- package/dist/{impl-CKQu30cA2.mjs.map → impl-CZ-KvZE02.mjs.map} +1 -1
- package/dist/impl-CbijbA-M2.mjs +2 -0
- package/dist/{impl-CJpPjFIi2.mjs.map → impl-CbijbA-M2.mjs.map} +1 -1
- package/dist/impl-CccuY3Za.mjs +12 -0
- package/dist/impl-CccuY3Za.mjs.map +1 -0
- package/dist/impl-CclEOdC32.mjs +2 -0
- package/dist/{impl-B0oCwFpP2.mjs.map → impl-CclEOdC32.mjs.map} +1 -1
- package/dist/impl-Cq5wI-kP.mjs +2 -0
- package/dist/impl-Cq5wI-kP.mjs.map +1 -0
- package/dist/impl-CrY1za0t.mjs +2 -0
- package/dist/impl-CrY1za0t.mjs.map +1 -0
- package/dist/impl-CusKk_JR2.mjs +2 -0
- package/dist/{impl-BzhraaBB2.mjs.map → impl-CusKk_JR2.mjs.map} +1 -1
- package/dist/impl-CzbVqbm0.mjs +5 -0
- package/dist/impl-CzbVqbm0.mjs.map +1 -0
- package/dist/impl-D33Zr0vh2.mjs +2 -0
- package/dist/impl-D33Zr0vh2.mjs.map +1 -0
- package/dist/impl-DG9RwTkA2.mjs +2 -0
- package/dist/{impl-XKBP7s772.mjs.map → impl-DG9RwTkA2.mjs.map} +1 -1
- package/dist/impl-DQG3PiAW2.mjs +2 -0
- package/dist/{impl-B3whGgMU2.mjs.map → impl-DQG3PiAW2.mjs.map} +1 -1
- package/dist/impl-DRimS_G8.mjs +2 -0
- package/dist/impl-DRimS_G8.mjs.map +1 -0
- package/dist/impl-DWBQKUuq.mjs +2 -0
- package/dist/{impl-B0-rCxY1.mjs.map → impl-DWBQKUuq.mjs.map} +1 -1
- package/dist/impl-DbF7uw7f2.mjs +2 -0
- package/dist/{impl-CAAQ0OKP2.mjs.map → impl-DbF7uw7f2.mjs.map} +1 -1
- package/dist/impl-DbPLuDc22.mjs +2 -0
- package/dist/impl-DbPLuDc22.mjs.map +1 -0
- package/dist/impl-DiyWNLJq.mjs +2 -0
- package/dist/impl-DiyWNLJq.mjs.map +1 -0
- package/dist/impl-DlaWf-oS2.mjs +2 -0
- package/dist/impl-DlaWf-oS2.mjs.map +1 -0
- package/dist/impl-Dpes0u_6.mjs +2 -0
- package/dist/{impl-ByeEmvdo.mjs.map → impl-Dpes0u_6.mjs.map} +1 -1
- package/dist/impl-DxXWaXFU.mjs +2 -0
- package/dist/impl-DxXWaXFU.mjs.map +1 -0
- package/dist/impl-DzJG5HaX.mjs +2 -0
- package/dist/impl-DzJG5HaX.mjs.map +1 -0
- package/dist/impl-GYM4LDKp2.mjs +2 -0
- package/dist/{impl-B7qkiYZY2.mjs.map → impl-GYM4LDKp2.mjs.map} +1 -1
- package/dist/{impl-B24TOrY-.mjs → impl-GnxjtYL7.mjs} +2 -2
- package/dist/impl-GnxjtYL7.mjs.map +1 -0
- package/dist/impl-PYtpY5hs2.mjs +2 -0
- package/dist/impl-PYtpY5hs2.mjs.map +1 -0
- package/dist/impl-QeWNZCg4.mjs +3 -0
- package/dist/impl-QeWNZCg4.mjs.map +1 -0
- package/dist/impl-V_ffkzbd2.mjs +2 -0
- package/dist/{impl-DK0UUhuK2.mjs.map → impl-V_ffkzbd2.mjs.map} +1 -1
- package/dist/impl-_rrZ0KXo.mjs +3 -0
- package/dist/impl-_rrZ0KXo.mjs.map +1 -0
- package/dist/impl-_tY0CJdZ.mjs +5 -0
- package/dist/impl-_tY0CJdZ.mjs.map +1 -0
- package/dist/impl-nJ7LzilX2.mjs +2 -0
- package/dist/impl-nJ7LzilX2.mjs.map +1 -0
- package/dist/impl-p0AyZWFL.mjs +2 -0
- package/dist/impl-p0AyZWFL.mjs.map +1 -0
- package/dist/impl-s5h7dIlv2.mjs +2 -0
- package/dist/{impl-oNhkS5zO2.mjs.map → impl-s5h7dIlv2.mjs.map} +1 -1
- package/dist/impl-uKjAibIR.mjs +2 -0
- package/dist/impl-uKjAibIR.mjs.map +1 -0
- package/dist/impl-wf0PvJms.mjs +2 -0
- package/dist/impl-wf0PvJms.mjs.map +1 -0
- package/dist/impl-xRwX5ZLK.mjs +2 -0
- package/dist/impl-xRwX5ZLK.mjs.map +1 -0
- package/dist/index.d.mts +142 -78
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/initializeCliRuntime-B7zDhMok.mjs +2 -0
- package/dist/initializeCliRuntime-B7zDhMok.mjs.map +1 -0
- package/dist/{inquirer-B0OF_nRe.mjs → inquirer-DNa31Mkx.mjs} +2 -2
- package/dist/{inquirer-B0OF_nRe.mjs.map → inquirer-DNa31Mkx.mjs.map} +1 -1
- package/dist/listFiles-DrxRhlZ2.mjs +2 -0
- package/dist/listFiles-DrxRhlZ2.mjs.map +1 -0
- package/dist/logger-CB_h_zbj.mjs +2 -0
- package/dist/logger-CB_h_zbj.mjs.map +1 -0
- package/dist/mapConsentCsvRowsToInputs-DA7BRD7M.mjs +2 -0
- package/dist/mapConsentCsvRowsToInputs-DA7BRD7M.mjs.map +1 -0
- package/dist/{markRequestDataSiloIdsCompleted-BvfxBmzu.mjs → markRequestDataSiloIdsCompleted-CK7PNwTz.mjs} +2 -2
- package/dist/{markRequestDataSiloIdsCompleted-BvfxBmzu.mjs.map → markRequestDataSiloIdsCompleted-CK7PNwTz.mjs.map} +1 -1
- package/dist/{markSilentPrivacyRequests-CRGg650V.mjs → markSilentPrivacyRequests-Cb-J9ckA.mjs} +2 -2
- package/dist/{markSilentPrivacyRequests-CRGg650V.mjs.map → markSilentPrivacyRequests-Cb-J9ckA.mjs.map} +1 -1
- package/dist/{mergeTranscendInputs-DjPe49yR.mjs → mergeTranscendInputs-CkpitZbH.mjs} +2 -2
- package/dist/{mergeTranscendInputs-DjPe49yR.mjs.map → mergeTranscendInputs-CkpitZbH.mjs.map} +1 -1
- package/dist/{notifyPrivacyRequestsAdditionalTime-vHikIxVO.mjs → notifyPrivacyRequestsAdditionalTime-it1FA62W.mjs} +2 -2
- package/dist/{notifyPrivacyRequestsAdditionalTime-vHikIxVO.mjs.map → notifyPrivacyRequestsAdditionalTime-it1FA62W.mjs.map} +1 -1
- package/dist/{parquetToCsvOneFile-0O4iLz0t.mjs → parquetToCsvOneFile-Dtz90qfJ.mjs} +2 -2
- package/dist/{parquetToCsvOneFile-0O4iLz0t.mjs.map → parquetToCsvOneFile-Dtz90qfJ.mjs.map} +1 -1
- package/dist/{parseAttributesFromString-CYcxsS3n.mjs → parseAttributesFromString-BxJcnKmn.mjs} +2 -2
- package/dist/{parseAttributesFromString-CYcxsS3n.mjs.map → parseAttributesFromString-BxJcnKmn.mjs.map} +1 -1
- package/dist/{parseVariablesFromString-B4TUkJRF.mjs → parseVariablesFromString-cu5gPC3M.mjs} +1 -1
- package/dist/{parseVariablesFromString-B4TUkJRF.mjs.map → parseVariablesFromString-cu5gPC3M.mjs.map} +1 -1
- package/dist/{pullAllDatapoints-DJno8LkB.mjs → pullAllDatapoints-XqreMBT5.mjs} +2 -2
- package/dist/{pullAllDatapoints-DJno8LkB.mjs.map → pullAllDatapoints-XqreMBT5.mjs.map} +1 -1
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DE7vqkyt.mjs → pullChunkedCustomSiloOutstandingIdentifiers-DuPDOm6f.mjs} +2 -2
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DE7vqkyt.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-DuPDOm6f.mjs.map} +1 -1
- package/dist/{pullConsentManagerMetrics-C41UhU8u.mjs → pullConsentManagerMetrics-Dk5IejaY.mjs} +2 -2
- package/dist/{pullConsentManagerMetrics-C41UhU8u.mjs.map → pullConsentManagerMetrics-Dk5IejaY.mjs.map} +1 -1
- package/dist/{pullManualEnrichmentIdentifiersToCsv-DXYFOoqY.mjs → pullManualEnrichmentIdentifiersToCsv-CAD1navz.mjs} +2 -2
- package/dist/{pullManualEnrichmentIdentifiersToCsv-DXYFOoqY.mjs.map → pullManualEnrichmentIdentifiersToCsv-CAD1navz.mjs.map} +1 -1
- package/dist/{pullTranscendConfiguration-DbRVLKq5.mjs → pullTranscendConfiguration-NcFjHE8k.mjs} +2 -2
- package/dist/{pullTranscendConfiguration-DbRVLKq5.mjs.map → pullTranscendConfiguration-NcFjHE8k.mjs.map} +1 -1
- package/dist/{pullUnstructuredSubDataPointRecommendations-B9xIDPf2.mjs → pullUnstructuredSubDataPointRecommendations-Cf4irXl4.mjs} +2 -2
- package/dist/{pullUnstructuredSubDataPointRecommendations-B9xIDPf2.mjs.map → pullUnstructuredSubDataPointRecommendations-Cf4irXl4.mjs.map} +1 -1
- package/dist/pushCronIdentifiersFromCsv-BGaJycWo.mjs +2 -0
- package/dist/{pushCronIdentifiersFromCsv-BCyj2uxq.mjs.map → pushCronIdentifiersFromCsv-BGaJycWo.mjs.map} +1 -1
- package/dist/pushManualEnrichmentIdentifiersFromCsv-B9okRkhL.mjs +2 -0
- package/dist/{pushManualEnrichmentIdentifiersFromCsv-EFfarcCs.mjs.map → pushManualEnrichmentIdentifiersFromCsv-B9okRkhL.mjs.map} +1 -1
- package/dist/readCsv-CmRYYFJc.mjs +2 -0
- package/dist/readCsv-CmRYYFJc.mjs.map +1 -0
- package/dist/{readTranscendYaml-bL1qFPqv.mjs → readTranscendYaml-DtJz9mor.mjs} +3 -3
- package/dist/readTranscendYaml-DtJz9mor.mjs.map +1 -0
- package/dist/{removeUnverifiedRequestIdentifiers-DqXcSHOr.mjs → removeUnverifiedRequestIdentifiers-DJhxiy_D.mjs} +2 -2
- package/dist/{removeUnverifiedRequestIdentifiers-DqXcSHOr.mjs.map → removeUnverifiedRequestIdentifiers-DJhxiy_D.mjs.map} +1 -1
- package/dist/{request-BIplTb3L.mjs → request-CCCU2SdV.mjs} +1 -1
- package/dist/{request-BIplTb3L.mjs.map → request-CCCU2SdV.mjs.map} +1 -1
- package/dist/{retryRequestDataSilos-DDdC7nXr.mjs → retryRequestDataSilos-6JfyZclD.mjs} +2 -2
- package/dist/{retryRequestDataSilos-DDdC7nXr.mjs.map → retryRequestDataSilos-6JfyZclD.mjs.map} +1 -1
- package/dist/runOpa-Q2r3qPsi.mjs +2 -0
- package/dist/runOpa-Q2r3qPsi.mjs.map +1 -0
- package/dist/{skipPreflightJobs-Cl98mx0Z.mjs → skipPreflightJobs-xpbtJ3dK.mjs} +2 -2
- package/dist/{skipPreflightJobs-Cl98mx0Z.mjs.map → skipPreflightJobs-xpbtJ3dK.mjs.map} +1 -1
- package/dist/{skipRequestDataSilos-mxRGsUpY.mjs → skipRequestDataSilos-B7RA6I3Z.mjs} +2 -2
- package/dist/{skipRequestDataSilos-mxRGsUpY.mjs.map → skipRequestDataSilos-B7RA6I3Z.mjs.map} +1 -1
- package/dist/{streamPrivacyRequestsToCsv-Dbu1NoDu.mjs → streamPrivacyRequestsToCsv-DT31SP6w.mjs} +2 -2
- package/dist/{streamPrivacyRequestsToCsv-Dbu1NoDu.mjs.map → streamPrivacyRequestsToCsv-DT31SP6w.mjs.map} +1 -1
- package/dist/{syncCodePackages-Dhm5jI6B.mjs → syncCodePackages-ozt9aBXf.mjs} +2 -2
- package/dist/{syncCodePackages-Dhm5jI6B.mjs.map → syncCodePackages-ozt9aBXf.mjs.map} +1 -1
- package/dist/{updateConsentManagerVersionToLatest-BbSaHE83.mjs → updateConsentManagerVersionToLatest-CCzWEBEj.mjs} +2 -2
- package/dist/{updateConsentManagerVersionToLatest-BbSaHE83.mjs.map → updateConsentManagerVersionToLatest-CCzWEBEj.mjs.map} +1 -1
- package/dist/{uploadConsents-DAUUuqxb.mjs → uploadConsents-CDqFNWX_.mjs} +2 -2
- package/dist/{uploadConsents-DAUUuqxb.mjs.map → uploadConsents-CDqFNWX_.mjs.map} +1 -1
- package/dist/{uploadPrivacyRequestsFromCsv-CT-zfd4U.mjs → uploadPrivacyRequestsFromCsv-CVpBFaYB.mjs} +2 -2
- package/dist/{uploadPrivacyRequestsFromCsv-CT-zfd4U.mjs.map → uploadPrivacyRequestsFromCsv-CVpBFaYB.mjs.map} +1 -1
- package/dist/validateTranscendAuth-3guZJPKH.mjs +2 -0
- package/dist/validateTranscendAuth-3guZJPKH.mjs.map +1 -0
- package/dist/{writeCsv-DMw5OmWp.mjs → writeCsv-rhlEBjYp.mjs} +1 -1
- package/dist/{writeCsv-DMw5OmWp.mjs.map → writeCsv-rhlEBjYp.mjs.map} +1 -1
- package/package.json +4 -4
- package/dist/collectCsvFilesOrExit-BPo8Mjy7.mjs +0 -2
- package/dist/collectCsvFilesOrExit-BPo8Mjy7.mjs.map +0 -1
- package/dist/collectParquetFilesOrExit-DVS9_OSv.mjs +0 -2
- package/dist/collectParquetFilesOrExit-DVS9_OSv.mjs.map +0 -1
- package/dist/consentManagersToBusinessEntities-rf8_xu71.mjs +0 -5
- package/dist/consentManagersToBusinessEntities-rf8_xu71.mjs.map +0 -1
- package/dist/context-Br0NHHOk.mjs +0 -2
- package/dist/context-Br0NHHOk.mjs.map +0 -1
- package/dist/createExtraKeyHandler-ComtD6CG.mjs +0 -14
- package/dist/createExtraKeyHandler-ComtD6CG.mjs.map +0 -1
- package/dist/done-input-validation-DL31vk7g.mjs +0 -2
- package/dist/done-input-validation-DL31vk7g.mjs.map +0 -1
- package/dist/impl-4Habov2V.mjs +0 -2
- package/dist/impl-4Habov2V.mjs.map +0 -1
- package/dist/impl-7pxeoDZg.mjs +0 -5
- package/dist/impl-7pxeoDZg.mjs.map +0 -1
- package/dist/impl-B0-rCxY1.mjs +0 -2
- package/dist/impl-B0oCwFpP2.mjs +0 -2
- package/dist/impl-B24TOrY-.mjs.map +0 -1
- package/dist/impl-B2eZGemA.mjs +0 -2
- package/dist/impl-B2eZGemA.mjs.map +0 -1
- package/dist/impl-B3whGgMU2.mjs +0 -2
- package/dist/impl-B7ceQwag.mjs +0 -2
- package/dist/impl-B7ceQwag.mjs.map +0 -1
- package/dist/impl-B7qkiYZY2.mjs +0 -2
- package/dist/impl-BTFeQDKS.mjs +0 -2
- package/dist/impl-BTFeQDKS.mjs.map +0 -1
- package/dist/impl-B_s0saYs2.mjs +0 -2
- package/dist/impl-B_s0saYs2.mjs.map +0 -1
- package/dist/impl-BeoY4iKA.mjs +0 -2
- package/dist/impl-BeoY4iKA.mjs.map +0 -1
- package/dist/impl-BmQR1Pae.mjs +0 -3
- package/dist/impl-BmQR1Pae.mjs.map +0 -1
- package/dist/impl-BnzPrDmM.mjs +0 -2
- package/dist/impl-BnzPrDmM.mjs.map +0 -1
- package/dist/impl-BoZZp_W8.mjs +0 -2
- package/dist/impl-BoZZp_W8.mjs.map +0 -1
- package/dist/impl-BohgbWOH.mjs +0 -2
- package/dist/impl-BohgbWOH.mjs.map +0 -1
- package/dist/impl-Bur_bNXN.mjs +0 -2
- package/dist/impl-Bur_bNXN.mjs.map +0 -1
- package/dist/impl-BwuWn3TM.mjs +0 -2
- package/dist/impl-BwuWn3TM.mjs.map +0 -1
- package/dist/impl-BxQE7dL92.mjs +0 -2
- package/dist/impl-BxQE7dL92.mjs.map +0 -1
- package/dist/impl-ByeEmvdo.mjs +0 -2
- package/dist/impl-BzhraaBB2.mjs +0 -2
- package/dist/impl-C3S5iupW2.mjs +0 -2
- package/dist/impl-C3f_H_77.mjs +0 -3
- package/dist/impl-C3f_H_77.mjs.map +0 -1
- package/dist/impl-CAAQ0OKP2.mjs +0 -2
- package/dist/impl-CDGqGw3I.mjs +0 -2
- package/dist/impl-CDGqGw3I.mjs.map +0 -1
- package/dist/impl-CJpPjFIi2.mjs +0 -2
- package/dist/impl-CKQu30cA2.mjs +0 -2
- package/dist/impl-CQCQSmNx2.mjs +0 -2
- package/dist/impl-CQCQSmNx2.mjs.map +0 -1
- package/dist/impl-CZG9gzzR.mjs +0 -3
- package/dist/impl-CZG9gzzR.mjs.map +0 -1
- package/dist/impl-Chska4J8.mjs +0 -3
- package/dist/impl-Chska4J8.mjs.map +0 -1
- package/dist/impl-CkoQHhc8.mjs +0 -12
- package/dist/impl-CkoQHhc8.mjs.map +0 -1
- package/dist/impl-Cl3hf0Pd.mjs +0 -2
- package/dist/impl-Cl3hf0Pd.mjs.map +0 -1
- package/dist/impl-CnrK11Gr2.mjs +0 -2
- package/dist/impl-CnrK11Gr2.mjs.map +0 -1
- package/dist/impl-CoKWGTEu2.mjs +0 -2
- package/dist/impl-CoKWGTEu2.mjs.map +0 -1
- package/dist/impl-Cpirdh8t2.mjs +0 -2
- package/dist/impl-Cpirdh8t2.mjs.map +0 -1
- package/dist/impl-D0-ioxpZ.mjs +0 -2
- package/dist/impl-D0-ioxpZ.mjs.map +0 -1
- package/dist/impl-DBK5c6d0.mjs +0 -2
- package/dist/impl-DBK5c6d0.mjs.map +0 -1
- package/dist/impl-DEZrkNw9.mjs +0 -2
- package/dist/impl-DEZrkNw9.mjs.map +0 -1
- package/dist/impl-DK0UUhuK2.mjs +0 -2
- package/dist/impl-DLWhxaMi.mjs +0 -2
- package/dist/impl-DLWhxaMi.mjs.map +0 -1
- package/dist/impl-DmODS2cY.mjs +0 -2
- package/dist/impl-DmODS2cY.mjs.map +0 -1
- package/dist/impl-DoY3Yb0D.mjs +0 -2
- package/dist/impl-DoY3Yb0D.mjs.map +0 -1
- package/dist/impl-DojHsd-e2.mjs +0 -2
- package/dist/impl-DojHsd-e2.mjs.map +0 -1
- package/dist/impl-DvSnW_IA.mjs +0 -7
- package/dist/impl-QK9-ui6X.mjs.map +0 -1
- package/dist/impl-RwrRqICz.mjs +0 -3
- package/dist/impl-RwrRqICz.mjs.map +0 -1
- package/dist/impl-XKBP7s772.mjs +0 -2
- package/dist/impl-eW9ZxuVu2.mjs +0 -3
- package/dist/impl-hGwy9khM2.mjs +0 -2
- package/dist/impl-oNhkS5zO2.mjs +0 -2
- package/dist/impl-rXmcMRG5.mjs +0 -2
- package/dist/impl-rXmcMRG5.mjs.map +0 -1
- package/dist/impl-wJEOzIpn.mjs +0 -2
- package/dist/impl-wJEOzIpn.mjs.map +0 -1
- package/dist/impl-xIb20rTt.mjs +0 -2
- package/dist/impl-xIb20rTt.mjs.map +0 -1
- package/dist/listFiles-C5kubvdN.mjs +0 -2
- package/dist/listFiles-C5kubvdN.mjs.map +0 -1
- package/dist/logger-Ckep4QXn.mjs +0 -2
- package/dist/logger-Ckep4QXn.mjs.map +0 -1
- package/dist/pushCronIdentifiersFromCsv-BCyj2uxq.mjs +0 -2
- package/dist/pushManualEnrichmentIdentifiersFromCsv-EFfarcCs.mjs +0 -2
- package/dist/readCsv--FfP8n-H.mjs +0 -2
- package/dist/readCsv--FfP8n-H.mjs.map +0 -1
- package/dist/readTranscendYaml-bL1qFPqv.mjs.map +0 -1
- package/dist/runOpa-D511z37u.mjs +0 -2
- package/dist/runOpa-D511z37u.mjs.map +0 -1
- package/dist/uploadCookiesFromCsv-tEobd_k1.mjs +0 -2
- package/dist/uploadCookiesFromCsv-tEobd_k1.mjs.map +0 -1
- package/dist/uploadDataFlowsFromCsv-B9Mcdixu.mjs +0 -2
- package/dist/uploadDataFlowsFromCsv-B9Mcdixu.mjs.map +0 -1
- package/dist/validateTranscendAuth-CAO5ktnu.mjs +0 -2
- package/dist/validateTranscendAuth-CAO5ktnu.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"consentManagersToBusinessEntities-rf8_xu71.mjs","names":[],"sources":["../src/lib/consent-manager/consentManagersToBusinessEntities.ts"],"sourcesContent":["import { BusinessEntityInput, ConsentManagerInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\n\n/**\n * Combine multiple consent manager configurations into a list of business entity configurations\n *\n * @param inputs - Consent manager configurations to combine\n * @returns Business entity configuration input\n */\nexport function consentManagersToBusinessEntities(\n inputs: {\n /** Name of business entity */\n name: string;\n /** Consent manager input */\n input?: ConsentManagerInput;\n }[],\n): BusinessEntityInput[] {\n // Construct the business entities YAML definition\n const businessEntities = inputs.map(\n ({ name, input }): BusinessEntityInput => ({\n // Title of Transcend Instance\n title: name.replace('.yml', ''),\n attributes: [\n // Sync domain list\n ...(input?.domains\n ? [\n {\n key: 'Transcend Domain List',\n values: [...new Set(input.domains)],\n },\n ]\n : []),\n // Sync bundle URLs\n ...(input?.bundleUrls\n ? [\n {\n key: 'Airgap Production URL',\n values: [input.bundleUrls.PRODUCTION],\n },\n {\n key: 'Airgap Test URL',\n values: [input.bundleUrls.TEST],\n },\n {\n key: 'Airgap XDI URL',\n values: [input.bundleUrls.PRODUCTION.replace('airgap.js', 'xdi.js')],\n },\n ]\n : []),\n // Sync partition keys\n ...(input?.partition\n ? [\n {\n key: 'Consent Partition Key',\n values: [input.partition],\n },\n ]\n : []),\n ],\n }),\n );\n\n // Log out info on airgap scripts to host\n logger.info('\\n\\n~~~~~~~~~~~\\nAirgap scripts to host:');\n businessEntities.forEach(({ attributes, title }, ind) => {\n attributes\n ?.find((attr) => attr.key === 'Airgap Production URL')\n ?.values?.forEach((url) => {\n logger.info(`${ind}) ${title} - ${url}`);\n });\n });\n\n return businessEntities;\n}\n"],"mappings":"0CASA,SAAgB,EACd,EAMuB,CAEvB,IAAM,EAAmB,EAAO,KAC7B,CAAE,OAAM,YAAkC,CAEzC,MAAO,EAAK,QAAQ,OAAQ,GAAG,CAC/B,WAAY,CAEV,GAAI,GAAO,QACP,CACE,CACE,IAAK,wBACL,OAAQ,CAAC,GAAG,IAAI,IAAI,EAAM,QAAQ,CAAC,CACpC,CACF,CACD,EAAE,CAEN,GAAI,GAAO,WACP,CACE,CACE,IAAK,wBACL,OAAQ,CAAC,EAAM,WAAW,WAAW,CACtC,CACD,CACE,IAAK,kBACL,OAAQ,CAAC,EAAM,WAAW,KAAK,CAChC,CACD,CACE,IAAK,iBACL,OAAQ,CAAC,EAAM,WAAW,WAAW,QAAQ,YAAa,SAAS,CAAC,CACrE,CACF,CACD,EAAE,CAEN,GAAI,GAAO,UACP,CACE,CACE,IAAK,wBACL,OAAQ,CAAC,EAAM,UAAU,CAC1B,CACF,CACD,EAAE,CACP,CACF,EACF,CAYD,OATA,EAAO,KAAK;;;yBAA2C,CACvD,EAAiB,SAAS,CAAE,aAAY,SAAS,IAAQ,CACvD,GACI,KAAM,GAAS,EAAK,MAAQ,wBAAwB,EACpD,QAAQ,QAAS,GAAQ,CACzB,EAAO,KAAK,GAAG,EAAI,IAAI,EAAM,KAAK,IAAM,EACxC,EACJ,CAEK"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-Br0NHHOk.mjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { StricliAutoCompleteContext } from '@stricli/auto-complete';\nimport type { CommandContext } from '@stricli/core';\n\nexport interface LocalContext extends CommandContext, StricliAutoCompleteContext {\n /** The Node.js process object */\n readonly process: NodeJS.Process;\n // ...\n}\n\n/**\n * Builds the context for the CLI.\n *\n * @param process - The Node.js process object.\n * @returns The context for the CLI.\n */\nexport function buildContext(process: NodeJS.Process): LocalContext {\n return {\n process,\n os,\n fs,\n path,\n };\n}\n"],"mappings":"uEAmBA,SAAgB,EAAa,EAAuC,CAClE,MAAO,CACL,UACA,KACA,KACA,OACD"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./constants-DKKXqoSr.mjs";import{createReadStream as t,readFileSync as n,statSync as r}from"node:fs";import{basename as i}from"node:path";import a from"colors";import*as o from"node:readline";function s(e,t,r){process.stdout.write(`\x1B[2J\x1B[H`);let i=e=>/\b(ERROR|uncaughtException|unhandledRejection)\b/i.test(e),a=e=>/\b(WARN|WARNING)\b/i.test(e),o=[];for(let[,s]of e){if(!s)continue;let e=[];for(let n of t)n===`out`&&s.outPath&&e.push({path:s.outPath,src:`out`}),n===`err`&&s.errPath&&e.push({path:s.errPath,src:`err`}),n===`structured`&&s.structuredPath&&e.push({path:s.structuredPath,src:`structured`}),s.warnPath&&n===`warn`&&e.push({path:s.warnPath,src:`warn`}),s.infoPath&&n===`info`&&e.push({path:s.infoPath,src:`info`});for(let{path:t,src:s}of e){let e=``;try{e=n(t,`utf8`)}catch{continue}for(let t of e.split(`
|
|
2
|
-
`)){if(!t)continue;let e=t.replace(/\x1B\[[0-9;]*m/g,``);if(r===`all`){o.push(t);continue}if(r===`error`){i(e)&&o.push(t);continue}if(a(e)||s===`err`&&!i(e)){o.push(t);continue}}}}o.sort((e,t)=>{let n=e.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)?.[0]??``,r=t.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)?.[0]??``;return n.localeCompare(r)}),process.stdout.write(`${o.join(`
|
|
3
|
-
`)}\n`),process.stdout.write(`
|
|
4
|
-
Press Esc/Ctrl+] to return to dashboard.
|
|
5
|
-
`)}function c(e,t,n){if(t.ctrl&&t.name===`c`)return{type:`CTRL_C`};if(n===`dashboard`)return t.name&&/^[0-9]$/.test(t.name)?{type:`ATTACH`,id:Number(t.name)}:t.name===`tab`&&!t.shift?{type:`CYCLE`,delta:1}:t.name===`tab`&&t.shift?{type:`CYCLE`,delta:-1}:t.name===`q`?{type:`QUIT`}:null;if(t.name===`escape`||t.ctrl&&t.name===`]`)return{type:`DETACH`};if(t.ctrl&&t.name===`d`)return{type:`CTRL_D`};let r=t.sequence??e??``;return r?{type:`FORWARD`,sequence:r}:null}async function l(e,n,i){await new Promise(a=>{try{let o=r(e),s=t(e,{start:Math.max(0,o.size-n),encoding:`utf8`});s.on(`data`,e=>i(e)),s.on(`end`,()=>a()),s.on(`error`,()=>a())}catch{a()}})}function u(e){return[...e.keys()].sort((e,t)=>e-t)}function d(e,t,n){if(!e.length)return null;let r=t??e[0],i=e.indexOf(r);return i===-1&&(i=0),i=(i+n+e.length)%e.length,e[i]}function f(t){let{workers:n,onAttach:r,onDetach:i,onCtrlC:a,getLogPaths:s,replayBytes:f=200*1024,replayWhich:p=[`out`,`err`],onEnterAttachScreen:m,ports:h}=t,g=h?.stdin??process.stdin,_=h?.stdout??process.stdout,v=h?.stderr??process.stderr,y=(...t)=>{if(e)try{(h?.stderr??process.stderr).write(`[keys] ${t.map(String).join(` `)}\n`)}catch{}};if(!g.isTTY)return()=>{};o.emitKeypressEvents(g),g.setRawMode?.(!0);let b=`dashboard`,x=null,S=null,C=null;async function w(e){if(!s)return;let t=s(e);if(!t)return;let n=[];for(let e of p)e===`out`&&n.push(t.outPath),e===`err`&&n.push(t.errPath),e===`structured`&&n.push(t.structuredPath);if(n.length){_.write(`
|
|
6
|
-
------------ replay ------------
|
|
7
|
-
`);for(let e of n)_.write(`\n--- ${e} (last ~${Math.floor(f/1024)}KB) ---\n`),await l(e,f,e=>_.write(e));_.write(`
|
|
8
|
-
--------------------------------
|
|
9
|
-
|
|
10
|
-
`)}}let T=async e=>{y(`attach()`,`id=${e}`);let t=n.get(e);t&&(b===`attached`&&E(),b=`attached`,x=e,m?.(e),r?.(e),await w(e),S=e=>_.write(e),C=e=>v.write(e),t.stdout?.on(`data`,S),t.stderr?.on(`data`,C),t.once(`exit`,()=>{x===e&&E()}))},E=()=>{if(y(`detach()`,`id=${x}`),x==null)return;let e=x,t=n.get(e);t&&(S&&t.stdout?.off(`data`,S),C&&t.stderr?.off(`data`,C)),S=null,C=null,x=null,b=`dashboard`,i?.()},D=(e,t)=>{y(`keypress`,JSON.stringify({str:e,name:t.name,seq:t.sequence,ctrl:t.ctrl,meta:t.meta,shift:t.shift,mode:b}));let r=c(e,t,b);if(y(`mapped`,JSON.stringify(r)),r)switch(r.type){case`CTRL_C`:if(y(`CTRL_C`),b===`attached`&&x!=null){let e=n.get(x);try{e?.kill(`SIGINT`)}catch{}E();return}a?.();return;case`ATTACH`:if(y(`ATTACH`,`id=${r.id}`,`has=${n.has(r.id)}`),b!==`dashboard`)return;n.has(r.id)&&T(r.id);return;case`CYCLE`:{if(y(`CYCLE`,`delta=${r.delta}`),b!==`dashboard`)return;let e=d(u(n),x,r.delta);e!=null&&T(e);return}case`QUIT`:if(b!==`dashboard`)return;a?.();return;case`DETACH`:y(`DETACH`),b===`attached`&&E();return;case`CTRL_D`:if(b===`attached`&&x!=null){let e=n.get(x);try{e?.stdin?.end()}catch{}}return;case`FORWARD`:if(b===`attached`&&x!=null){let e=n.get(x);try{e?.stdin?.write(r.sequence)}catch{}}}},O=e=>{if(b===`attached`&&x!=null){let t=n.get(x);try{t?.stdin?.write(e)}catch{}}};return g.on(`keypress`,D),g.on(`data`,O),()=>{g.off(`keypress`,D),g.off(`data`,O),g.setRawMode?.(!1),_.write(`\x1B[?25h`)}}let p=``;const m=(e,t)=>{let n=Math.min(e-1,9),r=e<=1?`0`:`0-${n}`,i=e>10?` (Tab/Shift+Tab for ≥10)`:``;return t?a.dim(`Run complete — digits to view logs • Tab/Shift+Tab cycle • Esc/Ctrl+] detach • q to quit`):a.dim(`Hotkeys: [${r}] attach${i} • e=errors • w=warnings • i=info • l=logs • Tab/Shift+Tab • Esc/Ctrl+] detach • Ctrl+C exit`)};function h(e,t,n=!1){let r=[...t.renderHeader(e),``,...t.renderWorkers(e),...n?[]:[``,m(e.poolSize,e.final)],...t.renderExtras?[``].concat(t.renderExtras(e)):[]].join(`
|
|
11
|
-
`);!e.final&&r===p||(p=r,e.final?process.stdout.write(`\x1B[?25h`):(process.stdout.write(`\x1B[?25l`),o.cursorTo(process.stdout,0,0),o.clearScreenDown(process.stdout)),process.stdout.write(`${r}\n`))}function g(e){return typeof e==`number`?e.toLocaleString():`0`}function _(e,t=40){let n=Math.floor(Math.max(0,Math.min(100,Math.floor(e)))/100*t);return`█`.repeat(n)+`░`.repeat(t-n)}function v(e){let t=[...e.workerState.values()].filter(e=>e.busy).length,n=e.filesCompleted+e.filesFailed;return{done:n,inProgress:t,pct:e.filesTotal===0?100:Math.floor(n/Math.max(1,e.filesTotal)*100)}}function y(e,t=[]){let{title:n,poolSize:r,cpuCount:i,filesTotal:o,filesCompleted:s,filesFailed:c,throughput:l}=e,{inProgress:u,pct:d}=v(e),f=[`${a.bold(n)} — ${r} workers ${a.dim(`(CPU avail: ${i})`)}`,`${a.dim(`Files`)} ${g(o)} ${a.dim(`Completed`)} ${g(s)} ${a.dim(`Failed`)} ${c?a.red(g(c)):g(c)} ${a.dim(`In-flight`)} ${g(u)}`,`[${_(d)}] ${d}%`];if(l){let t=l.jobsR10s>0||l.jobsR60s>0,n=Math.round((t?l.jobsR10s:l.r10s)*3600).toLocaleString(),r=Math.round((t?l.jobsR60s:l.r60s)*3600).toLocaleString(),i=t?`rec`:`files`,o=e.throughput?.successSoFar==null?``:` Newly uploaded: ${g(e.throughput.successSoFar)}`;f.push(a.cyan(`Throughput: ${n} ${i}/hr (1h: ${r} ${i}/hr)${o}`))}return t.length?f.concat(t):f}function b(e,t=e=>e?i(e):`-`){return[...e.workerState.entries()].map(([e,n])=>{let r=n.lastLevel===`error`?a.red(`ERROR `):n.lastLevel===`warn`?a.yellow(`WARN `):n.busy?a.green(`WORKING`):a.dim(`IDLE `),i=t(n.file),o=n.startedAt?`${Math.floor((Date.now()-n.startedAt)/1e3)}s`:`-`,s=n.progress?.processed??0,c=n.progress?.total??0,l=c>0?Math.floor(s/c*100):0;return` [w${e}] ${r} | ${i} | ${o} | [${c>0?_(l,18):` `.repeat(18)}] ${c>0?`${s.toLocaleString()}/${c.toLocaleString()} (${l}%)`:a.dim(`—`)}`})}function x(e){let{logsBySlot:t,repaint:n,setPaused:r,exportMgr:i,exportStatus:a,custom:o}=e,c=e=>{process.stdout.write(`${e}\n`)},l=(e,t)=>{let r=Date.now(),i=a?.[e]??{path:t};a&&(a[e]={path:t||i.path,savedAt:r,exported:!0},n())},u=!1,d=(e,i)=>{u||(u=!0,r(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Combined logs viewer (press Esc or Ctrl+] to return)
|
|
12
|
-
|
|
13
|
-
`),(async()=>{try{await s(t,e,i)}catch{u=!1,r(!1),n()}})())},f=(e,n)=>{if(i)try{let r=i.exportCombinedLogs(t,e);c(`\nWrote combined ${n} logs to: ${r}`),l(e,r)}catch{c(`\nFailed to write combined ${n} logs`)}};return e=>{let t=e.toString(`utf8`);if(t===`e`){d([`err`],`error`);return}if(t===`w`){d([`warn`,`err`],`warn`);return}if(t===`i`){d([`info`],`all`);return}if(t===`l`){d([`out`,`err`,`structured`],`all`);return}if(t===`E`){f(`error`,`error`);return}if(t===`W`){f(`warn`,`warn`);return}if(t===`I`){f(`info`,`info`);return}if(t===`A`){f(`all`,`ALL`);return}let i=o?.[t];if(i){i({noteExport:l,say:c});return}(t===`\x1B`||t===``)&&(u=!1,r(!1),n())}}export{f as a,h as i,y as n,b as r,x as t};
|
|
14
|
-
//# sourceMappingURL=createExtraKeyHandler-ComtD6CG.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createExtraKeyHandler-ComtD6CG.mjs","names":[],"sources":["../src/lib/pooling/showCombinedLogs.ts","../src/lib/pooling/keymap.ts","../src/lib/pooling/replayFileTailToStdout.ts","../src/lib/pooling/workerIds.ts","../src/lib/pooling/installInteractiveSwitcher.ts","../src/lib/pooling/dashboardPlugin.ts","../src/lib/pooling/uiPlugins.ts","../src/lib/pooling/createExtraKeyHandler.ts"],"sourcesContent":["/* eslint-disable no-continue, no-control-regex */\nimport { readFileSync } from 'node:fs';\n\nimport type { WorkerLogPaths } from '@transcend-io/utils';\n\n/**\n * Log locations\n */\nexport type LogLocation = 'out' | 'err' | 'structured' | 'warn' | 'info';\n\n/**\n * Which logs to show in the combined output.\n * Can include 'out' (stdout), 'err' (stderr), 'structured' (\n */\nexport type WhichLogs = Array<LogLocation>;\n\n/**\n * Show combined logs from all worker processes.\n *\n * @param slotLogPaths - Map of worker IDs to their log file paths.\n * @param whichList - one or more sources to include (e.g., ['err','out'])\n * @param filterLevel - 'error', 'warn', or 'all' to filter log levels.\n */\nexport function showCombinedLogs(\n slotLogPaths: Map<number, WorkerLogPaths | undefined>,\n whichList: WhichLogs,\n filterLevel: 'error' | 'warn' | 'all',\n): void {\n process.stdout.write('\\x1b[2J\\x1b[H');\n\n const isError = (t: string): boolean =>\n /\\b(ERROR|uncaughtException|unhandledRejection)\\b/i.test(t);\n const isWarnTag = (t: string): boolean => /\\b(WARN|WARNING)\\b/i.test(t);\n\n const lines: string[] = [];\n\n for (const [, paths] of slotLogPaths) {\n if (!paths) continue;\n\n const files: Array<{\n /** Absolute file path to read from */\n path: string;\n /** Source type for this file, used for classification */\n src: LogLocation;\n }> = [];\n for (const which of whichList) {\n if (which === 'out' && paths.outPath) {\n files.push({ path: paths.outPath, src: 'out' });\n }\n if (which === 'err' && paths.errPath) {\n files.push({ path: paths.errPath, src: 'err' });\n }\n if (which === 'structured' && paths.structuredPath) {\n files.push({ path: paths.structuredPath, src: 'structured' });\n }\n if (paths.warnPath && which === 'warn') {\n files.push({ path: paths.warnPath, src: 'warn' });\n }\n if (paths.infoPath && which === 'info') {\n files.push({ path: paths.infoPath, src: 'info' });\n }\n }\n\n for (const { path, src } of files) {\n let text = '';\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n continue;\n }\n\n for (const ln of text.split('\\n')) {\n if (!ln) continue;\n\n const clean = ln.replace(/\\x1B\\[[0-9;]*m/g, '');\n\n if (filterLevel === 'all') {\n lines.push(ln);\n continue;\n }\n\n if (filterLevel === 'error') {\n if (isError(clean)) lines.push(ln);\n continue;\n }\n\n // filterLevel === 'warn'\n // Accept:\n // - explicit WARN tag anywhere\n // - OR lines from stderr that are NOT explicit errors (many warn libs print to stderr)\n // - OR lines containing the word \"warning\" (common in some libs)\n if (isWarnTag(clean) || (src === 'err' && !isError(clean))) {\n lines.push(ln);\n continue;\n }\n }\n }\n }\n\n // simple time-sort; each worker often prefixes ISO timestamps\n lines.sort((a, b) => {\n const ta = a.match(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)?.[0] ?? '';\n const tb = b.match(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)?.[0] ?? '';\n return ta.localeCompare(tb);\n });\n\n process.stdout.write(`${lines.join('\\n')}\\n`);\n process.stdout.write('\\nPress Esc/Ctrl+] to return to dashboard.\\n');\n}\n/* eslint-enable no-continue, no-control-regex */\n","import type * as readline from 'node:readline';\n\n/**\n * Map a key press to an action in the interactive dashboard.\n */\nexport type Action =\n | {\n /** Indicates attaching to a session by id. */\n type: 'ATTACH';\n /** The id of the session to attach to. */\n id: number;\n }\n | {\n /** Indicates cycling through sessions. */\n type: 'CYCLE';\n /** The direction to cycle: +1 for next, -1 for previous. */\n delta: number;\n }\n | {\n /** Indicates detaching from the current session. */\n type: 'DETACH';\n }\n | {\n /** Indicates the Ctrl+C key combination was pressed. */\n type: 'CTRL_C';\n }\n | {\n /** Indicates the Ctrl+D key combination was pressed. */\n type: 'CTRL_D';\n }\n | {\n /** Indicates quitting the dashboard. */\n type: 'QUIT';\n }\n | {\n /** Forwards an unhandled key sequence. */\n type: 'FORWARD';\n /** The key sequence to forward. */\n sequence: string;\n };\n\n/**\n * Map a key press to an action in the interactive dashboard.\n *\n * @param str - The string representation of the key press.\n * @param key - The key object containing details about the key press.\n * @param mode - The current mode of the dashboard, either 'dashboard' or 'attached'.\n * @returns An Action object representing the mapped action, or null if no action is mapped.\n */\nexport function keymap(\n str: string,\n key: readline.Key,\n mode: 'dashboard' | 'attached',\n): Action | null {\n if (key.ctrl && key.name === 'c') return { type: 'CTRL_C' };\n\n if (mode === 'dashboard') {\n if (key.name && /^[0-9]$/.test(key.name)) {\n return { type: 'ATTACH', id: Number(key.name) };\n }\n if (key.name === 'tab' && !key.shift) return { type: 'CYCLE', delta: +1 };\n if (key.name === 'tab' && key.shift) return { type: 'CYCLE', delta: -1 };\n if (key.name === 'q') return { type: 'QUIT' };\n return null;\n }\n\n // attached\n if (key.name === 'escape' || (key.ctrl && key.name === ']')) {\n return { type: 'DETACH' };\n }\n if (key.ctrl && key.name === 'd') return { type: 'CTRL_D' };\n\n const sequence = key.sequence ?? str ?? '';\n return sequence ? { type: 'FORWARD', sequence } : null;\n}\n","import { createReadStream, statSync } from 'node:fs';\n\n/**\n * Replay the tail of a file to stdout.\n *\n * @param path - The absolute path to the file to read.\n * @param maxBytes - The maximum number of bytes to read from the end of the file.\n * @param write - A function to write the output to stdout.\n */\nexport async function replayFileTailToStdout(\n path: string,\n maxBytes: number,\n write: (s: string) => void,\n): Promise<void> {\n await new Promise<void>((resolve) => {\n try {\n const st = statSync(path);\n const start = Math.max(0, st.size - maxBytes);\n const stream = createReadStream(path, { start, encoding: 'utf8' });\n stream.on('data', (chunk) => write(chunk as string));\n stream.on('end', () => resolve());\n stream.on('error', () => resolve());\n } catch {\n resolve();\n }\n });\n}\n","import type { ChildProcess } from 'node:child_process';\n\n/**\n * Get the sorted list of worker IDs from a map of ChildProcess instances.\n *\n * @param m - Map of worker IDs to ChildProcess instances.\n * @returns Sorted array of worker IDs.\n */\nexport function getWorkerIds(m: Map<number, ChildProcess>): number[] {\n return [...m.keys()].sort((a, b) => a - b);\n}\n\n/**\n * Cycles through an array of numeric IDs, returning the next ID based on a delta.\n *\n * If the `current` ID is not provided or not found in the array, the first ID is used as the starting point.\n * The function then moves forward or backward in the array by `delta` positions, wrapping around if necessary.\n *\n * @param ids - Array of numeric IDs to cycle through.\n * @param current - The current ID to start cycling from. If `null` or not found, starts from the first ID.\n * @param delta - The number of positions to move forward (positive) or backward (negative) in the array.\n * @returns The next ID in the array after cycling, or `null` if the array is empty.\n */\nexport function cycleWorkers(ids: number[], current: number | null, delta: number): number | null {\n if (!ids.length) return null;\n const cur = current == null ? ids[0] : current;\n let i = ids.indexOf(cur);\n if (i === -1) i = 0;\n i = (i + delta + ids.length) % ids.length;\n return ids[i]!;\n}\n","import type { ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\n\nimport type { WorkerLogPaths } from '@transcend-io/utils';\n\nimport { DEBUG } from '../../constants.js';\nimport { keymap } from './keymap.js';\nimport { replayFileTailToStdout } from './replayFileTailToStdout.js';\nimport type { WhichLogs } from './showCombinedLogs.js';\nimport { cycleWorkers, getWorkerIds } from './workerIds.js';\n\n/**\n * Key action types for the interactive switcher\n */\nexport type InteractiveDashboardMode = 'dashboard' | 'attached';\n\nexport interface SwitcherPorts {\n /** Standard input stream */\n stdin: NodeJS.ReadStream;\n /** Standard output stream */\n stdout: NodeJS.WriteStream;\n /** Standard error stream */\n stderr: NodeJS.WriteStream;\n}\n\n/**\n * Install an interactive switcher for managing worker processes.\n *\n * @param opts - Options for the switcher\n * @returns A cleanup function to remove the switcher\n */\nexport function installInteractiveSwitcher(opts: {\n /** Registry of live workers by id */\n workers: Map<number, ChildProcess>;\n /** Hooks */\n onAttach?: (id: number) => void;\n /** Optional detach handler */\n onDetach?: () => void;\n /** Optional Ctrl+C handler for parent graceful shutdown in dashboard */\n onCtrlC?: () => void; // parent graceful shutdown in dashboard\n /** Provide log paths so we can replay the tail on attach */\n getLogPaths?: (id: number) => WorkerLogPaths | undefined;\n /** How many bytes to replay from the end of each file (default 200 KB) */\n replayBytes?: number;\n /** Which logs to replay first (default ['out','err']) */\n replayWhich?: WhichLogs;\n /** Print a small banner/clear screen before replaying (optional) */\n onEnterAttachScreen?: (id: number) => void;\n /** Optional stdio ports for testing; defaults to process stdio */\n ports?: SwitcherPorts;\n}): () => void {\n const {\n workers,\n onAttach,\n onDetach,\n onCtrlC,\n getLogPaths,\n replayBytes = 200 * 1024,\n replayWhich = ['out', 'err'],\n onEnterAttachScreen,\n ports,\n } = opts;\n\n const stdin = ports?.stdin ?? process.stdin;\n const stdout = ports?.stdout ?? process.stdout;\n const stderr = ports?.stderr ?? process.stderr;\n\n const d = (...a: unknown[]): void => {\n if (DEBUG) {\n try {\n (ports?.stderr ?? process.stderr).write(`[keys] ${a.map(String).join(' ')}\\n`);\n } catch {\n // noop\n }\n }\n };\n\n if (!stdin.isTTY) {\n // Not a TTY; return a no-op cleanup\n return () => {\n // noop\n };\n }\n\n readline.emitKeypressEvents(stdin);\n stdin.setRawMode?.(true);\n\n let mode: InteractiveDashboardMode = 'dashboard';\n let focus: number | null = null;\n\n // live mirroring handlers while attached\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let outHandler: ((chunk: any) => void) | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let errHandler: ((chunk: any) => void) | null = null;\n\n /**\n * Cycle through worker IDs, wrapping around.\n *\n * @param id - The current worker ID to start cycling from.\n * @returns The next worker ID after cycling, or null if no workers are available.\n */\n async function replayLogs(id: number): Promise<void> {\n if (!getLogPaths) return;\n const paths = getLogPaths(id);\n if (!paths) return;\n\n const toReplay: string[] = [];\n for (const which of replayWhich) {\n if (which === 'out') toReplay.push(paths.outPath);\n if (which === 'err') toReplay.push(paths.errPath);\n if (which === 'structured') toReplay.push(paths.structuredPath);\n }\n\n if (toReplay.length) {\n stdout.write('\\n------------ replay ------------\\n');\n for (const p of toReplay) {\n stdout.write(`\\n--- ${p} (last ~${Math.floor(replayBytes / 1024)}KB) ---\\n`);\n await replayFileTailToStdout(p, replayBytes, (s) => stdout.write(s));\n }\n stdout.write('\\n--------------------------------\\n\\n');\n }\n }\n\n const attach = async (id: number): Promise<void> => {\n d('attach()', `id=${id}`); // at function entry\n\n const w = workers.get(id);\n if (!w) return;\n\n // Detach any previous focus\n if (mode === 'attached') detach();\n\n mode = 'attached';\n focus = id;\n\n // UX: clear + banner\n onEnterAttachScreen?.(id);\n\n onAttach?.(id); // prints “Attached to worker …” and clears\n await replayLogs(id); // now the tail stays visible\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outHandler = (chunk: any) => stdout.write(chunk);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errHandler = (chunk: any) => stderr.write(chunk);\n w.stdout?.on('data', outHandler);\n w.stderr?.on('data', errHandler);\n\n // auto-detach if child exits\n const onExit = (): void => {\n if (focus === id) detach();\n };\n w.once('exit', onExit);\n };\n\n const detach = (): void => {\n d('detach()', `id=${focus}`); // at function entry\n\n if (focus == null) return;\n const id = focus;\n const w = workers.get(id);\n if (w) {\n if (outHandler) w.stdout?.off('data', outHandler);\n if (errHandler) w.stderr?.off('data', errHandler);\n }\n outHandler = null;\n errHandler = null;\n focus = null;\n mode = 'dashboard';\n onDetach?.();\n };\n\n const onKey = (str: string, key: readline.Key): void => {\n d(\n 'keypress',\n JSON.stringify({\n str,\n name: key.name,\n seq: key.sequence,\n ctrl: key.ctrl,\n meta: key.meta,\n shift: key.shift,\n mode,\n }),\n );\n const act = keymap(str, key, mode);\n d('mapped', JSON.stringify(act));\n\n if (!act) return;\n\n // eslint-disable-next-line default-case\n switch (act.type) {\n case 'CTRL_C': {\n d('CTRL_C');\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.kill('SIGINT');\n } catch {\n // noop\n }\n // optional: auto-detach so second Ctrl+C exits parent\n detach();\n return;\n }\n onCtrlC?.();\n return;\n }\n\n case 'ATTACH': {\n d('ATTACH', `id=${act.id}`, `has=${workers.has(act.id)}`);\n\n if (mode !== 'dashboard') return;\n // eslint-disable-next-line no-void\n if (workers.has(act.id)) void attach(act.id);\n return;\n }\n\n case 'CYCLE': {\n d('CYCLE', `delta=${act.delta}`);\n if (mode !== 'dashboard') return;\n const next = cycleWorkers(getWorkerIds(workers), focus, act.delta);\n // eslint-disable-next-line no-void\n if (next != null) void attach(next);\n return;\n }\n\n case 'QUIT': {\n if (mode !== 'dashboard') return;\n onCtrlC?.();\n return;\n }\n\n case 'DETACH': {\n d('DETACH');\n if (mode === 'attached') detach();\n return;\n }\n\n case 'CTRL_D': {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.end();\n } catch {\n // noop\n }\n }\n return;\n }\n\n case 'FORWARD': {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.write(act.sequence);\n } catch {\n // noop\n }\n }\n }\n }\n };\n\n // Raw bytes fallback (usually not hit because keypress handles it)\n const onData = (chunk: Buffer): void => {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.write(chunk);\n } catch {\n // noop\n }\n }\n };\n\n const cleanup = (): void => {\n stdin.off('keypress', onKey);\n stdin.off('data', onData);\n stdin.setRawMode?.(false);\n stdout.write('\\x1b[?25h');\n };\n\n stdin.on('keypress', onKey);\n stdin.on('data', onData);\n\n return cleanup;\n}\n","// lib/pooling/dashboardPlugin.ts\nimport * as readline from 'node:readline';\n\nimport type { ObjByString } from '@transcend-io/type-utils';\nimport type { SlotState } from '@transcend-io/utils';\nimport colors from 'colors';\n\n/**\n * A dashboard plugin defines how to render the worker pool UI.\n * Commands can supply a plugin to customize:\n * - The header block (summary stats, title, etc.)\n * - Per-worker rows (one line per worker slot)\n * - Optional extras (artifact exports, breakdowns, footers)\n *\n * @template TTotals - The shape of the aggregate totals object maintained by the command.\n */\nexport interface DashboardPlugin<TTotals, TSlotState extends ObjByString> {\n /**\n * Render the header block of the dashboard.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one line in the header.\n */\n renderHeader: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n\n /**\n * Render per-worker rows, usually one line per worker slot.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one row in the workers section.\n */\n renderWorkers: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n\n /**\n * Render any optional extra blocks that appear after the worker rows.\n * Useful for printing export paths, aggregated metrics, breakdowns, etc.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one additional line.\n */\n renderExtras?: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n}\n\n/**\n * Shared context object passed into all render methods of a {@link DashboardPlugin}.\n *\n * @template TTotals - The shape of the aggregate totals object maintained by the command.\n */\nexport type CommonCtx<TTotals, TSlotState extends ObjByString> = {\n /** Human-readable title for the dashboard (e.g., \"Parallel uploader\"). */\n title: string;\n\n /** Number of worker processes spawned in the pool. */\n poolSize: number;\n\n /** Logical CPU count, included for informational display. */\n cpuCount: number;\n\n /** Total number of \"files\" or logical units the command expects to process. */\n filesTotal: number;\n\n /** Count of successfully completed files/tasks. */\n filesCompleted: number;\n\n /** Count of failed files/tasks. */\n filesFailed: number;\n\n /**\n * State of each worker slot, keyed by worker id.\n * Includes busy flag, file label, start time, last log badge, and progress.\n */\n workerState: Map<number, SlotState<TSlotState>>;\n\n /**\n * Aggregate totals maintained by the command’s hook logic.\n * Domain-specific metrics (e.g., rows uploaded, bytes processed) can be surfaced here.\n */\n totals: TTotals;\n\n /**\n * Throughput metrics tracked by the runner:\n * - successSoFar: convenience alias for completed count\n * - r10s: completions/sec averaged over last 10s\n * - r60s: completions/sec averaged over last 60s\n */\n throughput: {\n /** Cumulative count of successful completions so far. */\n successSoFar: number;\n /** Recent file-level throughput rate over the last 10 seconds. */\n r10s: number;\n /** Recent file-level throughput rate over the last 60 seconds. */\n r60s: number;\n /** Recent job/record-level throughput rate over the last 10 seconds. */\n jobsR10s: number;\n /** Recent job/record-level throughput rate over the last 60 seconds. */\n jobsR60s: number;\n };\n\n /** True when the pool has fully drained and all workers have exited. */\n final: boolean;\n\n /**\n * Optional export status payload provided by the command.\n * Useful for rendering artifact paths or \"latest export\" summaries.\n */\n exportStatus?: Record<string, unknown>;\n};\n\n/** The most recently rendered frame, cached to suppress flicker from duplicate renders. */\nlet lastFrame = '';\n\n/**\n * Generate the hotkeys hint string that appears at the bottom of the dashboard.\n *\n * @param poolSize - The number of worker slots in the pool.\n * @param final - Whether the run has completed.\n * @returns A dimmed string listing the supported hotkeys for attach/detach/quit.\n */\nexport const hotkeysHint = (poolSize: number, final: boolean): string => {\n const maxDigit = Math.min(poolSize - 1, 9);\n const digitRange = poolSize <= 1 ? '0' : `0-${maxDigit}`;\n const extra = poolSize > 10 ? ' (Tab/Shift+Tab for ≥10)' : '';\n return final\n ? colors.dim(\n 'Run complete — digits to view logs • Tab/Shift+Tab cycle • Esc/Ctrl+] detach • q to quit',\n )\n : colors.dim(\n `Hotkeys: [${digitRange}] attach${extra} • e=errors • w=warnings • i=info • l=logs • ` +\n 'Tab/Shift+Tab • Esc/Ctrl+] detach • Ctrl+C exit',\n );\n};\n\n/**\n * Render the dashboard using a supplied {@link DashboardPlugin}.\n *\n * The frame is composed of:\n * - Header lines\n * - A blank separator\n * - Worker rows\n * - A blank separator\n * - Hotkeys hint\n * - Optional extras (if plugin supplies them)\n *\n * Optimizations:\n * - Suppresses re-renders if the frame is identical to the previous frame (flicker-free).\n * - Hides the terminal cursor during live updates, restoring it when final.\n *\n * @param ctx - Shared context containing pool state, worker state, totals, throughput, etc.\n * @param plugin - The plugin that defines how to render the header, workers, and optional extras.\n * @param viewerMode - If true, renders in viewer mode (no ability to switch between files).\n */\nexport function dashboardPlugin<TTotals, TSlotState extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlotState>,\n plugin: DashboardPlugin<TTotals, TSlotState>,\n viewerMode = false,\n): void {\n const frame = [\n ...plugin.renderHeader(ctx),\n '',\n ...plugin.renderWorkers(ctx),\n ...(viewerMode ? [] : ['', hotkeysHint(ctx.poolSize, ctx.final)]),\n ...(plugin.renderExtras ? [''].concat(plugin.renderExtras(ctx)) : []),\n ].join('\\n');\n\n // Skip duplicate renders during live runs to avoid flicker.\n if (!ctx.final && frame === lastFrame) return;\n lastFrame = frame;\n\n if (!ctx.final) {\n // Hide cursor and repaint in place\n process.stdout.write('\\x1b[?25l');\n readline.cursorTo(process.stdout, 0, 0);\n readline.clearScreenDown(process.stdout);\n } else {\n // Restore cursor on final render\n process.stdout.write('\\x1b[?25h');\n }\n process.stdout.write(`${frame}\\n`);\n}\n","import { basename } from 'node:path';\n\nimport type { ObjByString } from '@transcend-io/type-utils';\nimport colors from 'colors';\n\nimport type { CommonCtx } from './dashboardPlugin.js';\n\n/**\n * Progress snapshot for a worker slot in the chunk-csv command.\n */\nexport type ChunkSlotProgress = {\n /** Absolute path of the file being processed by this worker. */\n filePath?: string;\n /** Number of rows processed so far in this file. */\n processed?: number;\n /** Optional total number of rows in the file (if known). */\n total?: number;\n};\n\n/**\n * Format a number safely for display.\n *\n * @param n - The number to format (or `undefined`).\n * @returns A localized string representation, or \"0\".\n */\nexport function fmtNum(n: number | undefined): string {\n return typeof n === 'number' ? n.toLocaleString() : '0';\n}\n\n/**\n * Draw a horizontal bar of length `width` filled to `pct` percent.\n *\n * @param pct - Percentage 0..100.\n * @param width - Number of characters in the bar.\n * @returns A string like \"████░░░░\".\n */\nexport function pctBar(pct: number, width = 40): string {\n const clamped = Math.max(0, Math.min(100, Math.floor(pct)));\n const filled = Math.floor((clamped / 100) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\n/**\n * Compute pool-wide progress values needed by headers.\n *\n * @param ctx - Dashboard context containing pool state, worker state, totals, etc.\n * @returns An object with `done`, `inProgress`, and `pct` properties.\n */\nexport function poolProgress<TTotals, TSlot extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlot>,\n): {\n /** Count of successfully completed files/tasks. */\n done: number;\n /** Count of currently in-progress files/tasks. */\n inProgress: number;\n /** Percentage of completion (0-100). */\n pct: number;\n} {\n const inProgress = [...ctx.workerState.values()].filter((s) => s.busy).length;\n const done = ctx.filesCompleted + ctx.filesFailed;\n const pct = ctx.filesTotal === 0 ? 100 : Math.floor((done / Math.max(1, ctx.filesTotal)) * 100);\n return { done, inProgress, pct };\n}\n\n/**\n * Compose the common header lines (title, pool stats, progress bar, throughput).\n *\n * @param ctx - Dashboard context.\n * @param extraLines - Optional extra lines (e.g., totals block).\n * @returns Header lines.\n */\nexport function makeHeader<TTotals, TSlot extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlot>,\n extraLines: string[] = [],\n): string[] {\n const { title, poolSize, cpuCount, filesTotal, filesCompleted, filesFailed, throughput } = ctx;\n const { inProgress, pct } = poolProgress(ctx);\n\n const lines: string[] = [\n `${colors.bold(title)} — ${poolSize} workers ${colors.dim(`(CPU avail: ${cpuCount})`)}`,\n `${colors.dim('Files')} ${fmtNum(filesTotal)} ${colors.dim(\n 'Completed',\n )} ${fmtNum(filesCompleted)} ${colors.dim('Failed')} ${\n filesFailed ? colors.red(fmtNum(filesFailed)) : fmtNum(filesFailed)\n } ${colors.dim('In-flight')} ${fmtNum(inProgress)}`,\n `[${pctBar(pct)}] ${pct}%`,\n ];\n\n if (throughput) {\n const jobsActive = throughput.jobsR10s > 0 || throughput.jobsR60s > 0;\n const perHour10 = Math.round(\n (jobsActive ? throughput.jobsR10s : throughput.r10s) * 3600,\n ).toLocaleString();\n const perHour60 = Math.round(\n (jobsActive ? throughput.jobsR60s : throughput.r60s) * 3600,\n ).toLocaleString();\n const unit = jobsActive ? 'rec' : 'files';\n const suffix =\n ctx.throughput?.successSoFar != null\n ? ` Newly uploaded: ${fmtNum(ctx.throughput.successSoFar)}`\n : '';\n lines.push(\n colors.cyan(`Throughput: ${perHour10} ${unit}/hr (1h: ${perHour60} ${unit}/hr)${suffix}`),\n );\n }\n\n return extraLines.length ? lines.concat(extraLines) : lines;\n}\n\n/**\n * Render per-worker rows with a compact progress bar and status badge.\n *\n * @param ctx - Dashboard context (slot progress type must have processed/total?).\n * @param getFileLabel - Optional: override how the filename is shown.\n * @returns Array of strings, each representing one worker row.\n */\nexport function makeWorkerRows<TTotals, TSlot extends Omit<ChunkSlotProgress, 'filePath'>>(\n ctx: CommonCtx<TTotals, TSlot>,\n getFileLabel: (file: string | null | undefined) => string = (file) =>\n file ? basename(file) : '-',\n): string[] {\n const miniWidth = 18;\n\n return [...ctx.workerState.entries()].map(([id, s]) => {\n const badge =\n s.lastLevel === 'error'\n ? colors.red('ERROR ')\n : s.lastLevel === 'warn'\n ? colors.yellow('WARN ')\n : s.busy\n ? colors.green('WORKING')\n : colors.dim('IDLE ');\n\n const fname = getFileLabel(s.file);\n const elapsed = s.startedAt ? `${Math.floor((Date.now() - s.startedAt) / 1000)}s` : '-';\n\n const processed = s.progress?.processed ?? 0;\n const total = s.progress?.total ?? 0;\n const pctw = total > 0 ? Math.floor((processed / total) * 100) : 0;\n const mini = total > 0 ? pctBar(pctw, miniWidth) : ' '.repeat(miniWidth);\n const miniTxt =\n total > 0\n ? `${processed.toLocaleString()}/${total.toLocaleString()} (${pctw}%)`\n : colors.dim('—');\n\n return ` [w${id}] ${badge} | ${fname} | ${elapsed} | [${mini}] ${miniTxt}`;\n });\n}\n","import type { ExportStatusMap, SlotPaths } from '@transcend-io/utils';\n\nimport { showCombinedLogs, type LogLocation } from './showCombinedLogs.js';\n\n/** Severity filter applied by the viewer. */\ntype ViewLevel = 'error' | 'warn' | 'all';\n\n/**\n * Options for {@link createExtraKeyHandler}.\n */\nexport type CreateExtraKeyHandlerOpts = {\n /**\n * Per-slot log file paths maintained by the runner; used to stream or export logs.\n */\n logsBySlot: SlotPaths;\n\n /**\n * Request an immediate dashboard repaint (e.g., after updating export status).\n */\n repaint: () => void;\n\n /**\n * Pause/unpause dashboard repainting. The handler pauses while a viewer is open\n * to prevent the dashboard from overwriting the viewer output, then resumes on exit.\n */\n setPaused: (p: boolean) => void;\n\n /**\n * Optional export manager to enable uppercase export keys:\n * - `E` (errors) • `W` (warnings) • `I` (info) • `A` (all)\n *\n * Provide this only if your command supports writing combined log files.\n */\n exportMgr?: {\n /** Destination directory for exported artifacts. */\n exportsDir: string;\n /**\n * Write a combined log file for the selected severity and return the absolute path.\n *\n * @param logs - Log paths to combine.\n * @param which - Severity selection.\n * @returns Absolute path to the written file.\n */\n exportCombinedLogs: (logs: SlotPaths, which: 'error' | 'warn' | 'info' | 'all') => string;\n };\n\n /**\n * Optional “Exports” status map. If provided, the handler updates timestamps\n * when exports are written so your dashboard panel can reflect “last saved” times.\n */\n exportStatus?: ExportStatusMap;\n\n /**\n * Optional custom key bindings for command-specific actions.\n * Each handler receives helpers to print messages and to update the exports panel.\n *\n * Example:\n * ```ts\n * custom: {\n * F: async ({ say, noteExport }) => {\n * const p = await writeFailingUpdatesCsv(...);\n * say(`Wrote failing updates to: ${p}`);\n * noteExport('failuresCsv', p);\n * }\n * }\n * ```\n */\n custom?: Record<\n string,\n (ctx: {\n /** Update {@link exportStatus} (if present) and repaint the dashboard. */\n noteExport: (slot: keyof ExportStatusMap, absPath: string) => void;\n /** Print a line to stdout, automatically newline-terminated. */\n say: (s: string) => void;\n }) => void | Promise<void>\n >;\n};\n\n/**\n * Create a keypress handler for interactive viewers/exports.\n * Shared handler for \"extra\" keyboard shortcuts used by the interactive dashboard.\n *\n * It wires:\n * - **Viewers (lowercase):** `e` (errors), `w` (warnings), `i` (info), `l` (all)\n * - **Exports (uppercase, optional):** `E` (errors), `W` (warnings), `I` (info), `A` (all)\n * - **Dismiss:** `Esc` or `Ctrl+]` exits a viewer and returns to the dashboard\n * - **Custom keys (optional):** Provide a `custom` map to handle command-specific bindings\n *\n * Usage (inside `runPool({... extraKeyHandler })`):\n * ```ts\n * extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n * createExtraKeyHandler({ logsBySlot, repaint, setPaused })\n * ```\n *\n * If you also want export hotkeys + an \"Exports\" panel:\n * ```ts\n * extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n * createExtraKeyHandler({\n * logsBySlot, repaint, setPaused,\n * exportMgr, // enables E/W/I/A\n * exportStatus, // keeps panel timestamps up to date\n * custom: { // optional, e.g. 'F' to export a CSV\n * F: async ({ say, noteExport }) => { ... }\n * }\n * })\n * ```\n *\n * @param opts - Configuration for viewers, exports, and custom keys.\n * @returns A `(buf: Buffer) => void` handler suitable for `process.stdin.on('data', ...)`.\n */\nexport function createExtraKeyHandler(opts: CreateExtraKeyHandlerOpts): (buf: Buffer) => void {\n const { logsBySlot, repaint, setPaused, exportMgr, exportStatus, custom } = opts;\n\n const say = (s: string): void => {\n process.stdout.write(`${s}\\n`);\n };\n\n /**\n * Record that an export was written and trigger a repaint so the dashboard’s\n * \"Exports\" panel shows the updated timestamp/path.\n *\n * @param slot - Slot name in {@link ExportStatusMap} (e.g., \"error\", \"warn\", etc.).\n * @param p - Absolute path to the exported file.\n */\n const noteExport = (slot: keyof ExportStatusMap, p: string): void => {\n const now = Date.now();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cur: any = exportStatus?.[slot] ?? { path: p };\n if (exportStatus) {\n exportStatus[slot] = {\n path: p || cur.path,\n savedAt: now,\n exported: true,\n };\n repaint();\n }\n };\n\n let viewing = false; // optional guard to prevent stacking viewers\n\n /**\n * Show an inline combined log viewer for the selected sources/level.\n * Pauses dashboard repaint to keep the viewer visible until the user exits.\n *\n * @param sources - Log sources to include (e.g., \"err\", \"warn\", \"info\").\n * @param level - Severity level to filter by (e.g., \"error\", \"warn\", \"all\").\n */\n const view = (sources: LogLocation[], level: ViewLevel): void => {\n if (viewing) return;\n viewing = true;\n setPaused(true);\n\n // optional UX: clear screen and show a hint\n process.stdout.write('\\x1b[2J\\x1b[H'); // clear+home\n process.stdout.write('Combined logs viewer (press Esc or Ctrl+] to return)\\n\\n');\n\n (async () => {\n try {\n await showCombinedLogs(logsBySlot, sources, level);\n // NOTE: do NOT unpause here; ESC will handle it.\n } catch {\n // If showCombinedLogs throws, recover and unpause\n viewing = false;\n setPaused(false);\n repaint();\n }\n })();\n };\n\n /**\n * Export combined logs (if an export manager was provided).\n *\n * @param which - Severity to export (e.g., \"error\", \"warn\", \"info\", \"all\").\n * @param label - Human-readable label for the export (e.g., \"error\", \"warn\").\n */\n const exportCombined = (which: 'error' | 'warn' | 'info' | 'all', label: string): void => {\n if (!exportMgr) return;\n try {\n const p = exportMgr.exportCombinedLogs(logsBySlot, which);\n say(`\\nWrote combined ${label} logs to: ${p}`);\n noteExport(which as keyof ExportStatusMap, p);\n } catch {\n say(`\\nFailed to write combined ${label} logs`);\n }\n };\n\n // The keypress handler the runner will attach to stdin.\n return (buf: Buffer): void => {\n const s = buf.toString('utf8');\n\n // Viewers (lowercase)\n if (s === 'e') {\n view(['err'], 'error');\n return;\n }\n if (s === 'w') {\n view(['warn', 'err'], 'warn');\n return;\n }\n if (s === 'i') {\n view(['info'], 'all');\n return;\n }\n if (s === 'l') {\n view(['out', 'err', 'structured'], 'all');\n return;\n }\n\n // Exports (uppercase) — enabled only when exportMgr is present\n if (s === 'E') {\n exportCombined('error', 'error');\n return;\n }\n if (s === 'W') {\n exportCombined('warn', 'warn');\n return;\n }\n if (s === 'I') {\n exportCombined('info', 'info');\n return;\n }\n if (s === 'A') {\n exportCombined('all', 'ALL');\n return;\n }\n\n // Command-specific bindings\n const fn = custom?.[s];\n if (fn) {\n fn({ noteExport, say });\n return;\n }\n\n // Exit a viewer (Esc / Ctrl+]) — resume dashboard\n if (s === '\\x1b' || s === '\\x1d') {\n viewing = false;\n setPaused(false);\n repaint();\n }\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"done-input-validation-DL31vk7g.mjs","names":[],"sources":["../src/lib/cli/done-input-validation.ts"],"sourcesContent":["/**\n * If the environment variable `DEVELOPMENT_MODE_VALIDATE_ONLY` is set,\n * this function will exit the process with a status code of 0.\n *\n * This is useful for development mode, where we want to validate the\n * command flags without actually running the command.\n *\n * This should be called after input validation, and must be agnostic to the environment (e.g., the existence of a file on the file system)\n *\n * @param exit - The function to exit the process.\n */\nexport function doneInputValidation(exit: (code?: number) => void): void {\n if (process.env.DEVELOPMENT_MODE_VALIDATE_ONLY === 'true') {\n exit(0);\n }\n}\n"],"mappings":"AAWA,SAAgB,EAAoB,EAAqC,CACnE,QAAQ,IAAI,iCAAmC,QACjD,EAAK,EAAE"}
|
package/dist/impl-4Habov2V.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{n as t}from"./buildXdiSyncEndpoint-DPAOTaDK.mjs";import{t as n}from"./validateTranscendAuth-CAO5ktnu.mjs";import{t as r}from"./done-input-validation-DL31vk7g.mjs";import{writeFileSync as i}from"node:fs";import a from"colors";async function o({auth:o,xdiLocation:s,file:c,removeIpAddresses:l,domainBlockList:u,xdiAllowedCommands:d,transcendUrl:f}){r(this.process.exit);let{syncGroups:p,html:m}=await t(await n(o),{xdiLocation:s,transcendUrl:f,removeIpAddresses:l,domainBlockList:u.length>0?u:void 0,xdiAllowedCommands:d});e.info(a.green(`Successfully constructed sync endpoint for sync groups: ${JSON.stringify(p,null,2)}`)),i(c,m),e.info(a.green(`Wrote configuration to file "${c}"!`))}export{o as buildXdiSyncEndpoint};
|
|
2
|
-
//# sourceMappingURL=impl-4Habov2V.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-4Habov2V.mjs","names":["buildXdiSyncEndpointHelper"],"sources":["../src/commands/consent/build-xdi-sync-endpoint/impl.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildXdiSyncEndpoint as buildXdiSyncEndpointHelper } from '../../../lib/consent-manager/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface BuildXdiSyncEndpointCommandFlags {\n auth: string;\n xdiLocation: string;\n file: string;\n removeIpAddresses: boolean;\n domainBlockList: string[];\n xdiAllowedCommands: string;\n transcendUrl: string;\n}\n\nexport async function buildXdiSyncEndpoint(\n this: LocalContext,\n {\n auth,\n xdiLocation,\n file,\n removeIpAddresses,\n domainBlockList,\n xdiAllowedCommands,\n transcendUrl,\n }: BuildXdiSyncEndpointCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Build the sync endpoint\n const { syncGroups, html } = await buildXdiSyncEndpointHelper(apiKeyOrList, {\n xdiLocation,\n transcendUrl,\n removeIpAddresses,\n domainBlockList: domainBlockList.length > 0 ? domainBlockList : undefined,\n xdiAllowedCommands,\n });\n\n // Log success\n logger.info(\n colors.green(\n `Successfully constructed sync endpoint for sync groups: ${JSON.stringify(\n syncGroups,\n null,\n 2,\n )}`,\n ),\n );\n\n // Write to disk\n writeFileSync(file, html);\n logger.info(colors.green(`Wrote configuration to file \"${file}\"!`));\n}\n"],"mappings":"kRAoBA,eAAsB,EAEpB,CACE,OACA,cACA,OACA,oBACA,kBACA,qBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAMtC,GAAM,CAAE,aAAY,QAAS,MAAMA,EAA2B,MAHnC,EAAsB,EAAK,CAGsB,CAC1E,cACA,eACA,oBACA,gBAAiB,EAAgB,OAAS,EAAI,EAAkB,IAAA,GAChE,qBACD,CAAC,CAGF,EAAO,KACL,EAAO,MACL,2DAA2D,KAAK,UAC9D,EACA,KACA,EACD,GACF,CACF,CAGD,EAAc,EAAM,EAAK,CACzB,EAAO,KAAK,EAAO,MAAM,gCAAgC,EAAK,IAAI,CAAC"}
|
package/dist/impl-7pxeoDZg.mjs
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./done-input-validation-DL31vk7g.mjs";import{spawn as n}from"node:child_process";import r from"node:fs";import i from"node:path";import a from"fast-glob";import o from"colors";function s(e,t,n){return new Promise((i,a)=>{let o=r.createReadStream(e),s=Buffer.alloc(0),c=t.length,l=0;o.on(`data`,e=>{let r=typeof e==`string`?Buffer.from(e):e;if(n){let e=n-l;if(e<=0){o.destroy(),i(!1);return}r.length>e&&(r=r.subarray(0,e)),l+=r.length}let a=s.length?Buffer.concat([s,r]):r;if(a.toString(`utf8`).toLowerCase().includes(t.toString(`utf8`))){o.destroy(),i(!0);return}s=c>1?Buffer.from(a.subarray(Math.max(0,a.length-(c-1)))):Buffer.alloc(0)}),o.on(`error`,a),o.on(`close`,()=>i(!1)),o.on(`end`,()=>i(!1))})}async function c(e,t,n){let r=0,i=Array.from({length:Math.min(t,e.length)},async()=>{for(;;){let t=r;if(r+=1,t>=e.length)return;await n(e[t])}});await Promise.all(i)}function l(e,t){return new Promise((r,i)=>{let a=n(e,[`-noheader`,`-batch`,`-cmd`,t],{stdio:[`ignore`,`pipe`,`pipe`]}),o=``,s=``;a.stdout.on(`data`,e=>{o+=String(e)}),a.stderr.on(`data`,e=>{s+=String(e)}),a.on(`error`,i),a.on(`close`,e=>{e===0?r(o):i(Error(`duckdb exited ${e}: ${s}`))})})}async function u(e,t){return(await l(e,[`SELECT column_name`,`FROM parquet_schema('${t.replace(/'/g,`''`)}')`,`WHERE lower(column_type) LIKE '%varchar%'`,` OR lower(column_type) LIKE '%string%';`].join(`
|
|
2
|
-
`))).split(`
|
|
3
|
-
`).map(e=>e.trim()).filter(Boolean)}async function d(e,t,n){let r=await u(e,t);if(r.length===0)return!1;let i=t.replace(/'/g,`''`),a=r.map(e=>`"${e.replace(/"/g,`""`)}" = '${n.replace(/'/g,`''`)}'`).join(` OR `);return(await l(e,[`SELECT 1 AS hit FROM read_parquet('${i}')`,`WHERE ${a}`,`LIMIT 1;`].join(`
|
|
4
|
-
`))).trim().length>0}async function f(n){t(this.process.exit);let{needle:r,root:l,exts:u,noParquet:f,concurrency:p,maxBytes:m}=n,h=i.resolve(l),g=new Set(u.split(`,`).map(e=>e.trim().replace(/^\./,``).toLowerCase()).filter(Boolean)),_=Array.from(g).map(e=>`**/*.${e}`);e.info(o.green(`Searching for "${r}" in ${h} (exts: ${[...g].join(`, `)})`));let v=await a(_,{cwd:h,absolute:!0,onlyFiles:!0,followSymbolicLinks:!1,suppressErrors:!0}),y=Buffer.from(r.toLowerCase(),`utf8`),b=[];if(await c(v,p,async e=>{try{await s(e,y,m)&&(b.push(e),this.process.stdout.write(`${e}\n`))}catch{}}),!f){let t=await a([`**/*.parquet`],{cwd:h,absolute:!0,onlyFiles:!0,followSymbolicLinks:!1,suppressErrors:!0});t.length>0&&(e.info(o.green(`Scanning ${t.length} parquet file(s) via DuckDB...`)),await c(t,Math.max(2,Math.floor(p/4)),async e=>{try{await d(`duckdb`,e,r)&&(b.push(e),this.process.stdout.write(`${e}\n`))}catch{}}))}e.info(o.green(`Done. Found ${b.length} matching file(s).`))}export{f as findTextInFolder};
|
|
5
|
-
//# sourceMappingURL=impl-7pxeoDZg.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-7pxeoDZg.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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"}
|
package/dist/impl-B0-rCxY1.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./notifyPrivacyRequestsAdditionalTime-vHikIxVO.mjs";import{t}from"./done-input-validation-DL31vk7g.mjs";async function n({auth:n,transcendUrl:r,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s,actions:c,daysLeft:l,days:u,requestIds:d,emailTemplate:f,concurrency:p}){t(this.process.exit),await e({transcendUrl:r,requestActions:c,auth:n,emailTemplate:f,days:u,daysLeft:l,requestIds:d,concurrency:p,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s})}export{n as notifyAdditionalTime};
|
|
2
|
-
//# sourceMappingURL=impl-B0-rCxY1.mjs.map
|
package/dist/impl-B0oCwFpP2.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./skipPreflightJobs-Cl98mx0Z.mjs";import{t}from"./done-input-validation-DL31vk7g.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-B0oCwFpP2.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-B24TOrY-.mjs","names":[],"sources":["../src/lib/code-scanning/findCodePackagesInFolder.ts","../src/commands/inventory/scan-packages/impl.ts"],"sourcesContent":["import { getEntries } from '@transcend-io/type-utils';\nimport colors from 'colors';\nimport fastGlob from 'fast-glob';\n\nimport { CodePackageInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { CODE_SCANNING_CONFIGS } from './constants.js';\n\n/**\n * Helper to scan and discovery all of the code packages within a folder\n *\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findCodePackagesInFolder({\n scanPath,\n ignoreDirs = [],\n repositoryName,\n}: {\n /** The name of the github repository reporting packages for */\n repositoryName: string;\n /** Where to look for package.json files */\n scanPath: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs?: string[];\n}): Promise<CodePackageInput[]> {\n const allCodePackages = await Promise.all(\n getEntries(CODE_SCANNING_CONFIGS).map(async ([codePackageType, config]) => {\n const { ignoreDirs: configIgnoreDirs, supportedFiles, scanFunction } = config;\n const dirsToIgnore = [...ignoreDirs, ...configIgnoreDirs].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${supportedFiles.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(\n colors.magenta(`Scanning: ${filesToScan.length} files of type ${codePackageType}`),\n );\n const allPackages = filesToScan\n .map((filePath) =>\n scanFunction(filePath).map((result) => ({\n ...result,\n relativePath: filePath.replace(`${scanPath}/`, ''),\n })),\n )\n .flat();\n logger.info(\n colors.green(\n `Found: ${allPackages.length} packages and ${\n allPackages.map(({ softwareDevelopmentKits = [] }) => softwareDevelopmentKits).flat()\n .length\n } sdks`,\n ),\n );\n\n return allPackages.map(\n (pkg): CodePackageInput => ({\n ...pkg,\n type: codePackageType,\n repositoryName,\n }),\n );\n } catch (error) {\n throw new Error(`Error scanning globs ${supportedFiles} with error: ${error}`);\n }\n }),\n );\n\n return allCodePackages.flat();\n}\n","import { execSync } from 'child_process';\n\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findCodePackagesInFolder } from '../../../lib/code-scanning/index.js';\nimport { syncCodePackages } from '../../../lib/graphql/index.js';\nimport { logger } from '../../../logger.js';\n\nconst REPO_ERROR =\n 'A repository name must be provided. ' +\n 'You can specify using --repositoryName=$REPO_NAME or by ensuring the ' +\n 'command \"git config --get remote.origin.url\" returns the name of the repository';\n\nexport interface ScanPackagesCommandFlags {\n auth: string;\n scanPath: string;\n ignoreDirs?: string[];\n repositoryName?: string;\n transcendUrl: string;\n}\n\nexport async function scanPackages(\n this: LocalContext,\n { auth, scanPath, ignoreDirs, repositoryName, transcendUrl }: ScanPackagesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Ensure repository name is specified\n let gitRepositoryName = repositoryName;\n if (!gitRepositoryName) {\n try {\n const name = execSync(`cd ${scanPath} && git config --get remote.origin.url`);\n // Trim and parse the URL\n const url = name.toString('utf-8').trim();\n [gitRepositoryName] = !url.includes('https:')\n ? (url.split(':').pop() || '').split('.')\n : url.split('/').slice(3).join('/').split('.');\n if (!gitRepositoryName) {\n logger.error(colors.red(REPO_ERROR));\n this.process.exit(1);\n }\n } catch (err) {\n logger.error(colors.red(`${REPO_ERROR} - Got error: ${err.message}`));\n this.process.exit(1);\n }\n }\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Scan the codebase to discovery packages\n const results = await findCodePackagesInFolder({\n scanPath,\n ignoreDirs,\n repositoryName: gitRepositoryName,\n });\n\n // Report scan to Transcend\n await syncCodePackages(client, results);\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/code-scanning/code-packages';\n\n // Indicate success\n logger.info(\n colors.green(\n `Scan found ${results.length} packages at ${scanPath}! ` + `View results at '${newUrl.href}'`,\n ),\n );\n}\n"],"mappings":"qbAcA,eAAsB,EAAyB,CAC7C,WACA,aAAa,EAAE,CACf,kBAQ8B,CA4C9B,OAAO,MA3CuB,QAAQ,IACpC,EAAW,EAAsB,CAAC,IAAI,MAAO,CAAC,EAAiB,KAAY,CACzE,GAAM,CAAE,WAAY,EAAkB,iBAAgB,gBAAiB,EACjE,EAAe,CAAC,GAAG,EAAY,GAAG,EAAiB,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CACzF,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KACL,EAAO,QAAQ,aAAa,EAAY,OAAO,iBAAiB,IAAkB,CACnF,CACD,IAAM,EAAc,EACjB,IAAK,GACJ,EAAa,EAAS,CAAC,IAAK,IAAY,CACtC,GAAG,EACH,aAAc,EAAS,QAAQ,GAAG,EAAS,GAAI,GAAG,CACnD,EAAE,CACJ,CACA,MAAM,CAUT,OATA,EAAO,KACL,EAAO,MACL,UAAU,EAAY,OAAO,gBAC3B,EAAY,KAAK,CAAE,0BAA0B,EAAE,IAAO,EAAwB,CAAC,MAAM,CAClF,OACJ,OACF,CACF,CAEM,EAAY,IAChB,IAA2B,CAC1B,GAAG,EACH,KAAM,EACN,iBACD,EACF,OACM,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAe,eAAe,IAAQ,GAEhF,CACH,EAEsB,MAAM,CCzD/B,MAAM,EACJ,2LAYF,eAAsB,EAEpB,CAAE,OAAM,WAAU,aAAY,iBAAgB,gBAC/B,CACf,EAAoB,KAAK,QAAQ,KAAK,CAGtC,IAAI,EAAoB,EACxB,GAAI,CAAC,EACH,GAAI,CAGF,IAAM,EAFO,EAAS,MAAM,EAAS,wCAErB,CAAC,SAAS,QAAQ,CAAC,MAAM,CACzC,CAAC,GAAsB,EAAI,SAAS,SAAS,CAEzC,EAAI,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,EAD3C,EAAI,MAAM,IAAI,CAAC,KAAK,EAAI,IAAI,MAAM,IAAI,CAEtC,IACH,EAAO,MAAM,EAAO,IAAI,EAAW,CAAC,CACpC,KAAK,QAAQ,KAAK,EAAE,QAEf,EAAK,CACZ,EAAO,MAAM,EAAO,IAAI,GAAG,EAAW,gBAAgB,EAAI,UAAU,CAAC,CACrE,KAAK,QAAQ,KAAK,EAAE,CAKxB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAU,MAAM,EAAyB,CAC7C,WACA,aACA,eAAgB,EACjB,CAAC,CAGF,MAAM,EAAiB,EAAQ,EAAQ,CAEvC,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,+BAGlB,EAAO,KACL,EAAO,MACL,cAAc,EAAQ,OAAO,eAAe,EAAS,qBAA0B,EAAO,KAAK,GAC5F,CACF"}
|
package/dist/impl-B2eZGemA.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{a as t,r as n}from"./readTranscendYaml-bL1qFPqv.mjs";import{t as r}from"./listFiles-C5kubvdN.mjs";import{t as i}from"./done-input-validation-DL31vk7g.mjs";import{t as a}from"./dataFlowsToDataSilos-DRuAfwIn.mjs";import{difference as o}from"lodash-es";import{existsSync as s,lstatSync as c}from"node:fs";import{join as l}from"node:path";import u from"colors";import{buildTranscendGraphQLClient as d,fetchAndIndexCatalogs as f}from"@transcend-io/sdk";async function p({auth:p,dataFlowsYmlFolder:m,output:h,ignoreYmls:g=[],transcendUrl:_}){i(this.process.exit),(!s(m)||!c(m).isDirectory())&&(e.error(u.red(`Folder does not exist: "${m}"`)),this.process.exit(1));let v=g.map(e=>e.split(`.`)[0]),y=r(m).map(e=>{let{"data-flows":t=[]}=n(l(m,e)),{adTechDataSilos:r,siteTechDataSilos:i}=a(t,{serviceToSupportedIntegration:T,serviceToTitle:w});return{adTechDataSilos:r,siteTechDataSilos:i,organizationName:e.split(`.`)[0]}}),b={};y.forEach(({adTechDataSilos:e,siteTechDataSilos:t,organizationName:n})=>{[...e,...t].forEach(e=>{let t=e[`outer-type`]||e.integrationName;b[t]||(b[t]=[]),b[t].push(n),b[t]=[...new Set(b[t])]})});let x=[...new Set(y.map(({adTechDataSilos:e})=>e.map(e=>e[`outer-type`]||e.integrationName)).flat())],S=o([...new Set(y.map(({siteTechDataSilos:e})=>e.map(e=>e[`outer-type`]||e.integrationName)).flat())],x),C={};y.forEach(({adTechDataSilos:e,siteTechDataSilos:t})=>{[...e,...t].forEach(e=>{let t=e[`outer-type`]||e.integrationName,n=e.attributes?.find(e=>e.key===`Found On Domain`);C[t]||(C[t]=[]),C[t].push(...n?.values||[]),C[t]=[...new Set(C[t])]})});let{serviceToTitle:w,serviceToSupportedIntegration:T}=await f(d(_,p),{logger:e}),E=[...x,...S].map(e=>({title:w[e],...T[e]?{integrationName:e}:{integrationName:`promptAPerson`,"outer-type":e},attributes:[{key:`Tech Type`,values:[`Ad Tech`]},{key:`Business Units`,values:o(b[e]||[],v)},{key:`Found On Domain`,values:C[e]||[]}]}));e.log(`Total Services: ${E.length}`),e.log(`Ad Tech Services: ${x.length}`),e.log(`Site Tech Services: ${S.length}`),t(h,{"data-silos":E})}export{p as deriveDataSilosFromDataFlowsCrossInstance};
|
|
2
|
-
//# sourceMappingURL=impl-B2eZGemA.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-B2eZGemA.mjs","names":[],"sources":["../src/commands/inventory/derive-data-silos-from-data-flows-cross-instance/impl.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { buildTranscendGraphQLClient, fetchAndIndexCatalogs } from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { difference } from 'lodash-es';\n\nimport { DataFlowInput } from '../../../codecs.js';\nimport type { LocalContext } from '../../../context.js';\nimport { listFiles } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { dataFlowsToDataSilos } from '../../../lib/consent-manager/dataFlowsToDataSilos.js';\nimport { readTranscendYaml, writeTranscendYaml } from '../../../lib/readTranscendYaml.js';\nimport { logger } from '../../../logger.js';\n\nexport interface DeriveDataSilosFromDataFlowsCrossInstanceCommandFlags {\n auth: string;\n dataFlowsYmlFolder: string;\n output: string;\n ignoreYmls?: string[];\n transcendUrl: string;\n}\n\nexport async function deriveDataSilosFromDataFlowsCrossInstance(\n this: LocalContext,\n {\n auth,\n dataFlowsYmlFolder,\n output,\n ignoreYmls = [],\n transcendUrl,\n }: DeriveDataSilosFromDataFlowsCrossInstanceCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Ensure folder is passed\n if (!existsSync(dataFlowsYmlFolder) || !lstatSync(dataFlowsYmlFolder).isDirectory()) {\n logger.error(colors.red(`Folder does not exist: \"${dataFlowsYmlFolder}\"`));\n this.process.exit(1);\n }\n\n // Ignore the data flows in these yml files\n const instancesToIgnore = ignoreYmls.map((x) => x.split('.')[0]);\n\n // Map over each data flow yml file and convert to data silo configurations\n const dataSiloInputs = listFiles(dataFlowsYmlFolder).map((directory) => {\n // read in the data flows for a specific instance\n const { 'data-flows': dataFlows = [] } = readTranscendYaml(join(dataFlowsYmlFolder, directory));\n\n // map the data flows to data silos\n const { adTechDataSilos, siteTechDataSilos } = dataFlowsToDataSilos(\n dataFlows as DataFlowInput[],\n {\n serviceToSupportedIntegration,\n serviceToTitle,\n },\n );\n\n return {\n adTechDataSilos,\n siteTechDataSilos,\n organizationName: directory.split('.')[0],\n };\n });\n\n // Mapping from service name to instances that have that service\n const serviceToInstance: { [k in string]: string[] } = {};\n dataSiloInputs.forEach(({ adTechDataSilos, siteTechDataSilos, organizationName }) => {\n const allDataSilos = [...adTechDataSilos, ...siteTechDataSilos];\n allDataSilos.forEach((dataSilo) => {\n const service = dataSilo['outer-type'] || dataSilo.integrationName;\n // create mapping to instance\n if (!serviceToInstance[service]) {\n serviceToInstance[service] = [];\n }\n serviceToInstance[service]!.push(organizationName);\n serviceToInstance[service] = [...new Set(serviceToInstance[service])];\n });\n });\n\n // List of ad tech integrations\n const adTechIntegrations = [\n ...new Set(\n dataSiloInputs\n .map(({ adTechDataSilos }) =>\n adTechDataSilos.map((silo) => silo['outer-type'] || silo.integrationName),\n )\n .flat(),\n ),\n ];\n\n // List of site tech integrations\n const siteTechIntegrations = difference(\n [\n ...new Set(\n dataSiloInputs\n .map(({ siteTechDataSilos }) =>\n siteTechDataSilos.map((silo) => silo['outer-type'] || silo.integrationName),\n )\n .flat(),\n ),\n ],\n adTechIntegrations,\n );\n\n // Mapping from service name to list of\n const serviceToFoundOnDomain: { [k in string]: string[] } = {};\n dataSiloInputs.forEach(({ adTechDataSilos, siteTechDataSilos }) => {\n const allDataSilos = [...adTechDataSilos, ...siteTechDataSilos];\n allDataSilos.forEach((dataSilo) => {\n const service = dataSilo['outer-type'] || dataSilo.integrationName;\n const foundOnDomain = dataSilo.attributes?.find((attr) => attr.key === 'Found On Domain');\n // create mapping to instance\n if (!serviceToFoundOnDomain[service]) {\n serviceToFoundOnDomain[service] = [];\n }\n serviceToFoundOnDomain[service]!.push(...(foundOnDomain?.values || []));\n serviceToFoundOnDomain[service] = [...new Set(serviceToFoundOnDomain[service])];\n });\n });\n\n // Fetch all integrations in the catalog\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n const { serviceToTitle, serviceToSupportedIntegration } = await fetchAndIndexCatalogs(client, {\n logger,\n });\n\n // construct the aggregated data silo inputs\n const dataSilos = [...adTechIntegrations, ...siteTechIntegrations].map((service) => ({\n title: serviceToTitle[service],\n ...(serviceToSupportedIntegration[service]\n ? { integrationName: service }\n : { integrationName: 'promptAPerson', 'outer-type': service }),\n attributes: [\n {\n key: 'Tech Type',\n values: ['Ad Tech'],\n },\n {\n key: 'Business Units',\n values: difference(serviceToInstance[service] || [], instancesToIgnore),\n },\n {\n key: 'Found On Domain',\n values: serviceToFoundOnDomain[service] || [],\n },\n ],\n }));\n\n // Log output\n logger.log(`Total Services: ${dataSilos.length}`);\n logger.log(`Ad Tech Services: ${adTechIntegrations.length}`);\n logger.log(`Site Tech Services: ${siteTechIntegrations.length}`);\n\n // Write to yaml\n writeTranscendYaml(output, {\n 'data-silos': dataSilos,\n });\n}\n"],"mappings":"ifAuBA,eAAsB,EAEpB,CACE,OACA,qBACA,SACA,aAAa,EAAE,CACf,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,EAGlC,CAAC,EAAW,EAAmB,EAAI,CAAC,EAAU,EAAmB,CAAC,aAAa,IACjF,EAAO,MAAM,EAAO,IAAI,2BAA2B,EAAmB,GAAG,CAAC,CAC1E,KAAK,QAAQ,KAAK,EAAE,EAItB,IAAM,EAAoB,EAAW,IAAK,GAAM,EAAE,MAAM,IAAI,CAAC,GAAG,CAG1D,EAAiB,EAAU,EAAmB,CAAC,IAAK,GAAc,CAEtE,GAAM,CAAE,aAAc,EAAY,EAAE,EAAK,EAAkB,EAAK,EAAoB,EAAU,CAAC,CAGzF,CAAE,kBAAiB,qBAAsB,EAC7C,EACA,CACE,gCACA,iBACD,CACF,CAED,MAAO,CACL,kBACA,oBACA,iBAAkB,EAAU,MAAM,IAAI,CAAC,GACxC,EACD,CAGI,EAAiD,EAAE,CACzD,EAAe,SAAS,CAAE,kBAAiB,oBAAmB,sBAAuB,CAEnF,CADsB,GAAG,EAAiB,GAAG,EACjC,CAAC,QAAS,GAAa,CACjC,IAAM,EAAU,EAAS,eAAiB,EAAS,gBAE9C,EAAkB,KACrB,EAAkB,GAAW,EAAE,EAEjC,EAAkB,GAAU,KAAK,EAAiB,CAClD,EAAkB,GAAW,CAAC,GAAG,IAAI,IAAI,EAAkB,GAAS,CAAC,EACrE,EACF,CAGF,IAAM,EAAqB,CACzB,GAAG,IAAI,IACL,EACG,KAAK,CAAE,qBACN,EAAgB,IAAK,GAAS,EAAK,eAAiB,EAAK,gBAAgB,CAC1E,CACA,MAAM,CACV,CACF,CAGK,EAAuB,EAC3B,CACE,GAAG,IAAI,IACL,EACG,KAAK,CAAE,uBACN,EAAkB,IAAK,GAAS,EAAK,eAAiB,EAAK,gBAAgB,CAC5E,CACA,MAAM,CACV,CACF,CACD,EACD,CAGK,EAAsD,EAAE,CAC9D,EAAe,SAAS,CAAE,kBAAiB,uBAAwB,CAEjE,CADsB,GAAG,EAAiB,GAAG,EACjC,CAAC,QAAS,GAAa,CACjC,IAAM,EAAU,EAAS,eAAiB,EAAS,gBAC7C,EAAgB,EAAS,YAAY,KAAM,GAAS,EAAK,MAAQ,kBAAkB,CAEpF,EAAuB,KAC1B,EAAuB,GAAW,EAAE,EAEtC,EAAuB,GAAU,KAAK,GAAI,GAAe,QAAU,EAAE,CAAE,CACvE,EAAuB,GAAW,CAAC,GAAG,IAAI,IAAI,EAAuB,GAAS,CAAC,EAC/E,EACF,CAIF,GAAM,CAAE,iBAAgB,iCAAkC,MAAM,EADjD,EAA4B,EAAc,EACmC,CAAE,CAC5F,SACD,CAAC,CAGI,EAAY,CAAC,GAAG,EAAoB,GAAG,EAAqB,CAAC,IAAK,IAAa,CACnF,MAAO,EAAe,GACtB,GAAI,EAA8B,GAC9B,CAAE,gBAAiB,EAAS,CAC5B,CAAE,gBAAiB,gBAAiB,aAAc,EAAS,CAC/D,WAAY,CACV,CACE,IAAK,YACL,OAAQ,CAAC,UAAU,CACpB,CACD,CACE,IAAK,iBACL,OAAQ,EAAW,EAAkB,IAAY,EAAE,CAAE,EAAkB,CACxE,CACD,CACE,IAAK,kBACL,OAAQ,EAAuB,IAAY,EAAE,CAC9C,CACF,CACF,EAAE,CAGH,EAAO,IAAI,mBAAmB,EAAU,SAAS,CACjD,EAAO,IAAI,qBAAqB,EAAmB,SAAS,CAC5D,EAAO,IAAI,uBAAuB,EAAqB,SAAS,CAGhE,EAAmB,EAAQ,CACzB,aAAc,EACf,CAAC"}
|
package/dist/impl-B3whGgMU2.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./skipRequestDataSilos-mxRGsUpY.mjs";import{t}from"./done-input-validation-DL31vk7g.mjs";async function n({auth:n,dataSiloId:r,status:i,statuses:a,transcendUrl:o,actionTypes:s}){t(this.process.exit),await e({transcendUrl:o,auth:n,status:i,dataSiloId:r,requestStatuses:a,actionTypes:s})}export{n as skipRequestDataSilos};
|
|
2
|
-
//# sourceMappingURL=impl-B3whGgMU2.mjs.map
|
package/dist/impl-B7ceQwag.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./collectParquetFilesOrExit-DVS9_OSv.mjs";import{t as n}from"./done-input-validation-DL31vk7g.mjs";import{a as r,i,n as a,r as o,t as s}from"./createExtraKeyHandler-ComtD6CG.mjs";import c from"colors";import{CHILD_FLAG as l,PoolCancelledError as u,computePoolSize as d,resolveWorkerPath as f,runPool as p}from"@transcend-io/utils";function m(e){return a(e)}function h(e){return o(e)}const g={renderHeader:m,renderWorkers:h};async function _(a){n(this.process.exit);let{directory:o,outputDir:m,clearOutputDir:h,concurrency:_,viewerMode:v}=a,y=t(o,this),{poolSize:b,cpuCount:x}=d(_,y.length);e.info(c.green(`Converting ${y.length} Parquet file(s) → CSV with pool size ${b} (CPU=${x})`));let S=y.map(e=>({filePath:e,options:{outputDir:m,clearOutputDir:h}}));await p({title:`Parquet → CSV - ${o}`,baseDir:o||m||process.cwd(),childFlag:l,childModulePath:f(import.meta.url,`commands/admin/parquet-to-csv/worker.mjs`),poolSize:b,cpuCount:x,filesTotal:y.length,hooks:{nextTask:()=>S.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:v,render:e=>i(e,g,v),installInteractiveSwitcher:v?void 0:({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,setPaused:o,repaint:s})=>r({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,onAttach:()=>o(!0),onDetach:()=>{o(!1),s()},onEnterAttachScreen:e=>{o(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Attached to worker ${e}. (Esc/Ctrl+] detach \u2022 Ctrl+D EOF \u2022 Ctrl+C SIGINT)\n`)}}),extraKeyHandler:({logsBySlot:e,repaint:t,setPaused:n})=>s({logsBySlot:e,repaint:t,setPaused:n})}).catch(e=>{throw e instanceof u&&process.exit(130),e})}export{_ as parquetToCsv};
|
|
2
|
-
//# sourceMappingURL=impl-B7ceQwag.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-B7ceQwag.mjs","names":[],"sources":["../src/commands/admin/parquet-to-csv/ui/plugin.ts","../src/commands/admin/parquet-to-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for parquet-to-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for parquet-to-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const parquetToCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectParquetFilesOrExit } from '../../../lib/helpers/index.js';\nimport {\n createExtraKeyHandler,\n dashboardPlugin,\n installInteractiveSwitcher,\n} from '../../../lib/pooling/index.js';\nimport { logger } from '../../../logger.js';\nimport { parquetToCsvPlugin } from './ui/index.js';\nimport type { ParquetProgress, ParquetResult, ParquetTask } from './worker.js';\n\n/** No custom totals for the header; the runner’s built-ins suffice. */\ntype Totals = Record<string, never>;\n\nexport type ParquetToCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Convert all Parquet files in a directory to CSV, in parallel.\n *\n * @param flags - The command flags.\n */\nexport async function parquetToCsv(\n this: LocalContext,\n flags: ParquetToCsvCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { directory, outputDir, clearOutputDir, concurrency, viewerMode } = flags;\n\n /* 1) Discover .parquet inputs */\n const files = collectParquetFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n logger.info(\n colors.green(\n `Converting ${files.length} Parquet file(s) → CSV with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Build FIFO queue of tasks (one per file) */\n const queue = files.map<ParquetTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir },\n }));\n\n /* 4) Pool hooks */\n const hooks: PoolHooks<ParquetTask, ParquetProgress, ParquetResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n postProcess: async () => {\n // nothing special post-run\n },\n };\n\n /* 5) Launch the pool runner with custom dashboard plugin */\n await runPool({\n title: `Parquet → CSV - ${directory}`,\n baseDir: directory || outputDir || process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/parquet-to-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n render: (input) => dashboardPlugin(input, parquetToCsvPlugin, viewerMode),\n installInteractiveSwitcher: viewerMode\n ? undefined\n : ({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n setPaused,\n repaint: rp,\n }) =>\n installInteractiveSwitcher({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n onAttach: () => setPaused(true),\n onDetach: () => {\n setPaused(false);\n rp();\n },\n onEnterAttachScreen: (id) => {\n setPaused(true);\n process.stdout.write('\\x1b[2J\\x1b[H');\n process.stdout.write(\n `Attached to worker ${id}. (Esc/Ctrl+] detach \\u2022 Ctrl+D EOF \\u2022 Ctrl+C SIGINT)\\n`,\n );\n },\n }),\n extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n createExtraKeyHandler({ logsBySlot, repaint, setPaused }),\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"mYAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAAkE,CAC7E,eACA,gBAED,CCKD,eAAsB,EAEpB,EACe,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAe,EAGpE,EAAQ,EAA0B,EAAW,KAAK,CAGlD,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,EAAO,KACL,EAAO,MACL,cAAc,EAAM,OAAO,wCAAwC,EAAS,QAAQ,EAAS,GAC9F,CACF,CAGD,IAAM,EAAQ,EAAM,IAAkB,IAAc,CAClD,WACA,QAAS,CAAE,YAAW,iBAAgB,CACvC,EAAE,CAgBH,MAAM,EAAQ,CACZ,MAAO,mBAAmB,IAC1B,QAAS,GAAa,GAAa,QAAQ,KAAK,CAChD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,2CAA2C,CAC/F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CApBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EACpD,YAAa,SAAY,GAcpB,CACL,aACA,OAAS,GAAU,EAAgB,EAAO,EAAoB,EAAW,CACzE,2BAA4B,EACxB,IAAA,IACC,CACC,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,YACA,QAAS,KAET,EAA2B,CACzB,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,aAAgB,EAAU,GAAK,CAC/B,aAAgB,CACd,EAAU,GAAM,CAChB,GAAI,EAEN,oBAAsB,GAAO,CAC3B,EAAU,GAAK,CACf,QAAQ,OAAO,MAAM,gBAAgB,CACrC,QAAQ,OAAO,MACb,sBAAsB,EAAG,gEAC1B,EAEJ,CAAC,CACR,iBAAkB,CAAE,aAAY,UAAS,eACvC,EAAsB,CAAE,aAAY,UAAS,YAAW,CAAC,CAC5D,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,QAAQ,KAAK,IAAI,CAEb,GACN"}
|
package/dist/impl-B7qkiYZY2.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./retryRequestDataSilos-DDdC7nXr.mjs";import{t}from"./done-input-validation-DL31vk7g.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-B7qkiYZY2.mjs.map
|
package/dist/impl-BTFeQDKS.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./updateConsentManagerVersionToLatest-BbSaHE83.mjs";import{t as n}from"./validateTranscendAuth-CAO5ktnu.mjs";import{t as r}from"./done-input-validation-DL31vk7g.mjs";import{ConsentBundleType as i}from"@transcend-io/privacy-types";import a from"colors";import{mapSeries as o}from"@transcend-io/utils";async function s({auth:s,bundleTypes:c=[i.Production,i.Test],deploy:l,transcendUrl:u}){r(this.process.exit);let d=await n(s);typeof d==`string`?(await t({deploy:l,transcendUrl:u,auth:d,bundleTypes:c}),e.info(a.green(`Successfully updated Consent Manager!`))):(await o(d,async n=>{e.info(a.magenta(`Updating Consent Manager for organization "${n.organizationName}"...`)),await t({deploy:l,transcendUrl:u,auth:n.apiKey,bundleTypes:c}),e.info(a.green(`Successfully updated Consent Manager for organization "${n.organizationName}"!`))}),e.info(a.green(`Successfully updated Consent Managers!`)))}export{s as updateConsentManager};
|
|
2
|
-
//# sourceMappingURL=impl-BTFeQDKS.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BTFeQDKS.mjs","names":[],"sources":["../src/commands/consent/update-consent-manager/impl.ts"],"sourcesContent":["import { ConsentBundleType } from '@transcend-io/privacy-types';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { updateConsentManagerVersionToLatest } from '../../../lib/consent-manager/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface UpdateConsentManagerCommandFlags {\n auth: string;\n bundleTypes: ConsentBundleType[];\n deploy: boolean;\n transcendUrl: string;\n}\n\nexport async function updateConsentManager(\n this: LocalContext,\n {\n auth,\n bundleTypes = [ConsentBundleType.Production, ConsentBundleType.Test],\n deploy,\n transcendUrl,\n }: UpdateConsentManagerCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Handle single update\n if (typeof apiKeyOrList === 'string') {\n // Update consent manager\n await updateConsentManagerVersionToLatest({\n deploy,\n transcendUrl,\n auth: apiKeyOrList,\n bundleTypes,\n });\n logger.info(colors.green('Successfully updated Consent Manager!'));\n } else {\n await mapSeries(apiKeyOrList, async (apiKey) => {\n logger.info(\n colors.magenta(`Updating Consent Manager for organization \"${apiKey.organizationName}\"...`),\n );\n\n await updateConsentManagerVersionToLatest({\n deploy,\n transcendUrl,\n auth: apiKey.apiKey,\n bundleTypes,\n });\n\n logger.info(\n colors.green(\n `Successfully updated Consent Manager for organization \"${apiKey.organizationName}\"!`,\n ),\n );\n });\n logger.info(colors.green('Successfully updated Consent Managers!'));\n }\n}\n"],"mappings":"oWAiBA,eAAsB,EAEpB,CACE,OACA,cAAc,CAAC,EAAkB,WAAY,EAAkB,KAAK,CACpE,SACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAGtC,IAAM,EAAe,MAAM,EAAsB,EAAK,CAGlD,OAAO,GAAiB,UAE1B,MAAM,EAAoC,CACxC,SACA,eACA,KAAM,EACN,cACD,CAAC,CACF,EAAO,KAAK,EAAO,MAAM,wCAAwC,CAAC,GAElE,MAAM,EAAU,EAAc,KAAO,IAAW,CAC9C,EAAO,KACL,EAAO,QAAQ,8CAA8C,EAAO,iBAAiB,MAAM,CAC5F,CAED,MAAM,EAAoC,CACxC,SACA,eACA,KAAM,EAAO,OACb,cACD,CAAC,CAEF,EAAO,KACL,EAAO,MACL,0DAA0D,EAAO,iBAAiB,IACnF,CACF,EACD,CACF,EAAO,KAAK,EAAO,MAAM,yCAAyC,CAAC"}
|
package/dist/impl-B_s0saYs2.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./cancelPrivacyRequests-DIfhHbQn.mjs";import{t}from"./done-input-validation-DL31vk7g.mjs";async function n({auth:n,actions:r,statuses:i=[],requestIds:a,silentModeBefore:o,createdAtBefore:s,createdAtAfter:c,updatedAtBefore:l,updatedAtAfter:u,cancellationTitle:d,transcendUrl:f,concurrency:p}){t(this.process.exit),await e({transcendUrl:f,requestActions:r,auth:n,cancellationTitle:d,requestIds:a,statuses:i,concurrency:p,silentModeBefore:o?new Date(o):void 0,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})}export{n as cancel};
|
|
2
|
-
//# sourceMappingURL=impl-B_s0saYs2.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-B_s0saYs2.mjs","names":[],"sources":["../src/commands/request/cancel/impl.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { cancelPrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface CancelCommandFlags {\n auth: string;\n actions: RequestAction[];\n statuses?: RequestStatus[];\n requestIds?: string[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n cancellationTitle: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function cancel(\n this: LocalContext,\n {\n auth,\n actions,\n statuses = [],\n requestIds,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n cancellationTitle,\n transcendUrl,\n concurrency,\n }: CancelCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await cancelPrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n cancellationTitle,\n requestIds,\n statuses,\n concurrency,\n silentModeBefore: silentModeBefore ? new Date(silentModeBefore) : undefined,\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 });\n}\n"],"mappings":"6GAqBA,eAAsB,EAEpB,CACE,OACA,UACA,WAAW,EAAE,CACb,aACA,mBACA,kBACA,iBACA,kBACA,iBACA,oBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAsB,CAC1B,eACA,eAAgB,EAChB,OACA,oBACA,aACA,WACA,cACA,iBAAkB,EAAmB,IAAI,KAAK,EAAiB,CAAG,IAAA,GAClE,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,GAC7D,CAAC"}
|
package/dist/impl-BeoY4iKA.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./collectCsvFilesOrExit-BPo8Mjy7.mjs";import{t as n}from"./done-input-validation-DL31vk7g.mjs";import{a as r,i,n as a,r as o,t as s}from"./createExtraKeyHandler-ComtD6CG.mjs";import c from"colors";import{CHILD_FLAG as l,PoolCancelledError as u,computePoolSize as d,resolveWorkerPath as f,runPool as p}from"@transcend-io/utils";function m(e){return a(e)}function h(e){return o(e)}const g={renderHeader:m,renderWorkers:h};async function _(a){n(this.process.exit);let{directory:o,outputDir:m,clearOutputDir:h,chunkSizeMB:_,concurrency:v,viewerMode:y}=a,b=t(o,this),{poolSize:x,cpuCount:S}=d(v,b.length);e.info(c.green(`Chunking ${b.length} CSV file(s) with pool size ${x} (CPU=${S})`));let C=b.map(e=>({filePath:e,options:{outputDir:m,clearOutputDir:h,chunkSizeMB:_}}));await p({title:`Chunk CSV - ${o}`,baseDir:o||m||process.cwd(),childFlag:l,childModulePath:f(import.meta.url,`commands/admin/chunk-csv/worker.mjs`),poolSize:x,cpuCount:S,filesTotal:b.length,hooks:{nextTask:()=>C.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:y,render:e=>i(e,g,y),installInteractiveSwitcher:y?void 0:({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,setPaused:o,repaint:s})=>r({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,onAttach:()=>o(!0),onDetach:()=>{o(!1),s()},onEnterAttachScreen:e=>{o(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Attached to worker ${e}. (Esc/Ctrl+] detach \u2022 Ctrl+D EOF \u2022 Ctrl+C SIGINT)\n`)}}),extraKeyHandler:({logsBySlot:e,repaint:t,setPaused:n})=>s({logsBySlot:e,repaint:t,setPaused:n})}).catch(e=>{throw e instanceof u&&process.exit(130),e})}export{_ as chunkCsv};
|
|
2
|
-
//# sourceMappingURL=impl-BeoY4iKA.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BeoY4iKA.mjs","names":[],"sources":["../src/commands/admin/chunk-csv/ui/plugin.ts","../src/commands/admin/chunk-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for chunk-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for chunk-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const chunkCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectCsvFilesOrExit } from '../../../lib/helpers/collectCsvFilesOrExit.js';\nimport {\n createExtraKeyHandler,\n dashboardPlugin,\n installInteractiveSwitcher,\n} from '../../../lib/pooling/index.js';\nimport { logger } from '../../../logger.js';\nimport { chunkCsvPlugin } from './ui/index.js';\nimport type { ChunkProgress, ChunkResult, ChunkTask } from './worker.js';\n\n/**\n * Totals aggregate for this command.\n * We don’t need custom counters since the runner already tracks\n * completed/failed counts in its header — so we just use an empty record.\n */\ntype Totals = Record<string, never>;\n\n/**\n * CLI flags accepted by the `chunk-csv` command.\n *\n * These are passed down from the CLI parser into the parent process.\n */\nexport type ChunkCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n chunkSizeMB: number;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Parent entrypoint for chunking many CSVs in parallel using the worker pool runner.\n *\n * Lifecycle:\n * 1) Discover CSV inputs (exit if none).\n * 2) Compute pool size (CPU-count heuristic or --concurrency).\n * 3) Build a FIFO queue of `ChunkTask`s.\n * 4) Define pool hooks to drive task assignment, progress, and result handling.\n * 5) Launch the pool with `runPool`, rendering via the `chunkCsvPlugin`.\n *\n * @param this - Bound CLI context (provides process exit + logging).\n * @param flags - CLI options for the run.\n */\nexport async function chunkCsv(this: LocalContext, flags: ChunkCsvCommandFlags): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { directory, outputDir, clearOutputDir, chunkSizeMB, concurrency, viewerMode } = flags;\n\n /* 1) Discover CSV inputs */\n const files = collectCsvFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n logger.info(\n colors.green(\n `Chunking ${files.length} CSV file(s) with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Prepare a simple FIFO queue of tasks (one per file). */\n const queue = files.map<ChunkTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir, chunkSizeMB },\n }));\n\n /* 4) Define pool hooks to adapt runner to this command. */\n const hooks: PoolHooks<ChunkTask, ChunkProgress, ChunkResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n // postProcess receives log context when viewerMode=true — we don’t need it here.\n postProcess: async () => {\n // nothing extra for chunk-csv\n },\n };\n\n /* 5) Launch the pool runner with our hooks and custom dashboard plugin. */\n await runPool({\n title: `Chunk CSV - ${directory}`,\n baseDir: directory || outputDir || process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/chunk-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n render: (input) => dashboardPlugin(input, chunkCsvPlugin, viewerMode),\n installInteractiveSwitcher: viewerMode\n ? undefined\n : ({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n setPaused,\n repaint: rp,\n }) =>\n installInteractiveSwitcher({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n onAttach: () => setPaused(true),\n onDetach: () => {\n setPaused(false);\n rp();\n },\n onEnterAttachScreen: (id) => {\n setPaused(true);\n process.stdout.write('\\x1b[2J\\x1b[H');\n process.stdout.write(\n `Attached to worker ${id}. (Esc/Ctrl+] detach \\u2022 Ctrl+D EOF \\u2022 Ctrl+C SIGINT)\\n`,\n );\n },\n }),\n extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n createExtraKeyHandler({\n logsBySlot,\n repaint,\n setPaused,\n }),\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"+XAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAA8D,CACzE,eACA,gBAED,CCuBD,eAAsB,EAA6B,EAA4C,CAC7F,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAa,cAAe,EAGjF,EAAQ,EAAsB,EAAW,KAAK,CAG9C,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,EAAO,KACL,EAAO,MACL,YAAY,EAAM,OAAO,8BAA8B,EAAS,QAAQ,EAAS,GAClF,CACF,CAGD,IAAM,EAAQ,EAAM,IAAgB,IAAc,CAChD,WACA,QAAS,CAAE,YAAW,iBAAgB,cAAa,CACpD,EAAE,CAiBH,MAAM,EAAQ,CACZ,MAAO,eAAe,IACtB,QAAS,GAAa,GAAa,QAAQ,KAAK,CAChD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,sCAAsC,CAC1F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CArBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EAEpD,YAAa,SAAY,GAcpB,CACL,aACA,OAAS,GAAU,EAAgB,EAAO,EAAgB,EAAW,CACrE,2BAA4B,EACxB,IAAA,IACC,CACC,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,YACA,QAAS,KAET,EAA2B,CACzB,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,aAAgB,EAAU,GAAK,CAC/B,aAAgB,CACd,EAAU,GAAM,CAChB,GAAI,EAEN,oBAAsB,GAAO,CAC3B,EAAU,GAAK,CACf,QAAQ,OAAO,MAAM,gBAAgB,CACrC,QAAQ,OAAO,MACb,sBAAsB,EAAG,gEAC1B,EAEJ,CAAC,CACR,iBAAkB,CAAE,aAAY,UAAS,eACvC,EAAsB,CACpB,aACA,UACA,YACD,CAAC,CACL,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,QAAQ,KAAK,IAAI,CAEb,GACN"}
|
package/dist/impl-BmQR1Pae.mjs
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{r as e,t}from"./policyEngineCliError-BnBghLd1.mjs";import{i as n,r,t as i}from"./printResult-oXnpZu_9.mjs";import{t as a}from"./formatPolicyBundleVersionSummary-Bo7DYxoy.mjs";import{n as o}from"./resolveBundleIdByName-By5Vl8Iz.mjs";import{t as s}from"./logger-Ckep4QXn.mjs";import{t as c}from"./done-input-validation-DL31vk7g.mjs";import l from"colors";async function u({"bundle-name":u,auth:d,"transcend-url":f,json:p,debug:m=!1}){c(this.process.exit),e(m);let h=n(f,d),g=await o(h,u);if(!g)throw Error(`Policy bundle "${u}" was not found for this organization.`);s.info(l.green(`Deactivating active version for bundle "${u}"...`));let _;try{_=await h.post(`v1/policy-engine/policy-bundles/${g}/deactivate`).json()}catch(e){if(e?.response?.statusCode===409)throw new t(`Policy bundle "${u}" has no active version.`,{cause:e});r(e)}i(this.process.stdout,{json:p,data:_,renderTable:()=>[`bundleId ${_.bundle.id}`,`bundleName ${_.bundle.bundleName}`,a(_.version)].join(`
|
|
2
|
-
`)}),s.info(l.green(`Policy bundle version deactivated.`))}export{u as deactivate};
|
|
3
|
-
//# sourceMappingURL=impl-BmQR1Pae.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BmQR1Pae.mjs","names":[],"sources":["../src/commands/policy/deactivate/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { logger } from '../../../logger.js';\nimport {\n buildPolicyEngineClient,\n formatPolicyBundleVersionSummary,\n printResult,\n resolveBundleIdByName,\n setPolicyEngineCliDebug,\n throwPolicyEngineRequestError,\n PolicyEngineCliError,\n} from '../helpers/index.js';\nimport type { DeactivatePolicyBundleResponse } from '../types.js';\n\n/** CLI flags for `transcend policy deactivate`. */\nexport interface DeactivateCommandFlags {\n /** Logical bundle name to deactivate */\n 'bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Print raw JSON response */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Deactivate the currently active version of a policy bundle.\n *\n * Resolves `--bundle-name` to the parent bundle UUID internally, then calls the\n * Policy Engine deactivate endpoint. The bundle is addressed by name only -- the\n * UUID is never exposed to the operator.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function deactivate(\n this: LocalContext,\n {\n 'bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n json,\n debug = false,\n }: DeactivateCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n\n const resolvedBundleId = await resolveBundleIdByName(client, bundleName);\n if (!resolvedBundleId) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n\n logger.info(colors.green(`Deactivating active version for bundle \"${bundleName}\"...`));\n\n let body: DeactivatePolicyBundleResponse;\n try {\n body = await client\n .post(`v1/policy-engine/policy-bundles/${resolvedBundleId}/deactivate`)\n .json<DeactivatePolicyBundleResponse>();\n } catch (err) {\n // The monolith 409 references the internal bundle UUID; rewrite it to the\n // user-supplied bundle name so the error is actionable.\n const statusCode = (err as { response?: { statusCode?: number } })?.response?.statusCode;\n if (statusCode === 409) {\n throw new PolicyEngineCliError(`Policy bundle \"${bundleName}\" has no active version.`, {\n cause: err,\n });\n }\n throwPolicyEngineRequestError(err);\n }\n\n printResult(this.process.stdout, {\n json,\n data: body,\n renderTable: () =>\n [\n `bundleId ${body.bundle.id}`,\n `bundleName ${body.bundle.bundleName}`,\n formatPolicyBundleVersionSummary(body.version),\n ].join('\\n'),\n });\n\n logger.info(colors.green('Policy bundle version deactivated.'));\n}\n"],"mappings":"wWAwCA,eAAsB,EAEpB,CACE,cAAe,EACf,OACA,gBAAiB,EACjB,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,KAAK,CACtC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CAEpD,EAAmB,MAAM,EAAsB,EAAQ,EAAW,CACxE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,EAAO,KAAK,EAAO,MAAM,2CAA2C,EAAW,MAAM,CAAC,CAEtF,IAAI,EACJ,GAAI,CACF,EAAO,MAAM,EACV,KAAK,mCAAmC,EAAiB,aAAa,CACtE,MAAsC,OAClC,EAAK,CAIZ,GADoB,GAAgD,UAAU,aAC3D,IACjB,MAAM,IAAI,EAAqB,kBAAkB,EAAW,0BAA2B,CACrF,MAAO,EACR,CAAC,CAEJ,EAA8B,EAAI,CAGpC,EAAY,KAAK,QAAQ,OAAQ,CAC/B,OACA,KAAM,EACN,gBACE,CACE,eAAe,EAAK,OAAO,KAC3B,eAAe,EAAK,OAAO,aAC3B,EAAiC,EAAK,QAAQ,CAC/C,CAAC,KAAK;EAAK,CACf,CAAC,CAEF,EAAO,KAAK,EAAO,MAAM,qCAAqC,CAAC"}
|
package/dist/impl-BnzPrDmM.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{C as t}from"./codecs-DJFlZLGT.mjs";import{a as n}from"./readTranscendYaml-bL1qFPqv.mjs";import{t as r}from"./done-input-validation-DL31vk7g.mjs";import{ConsentTrackerStatus as i,DataFlowScope as a}from"@transcend-io/privacy-types";import{existsSync as o,readFileSync as s}from"node:fs";import c from"colors";import{decodeCodec as l}from"@transcend-io/type-utils";import*as u from"io-ts";function d({file:d,output:f}){r(this.process.exit),o(d)||(e.error(c.red(`File does not exist: --file="${d}"`)),this.process.exit(1));let p=l(u.array(t),s(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(c.green(`Successfully wrote ${m.length} data flows and ${h.length} cookies to file "${f}"`))}export{d as consentManagerServiceJsonToYml};
|
|
2
|
-
//# sourceMappingURL=impl-BnzPrDmM.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BnzPrDmM.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"}
|
package/dist/impl-BoZZp_W8.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{l as e}from"./constants-DKKXqoSr.mjs";import{t}from"./generateCrossAccountApiKeys-B1nowja2.mjs";import{t as n}from"./done-input-validation-DL31vk7g.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-BoZZp_W8.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BoZZp_W8.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"}
|
package/dist/impl-BohgbWOH.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{a as t,r as n}from"./readTranscendYaml-bL1qFPqv.mjs";import{t as r}from"./listFiles-C5kubvdN.mjs";import{t as i}from"./done-input-validation-DL31vk7g.mjs";import{t as a}from"./dataFlowsToDataSilos-DRuAfwIn.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-BohgbWOH.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BohgbWOH.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"}
|
package/dist/impl-Bur_bNXN.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./readCsv--FfP8n-H.mjs";import{a as n}from"./writeCsv-DMw5OmWp.mjs";import{t as r}from"./done-input-validation-DL31vk7g.mjs";import{SombraStandardScope as i}from"@transcend-io/privacy-types";import{existsSync as a}from"node:fs";import o from"colors";import*as s from"io-ts";import{buildTranscendGraphQLClient as c,createPreferenceAccessTokens as l}from"@transcend-io/sdk";import u from"cli-progress";async function d({auth:d,file:f,transcendUrl:p,duration:m,subjectType:h,emailColumnName:g,coreIdentifierColumnName:_}){r(this.process.exit),a(f)||(e.error(o.red(`File does not exist: "${f}". Please provide a valid path to a CSV file.`)),this.process.exit(1));try{let r=c(p,d),a=t(f,s.type({[g]:s.string,..._?{[_]:s.string}:{}}));if(!a.length)throw Error(`Input CSV is empty.`);let v=a.map((e,t)=>[e,t]).filter(([e])=>!e[g]?.trim());if(v.length){let e=v.map(([,e])=>e+2).join(`, `);throw Error(`The following rows are missing the required "${g}" column: ${e}`)}if(_){let e=a.map((e,t)=>[e,t]).filter(([e])=>!e[_]?.trim());if(e.length){let t=e.map(([,e])=>e+2).join(`, `);throw Error(`The following rows are missing the required "${_}" column: ${t}`)}}let y=Math.max(1,Math.floor(m/1e3)),b=a.map((e,t)=>{let n=e[g].trim(),r=_?e[_]?.trim():void 0;return{subjectType:h,scopes:[i.PreferenceManagement],expiresIn:y,email:n,...r?{coreIdentifier:r}:{},index:t}}),x=new u.SingleBar({},u.Presets.shades_classic);x.start(b.length,0);let S=Date.now(),C=await l(r,{records:b,logger:e,emitProgress:e=>{x.update(e)}});x.update(b.length),x.stop();let w=C.map(({accessToken:e,input:t})=>{if(typeof t.index!=`number`)throw Error(`Internal error: missing input index.`);return{...a[t.index],token:e}});e.info(o.magenta(`Writing access tokens to file "${f}"...`)),await n(f,w,!0);let T=Math.round((Date.now()-S)/1e3);e.info(o.green(`Successfully generated ${C.length} access tokens to "${f}" in ${T}s!`))}catch(t){e.error(o.red(`An error occurred while generating access tokens: ${t?.message||String(t)}`)),this.process.exit(1)}}export{d as generateAccessTokens};
|
|
2
|
-
//# sourceMappingURL=impl-Bur_bNXN.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-Bur_bNXN.mjs","names":[],"sources":["../src/commands/consent/generate-access-tokens/impl.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { SombraStandardScope } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n createPreferenceAccessTokens,\n type PreferenceAccessTokenInputWithIndex,\n} from '@transcend-io/sdk';\nimport cliProgress from 'cli-progress';\nimport 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 { writeCsv } from '../../../lib/helpers/index.js';\nimport { readCsv } from '../../../lib/requests/index.js';\nimport { logger } from '../../../logger.js';\n\n/**\n * CLI flags accepted by the `generate-access-tokens` command.\n *\n * These are passed down from the CLI parser into the parent process.\n */\nexport type GenerateAccessTokenCommandFlags = {\n auth: string;\n file: string;\n duration: number;\n transcendUrl: string;\n subjectType: string;\n emailColumnName: string;\n coreIdentifierColumnName?: string;\n};\n\n/**\n * Take in a CSV of user identifiers and generate access tokens for each user.\n *\n * Expected CSV columns:\n * - [emailColumnName] (required)\n * - [coreIdentifierColumnName] (optional)\n *\n * @param this - Bound CLI context (provides process exit + logging).\n * @param flags - CLI options for the run.\n */\nexport async function generateAccessTokens(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n duration,\n subjectType,\n emailColumnName,\n coreIdentifierColumnName,\n }: GenerateAccessTokenCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n if (!existsSync(file)) {\n logger.error(\n colors.red(`File does not exist: \"${file}\". Please provide a valid path to a CSV file.`),\n );\n this.process.exit(1);\n }\n\n try {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read + parse CSV\n const codec = t.type({\n [emailColumnName]: t.string,\n ...(coreIdentifierColumnName ? { [coreIdentifierColumnName]: t.string } : {}),\n });\n const rows: Array<Record<string, string>> = readCsv(file, codec);\n if (!rows.length) {\n throw new Error('Input CSV is empty.');\n }\n\n // Ensure emails and core identifiers exist\n const missingEmail = rows\n .map((r, i) => [r, i] as const)\n .filter(([r]) => !r[emailColumnName]?.trim());\n if (missingEmail.length) {\n const rowNumbers = missingEmail\n .map(([, i]) => i + 2) // +2 to account for header row and 0-indexing\n .join(', ');\n throw new Error(\n `The following rows are missing the required \"${emailColumnName}\" column: ${rowNumbers}`,\n );\n }\n if (coreIdentifierColumnName) {\n const missingCoreId = rows\n .map((r, i) => [r, i] as const)\n .filter(([r]) => !r[coreIdentifierColumnName]?.trim());\n if (missingCoreId.length) {\n const rowNumbers = missingCoreId\n .map(([, i]) => i + 2) // +2 to account for header row and 0-indexing\n .join(', ');\n throw new Error(\n `The following rows are missing the required \"${coreIdentifierColumnName}\" column: ${rowNumbers}`,\n );\n }\n }\n\n // Duration provided by CLI is in ms; GraphQL expects seconds\n const expiresInSeconds = Math.max(1, Math.floor(duration / 1000));\n\n // Build inputs for GraphQL\n const inputs = rows.map((r, index): PreferenceAccessTokenInputWithIndex => {\n const email = r[emailColumnName].trim();\n const coreIdentifier = coreIdentifierColumnName\n ? r[coreIdentifierColumnName]?.trim()\n : undefined;\n const scopes = [SombraStandardScope.PreferenceManagement];\n return {\n subjectType,\n scopes,\n expiresIn: expiresInSeconds,\n email,\n ...(coreIdentifier ? { coreIdentifier } : {}),\n index,\n };\n });\n\n // Progress bar\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n progressBar.start(inputs.length, 0);\n\n // Kick off token creation (batched internally)\n const t0 = Date.now();\n const results = await createPreferenceAccessTokens(client, {\n records: inputs,\n logger,\n emitProgress: (progress) => {\n progressBar.update(progress);\n },\n });\n progressBar.update(inputs.length);\n progressBar.stop();\n\n // Prepare output CSV rows\n const outputRows = results.map(({ accessToken, input }) => {\n if (typeof input.index !== 'number') {\n throw new Error('Internal error: missing input index.');\n }\n return {\n ...rows[input.index],\n token: accessToken,\n };\n });\n\n logger.info(colors.magenta(`Writing access tokens to file \"${file}\"...`));\n await writeCsv(file, outputRows, true);\n\n const totalTimeSec = Math.round((Date.now() - t0) / 1000);\n logger.info(\n colors.green(\n `Successfully generated ${results.length} access tokens to \"${file}\" in ${totalTimeSec}s!`,\n ),\n );\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n logger.error(\n colors.red(\n `An error occurred while generating access tokens: ${err?.message || String(err)}`,\n ),\n );\n this.process.exit(1);\n }\n}\n"],"mappings":"wcA2CA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,WACA,cACA,kBACA,4BAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CACjC,EAAW,EAAK,GACnB,EAAO,MACL,EAAO,IAAI,yBAAyB,EAAK,+CAA+C,CACzF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,GAAI,CAEF,IAAM,EAAS,EAA4B,EAAc,EAAK,CAOxD,EAAsC,EAAQ,EAJtC,EAAE,KAAK,EAClB,GAAkB,EAAE,OACrB,GAAI,EAA2B,EAAG,GAA2B,EAAE,OAAQ,CAAG,EAAE,CAC7E,CAC8D,CAAC,CAChE,GAAI,CAAC,EAAK,OACR,MAAU,MAAM,sBAAsB,CAIxC,IAAM,EAAe,EAClB,KAAK,EAAG,IAAM,CAAC,EAAG,EAAE,CAAU,CAC9B,QAAQ,CAAC,KAAO,CAAC,EAAE,IAAkB,MAAM,CAAC,CAC/C,GAAI,EAAa,OAAQ,CACvB,IAAM,EAAa,EAChB,KAAK,EAAG,KAAO,EAAI,EAAE,CACrB,KAAK,KAAK,CACb,MAAU,MACR,gDAAgD,EAAgB,YAAY,IAC7E,CAEH,GAAI,EAA0B,CAC5B,IAAM,EAAgB,EACnB,KAAK,EAAG,IAAM,CAAC,EAAG,EAAE,CAAU,CAC9B,QAAQ,CAAC,KAAO,CAAC,EAAE,IAA2B,MAAM,CAAC,CACxD,GAAI,EAAc,OAAQ,CACxB,IAAM,EAAa,EAChB,KAAK,EAAG,KAAO,EAAI,EAAE,CACrB,KAAK,KAAK,CACb,MAAU,MACR,gDAAgD,EAAyB,YAAY,IACtF,EAKL,IAAM,EAAmB,KAAK,IAAI,EAAG,KAAK,MAAM,EAAW,IAAK,CAAC,CAG3D,EAAS,EAAK,KAAK,EAAG,IAA+C,CACzE,IAAM,EAAQ,EAAE,GAAiB,MAAM,CACjC,EAAiB,EACnB,EAAE,IAA2B,MAAM,CACnC,IAAA,GAEJ,MAAO,CACL,cACA,OAAA,CAHc,EAAoB,qBAG5B,CACN,UAAW,EACX,QACA,GAAI,EAAiB,CAAE,iBAAgB,CAAG,EAAE,CAC5C,QACD,EACD,CAGI,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CACrF,EAAY,MAAM,EAAO,OAAQ,EAAE,CAGnC,IAAM,EAAK,KAAK,KAAK,CACf,EAAU,MAAM,EAA6B,EAAQ,CACzD,QAAS,EACT,SACA,aAAe,GAAa,CAC1B,EAAY,OAAO,EAAS,EAE/B,CAAC,CACF,EAAY,OAAO,EAAO,OAAO,CACjC,EAAY,MAAM,CAGlB,IAAM,EAAa,EAAQ,KAAK,CAAE,cAAa,WAAY,CACzD,GAAI,OAAO,EAAM,OAAU,SACzB,MAAU,MAAM,uCAAuC,CAEzD,MAAO,CACL,GAAG,EAAK,EAAM,OACd,MAAO,EACR,EACD,CAEF,EAAO,KAAK,EAAO,QAAQ,kCAAkC,EAAK,MAAM,CAAC,CACzE,MAAM,EAAS,EAAM,EAAY,GAAK,CAEtC,IAAM,EAAe,KAAK,OAAO,KAAK,KAAK,CAAG,GAAM,IAAK,CACzD,EAAO,KACL,EAAO,MACL,0BAA0B,EAAQ,OAAO,qBAAqB,EAAK,OAAO,EAAa,IACxF,CACF,OAEM,EAAU,CACjB,EAAO,MACL,EAAO,IACL,qDAAqD,GAAK,SAAW,OAAO,EAAI,GACjF,CACF,CACD,KAAK,QAAQ,KAAK,EAAE"}
|
package/dist/impl-BwuWn3TM.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./pullUnstructuredSubDataPointRecommendations-B9xIDPf2.mjs";import{s as n}from"./writeCsv-DMw5OmWp.mjs";import{t as r}from"./done-input-validation-DL31vk7g.mjs";import{uniq as i}from"lodash-es";import a from"colors";import{buildTranscendGraphQLClient as o}from"@transcend-io/sdk";async function s({auth:s,file:c,transcendUrl:l,dataSiloIds:u,subCategories:d,status:f,includeEncryptedSnippets:p}){r(this.process.exit);try{let r=await t(o(l,s),{dataSiloIds:u,subCategories:d,status:f,includeEncryptedSnippets:p});e.info(a.magenta(`Writing unstructured discovery files to file "${c}"...`));let m=[];await n(c,r.map(e=>{let t={"Entry ID":e.id,"Data Silo ID":e.dataSiloId,"Object Path ID":e.scannedObjectPathId,"Object ID":e.scannedObjectId,...p?{Entry:e.name,"Context Snippet":e.contextSnippet}:{},"Data Category":`${e.dataSubCategory.category}:${e.dataSubCategory.name}`,"Classification Status":e.status,"Confidence Score":e.confidence,"Classification Method":e.classificationMethod,"Classifier Version":e.classifierVersion};return m=i([...m,...Object.keys(t)]),t}),m)}catch(t){e.error(a.red(`An error occurred syncing the unstructured discovery files: ${t.message}`)),this.process.exit(1)}e.info(a.green(`Successfully synced unstructured discovery files to disk at ${c}!`))}export{s as pullUnstructuredDiscoveryFiles};
|
|
2
|
-
//# sourceMappingURL=impl-BwuWn3TM.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BwuWn3TM.mjs","names":[],"sources":["../src/commands/inventory/pull-unstructured-discovery-files/impl.ts"],"sourcesContent":["import type { UnstructuredSubDataPointRecommendationStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\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 { pullUnstructuredSubDataPointRecommendations } from '../../../lib/data-inventory/index.js';\nimport { writeLargeCsv } from '../../../lib/helpers/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface PullUnstructuredDiscoveryFilesCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n dataSiloIds?: string[];\n subCategories?: string[];\n status?: UnstructuredSubDataPointRecommendationStatus[];\n includeEncryptedSnippets: boolean;\n}\n\nexport async function pullUnstructuredDiscoveryFiles(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n dataSiloIds,\n subCategories,\n status,\n includeEncryptedSnippets,\n }: PullUnstructuredDiscoveryFilesCommandFlags,\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 entries = await pullUnstructuredSubDataPointRecommendations(client, {\n dataSiloIds,\n subCategories, // TODO: https://transcend.height.app/T-40482 - do by name not ID\n status,\n includeEncryptedSnippets,\n });\n\n logger.info(colors.magenta(`Writing unstructured discovery files to file \"${file}\"...`));\n let headers: string[] = [];\n const inputs = entries.map((entry) => {\n const result = {\n 'Entry ID': entry.id,\n 'Data Silo ID': entry.dataSiloId,\n 'Object Path ID': entry.scannedObjectPathId,\n 'Object ID': entry.scannedObjectId,\n ...(includeEncryptedSnippets\n ? { Entry: entry.name, 'Context Snippet': entry.contextSnippet }\n : {}),\n 'Data Category': `${entry.dataSubCategory.category}:${entry.dataSubCategory.name}`,\n 'Classification Status': entry.status,\n 'Confidence Score': entry.confidence,\n 'Classification Method': entry.classificationMethod,\n 'Classifier Version': entry.classifierVersion,\n };\n headers = uniq([...headers, ...Object.keys(result)]);\n return result;\n });\n await writeLargeCsv(file, inputs, headers);\n } catch (err) {\n logger.error(\n colors.red(`An error occurred syncing the unstructured discovery files: ${err.message}`),\n );\n this.process.exit(1);\n }\n\n // Indicate success\n logger.info(colors.green(`Successfully synced unstructured discovery files to disk at ${file}!`));\n}\n"],"mappings":"gVAqBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,cACA,gBACA,SACA,4BAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAI,CAIF,IAAM,EAAU,MAAM,EAFP,EAA4B,EAAc,EAEe,CAAE,CACxE,cACA,gBACA,SACA,2BACD,CAAC,CAEF,EAAO,KAAK,EAAO,QAAQ,iDAAiD,EAAK,MAAM,CAAC,CACxF,IAAI,EAAoB,EAAE,CAmB1B,MAAM,EAAc,EAlBL,EAAQ,IAAK,GAAU,CACpC,IAAM,EAAS,CACb,WAAY,EAAM,GAClB,eAAgB,EAAM,WACtB,iBAAkB,EAAM,oBACxB,YAAa,EAAM,gBACnB,GAAI,EACA,CAAE,MAAO,EAAM,KAAM,kBAAmB,EAAM,eAAgB,CAC9D,EAAE,CACN,gBAAiB,GAAG,EAAM,gBAAgB,SAAS,GAAG,EAAM,gBAAgB,OAC5E,wBAAyB,EAAM,OAC/B,mBAAoB,EAAM,WAC1B,wBAAyB,EAAM,qBAC/B,qBAAsB,EAAM,kBAC7B,CAED,MADA,GAAU,EAAK,CAAC,GAAG,EAAS,GAAG,OAAO,KAAK,EAAO,CAAC,CAAC,CAC7C,GAEuB,CAAE,EAAQ,OACnC,EAAK,CACZ,EAAO,MACL,EAAO,IAAI,+DAA+D,EAAI,UAAU,CACzF,CACD,KAAK,QAAQ,KAAK,EAAE,CAItB,EAAO,KAAK,EAAO,MAAM,+DAA+D,EAAK,GAAG,CAAC"}
|
package/dist/impl-BxQE7dL92.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./policyEngineCliError-BnBghLd1.mjs";import{i as t,n,t as r}from"./printResult-oXnpZu_9.mjs";import{t as i}from"./renderTable-DKXvortp.mjs";import{n as a}from"./resolveBundleIdByName-By5Vl8Iz.mjs";import{t as o}from"./logger-Ckep4QXn.mjs";import{t as s}from"./done-input-validation-DL31vk7g.mjs";import c from"colors";async function l({"bundle-name":l,auth:u,"transcend-url":d,limit:f,after:p,json:m,debug:h=!1}){s(this.process.exit),e(h);let g=t(d,u),_=await a(g,l);if(!_)throw Error(`Policy bundle "${l}" was not found for this organization.`);o.info(c.green(`Listing versions for bundle "${l}"...`));let v={limit:f};p&&(v.after=p);let y=await n(g.get(`v1/policy-engine/policy-bundles/${_}/versions`,{searchParams:v}).json());r(this.process.stdout,{json:m,data:y,renderTable:()=>{if(y.nodes.length===0)return p?`No more versions for bundle "${l}" (end of results).`:`No versions found for bundle "${l}".`;let e=i([`id`,`version`,`createdAt`,`activatedAt`,`deactivatedAt`],y.nodes.map(e=>[e.id,e.version,e.createdAt,e.activatedAt??`-`,e.deactivatedAt??`-`]));return y.pageInfo.endCursor&&(e+=`\n\nafter: ${y.pageInfo.endCursor}`),e}})}export{l as versions};
|
|
2
|
-
//# sourceMappingURL=impl-BxQE7dL92.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-BxQE7dL92.mjs","names":[],"sources":["../src/commands/policy/versions/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { logger } from '../../../logger.js';\nimport { EMPTY_CELL } from '../constants.js';\nimport {\n buildPolicyEngineClient,\n policyEngineRequest,\n printResult,\n renderTable,\n resolveBundleIdByName,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { PolicyBundleVersionListResponse } from '../types.js';\n\n/** CLI flags for `transcend policy versions`. */\nexport interface VersionsCommandFlags {\n /** Tenant-unique bundle name */\n 'bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Page size */\n limit: number;\n /** Cursor from a previous page's pageInfo.endCursor */\n after?: string;\n /** Print raw JSON response */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * List versions for a policy bundle.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function versions(\n this: LocalContext,\n {\n 'bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n limit,\n after,\n json,\n debug = false,\n }: VersionsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const bundleId = await resolveBundleIdByName(client, bundleName);\n\n if (!bundleId) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n\n logger.info(colors.green(`Listing versions for bundle \"${bundleName}\"...`));\n\n const searchParams: Record<string, string | number> = { limit };\n if (after) {\n searchParams.after = after;\n }\n\n const body = await policyEngineRequest(\n client\n .get(`v1/policy-engine/policy-bundles/${bundleId}/versions`, {\n searchParams,\n })\n .json<PolicyBundleVersionListResponse>(),\n );\n\n printResult(this.process.stdout, {\n json,\n data: body,\n renderTable: () => {\n if (body.nodes.length === 0) {\n // Distinguish \"this page is empty because you paginated past the end\"\n // from \"the bundle genuinely has no versions\" — the latter is already\n // surfaced during version resolution upstream.\n return after\n ? `No more versions for bundle \"${bundleName}\" (end of results).`\n : `No versions found for bundle \"${bundleName}\".`;\n }\n\n const rows = body.nodes.map((version) => [\n version.id,\n version.version,\n version.createdAt,\n version.activatedAt ?? EMPTY_CELL,\n version.deactivatedAt ?? EMPTY_CELL,\n ]);\n\n let table = renderTable(['id', 'version', 'createdAt', 'activatedAt', 'deactivatedAt'], rows);\n if (body.pageInfo.endCursor) {\n table += `\\n\\nafter: ${body.pageInfo.endCursor}`;\n }\n return table;\n },\n });\n}\n"],"mappings":"iVAwCA,eAAsB,EAEpB,CACE,cAAe,EACf,OACA,gBAAiB,EACjB,QACA,QACA,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,KAAK,CACtC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CACpD,EAAW,MAAM,EAAsB,EAAQ,EAAW,CAEhE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,EAAO,KAAK,EAAO,MAAM,gCAAgC,EAAW,MAAM,CAAC,CAE3E,IAAM,EAAgD,CAAE,QAAO,CAC3D,IACF,EAAa,MAAQ,GAGvB,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,mCAAmC,EAAS,WAAY,CAC3D,eACD,CAAC,CACD,MAAuC,CAC3C,CAED,EAAY,KAAK,QAAQ,OAAQ,CAC/B,OACA,KAAM,EACN,gBAAmB,CACjB,GAAI,EAAK,MAAM,SAAW,EAIxB,OAAO,EACH,gCAAgC,EAAW,qBAC3C,iCAAiC,EAAW,IAWlD,IAAI,EAAQ,EAAY,CAAC,KAAM,UAAW,YAAa,cAAe,gBAAgB,CARzE,EAAK,MAAM,IAAK,GAAY,CACvC,EAAQ,GACR,EAAQ,QACR,EAAQ,UACR,EAAQ,aAAA,IACR,EAAQ,eAAA,IACT,CAE2F,CAAC,CAI7F,OAHI,EAAK,SAAS,YAChB,GAAS,cAAc,EAAK,SAAS,aAEhC,GAEV,CAAC"}
|
package/dist/impl-ByeEmvdo.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./bulkRetryEnrichers-DzbsrAL3.mjs";import{t}from"./done-input-validation-DL31vk7g.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-ByeEmvdo.mjs.map
|
package/dist/impl-BzhraaBB2.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./pullManualEnrichmentIdentifiersToCsv-DXYFOoqY.mjs";import{t}from"./done-input-validation-DL31vk7g.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-BzhraaBB2.mjs.map
|
package/dist/impl-C3S5iupW2.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./uploadPrivacyRequestsFromCsv-CT-zfd4U.mjs";import{t}from"./done-input-validation-DL31vk7g.mjs";import{splitCsvToList as n}from"@transcend-io/utils";async function r({auth:r,file:i,transcendUrl:a,cacheFilepath:o,requestReceiptFolder:s,sombraAuth:c,concurrency:l,attributes:u,isTest:d,isSilent:f,skipSendingReceipt:p,emailIsVerified:m,skipFilterStep:h,dryRun:g,debug:_,defaultPhoneCountryCode:v}){t(this.process.exit),await e({cacheFilepath:o,requestReceiptFolder:s,file:i,auth:r,sombraAuth:c,concurrency:l,transcendUrl:a,defaultPhoneCountryCode:v,attributes:n(u),debug:_,skipFilterStep:h,isSilent:f,skipSendingReceipt:p,emailIsVerified:m,isTest:d,dryRun:g})}export{r as upload};
|
|
2
|
-
//# sourceMappingURL=impl-C3S5iupW2.mjs.map
|
package/dist/impl-C3f_H_77.mjs
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{n as e,r as t,t as n}from"./runOpa-D511z37u.mjs";import{t as r}from"./logger-Ckep4QXn.mjs";import{n as i}from"./inquirer-B0OF_nRe.mjs";import{t as a}from"./done-input-validation-DL31vk7g.mjs";import o from"node:path";import s from"colors";async function c({dir:c}){a(this.process.exit),t();let l=o.resolve(c);r.info(s.green(`Linting policy bundle in ${l}...`));let u=await e([`check`,`--strict`,l]);u!==0&&this.process.exit(u);let{stdout:d}=await n([`fmt`,`--list`,l]),f=d.trim().split(`
|
|
2
|
-
`).filter(e=>e.length>0);if(f.length>0){r.error(s.red(`Policy files are not formatted:`)),f.forEach(e=>{r.error(s.red(` - ${e}`))}),r.error(``),await e([`fmt`,`--diff`,l]),this.process.stdin.isTTY||(r.error(s.red(`Cannot format policy files in a non-interactive environment.`)),this.process.exit(1)),await i({message:`Format the unformatted policy files listed above?`})||this.process.exit(1);let t=await e([`fmt`,`-w`,l]);t!==0&&this.process.exit(t),r.info(s.green(`Policy files formatted.`)),r.info(s.green(`Policy lint passed.`));return}r.info(s.green(`Policy lint passed.`))}export{c as lint};
|
|
3
|
-
//# sourceMappingURL=impl-C3f_H_77.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impl-C3f_H_77.mjs","names":[],"sources":["../src/commands/policy/lint/impl.ts"],"sourcesContent":["import path from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport { logger } from '../../../logger.js';\nimport { assertOpaInstalled, runOpa, runOPACapture } from '../helpers/index.js';\n\n/** CLI flags for `transcend policy lint`. */\nexport interface LintCommandFlags {\n /** Directory containing Rego policy files */\n dir: string;\n}\n\n/**\n * Local Rego lint via `opa check` and optional interactive formatting via `opa fmt`.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function lint(this: LocalContext, { dir }: LintCommandFlags): Promise<void> {\n doneInputValidation(this.process.exit);\n\n assertOpaInstalled();\n const resolvedDir = path.resolve(dir);\n\n logger.info(colors.green(`Linting policy bundle in ${resolvedDir}...`));\n\n const checkCode = await runOpa(['check', '--strict', resolvedDir]);\n if (checkCode !== 0) {\n this.process.exit(checkCode);\n }\n\n const { stdout } = await runOPACapture(['fmt', '--list', resolvedDir]);\n const unformattedFiles = stdout\n .trim()\n .split('\\n')\n .filter((file) => file.length > 0);\n\n if (unformattedFiles.length > 0) {\n logger.error(colors.red('Policy files are not formatted:'));\n unformattedFiles.forEach((file) => {\n logger.error(colors.red(` - ${file}`));\n });\n logger.error('');\n await runOpa(['fmt', '--diff', resolvedDir]);\n\n if (!this.process.stdin.isTTY) {\n logger.error(colors.red('Cannot format policy files in a non-interactive environment.'));\n this.process.exit(1);\n }\n\n const shouldFormat = await inquirerConfirmBoolean({\n message: 'Format the unformatted policy files listed above?',\n });\n if (!shouldFormat) {\n this.process.exit(1);\n }\n\n const fmtWriteCode = await runOpa(['fmt', '-w', resolvedDir]);\n if (fmtWriteCode !== 0) {\n this.process.exit(fmtWriteCode);\n }\n\n logger.info(colors.green('Policy files formatted.'));\n logger.info(colors.green('Policy lint passed.'));\n return;\n }\n\n logger.info(colors.green('Policy lint passed.'));\n}\n"],"mappings":"sPAsBA,eAAsB,EAAyB,CAAE,OAAwC,CACvF,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAoB,CACpB,IAAM,EAAc,EAAK,QAAQ,EAAI,CAErC,EAAO,KAAK,EAAO,MAAM,4BAA4B,EAAY,KAAK,CAAC,CAEvE,IAAM,EAAY,MAAM,EAAO,CAAC,QAAS,WAAY,EAAY,CAAC,CAC9D,IAAc,GAChB,KAAK,QAAQ,KAAK,EAAU,CAG9B,GAAM,CAAE,UAAW,MAAM,EAAc,CAAC,MAAO,SAAU,EAAY,CAAC,CAChE,EAAmB,EACtB,MAAM,CACN,MAAM;EAAK,CACX,OAAQ,GAAS,EAAK,OAAS,EAAE,CAEpC,GAAI,EAAiB,OAAS,EAAG,CAC/B,EAAO,MAAM,EAAO,IAAI,kCAAkC,CAAC,CAC3D,EAAiB,QAAS,GAAS,CACjC,EAAO,MAAM,EAAO,IAAI,OAAO,IAAO,CAAC,EACvC,CACF,EAAO,MAAM,GAAG,CAChB,MAAM,EAAO,CAAC,MAAO,SAAU,EAAY,CAAC,CAEvC,KAAK,QAAQ,MAAM,QACtB,EAAO,MAAM,EAAO,IAAI,+DAA+D,CAAC,CACxF,KAAK,QAAQ,KAAK,EAAE,EAMjB,MAHsB,EAAuB,CAChD,QAAS,oDACV,CAAC,EAEA,KAAK,QAAQ,KAAK,EAAE,CAGtB,IAAM,EAAe,MAAM,EAAO,CAAC,MAAO,KAAM,EAAY,CAAC,CACzD,IAAiB,GACnB,KAAK,QAAQ,KAAK,EAAa,CAGjC,EAAO,KAAK,EAAO,MAAM,0BAA0B,CAAC,CACpD,EAAO,KAAK,EAAO,MAAM,sBAAsB,CAAC,CAChD,OAGF,EAAO,KAAK,EAAO,MAAM,sBAAsB,CAAC"}
|