@transcend-io/cli 12.1.5 → 13.0.1
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/README.md +64 -14
- package/dist/{app-BMLQABJX.mjs → app-Bms-wwFP.mjs} +19 -19
- package/dist/app-Bms-wwFP.mjs.map +1 -0
- package/dist/{approvePrivacyRequests-CY6rQT4J.mjs → approvePrivacyRequests-DyLb38gV.mjs} +2 -2
- package/dist/{approvePrivacyRequests-CY6rQT4J.mjs.map → approvePrivacyRequests-DyLb38gV.mjs.map} +1 -1
- package/dist/bin/bash-complete.mjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/bin/deprecated-command.mjs +1 -1
- package/dist/{buildExamples-BNGtj-DW.mjs → buildExamples-Ck7gzWSG.mjs} +2 -2
- package/dist/{buildExamples-BNGtj-DW.mjs.map → buildExamples-Ck7gzWSG.mjs.map} +1 -1
- package/dist/{buildXdiSyncEndpoint-BNCfOc-g.mjs → buildXdiSyncEndpoint-etqb_c38.mjs} +2 -2
- package/dist/{buildXdiSyncEndpoint-BNCfOc-g.mjs.map → buildXdiSyncEndpoint-etqb_c38.mjs.map} +1 -1
- package/dist/{bulkRestartRequests-CGvODu3r.mjs → bulkRestartRequests-DWJ8N0fa.mjs} +2 -2
- package/dist/{bulkRestartRequests-CGvODu3r.mjs.map → bulkRestartRequests-DWJ8N0fa.mjs.map} +1 -1
- package/dist/{bulkRetryEnrichers-BgDd4GWH.mjs → bulkRetryEnrichers-J8CHMy_1.mjs} +2 -2
- package/dist/{bulkRetryEnrichers-BgDd4GWH.mjs.map → bulkRetryEnrichers-J8CHMy_1.mjs.map} +1 -1
- package/dist/{cancelPrivacyRequests-Ccsiwrnu.mjs → cancelPrivacyRequests-C9nFdfgW.mjs} +2 -2
- package/dist/{cancelPrivacyRequests-Ccsiwrnu.mjs.map → cancelPrivacyRequests-C9nFdfgW.mjs.map} +1 -1
- package/dist/codecs-8T8Jhxsr.mjs +2 -0
- package/dist/codecs-8T8Jhxsr.mjs.map +1 -0
- package/dist/{command-BjzdoKgJ.mjs → command-C-wEPTO5.mjs} +2 -2
- package/dist/{command-BjzdoKgJ.mjs.map → command-C-wEPTO5.mjs.map} +1 -1
- package/dist/constants-D6y_AX3P.mjs +2 -0
- package/dist/constants-D6y_AX3P.mjs.map +1 -0
- package/dist/{constants-FDjw7bPS.mjs → constants-I694qbRg.mjs} +2 -2
- package/dist/{constants-FDjw7bPS.mjs.map → constants-I694qbRg.mjs.map} +1 -1
- package/dist/{createPoolingCommandUi-BdtnLBBM.mjs → createPoolingCommandUi-BZr2HSiZ.mjs} +2 -2
- package/dist/{createPoolingCommandUi-BdtnLBBM.mjs.map → createPoolingCommandUi-BZr2HSiZ.mjs.map} +1 -1
- package/dist/{downloadPrivacyRequestFiles-C9-xSCpt.mjs → downloadPrivacyRequestFiles-CF_QjkR9.mjs} +2 -2
- package/dist/{downloadPrivacyRequestFiles-C9-xSCpt.mjs.map → downloadPrivacyRequestFiles-CF_QjkR9.mjs.map} +1 -1
- package/dist/fetchAllRequests-BV9K0wXv.mjs +2 -0
- package/dist/fetchAllRequests-BV9K0wXv.mjs.map +1 -0
- package/dist/{fuzzyMatchColumns-D18n9Beu.mjs → fuzzyMatchColumns-Djl3a7lV.mjs} +2 -2
- package/dist/{fuzzyMatchColumns-D18n9Beu.mjs.map → fuzzyMatchColumns-Djl3a7lV.mjs.map} +1 -1
- package/dist/{generateCrossAccountApiKeys-FtWwlf_L.mjs → generateCrossAccountApiKeys-BxW6xU40.mjs} +2 -2
- package/dist/{generateCrossAccountApiKeys-FtWwlf_L.mjs.map → generateCrossAccountApiKeys-BxW6xU40.mjs.map} +1 -1
- package/dist/{impl-SOebshza.mjs → impl-3VziEzJI.mjs} +2 -2
- package/dist/{impl-SOebshza.mjs.map → impl-3VziEzJI.mjs.map} +1 -1
- package/dist/{impl-DnDM9zcu.mjs → impl-7NFxUzSa.mjs} +2 -2
- package/dist/{impl-DnDM9zcu.mjs.map → impl-7NFxUzSa.mjs.map} +1 -1
- package/dist/{impl-Dg7XSQdO2.mjs → impl-7qTKg-YP2.mjs} +2 -2
- package/dist/{impl-Dg7XSQdO2.mjs.map → impl-7qTKg-YP2.mjs.map} +1 -1
- package/dist/{impl-zZd6fuXS.mjs → impl-AWYAfZ2C.mjs} +2 -2
- package/dist/{impl-zZd6fuXS.mjs.map → impl-AWYAfZ2C.mjs.map} +1 -1
- package/dist/{impl-B94dMG4x2.mjs → impl-B-BkGfqq2.mjs} +2 -2
- package/dist/{impl-B94dMG4x2.mjs.map → impl-B-BkGfqq2.mjs.map} +1 -1
- package/dist/{impl-Dd39KsYO.mjs → impl-B0NqrNcJ2.mjs} +2 -2
- package/dist/impl-B0NqrNcJ2.mjs.map +1 -0
- package/dist/{impl-C3vTm9zQ.mjs → impl-B5fkF8m2.mjs} +2 -2
- package/dist/{impl-C3vTm9zQ.mjs.map → impl-B5fkF8m2.mjs.map} +1 -1
- package/dist/{impl-xVmMN-Vt.mjs → impl-B9vbcV8J.mjs} +2 -2
- package/dist/{impl-xVmMN-Vt.mjs.map → impl-B9vbcV8J.mjs.map} +1 -1
- package/dist/{impl-CSnBFv5P.mjs → impl-BCTVuvlD.mjs} +2 -2
- package/dist/{impl-CSnBFv5P.mjs.map → impl-BCTVuvlD.mjs.map} +1 -1
- package/dist/impl-BfS6LtNo2.mjs +2 -0
- package/dist/impl-BfS6LtNo2.mjs.map +1 -0
- package/dist/{impl-qNF5eqX-.mjs → impl-BfU0GFmW.mjs} +1 -1
- package/dist/{impl-qNF5eqX-.mjs.map → impl-BfU0GFmW.mjs.map} +1 -1
- package/dist/{impl-BXGpJz21.mjs → impl-Bhmoagby.mjs} +2 -2
- package/dist/{impl-BXGpJz21.mjs.map → impl-Bhmoagby.mjs.map} +1 -1
- package/dist/{impl-COqlYiiw.mjs → impl-Bpiggf8H.mjs} +2 -2
- package/dist/{impl-COqlYiiw.mjs.map → impl-Bpiggf8H.mjs.map} +1 -1
- package/dist/{impl-D6frX-PK.mjs → impl-BsxD7toO.mjs} +2 -2
- package/dist/{impl-D6frX-PK.mjs.map → impl-BsxD7toO.mjs.map} +1 -1
- package/dist/{impl-Bs2pNgMK.mjs → impl-BvL9wElZ.mjs} +2 -2
- package/dist/{impl-Bs2pNgMK.mjs.map → impl-BvL9wElZ.mjs.map} +1 -1
- package/dist/{impl-DUYRVzMo.mjs → impl-BzzkiK_b.mjs} +1 -1
- package/dist/{impl-DUYRVzMo.mjs.map → impl-BzzkiK_b.mjs.map} +1 -1
- package/dist/{impl-DZoTWLfw2.mjs → impl-C-hBO0Wa2.mjs} +2 -2
- package/dist/{impl-DZoTWLfw2.mjs.map → impl-C-hBO0Wa2.mjs.map} +1 -1
- package/dist/{impl-bl6NF3Lr.mjs → impl-C6tbQV8G.mjs} +2 -2
- package/dist/{impl-bl6NF3Lr.mjs.map → impl-C6tbQV8G.mjs.map} +1 -1
- package/dist/{impl-BEiCEzl_2.mjs → impl-CHoglMch.mjs} +1 -1
- package/dist/impl-CHoglMch.mjs.map +1 -0
- package/dist/{impl-ClT3G845.mjs → impl-CQ3NctWn.mjs} +2 -2
- package/dist/{impl-ClT3G845.mjs.map → impl-CQ3NctWn.mjs.map} +1 -1
- package/dist/{impl-DhXzxQDN2.mjs → impl-CRif3TpB2.mjs} +2 -2
- package/dist/{impl-DhXzxQDN2.mjs.map → impl-CRif3TpB2.mjs.map} +1 -1
- package/dist/{impl-Cvyc-iTI2.mjs → impl-CWINXCFq2.mjs} +2 -2
- package/dist/{impl-Cvyc-iTI2.mjs.map → impl-CWINXCFq2.mjs.map} +1 -1
- package/dist/{impl-BLtOfbtk.mjs → impl-CaErz960.mjs} +2 -2
- package/dist/{impl-BLtOfbtk.mjs.map → impl-CaErz960.mjs.map} +1 -1
- package/dist/{impl-D6rMLiNB2.mjs → impl-CjOkPJJx.mjs} +2 -2
- package/dist/impl-CjOkPJJx.mjs.map +1 -0
- package/dist/{impl-yIVxAhCG2.mjs → impl-CpJIikeg2.mjs} +2 -2
- package/dist/{impl-yIVxAhCG2.mjs.map → impl-CpJIikeg2.mjs.map} +1 -1
- package/dist/{impl-XxYQHKO5.mjs → impl-CujcaHKR.mjs} +2 -2
- package/dist/{impl-XxYQHKO5.mjs.map → impl-CujcaHKR.mjs.map} +1 -1
- package/dist/{impl-BLOhoP-b2.mjs → impl-CzFfjx8n2.mjs} +2 -2
- package/dist/{impl-BLOhoP-b2.mjs.map → impl-CzFfjx8n2.mjs.map} +1 -1
- package/dist/{impl-QD3_9HTk.mjs → impl-CzgNvB64.mjs} +2 -2
- package/dist/{impl-QD3_9HTk.mjs.map → impl-CzgNvB64.mjs.map} +1 -1
- package/dist/{impl-B_N_fOq0.mjs → impl-D5BItJzQ.mjs} +2 -2
- package/dist/{impl-B_N_fOq0.mjs.map → impl-D5BItJzQ.mjs.map} +1 -1
- package/dist/{impl-DeCRXfAh2.mjs → impl-DEF-meSg2.mjs} +2 -2
- package/dist/{impl-DeCRXfAh2.mjs.map → impl-DEF-meSg2.mjs.map} +1 -1
- package/dist/{impl-CTOgxZFi.mjs → impl-DIz7yqDc.mjs} +2 -2
- package/dist/{impl-CTOgxZFi.mjs.map → impl-DIz7yqDc.mjs.map} +1 -1
- package/dist/{impl-DDVhG8Gf.mjs → impl-DLnVDCjy.mjs} +2 -2
- package/dist/{impl-DDVhG8Gf.mjs.map → impl-DLnVDCjy.mjs.map} +1 -1
- package/dist/{impl-DGtCNANL.mjs → impl-DMoMMAMW.mjs} +2 -2
- package/dist/{impl-DGtCNANL.mjs.map → impl-DMoMMAMW.mjs.map} +1 -1
- package/dist/{impl-ChQAmyBN.mjs → impl-DMwjar-u.mjs} +2 -2
- package/dist/{impl-ChQAmyBN.mjs.map → impl-DMwjar-u.mjs.map} +1 -1
- package/dist/{impl-Bz1wZxa-.mjs → impl-DUWlKcy6.mjs} +2 -2
- package/dist/{impl-Bz1wZxa-.mjs.map → impl-DUWlKcy6.mjs.map} +1 -1
- package/dist/{impl-D58JUOdA.mjs → impl-DY_TNWaO.mjs} +2 -2
- package/dist/{impl-D58JUOdA.mjs.map → impl-DY_TNWaO.mjs.map} +1 -1
- package/dist/{impl-Cp5o0Q2g.mjs → impl-D_8KoR4w.mjs} +2 -2
- package/dist/{impl-Cp5o0Q2g.mjs.map → impl-D_8KoR4w.mjs.map} +1 -1
- package/dist/{impl-VSo8bO-J.mjs → impl-DdL7paBD.mjs} +2 -2
- package/dist/{impl-VSo8bO-J.mjs.map → impl-DdL7paBD.mjs.map} +1 -1
- package/dist/{impl-0-_oxvck.mjs → impl-DioQW8jR.mjs} +2 -2
- package/dist/{impl-0-_oxvck.mjs.map → impl-DioQW8jR.mjs.map} +1 -1
- package/dist/{impl-EDwngLc7.mjs → impl-Dj4IYEXg.mjs} +2 -2
- package/dist/{impl-EDwngLc7.mjs.map → impl-Dj4IYEXg.mjs.map} +1 -1
- package/dist/{impl-BvwRiPSG.mjs → impl-DpW_rDzv.mjs} +2 -2
- package/dist/{impl-BvwRiPSG.mjs.map → impl-DpW_rDzv.mjs.map} +1 -1
- package/dist/{impl-Cb-7C1Ml2.mjs → impl-Dr1qLfh1.mjs} +12 -105
- package/dist/impl-Dr1qLfh1.mjs.map +1 -0
- package/dist/{impl-agm4lpyq.mjs → impl-HsRwcfRu.mjs} +2 -2
- package/dist/{impl-agm4lpyq.mjs.map → impl-HsRwcfRu.mjs.map} +1 -1
- package/dist/{impl-BHEAKFX02.mjs → impl-LT1FBKID2.mjs} +2 -2
- package/dist/{impl-BHEAKFX02.mjs.map → impl-LT1FBKID2.mjs.map} +1 -1
- package/dist/impl-Q2ZDQO_y2.mjs +2 -0
- package/dist/impl-Q2ZDQO_y2.mjs.map +1 -0
- package/dist/{impl-DFnWzZyY.mjs → impl-UtanPzK1.mjs} +2 -2
- package/dist/{impl-DFnWzZyY.mjs.map → impl-UtanPzK1.mjs.map} +1 -1
- package/dist/{impl-Ar7VAh0Z.mjs → impl-ZFp_SwYr.mjs} +2 -2
- package/dist/{impl-Ar7VAh0Z.mjs.map → impl-ZFp_SwYr.mjs.map} +1 -1
- package/dist/{impl-Hj5CgbWd.mjs → impl-eWsR0UvV.mjs} +2 -2
- package/dist/{impl-Hj5CgbWd.mjs.map → impl-eWsR0UvV.mjs.map} +1 -1
- package/dist/{impl-Ay6JeH-7.mjs → impl-kuuX5KaC.mjs} +2 -2
- package/dist/{impl-Ay6JeH-7.mjs.map → impl-kuuX5KaC.mjs.map} +1 -1
- package/dist/{impl-xY_5o78i.mjs → impl-mBJWy3lg.mjs} +2 -2
- package/dist/{impl-xY_5o78i.mjs.map → impl-mBJWy3lg.mjs.map} +1 -1
- package/dist/{impl-ojAnhhbi.mjs → impl-nWslO7Lu.mjs} +2 -2
- package/dist/{impl-ojAnhhbi.mjs.map → impl-nWslO7Lu.mjs.map} +1 -1
- package/dist/{impl-ApZGIx6l.mjs → impl-o66EB2o7.mjs} +2 -2
- package/dist/{impl-ApZGIx6l.mjs.map → impl-o66EB2o7.mjs.map} +1 -1
- package/dist/{impl-BCKUj-ko.mjs → impl-pqCx3OlD.mjs} +2 -2
- package/dist/{impl-BCKUj-ko.mjs.map → impl-pqCx3OlD.mjs.map} +1 -1
- package/dist/{impl-BpVe6fMe.mjs → impl-yxR3rwGm.mjs} +2 -2
- package/dist/{impl-BpVe6fMe.mjs.map → impl-yxR3rwGm.mjs.map} +1 -1
- package/dist/index.d.mts +36 -26
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{inquirer-jzIQWAvq.mjs → inquirer-DK1JbPA0.mjs} +2 -2
- package/dist/{inquirer-jzIQWAvq.mjs.map → inquirer-DK1JbPA0.mjs.map} +1 -1
- package/dist/{markRequestDataSiloIdsCompleted-JGJf33yp.mjs → markRequestDataSiloIdsCompleted-CRLlmf-g.mjs} +2 -2
- package/dist/{markRequestDataSiloIdsCompleted-JGJf33yp.mjs.map → markRequestDataSiloIdsCompleted-CRLlmf-g.mjs.map} +1 -1
- package/dist/{markSilentPrivacyRequests-BTI3rH-V.mjs → markSilentPrivacyRequests-CZIAGpw2.mjs} +2 -2
- package/dist/{markSilentPrivacyRequests-BTI3rH-V.mjs.map → markSilentPrivacyRequests-CZIAGpw2.mjs.map} +1 -1
- package/dist/{mergeTranscendInputs-B7WjxYMN.mjs → mergeTranscendInputs-9kQ3t5VY.mjs} +2 -2
- package/dist/{mergeTranscendInputs-B7WjxYMN.mjs.map → mergeTranscendInputs-9kQ3t5VY.mjs.map} +1 -1
- package/dist/{notifyPrivacyRequestsAdditionalTime-n5fvOJaA.mjs → notifyPrivacyRequestsAdditionalTime-KiF9dkuk.mjs} +2 -2
- package/dist/{notifyPrivacyRequestsAdditionalTime-n5fvOJaA.mjs.map → notifyPrivacyRequestsAdditionalTime-KiF9dkuk.mjs.map} +1 -1
- package/dist/{policy-bundle-manifest-DbbTXe0u.mjs → policy-bundle-manifest-DW1kUjMf.mjs} +2 -2
- package/dist/{policy-bundle-manifest-DbbTXe0u.mjs.map → policy-bundle-manifest-DW1kUjMf.mjs.map} +1 -1
- package/dist/{policy-project-discovery-DTSl0Gfl.mjs → policy-project-discovery-BSQ2Cow0.mjs} +4 -4
- package/dist/policy-project-discovery-BSQ2Cow0.mjs.map +1 -0
- package/dist/{policy-scaffold-config-RpxwwZ2H.mjs → policy-scaffold-config-B_Xbfv7q.mjs} +8 -8
- package/dist/policy-scaffold-config-B_Xbfv7q.mjs.map +1 -0
- package/dist/{project-discovery-BkHpTXDx.mjs → project-discovery-g29vd44a.mjs} +2 -2
- package/dist/{project-discovery-BkHpTXDx.mjs.map → project-discovery-g29vd44a.mjs.map} +1 -1
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DbybCU2T.mjs → pullChunkedCustomSiloOutstandingIdentifiers-ekuEZlzq.mjs} +2 -2
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DbybCU2T.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-ekuEZlzq.mjs.map} +1 -1
- package/dist/{pullManualEnrichmentIdentifiersToCsv-CxTPUfpV.mjs → pullManualEnrichmentIdentifiersToCsv-D710M8kt.mjs} +2 -2
- package/dist/{pullManualEnrichmentIdentifiersToCsv-CxTPUfpV.mjs.map → pullManualEnrichmentIdentifiersToCsv-D710M8kt.mjs.map} +1 -1
- package/dist/{pushCronIdentifiersFromCsv-CeRVlbFE.mjs → pushCronIdentifiersFromCsv-f8FSSFhM.mjs} +2 -2
- package/dist/{pushCronIdentifiersFromCsv-CeRVlbFE.mjs.map → pushCronIdentifiersFromCsv-f8FSSFhM.mjs.map} +1 -1
- package/dist/{pushManualEnrichmentIdentifiersFromCsv--4dYCvyv.mjs → pushManualEnrichmentIdentifiersFromCsv-6xOUhOpJ.mjs} +2 -2
- package/dist/{pushManualEnrichmentIdentifiersFromCsv--4dYCvyv.mjs.map → pushManualEnrichmentIdentifiersFromCsv-6xOUhOpJ.mjs.map} +1 -1
- package/dist/{readTranscendYaml-BfqQbPiT.mjs → readTranscendYaml-D576bvzR.mjs} +2 -2
- package/dist/{readTranscendYaml-BfqQbPiT.mjs.map → readTranscendYaml-D576bvzR.mjs.map} +1 -1
- package/dist/{removeUnverifiedRequestIdentifiers-CV6JGgt_.mjs → removeUnverifiedRequestIdentifiers-B8iIreP4.mjs} +2 -2
- package/dist/{removeUnverifiedRequestIdentifiers-CV6JGgt_.mjs.map → removeUnverifiedRequestIdentifiers-B8iIreP4.mjs.map} +1 -1
- package/dist/{retryRequestDataSilos-_OThvVwU.mjs → retryRequestDataSilos-BQuxZd4C.mjs} +2 -2
- package/dist/{retryRequestDataSilos-_OThvVwU.mjs.map → retryRequestDataSilos-BQuxZd4C.mjs.map} +1 -1
- package/dist/runRegalLintStep-DPaMm7Gg.mjs +3 -0
- package/dist/runRegalLintStep-DPaMm7Gg.mjs.map +1 -0
- package/dist/{scaffold-planning-BrX-pcz6.mjs → scaffold-planning-Bp_yqZWx.mjs} +2 -2
- package/dist/{scaffold-planning-BrX-pcz6.mjs.map → scaffold-planning-Bp_yqZWx.mjs.map} +1 -1
- package/dist/{skipPreflightJobs-D8og5pKe.mjs → skipPreflightJobs-BkTH4QOf.mjs} +2 -2
- package/dist/{skipPreflightJobs-D8og5pKe.mjs.map → skipPreflightJobs-BkTH4QOf.mjs.map} +1 -1
- package/dist/{skipRequestDataSilos-DUQ6AD_O.mjs → skipRequestDataSilos-sdfJ0gPn.mjs} +2 -2
- package/dist/{skipRequestDataSilos-DUQ6AD_O.mjs.map → skipRequestDataSilos-sdfJ0gPn.mjs.map} +1 -1
- package/dist/{streamPrivacyRequestsToCsv-BApu4dvI.mjs → streamPrivacyRequestsToCsv-D0PK8mjN.mjs} +2 -2
- package/dist/{streamPrivacyRequestsToCsv-BApu4dvI.mjs.map → streamPrivacyRequestsToCsv-D0PK8mjN.mjs.map} +1 -1
- package/dist/{updateConsentManagerVersionToLatest-BrgPZ5hX.mjs → updateConsentManagerVersionToLatest-EJaexjTY.mjs} +2 -2
- package/dist/{updateConsentManagerVersionToLatest-BrgPZ5hX.mjs.map → updateConsentManagerVersionToLatest-EJaexjTY.mjs.map} +1 -1
- package/dist/{uploadConsents-DRlDHQak.mjs → uploadConsents-DjvQVsIl.mjs} +2 -2
- package/dist/{uploadConsents-DRlDHQak.mjs.map → uploadConsents-DjvQVsIl.mjs.map} +1 -1
- package/dist/uploadPrivacyRequestsFromCsv-FvSx9zis.mjs +2 -0
- package/dist/uploadPrivacyRequestsFromCsv-FvSx9zis.mjs.map +1 -0
- package/dist/{validateTranscendAuth-D-dDINof.mjs → validateTranscendAuth-BrVGfq6X.mjs} +2 -2
- package/dist/{validateTranscendAuth-D-dDINof.mjs.map → validateTranscendAuth-BrVGfq6X.mjs.map} +1 -1
- package/package.json +6 -6
- package/dist/app-BMLQABJX.mjs.map +0 -1
- package/dist/codecs-CfcaFoZR.mjs +0 -2
- package/dist/codecs-CfcaFoZR.mjs.map +0 -1
- package/dist/constants-DlH2vWm_.mjs +0 -2
- package/dist/constants-DlH2vWm_.mjs.map +0 -1
- package/dist/fetchAllRequests-BI0tFl_a.mjs +0 -2
- package/dist/fetchAllRequests-BI0tFl_a.mjs.map +0 -1
- package/dist/impl-BEiCEzl_2.mjs.map +0 -1
- package/dist/impl-Cb-7C1Ml2.mjs.map +0 -1
- package/dist/impl-D6rMLiNB2.mjs.map +0 -1
- package/dist/impl-DNOgBcsu.mjs +0 -3
- package/dist/impl-DNOgBcsu.mjs.map +0 -1
- package/dist/impl-Dd39KsYO.mjs.map +0 -1
- package/dist/policy-project-discovery-DTSl0Gfl.mjs.map +0 -1
- package/dist/policy-scaffold-config-RpxwwZ2H.mjs.map +0 -1
- package/dist/uploadPrivacyRequestsFromCsv-FAGllBdd.mjs +0 -2
- package/dist/uploadPrivacyRequestsFromCsv-FAGllBdd.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impl-BfS6LtNo2.mjs","names":[],"sources":["../src/lib/policy/policy-check-model.ts","../src/commands/policy/helpers/collectPolicyRegoFiles.ts","../src/commands/policy/check/impl.ts"],"sourcesContent":["/** Stable policy check result schema version. */\nexport const POLICY_CHECK_RESULT_VERSION = 1;\n\n/** Stable multi-bundle check result schema version. */\nexport const POLICY_CHECK_MULTI_RESULT_VERSION = 2;\n\n/** Status of the full gate or an individual verification. */\nexport type PolicyCheckStatus = 'passed' | 'failed' | 'skipped';\n\n/** One named policy verification. */\nexport interface PolicyCheckStep {\n /** Stable verification name. */\n name:\n | 'manifest'\n | 'opa-version'\n | 'regal-version'\n | 'format'\n | 'opa-check'\n | 'regal-lint'\n | 'opa-test';\n /** Verification outcome. */\n status: PolicyCheckStatus;\n}\n\n/** Stable verification execution order. */\nexport const POLICY_CHECK_STEP_NAMES: PolicyCheckStep['name'][] = [\n 'manifest',\n 'opa-version',\n 'regal-version',\n 'format',\n 'opa-check',\n 'regal-lint',\n 'opa-test',\n];\n\n/** User-facing verification labels. */\nexport const POLICY_CHECK_STEP_LABELS: Readonly<Record<PolicyCheckStep['name'], string>> = {\n manifest: 'Manifest and package roots',\n 'opa-version': 'OPA 1.x',\n 'regal-version': 'Regal',\n format: 'OPA formatting',\n 'opa-check': 'OPA strict check',\n 'regal-lint': 'Regal lint',\n 'opa-test': 'OPA tests',\n};\n\n/** One machine-readable policy check diagnostic. */\nexport interface PolicyCheckDiagnostic {\n /** Stable diagnostic identifier. */\n code: string;\n /** Diagnostic severity. */\n severity: 'error';\n /** Human-readable detail, including captured tool output when available. */\n message: string;\n /** Optional path relative to the invocation directory. */\n path?: string;\n}\n\n/** Detected local policy tool versions. */\nexport interface PolicyCheckTools {\n /** Detected OPA version, or null when missing or unsupported. */\n opa: string | null;\n /** Detected Regal version, or null when missing or unsupported. */\n regal: string | null;\n}\n\n/** Stable result emitted by `transcend policy check --json` for one bundle. */\nexport interface PolicyCheckResult {\n /** Result schema version. */\n version: typeof POLICY_CHECK_RESULT_VERSION;\n /** Overall verification outcome. */\n status: Exclude<PolicyCheckStatus, 'skipped'>;\n /** Absolute policy bundle directory. */\n directory: string;\n /** Whether formatting repair was explicitly requested. */\n fix: boolean;\n /** Detected supported tool versions. */\n tools: PolicyCheckTools;\n /** Verification outcomes in stable execution order. */\n checks: PolicyCheckStep[];\n /** Files found to need OPA formatting, relative to the policy directory. */\n unformattedFiles: string[];\n /** Files repaired with OPA formatting, relative to the policy directory. */\n fixedFiles: string[];\n /** Ordered verification diagnostics. */\n diagnostics: PolicyCheckDiagnostic[];\n}\n\n/**\n * Stable result when `transcend policy check --json` verifies multiple bundles.\n *\n * Emitted only when the selected path is a workspace with more than one\n * publishable `*-bundle/` directory.\n */\nexport interface PolicyCheckMultiResult {\n /** Result schema version. */\n version: typeof POLICY_CHECK_MULTI_RESULT_VERSION;\n /** Overall verification outcome across all bundles. */\n status: Exclude<PolicyCheckStatus, 'skipped'>;\n /** Absolute policy workspace directory that was searched. */\n directory: string;\n /** Whether formatting repair was explicitly requested. */\n fix: boolean;\n /** Per-bundle results in discovery order. */\n results: PolicyCheckResult[];\n}\n","import path from 'node:path';\n\nimport type { LocalContext } from '../../../context.js';\nimport type { PolicyBundleRegoFile } from '../../../lib/policy/policy-bundle-manifest.js';\n\n/**\n * Collect Rego source snapshots without following symlinks.\n *\n * @param context - CLI context\n * @param projectDirectory - Absolute policy directory\n * @param currentDirectory - Current recursive directory\n * @returns Deterministically ordered Rego snapshots\n */\nexport function collectPolicyRegoFiles(\n context: LocalContext,\n projectDirectory: string,\n currentDirectory: string = projectDirectory,\n): PolicyBundleRegoFile[] {\n return context.fs\n .readdirSync(currentDirectory, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name))\n .flatMap((entry) => {\n const absolutePath = path.join(currentDirectory, entry.name);\n if (entry.isDirectory()) {\n return collectPolicyRegoFiles(context, projectDirectory, absolutePath);\n }\n if (!entry.isFile() || !entry.name.endsWith('.rego')) {\n return [];\n }\n return [\n {\n path: path.relative(projectDirectory, absolutePath).split(path.sep).join('/'),\n contents: context.fs.readFileSync(absolutePath, 'utf8'),\n },\n ];\n });\n}\n","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 {\n runCapturedProcess,\n type CapturedProcessRunner,\n} from '../../../lib/cli/run-captured-process.js';\nimport { validatePolicyBundleContents } from '../../../lib/policy/policy-bundle-manifest.js';\nimport {\n type PolicyCheckDiagnostic,\n type PolicyCheckMultiResult,\n type PolicyCheckResult,\n type PolicyCheckStep,\n POLICY_CHECK_MULTI_RESULT_VERSION,\n POLICY_CHECK_RESULT_VERSION,\n POLICY_CHECK_STEP_LABELS,\n POLICY_CHECK_STEP_NAMES,\n} from '../../../lib/policy/policy-check-model.js';\nimport { getPolicyProcessFailureMessage } from '../../../lib/policy/policy-process-output.js';\nimport {\n DEFAULT_POLICY_PROJECT_DIRECTORY,\n discoverPolicyBundleDirectories,\n resolvePolicyProjectDirectory,\n} from '../../../lib/policy/policy-project-discovery.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { collectPolicyRegoFiles } from '../helpers/collectPolicyRegoFiles.js';\nimport { probePolicyToolVersions } from '../helpers/probePolicyToolVersions.js';\nimport { runOpaFormatStep } from '../helpers/runOpaFormatStep.js';\nimport { runRegalLintStep } from '../helpers/runRegalLintStep.js';\n\n/** CLI flags for `transcend policy check`. */\nexport interface CheckCommandFlags {\n /** Apply OPA formatting. */\n fix: boolean;\n /** Disable the optional formatting confirmation. */\n noInteractive: boolean;\n /** Emit one stable JSON result on stdout. */\n json: boolean;\n}\n\n/**\n * Render the terminal summary for a policy verification result.\n *\n * @param context - CLI context\n * @param result - Completed verification result\n * @param heading - Optional section heading when checking multiple bundles\n */\nfunction renderResult(context: LocalContext, result: PolicyCheckResult, heading?: string): void {\n if (heading) {\n context.logger.info(`${colors.bold(heading)}\\n`);\n } else {\n context.logger.info(`${colors.bold('Policy verification')}\\n`);\n }\n result.checks.forEach(({ name, status }) => {\n const label = status === 'passed' ? 'PASS' : status === 'failed' ? 'FAIL' : 'SKIP';\n const styledLabel =\n status === 'passed'\n ? colors.green(label)\n : status === 'failed'\n ? colors.red(label)\n : colors.yellow(label);\n const version =\n name === 'opa-version' && result.tools.opa\n ? ` (${result.tools.opa})`\n : name === 'regal-version' && result.tools.regal\n ? ` (${result.tools.regal})`\n : '';\n context.logger.info(`${styledLabel} ${POLICY_CHECK_STEP_LABELS[name]}${version}`);\n });\n if (result.diagnostics.length > 0) {\n context.logger.error('');\n }\n result.diagnostics.forEach((diagnostic) => {\n const location = diagnostic.path ? `${diagnostic.path}: ` : '';\n context.logger.error(\n colors.red(`error [${diagnostic.code}]: ${location}${diagnostic.message}`),\n );\n });\n if (result.status === 'passed') {\n context.logger.info('');\n context.logger.info(colors.green('Policy verification passed.'));\n } else {\n context.logger.error('');\n context.logger.error(colors.red('Policy verification failed.'));\n }\n}\n\n/**\n * Verify one publishable policy bundle directory.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param resolvedDir - Absolute bundle directory\n * @param runner - Captured subprocess runner\n * @returns Completed verification result\n */\nasync function checkBundle(\n this: LocalContext,\n { fix, noInteractive, json }: CheckCommandFlags,\n resolvedDir: string,\n runner: CapturedProcessRunner,\n): Promise<PolicyCheckResult> {\n const checks: PolicyCheckStep[] = POLICY_CHECK_STEP_NAMES.map((name) => ({\n name,\n status: 'skipped',\n }));\n const diagnostics: PolicyCheckDiagnostic[] = [];\n const result: PolicyCheckResult = {\n version: POLICY_CHECK_RESULT_VERSION,\n status: 'passed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks,\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics,\n };\n const setStatus = (name: PolicyCheckStep['name'], status: PolicyCheckStep['status']): void => {\n checks.find((check) => check.name === name)!.status = status;\n };\n const addError = (code: string, message: string, diagnosticPath?: string): void => {\n diagnostics.push({\n code,\n severity: 'error',\n message,\n ...(diagnosticPath ? { path: diagnosticPath } : {}),\n });\n };\n\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n setStatus('manifest', 'failed');\n addError(\n 'project.directory',\n `Policy directory does not exist or is not a directory: ${resolvedDir}`,\n path.relative(this.process.cwd(), resolvedDir),\n );\n result.status = 'failed';\n return result;\n }\n\n const manifestPath = path.join(resolvedDir, POLICY_MANIFEST_FILENAME);\n try {\n validatePolicyBundleContents(\n this.fs.existsSync(manifestPath) ? this.fs.readFileSync(manifestPath, 'utf8') : undefined,\n collectPolicyRegoFiles(this, resolvedDir),\n );\n setStatus('manifest', 'passed');\n } catch (error) {\n setStatus('manifest', 'failed');\n addError(\n 'manifest.invalid',\n error instanceof Error ? error.message : String(error),\n path.relative(this.process.cwd(), manifestPath),\n );\n }\n\n const toolVersions = await probePolicyToolVersions.call(this, resolvedDir, runner);\n result.tools = { opa: toolVersions.opa, regal: toolVersions.regal };\n setStatus('opa-version', toolVersions.opaStatus);\n setStatus('regal-version', toolVersions.regalStatus);\n toolVersions.diagnostics.forEach((diagnostic) => {\n addError(diagnostic.code, diagnostic.message);\n });\n\n if (result.tools.opa) {\n const formatStep = await runOpaFormatStep.call(this, {\n resolvedDir,\n fix,\n noInteractive,\n json,\n fixCommandHint: 'transcend policy check --fix',\n runner,\n });\n result.unformattedFiles = formatStep.unformattedFiles;\n result.fixedFiles = formatStep.fixedFiles;\n setStatus('format', formatStep.status);\n formatStep.diagnostics.forEach((diagnostic) => {\n addError(diagnostic.code, diagnostic.message);\n });\n\n const checkResult = await runner(\n 'opa',\n ['check', '--strict', '--ignore', '*_test.rego', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (checkResult.code === 0) {\n setStatus('opa-check', 'passed');\n } else {\n setStatus('opa-check', 'failed');\n addError(\n 'opa.check',\n getPolicyProcessFailureMessage(\n checkResult,\n `opa check failed with exit code ${checkResult.code}`,\n ),\n );\n }\n }\n\n if (result.tools.regal) {\n const regalStep = await runRegalLintStep.call(this, { resolvedDir, runner });\n setStatus('regal-lint', regalStep.status);\n regalStep.diagnostics.forEach((diagnostic) => {\n addError(diagnostic.code, diagnostic.message);\n });\n }\n\n if (result.tools.opa) {\n const testResult = await runner(\n 'opa',\n ['test', '--fail-on-empty', '-b', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (testResult.code === 0) {\n setStatus('opa-test', 'passed');\n } else {\n setStatus('opa-test', 'failed');\n addError(\n 'opa.test',\n getPolicyProcessFailureMessage(\n testResult,\n `opa test --fail-on-empty -b failed with exit code ${testResult.code}`,\n ),\n );\n }\n }\n\n result.status = checks.some(({ status }) => status === 'failed') ? 'failed' : 'passed';\n return result;\n}\n\n/**\n * Verify local policy bundles with the shared upload contract, OPA, and Regal.\n *\n * With no directory (or the default workspace path), discovers every immediate\n * child that contains a `.manifest` and verifies each. Pass one bundle path to\n * verify a single publishable unit.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy workspace or bundle directory\n * @param runner - Captured subprocess runner\n */\nexport async function check(\n this: LocalContext,\n flags: CheckCommandFlags,\n directory: string = DEFAULT_POLICY_PROJECT_DIRECTORY,\n runner: CapturedProcessRunner = runCapturedProcess,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const { fix = false, noInteractive = false, json = false } = flags;\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n const missing: PolicyCheckResult = {\n version: POLICY_CHECK_RESULT_VERSION,\n status: 'failed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks: POLICY_CHECK_STEP_NAMES.map((name) => ({\n name,\n status: name === 'manifest' ? 'failed' : 'skipped',\n })),\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics: [\n {\n code: 'project.directory',\n severity: 'error',\n message: `Policy directory does not exist or is not a directory: ${resolvedDir}`,\n path: path.relative(this.process.cwd(), resolvedDir),\n },\n ],\n };\n if (json) {\n this.process.stdout.write(`${JSON.stringify(missing)}\\n`);\n } else {\n renderResult(this, missing);\n }\n this.process.exitCode = 1;\n return;\n }\n\n const bundleDirectories = discoverPolicyBundleDirectories(this, resolvedDir);\n if (bundleDirectories.length === 0) {\n const empty: PolicyCheckResult = {\n version: POLICY_CHECK_RESULT_VERSION,\n status: 'failed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks: POLICY_CHECK_STEP_NAMES.map((name) => ({\n name,\n status: name === 'manifest' ? 'failed' : 'skipped',\n })),\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics: [\n {\n code: 'project.bundles',\n severity: 'error',\n message:\n 'No publishable policy bundles found. Add one with `transcend policy new`, ' +\n 'or pass a directory that contains a `.manifest`.',\n path: path.relative(this.process.cwd(), resolvedDir) || '.',\n },\n ],\n };\n if (json) {\n this.process.stdout.write(`${JSON.stringify(empty)}\\n`);\n } else {\n renderResult(this, empty);\n }\n this.process.exitCode = 1;\n return;\n }\n\n const results: PolicyCheckResult[] = [];\n for (const bundleDirectory of bundleDirectories) {\n results.push(\n await checkBundle.call(this, { fix, noInteractive, json }, bundleDirectory, runner),\n );\n }\n\n const failed = results.some((result) => result.status === 'failed');\n if (json) {\n if (results.length === 1) {\n this.process.stdout.write(`${JSON.stringify(results[0])}\\n`);\n } else {\n const multi: PolicyCheckMultiResult = {\n version: POLICY_CHECK_MULTI_RESULT_VERSION,\n status: failed ? 'failed' : 'passed',\n directory: resolvedDir,\n fix,\n results,\n };\n this.process.stdout.write(`${JSON.stringify(multi)}\\n`);\n }\n } else if (results.length === 1) {\n renderResult(this, results[0]!);\n } else {\n results.forEach((result, index) => {\n if (index > 0) {\n this.logger.info('');\n }\n const relative = path.relative(this.process.cwd(), result.directory) || result.directory;\n renderResult(this, result, `Policy verification — ${relative}`);\n });\n }\n\n if (failed) {\n this.process.exitCode = 1;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{r as e,t}from"./policyEngineCliError-CZrOHhLv.mjs";import{i as n,r,t as i}from"./printResult-Dmwv78e7.mjs";import{t as a}from"./formatPolicyBundleVersionSummary-DCHl1Vhy.mjs";import{n as o}from"./resolveBundleIdByName-D7NUOpLc.mjs";import{t as s}from"./done-input-validation-LiTaCEzF.mjs";import{t as c}from"./command-output-BJcDRXNr.mjs";import l from"colors";async function u({"remote-bundle-name":u,auth:d,"transcend-url":f,json:p,debug:m=!1}){s(this.process),e(m);let h=c(this.logger,p),g=n(f,d),_=await o(g,u);if(!_)throw Error(`Policy bundle "${u}" was not found for this organization.`);h.info(l.green(`Deactivating active version for bundle "${u}"...`));let v;try{v=await g.post(`v1/policy-engine/policy-bundles/${_}/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:v,renderTable:()=>[`bundleId ${v.bundle.id}`,`bundleName ${v.bundle.bundleName}`,a(v.version)].join(`
|
|
2
2
|
`)}),h.info(l.green(`Policy bundle version deactivated.`))}export{u as deactivate};
|
|
3
|
-
//# sourceMappingURL=impl-
|
|
3
|
+
//# sourceMappingURL=impl-BfU0GFmW.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BfU0GFmW.mjs","names":[],"sources":["../src/commands/policy/deactivate/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { selectCommandLogger } from '../../../lib/cli/command-output.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.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 'remote-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 `--remote-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 'remote-bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n json,\n debug = false,\n }: DeactivateCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const commandLogger = selectCommandLogger(this.logger, json);\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 commandLogger.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 commandLogger.info(colors.green('Policy bundle version deactivated.'));\n}\n"],"mappings":"gXAwCA,eAAsB,EAEpB,CACE,qBAAsB,EACtB,OACA,gBAAiB,EACjB,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAgB,EAAoB,KAAK,OAAQ,EAAK,CACtD,EAAS,EAAwB,EAAc,EAAK,CAEpD,EAAmB,MAAM,EAAsB,EAAQ,EAAW,CACxE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,EAAc,KAAK,EAAO,MAAM,2CAA2C,EAAW,MAAM,CAAC,CAE7F,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,EAAc,KAAK,EAAO,MAAM,qCAAqC,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./pushManualEnrichmentIdentifiersFromCsv
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./pushManualEnrichmentIdentifiersFromCsv-6xOUhOpJ.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,transcendUrl:r,file:i,enricherId:a,concurrency:o,markSilent:s,sombraAuth:c}){t(this.process),await e({file:i,transcendUrl:r,enricherId:a,concurrency:o,markSilent:s,auth:n,sombraAuth:c})}export{n as pushIdentifiers};
|
|
2
|
+
//# sourceMappingURL=impl-Bhmoagby.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-Bhmoagby.mjs","names":[],"sources":["../src/commands/request/preflight/push-identifiers/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushManualEnrichmentIdentifiersFromCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PushIdentifiersCommandFlags {\n auth: string;\n enricherId: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n markSilent: boolean;\n concurrency: number;\n}\n\nexport async function pushIdentifiers(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n file,\n enricherId,\n concurrency,\n markSilent,\n sombraAuth,\n }: PushIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await pushManualEnrichmentIdentifiersFromCsv({\n file,\n transcendUrl,\n enricherId,\n concurrency,\n markSilent,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"8HAcA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,aACA,cACA,aACA,cAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAuC,CAC3C,OACA,eACA,aACA,cACA,aACA,OACA,aACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./pullChunkedCustomSiloOutstandingIdentifiers-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./pullChunkedCustomSiloOutstandingIdentifiers-ekuEZlzq.mjs";import{i as t,s as n}from"./writeCsv-CNZrq3zU.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{uniq as i}from"lodash-es";import a from"colors";async function o({file:o,transcendUrl:s,auth:c,sombraAuth:l,dataSiloId:u,actions:d,pageLimit:f,skipRequestCount:p,chunkSize:m}){p&&this.logger.info(a.yellow(`Skipping request count as requested. This may help speed up the call.`)),(Number.isNaN(m)||m<=0||m%f!==0)&&(this.logger.error(a.red(`Invalid chunk size: "${m}". Must be a positive integer that is a multiple of ${f}.`)),this.process.exit(1)),r(this.process);let{baseName:h,extension:g}=t(o),_=0;await e({transcendUrl:s,apiPageSize:f,savePageSize:m,onSave:async e=>{let t=`${h}-${_}${g}`;return this.logger.info(a.blue(`Saving ${e.length} identifiers to file "${t}"`)),await n(t,e,i(e.map(e=>Object.keys(e)).flat())),this.logger.info(a.green(`Successfully wrote ${e.length} identifiers to file "${t}"`)),_+=1,Promise.resolve()},actions:d,auth:c,sombraAuth:l,dataSiloId:u,skipRequestCount:p})}export{o as pullIdentifiers};
|
|
2
|
+
//# sourceMappingURL=impl-Bpiggf8H.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-Bpiggf8H.mjs","names":[],"sources":["../src/commands/request/cron/pull-identifiers/impl.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport colors from 'colors';\nimport { uniq } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n CsvFormattedIdentifier,\n pullChunkedCustomSiloOutstandingIdentifiers,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n actions: RequestAction[];\n pageLimit: number;\n skipRequestCount: boolean;\n chunkSize: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n {\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n actions,\n pageLimit,\n skipRequestCount,\n chunkSize,\n }: PullIdentifiersCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n this.logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n this.logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process);\n\n const { baseName, extension } = parseFilePath(file);\n let fileCount = 0;\n\n const onSave = async (chunk: CsvFormattedIdentifier[]): Promise<void> => {\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n this.logger.info(\n colors.blue(`Saving ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n\n const headers = uniq(chunk.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileName, chunk, headers);\n this.logger.info(\n colors.green(`Successfully wrote ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n fileCount += 1;\n return Promise.resolve();\n };\n\n // Pull down outstanding identifiers\n await pullChunkedCustomSiloOutstandingIdentifiers({\n transcendUrl,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n actions,\n auth,\n sombraAuth,\n dataSiloId,\n skipRequestCount,\n });\n}\n"],"mappings":"kPAwBA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,aACA,aACA,UACA,YACA,mBACA,aAEa,CACX,GACF,KAAK,OAAO,KACV,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,KAAK,OAAO,MACV,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,CAEjC,GAAM,CAAE,WAAU,aAAc,EAAc,EAAK,CAC/C,EAAY,EAkBhB,MAAM,EAA4C,CAChD,eACA,YAAa,EACb,aAAc,EACd,YApBoB,IAAmD,CACvE,IAAM,EAAmB,GAAG,EAAS,GAAG,IAAY,IAWpD,OAVA,KAAK,OAAO,KACV,EAAO,KAAK,UAAU,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAChF,CAGD,MAAM,EAAc,EAAkB,EADtB,EAAK,EAAM,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACR,CAAC,CACrD,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAC7F,CACD,GAAa,EACN,QAAQ,SAAS,EASxB,UACA,OACA,aACA,aACA,mBACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./removeUnverifiedRequestIdentifiers-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./removeUnverifiedRequestIdentifiers-B8iIreP4.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,transcendUrl:r,identifierNames:i,actions:a=[]}){t(this.process),await e({requestActions:a,transcendUrl:r,auth:n,identifierNames:i})}export{n as rejectUnverifiedIdentifiers};
|
|
2
|
+
//# sourceMappingURL=impl-BsxD7toO.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BsxD7toO.mjs","names":[],"sources":["../src/commands/request/reject-unverified-identifiers/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { removeUnverifiedRequestIdentifiers } from '../../../lib/requests/index.js';\n\nexport interface RejectUnverifiedIdentifiersCommandFlags {\n auth: string;\n identifierNames: string[];\n actions?: RequestAction[];\n transcendUrl: string;\n}\n\nexport async function rejectUnverifiedIdentifiers(\n this: LocalContext,\n { auth, transcendUrl, identifierNames, actions = [] }: RejectUnverifiedIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await removeUnverifiedRequestIdentifiers({\n requestActions: actions,\n transcendUrl,\n auth,\n identifierNames,\n });\n}\n"],"mappings":"0HAaA,eAAsB,EAEpB,CAAE,OAAM,eAAc,kBAAiB,UAAU,EAAE,EACpC,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAmC,CACvC,eAAgB,EAChB,eACA,OACA,kBACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./skipPreflightJobs-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./skipPreflightJobs-BkTH4QOf.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,transcendUrl:r,enricherIds:i}){t(this.process),await e({transcendUrl:r,auth:n,enricherIds:i})}export{n as skipPreflightJobs};
|
|
2
|
+
//# sourceMappingURL=impl-BvL9wElZ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BvL9wElZ.mjs","names":["skipPreflightJobsHelper"],"sources":["../src/commands/request/skip-preflight-jobs/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { skipPreflightJobs as skipPreflightJobsHelper } from '../../../lib/requests/index.js';\n\nexport interface SkipPreflightJobsCommandFlags {\n auth: string;\n enricherIds: string[];\n transcendUrl: string;\n}\n\nexport async function skipPreflightJobs(\n this: LocalContext,\n { auth, transcendUrl, enricherIds }: SkipPreflightJobsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await skipPreflightJobsHelper({\n transcendUrl,\n auth,\n enricherIds,\n });\n}\n"],"mappings":"yGAUA,eAAsB,EAEpB,CAAE,OAAM,eAAc,eACP,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAMA,EAAwB,CAC5B,eACA,OACA,cACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{r as e}from"./policyEngineCliError-CZrOHhLv.mjs";import{i as t,n,t as r}from"./printResult-Dmwv78e7.mjs";import{t as i}from"./renderTable-CZP2roD1.mjs";import{n as a}from"./resolveBundleIdByName-D7NUOpLc.mjs";import{t as o}from"./done-input-validation-LiTaCEzF.mjs";import{t as s}from"./command-output-BJcDRXNr.mjs";import c from"colors";async function l({"remote-bundle-name":l,auth:u,"transcend-url":d,limit:f,after:p,json:m,debug:h=!1}){o(this.process),e(h);let g=t(d,u),_=s(this.logger,m),v=await a(g,l);if(!v)throw Error(`Policy bundle "${l}" was not found for this organization.`);_.info(c.green(`Listing versions for bundle "${l}"...`));let y={limit:f};p&&(y.after=p);let b=await n(g.get(`v1/policy-engine/policy-bundles/${v}/versions`,{searchParams:y}).json());r(this.process.stdout,{json:m,data:b,renderTable:()=>{if(b.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`],b.nodes.map(e=>[e.id,e.version,e.createdAt,e.activatedAt??`-`,e.deactivatedAt??`-`]));return b.pageInfo.endCursor&&(e+=`\n\nafter: ${b.pageInfo.endCursor}`),e}})}export{l as versions};
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
2
|
+
//# sourceMappingURL=impl-BzzkiK_b.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-BzzkiK_b.mjs","names":[],"sources":["../src/commands/policy/versions/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { selectCommandLogger } from '../../../lib/cli/command-output.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.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 'remote-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 'remote-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);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const commandLogger = selectCommandLogger(this.logger, json);\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 commandLogger.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":"yVAwCA,eAAsB,EAEpB,CACE,qBAAsB,EACtB,OACA,gBAAiB,EACjB,QACA,QACA,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CACpD,EAAgB,EAAoB,KAAK,OAAQ,EAAK,CACtD,EAAW,MAAM,EAAsB,EAAQ,EAAW,CAEhE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,EAAc,KAAK,EAAO,MAAM,gCAAgC,EAAW,MAAM,CAAC,CAElF,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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{n as e}from"./constants-I694qbRg.mjs";import{s as t}from"./writeCsv-CNZrq3zU.mjs";import{t as n}from"./pullAllDatapoints-CNqQSSmF.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{groupBy as i,uniq as a}from"lodash-es";import o from"colors";import{buildTranscendGraphQLClient as s}from"@transcend-io/sdk";async function c({auth:c,file:l,transcendUrl:u,dataSiloIds:d,includeAttributes:f,includeGuessedCategories:p,parentCategories:m,subCategories:h=[]}){r(this.process);try{let e=await n(s(u,c),{dataSiloIds:d,includeGuessedCategories:p,parentCategories:m,includeAttributes:f,subCategories:h});this.logger.info(o.magenta(`Writing datapoints to file "${l}"...`));let r=[];await t(l,e.map(e=>{let t={"Property ID":e.id,"Data Silo":e.dataSilo.title,Object:e.dataPoint.name,"Object Path":e.dataPoint.path.join(`.`),Property:e.name,"Property Description":e.description,"Data Categories":e.categories.map(e=>`${e.category}:${e.name}`).join(`, `),"Guessed Category":e.pendingCategoryGuesses?.[0]?`${e.pendingCategoryGuesses[0].category.category}:${e.pendingCategoryGuesses[0].category.name}`:``,"Processing Purposes":e.purposes.map(e=>`${e.purpose}:${e.name}`).join(`, `),...Object.entries(i(e.attributeValues||[],({attributeKey:e})=>e.name)).reduce((e,[t,n])=>(e[t]=n.map(e=>e.name).join(`,`),e),{})};return r=a([...r,...Object.keys(t)]),t}),r)}catch(e){this.logger.error(o.red(`An error occurred syncing the datapoints: ${e.message}`)),this.process.exit(1)}this.logger.info(o.green(`Successfully synced datapoints to disk at ${l}! View at ${e}`))}export{c as pullDatapoints};
|
|
2
|
+
//# sourceMappingURL=impl-C-hBO0Wa2.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-C-hBO0Wa2.mjs","names":[],"sources":["../src/commands/inventory/pull-datapoints/impl.ts"],"sourcesContent":["import { DataCategoryType } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { uniq, groupBy } from 'lodash-es';\n\nimport { ADMIN_DASH_DATAPOINTS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { pullAllDatapoints } from '../../../lib/data-inventory/index.js';\nimport { writeLargeCsv } from '../../../lib/helpers/index.js';\n\nexport interface PullDatapointsCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n dataSiloIds?: string[];\n includeAttributes: boolean;\n includeGuessedCategories: boolean;\n parentCategories?: DataCategoryType[];\n subCategories?: string[];\n}\n\nexport async function pullDatapoints(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n dataSiloIds,\n includeAttributes,\n includeGuessedCategories,\n parentCategories,\n subCategories = [],\n }: PullDatapointsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n try {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const dataPoints = await pullAllDatapoints(client, {\n dataSiloIds,\n includeGuessedCategories,\n parentCategories,\n includeAttributes,\n subCategories, // TODO: https://transcend.height.app/T-40482 - do by name not ID\n });\n\n this.logger.info(colors.magenta(`Writing datapoints to file \"${file}\"...`));\n let headers: string[] = [];\n const inputs = dataPoints.map((point) => {\n const result = {\n 'Property ID': point.id,\n 'Data Silo': point.dataSilo.title,\n Object: point.dataPoint.name,\n 'Object Path': point.dataPoint.path.join('.'),\n Property: point.name,\n 'Property Description': point.description,\n 'Data Categories': point.categories\n .map((category) => `${category.category}:${category.name}`)\n .join(', '),\n 'Guessed Category': point.pendingCategoryGuesses?.[0]\n ? `${point.pendingCategoryGuesses![0]!.category.category}:${\n point.pendingCategoryGuesses![0]!.category.name\n }`\n : '',\n 'Processing Purposes': point.purposes\n .map((purpose) => `${purpose.purpose}:${purpose.name}`)\n .join(', '),\n ...Object.entries(\n groupBy(point.attributeValues || [], ({ attributeKey }) => attributeKey.name),\n ).reduce(\n (acc, [key, values]) => {\n acc[key] = values.map((value) => value.name).join(',');\n return acc;\n },\n {} as Record<string, string>,\n ),\n };\n headers = uniq([...headers, ...Object.keys(result)]);\n return result;\n });\n await writeLargeCsv(file, inputs, headers);\n } catch (err) {\n this.logger.error(colors.red(`An error occurred syncing the datapoints: ${err.message}`));\n this.process.exit(1);\n }\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Successfully synced datapoints to disk at ${file}! View at ${ADMIN_DASH_DATAPOINTS}`,\n ),\n );\n}\n"],"mappings":"2UAsBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,cACA,oBACA,2BACA,mBACA,gBAAgB,EAAE,EAEL,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAI,CAIF,IAAM,EAAa,MAAM,EAFV,EAA4B,EAAc,EAER,CAAE,CACjD,cACA,2BACA,mBACA,oBACA,gBACD,CAAC,CAEF,KAAK,OAAO,KAAK,EAAO,QAAQ,+BAA+B,EAAK,MAAM,CAAC,CAC3E,IAAI,EAAoB,EAAE,CAiC1B,MAAM,EAAc,EAhCL,EAAW,IAAK,GAAU,CACvC,IAAM,EAAS,CACb,cAAe,EAAM,GACrB,YAAa,EAAM,SAAS,MAC5B,OAAQ,EAAM,UAAU,KACxB,cAAe,EAAM,UAAU,KAAK,KAAK,IAAI,CAC7C,SAAU,EAAM,KAChB,uBAAwB,EAAM,YAC9B,kBAAmB,EAAM,WACtB,IAAK,GAAa,GAAG,EAAS,SAAS,GAAG,EAAS,OAAO,CAC1D,KAAK,KAAK,CACb,mBAAoB,EAAM,yBAAyB,GAC/C,GAAG,EAAM,uBAAwB,GAAI,SAAS,SAAS,GACrD,EAAM,uBAAwB,GAAI,SAAS,OAE7C,GACJ,sBAAuB,EAAM,SAC1B,IAAK,GAAY,GAAG,EAAQ,QAAQ,GAAG,EAAQ,OAAO,CACtD,KAAK,KAAK,CACb,GAAG,OAAO,QACR,EAAQ,EAAM,iBAAmB,EAAE,EAAG,CAAE,kBAAmB,EAAa,KAAK,CAC9E,CAAC,QACC,EAAK,CAAC,EAAK,MACV,EAAI,GAAO,EAAO,IAAK,GAAU,EAAM,KAAK,CAAC,KAAK,IAAI,CAC/C,GAET,EAAE,CACH,CACF,CAED,MADA,GAAU,EAAK,CAAC,GAAG,EAAS,GAAG,OAAO,KAAK,EAAO,CAAC,CAAC,CAC7C,GAEuB,CAAE,EAAQ,OACnC,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,6CAA6C,EAAI,UAAU,CAAC,CACzF,KAAK,QAAQ,KAAK,EAAE,CAItB,KAAK,OAAO,KACV,EAAO,MACL,6CAA6C,EAAK,YAAY,IAC/D,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./readCsv-DNcJ_UfU.mjs";import{t}from"./markRequestDataSiloIdsCompleted-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./readCsv-DNcJ_UfU.mjs";import{t}from"./markRequestDataSiloIdsCompleted-CRLlmf-g.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.mjs";import r from"colors";import*as i from"io-ts";const a=i.type({"Request Id":i.string});async function o({auth:i,dataSiloId:o,file:s,transcendUrl:c}){n(this.process),this.logger.info(r.magenta(`Reading "${s}" from disk`)),await t({requestIds:e(this.fs.readFileSync(s,`utf8`),a).map(e=>e[`Request Id`]),transcendUrl:c,auth:i,dataSiloId:o})}export{o as markRequestDataSilosCompleted};
|
|
2
|
+
//# sourceMappingURL=impl-C6tbQV8G.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-C6tbQV8G.mjs","names":[],"sources":["../src/commands/request/system/mark-request-data-silos-completed/impl.ts"],"sourcesContent":["import colors from 'colors';\nimport * as t from 'io-ts';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { markRequestDataSiloIdsCompleted } from '../../../../lib/cron/index.js';\nimport { parseCsv } from '../../../../lib/requests/readCsv.js';\n\nconst RequestIdRow = t.type({\n 'Request Id': t.string,\n});\n\nexport interface MarkRequestDataSilosCompletedCommandFlags {\n auth: string;\n dataSiloId: string;\n file: string;\n transcendUrl: string;\n}\n\nexport async function markRequestDataSilosCompleted(\n this: LocalContext,\n { auth, dataSiloId, file, transcendUrl }: MarkRequestDataSilosCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n this.logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = parseCsv(this.fs.readFileSync(file, 'utf8'), RequestIdRow);\n\n await markRequestDataSiloIdsCompleted({\n requestIds: activeResults.map((request) => request['Request Id']),\n transcendUrl,\n auth,\n dataSiloId,\n });\n}\n"],"mappings":"gNAQA,MAAM,EAAe,EAAE,KAAK,CAC1B,aAAc,EAAE,OACjB,CAAC,CASF,eAAsB,EAEpB,CAAE,OAAM,aAAY,OAAM,gBACX,CACf,EAAoB,KAAK,QAAQ,CAEjC,KAAK,OAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAG/D,MAAM,EAAgC,CACpC,WAHoB,EAAS,KAAK,GAAG,aAAa,EAAM,OAAO,CAAE,EAGxC,CAAC,IAAK,GAAY,EAAQ,cAAc,CACjE,eACA,OACA,aACD,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{r as e}from"./policyEngineCliError-CZrOHhLv.mjs";import{i as t,n,t as r}from"./printResult-Dmwv78e7.mjs";import{t as i}from"./resolveBundleIdByName-D7NUOpLc.mjs";import{t as a}from"./resolvePolicyBundleVersion-CKbF9vqc.mjs";import{t as o}from"./done-input-validation-LiTaCEzF.mjs";import{t as s}from"./command-output-BJcDRXNr.mjs";import c from"node:path";import l from"colors";import u from"got";function d(e,t){return`${e}-${t}.tar.gz`}function f(e,t){return[`bundleName ${e.bundleName}`,`version ${e.version}`,`output ${t}`,`sha256 ${e.sha256}`,`sizeBytes ${e.sizeBytes}`,`uploadedAt ${e.uploadedAt}`,`activatedAt ${e.activatedAt??`-`}`].join(`
|
|
2
2
|
`)}async function p({"remote-bundle-name":p,version:m,output:h,auth:g,"transcend-url":_,json:v,debug:y=!1}){o(this.process),e(y);let b=t(_,g),x=s(this.logger,v),S=await i(b,p);if(!S)throw Error(`Policy bundle "${p}" was not found for this organization.`);let C;if(m)C=(await a(b,S.id,{version:m})).id;else{if(!S.activeVersionId)throw Error(`Policy bundle "${p}" has no active version.`);C=S.activeVersionId}x.info(l.green(m?`Fetching download URL for bundle "${p}" version "${m}"...`:`Fetching download URL for active version of bundle "${p}"...`));let w=await n(b.get(`v1/policy-engine/policy-bundles/${S.id}/versions/${C}`).json());if(v){r(this.process.stdout,{json:!0,data:w});return}let T=c.resolve(h??d(p,w.version));x.info(l.green(`Downloading policy bundle to ${T}...`));let E;try{E=await u(w.downloadUrl).buffer()}catch(e){throw Error(`Failed to download policy bundle from the presigned URL: ${e instanceof Error?e.message:String(e)}`,{cause:e})}let D=c.dirname(T);this.fs.mkdirSync(D,{recursive:!0}),this.fs.writeFileSync(T,E),r(this.process.stdout,{json:!1,data:w,renderTable:()=>f(w,T)}),x.info(l.green(`Policy bundle downloaded successfully.`))}export{p as download};
|
|
3
|
-
//# sourceMappingURL=impl-
|
|
3
|
+
//# sourceMappingURL=impl-CHoglMch.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impl-CHoglMch.mjs","names":[],"sources":["../src/commands/policy/download/impl.ts"],"sourcesContent":["import path from 'node:path';\n\nimport colors from 'colors';\nimport got from 'got';\n\nimport type { LocalContext } from '../../../context.js';\nimport { selectCommandLogger } from '../../../lib/cli/command-output.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { EMPTY_CELL } from '../constants.js';\nimport {\n buildPolicyEngineClient,\n policyEngineRequest,\n printResult,\n resolveBundleByName,\n resolvePolicyBundleVersion,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { GetPolicyBundleVersionResponse } from '../types.js';\n\n/** CLI flags for `transcend policy download`. */\nexport interface DownloadCommandFlags {\n /** Tenant-unique bundle name */\n 'remote-bundle-name': string;\n /**\n * Caller-supplied version label to download.\n * When omitted, downloads the bundle's currently active version.\n */\n version?: string;\n /** Destination file path; defaults to `{bundleName}-{version}.tar.gz` */\n output?: string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Print metadata + presigned URL as JSON without writing a file */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Builds the default output path for a downloaded policy bundle.\n *\n * @param bundleName - Tenant-unique bundle name\n * @param version - Caller-supplied version label\n * @returns Relative path `{bundleName}-{version}.tar.gz`\n */\nexport function defaultPolicyDownloadOutputPath(bundleName: string, version: string): string {\n return `${bundleName}-${version}.tar.gz`;\n}\n\n/**\n * Formats download metadata for human-readable CLI output.\n *\n * @param body - Version metadata from the Policy Engine API\n * @param outputPath - Destination path written (or that would be written)\n * @returns Summary lines\n */\nfunction formatDownloadSummary(body: GetPolicyBundleVersionResponse, outputPath: string): string {\n return [\n `bundleName ${body.bundleName}`,\n `version ${body.version}`,\n `output ${outputPath}`,\n `sha256 ${body.sha256}`,\n `sizeBytes ${body.sizeBytes}`,\n `uploadedAt ${body.uploadedAt}`,\n `activatedAt ${body.activatedAt ?? EMPTY_CELL}`,\n ].join('\\n');\n}\n\n/**\n * Download a compiled policy bundle version to disk.\n *\n * Resolves `--remote-bundle-name` and an optional `--version` to IDs, fetches a\n * short-lived presigned S3 URL from the monolith, then downloads the `.tar.gz`\n * bytes directly from S3 (the monolith does not proxy the artifact).\n *\n * When `--version` is omitted, downloads the bundle's currently active version.\n * If the bundle has no active version, exits with an error.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function download(\n this: LocalContext,\n {\n 'remote-bundle-name': bundleName,\n version,\n output,\n auth,\n 'transcend-url': transcendUrl,\n json,\n debug = false,\n }: DownloadCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const commandLogger = selectCommandLogger(this.logger, json);\n\n const bundle = await resolveBundleByName(client, bundleName);\n if (!bundle) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n\n let versionId: string;\n if (version) {\n const resolvedVersion = await resolvePolicyBundleVersion(client, bundle.id, { version });\n versionId = resolvedVersion.id;\n } else {\n if (!bundle.activeVersionId) {\n throw new Error(`Policy bundle \"${bundleName}\" has no active version.`);\n }\n versionId = bundle.activeVersionId;\n }\n\n commandLogger.info(\n colors.green(\n version\n ? `Fetching download URL for bundle \"${bundleName}\" version \"${version}\"...`\n : `Fetching download URL for active version of bundle \"${bundleName}\"...`,\n ),\n );\n\n const body = await policyEngineRequest(\n client\n .get(`v1/policy-engine/policy-bundles/${bundle.id}/versions/${versionId}`)\n .json<GetPolicyBundleVersionResponse>(),\n );\n\n if (json) {\n printResult(this.process.stdout, {\n json: true,\n data: body,\n });\n return;\n }\n\n const outputPath = path.resolve(\n output ?? defaultPolicyDownloadOutputPath(bundleName, body.version),\n );\n\n commandLogger.info(colors.green(`Downloading policy bundle to ${outputPath}...`));\n\n let bundleBytes: Uint8Array;\n try {\n bundleBytes = await got(body.downloadUrl).buffer();\n } catch (err) {\n throw new Error(\n `Failed to download policy bundle from the presigned URL: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err },\n );\n }\n\n const outputDir = path.dirname(outputPath);\n this.fs.mkdirSync(outputDir, { recursive: true });\n this.fs.writeFileSync(outputPath, bundleBytes);\n\n printResult(this.process.stdout, {\n json: false,\n data: body,\n renderTable: () => formatDownloadSummary(body, outputPath),\n });\n\n commandLogger.info(colors.green('Policy bundle downloaded successfully.'));\n}\n"],"mappings":"oZA+CA,SAAgB,EAAgC,EAAoB,EAAyB,CAC3F,MAAO,GAAG,EAAW,GAAG,EAAQ,SAUlC,SAAS,EAAsB,EAAsC,EAA4B,CAC/F,MAAO,CACL,eAAe,EAAK,aACpB,eAAe,EAAK,UACpB,eAAe,IACf,eAAe,EAAK,SACpB,eAAe,EAAK,YACpB,eAAe,EAAK,aACpB,eAAe,EAAK,aAAA,MACrB,CAAC,KAAK;EAAK,CAgBd,eAAsB,EAEpB,CACE,qBAAsB,EACtB,UACA,SACA,OACA,gBAAiB,EACjB,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CACpD,EAAgB,EAAoB,KAAK,OAAQ,EAAK,CAEtD,EAAS,MAAM,EAAoB,EAAQ,EAAW,CAC5D,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,IAAI,EACJ,GAAI,EAEF,GAAY,MADkB,EAA2B,EAAQ,EAAO,GAAI,CAAE,UAAS,CAAC,EAC5D,OACvB,CACL,GAAI,CAAC,EAAO,gBACV,MAAU,MAAM,kBAAkB,EAAW,0BAA0B,CAEzE,EAAY,EAAO,gBAGrB,EAAc,KACZ,EAAO,MACL,EACI,qCAAqC,EAAW,aAAa,EAAQ,MACrE,uDAAuD,EAAW,MACvE,CACF,CAED,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,mCAAmC,EAAO,GAAG,YAAY,IAAY,CACzE,MAAsC,CAC1C,CAED,GAAI,EAAM,CACR,EAAY,KAAK,QAAQ,OAAQ,CAC/B,KAAM,GACN,KAAM,EACP,CAAC,CACF,OAGF,IAAM,EAAa,EAAK,QACtB,GAAU,EAAgC,EAAY,EAAK,QAAQ,CACpE,CAED,EAAc,KAAK,EAAO,MAAM,gCAAgC,EAAW,KAAK,CAAC,CAEjF,IAAI,EACJ,GAAI,CACF,EAAc,MAAM,EAAI,EAAK,YAAY,CAAC,QAAQ,OAC3C,EAAK,CACZ,MAAU,MACR,4DACE,aAAe,MAAQ,EAAI,QAAU,OAAO,EAAI,GAElD,CAAE,MAAO,EAAK,CACf,CAGH,IAAM,EAAY,EAAK,QAAQ,EAAW,CAC1C,KAAK,GAAG,UAAU,EAAW,CAAE,UAAW,GAAM,CAAC,CACjD,KAAK,GAAG,cAAc,EAAY,EAAY,CAE9C,EAAY,KAAK,QAAQ,OAAQ,CAC/B,KAAM,GACN,KAAM,EACN,gBAAmB,EAAsB,EAAM,EAAW,CAC3D,CAAC,CAEF,EAAc,KAAK,EAAO,MAAM,yCAAyC,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./pushCronIdentifiersFromCsv-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{t as e}from"./pushCronIdentifiersFromCsv-f8FSSFhM.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o}){t(this.process),await e({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o})}export{n as markIdentifiersCompleted};
|
|
2
|
+
//# sourceMappingURL=impl-CQ3NctWn.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-
|
|
1
|
+
{"version":3,"file":"impl-CQ3NctWn.mjs","names":[],"sources":["../src/commands/request/cron/mark-identifiers-completed/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushCronIdentifiersFromCsv } from '../../../../lib/cron/index.js';\n\nexport interface MarkIdentifiersCompletedCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n}\n\nexport async function markIdentifiersCompleted(\n this: LocalContext,\n { file, transcendUrl, auth, sombraAuth, dataSiloId }: MarkIdentifiersCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await pushCronIdentifiersFromCsv({\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n });\n}\n"],"mappings":"kHAYA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,aAAY,cACzB,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAA2B,CAC/B,OACA,eACA,OACA,aACA,aACD,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{o as e}from"./project-discovery-CWRjlFnC.mjs";import{t}from"./parseVariablesFromString-6TYW65LF.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.mjs";import{t as r}from"./missing-manifest-D8y1VL4p.mjs";import{a as i,l as a,n as o,o as s,t as c}from"./project-discovery-
|
|
1
|
+
import{o as e}from"./project-discovery-CWRjlFnC.mjs";import{t}from"./parseVariablesFromString-6TYW65LF.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.mjs";import{t as r}from"./missing-manifest-D8y1VL4p.mjs";import{a as i,l as a,n as o,o as s,t as c}from"./project-discovery-g29vd44a.mjs";import{n as l,t as u}from"./prompts-BhXfYD6g.mjs";import{t as d}from"./run-captured-process-BjaSDWXG.mjs";import{r as f,t as p}from"./deno-runtime-CB2HBach.mjs";import{t as m}from"./module-graph-CAT8_JCG.mjs";import{CustomFunctionPayloadType as h,CustomFunctionType as g}from"@transcend-io/privacy-types";import{join as _}from"node:path";import v from"colors";import{tmpdir as y}from"node:os";import{Buffer as b}from"node:buffer";import{DSR_DATAPOINT_CUSTOM_FUNCTION_PAYLOAD_SCHEMA as x,DSR_REQUEST_ENRICHER_CUSTOM_FUNCTION_PAYLOAD_SCHEMA as S,GENERAL_CUSTOM_FUNCTION_PAYLOAD_SCHEMA as C}from"@transcend-io/custom-function-types";import w from"ajv";import{stripVTControlCharacters as T}from"node:util";const E=3e4,D=1024*1024,O=_(y(),`transcend-custom-functions-deno`),k=new w({allErrors:!0,strict:!1}),A={general:k.compile(C),datapoint:k.compile(x),enricher:k.compile(S)};function j(e,t,n){let r=t,i=r.extras??{},a=i.profile,o=e.type??g.General,s=o===g.Dsr&&n!==h.RequestEnricher&&a?.identifier===`{{identifier}}`?{...a,identifier:`example-identifier`}:a,c=i.dataSilo,l=o===g.Dsr?{...i,...s?{profile:s}:{},dataSilo:{title:e.name,description:``,link:``,...c,id:e.dataSiloId??c?.id??`00000000-0000-4000-8000-000000000000`}}:s?{...i,profile:s}:i;return{...r,...Object.keys(l).length>0?{extras:l}:{},coreIdentifier:r.coreIdentifier??{value:`example-identifier`}}}function M(e,t){let n=(e.type??g.General)===g.Dsr?t.payloadType===h.RequestEnricher?A.enricher:A.datapoint:A.general;if(!n(t.payload)){let t=(n.errors??[]).map(e=>`${e.instancePath||`/`} ${e.message??`is invalid`}`).join(`; `);throw Error(`Invalid test payload for "${e.name}": ${t}`)}}function N(e,t,n={}){M(e,t);let r=e.env??{},i=Object.keys(r),o=e.allowedHosts??[];a(e);let s=n.allowNetwork?o.length===0?[`--allow-net=localhost`]:o[0]===`*`?[`--allow-net`]:[`--allow-net=${o.join(`,`)}`]:[],c=(e.type??g.General)===g.Dsr&&t.payloadType===h.RequestEnricher?`enricher`:`default`,l=`data:application/javascript;base64,${b.from(`
|
|
2
2
|
const input = JSON.parse(await new Response(Deno.stdin.readable).text());
|
|
3
3
|
for (const [name, value] of Object.entries(input.functionArgs.environment)) {
|
|
4
4
|
Deno.env.set(name, value);
|
|
@@ -88,4 +88,4 @@ try {
|
|
|
88
88
|
`)).filter(e=>{let t=e.codePointAt(0);return t===9||t===10||t>=32&&t!==127&&!(t>=128&&t<=159)}).join(``)}function F(e,t={},n=!1){let r=Object.values(t).filter(e=>e.length>0).map(P).sort((e,t)=>t.length-e.length),i=P(e);if(n){let e=Math.max(0,...r.map(e=>{let t=Math.min(e.length-1,i.length);for(let n=t;n>0;--n)if(i.endsWith(e.slice(0,n)))return n;return 0}));e>0&&(i=i.slice(0,-e))}return r.reduce((e,t)=>e.split(t).join(`[REDACTED]`),i)}function I(e,t=D){let n=b.from(e);if(n.length<=t)return{output:e,truncated:!1};let r=t;for(;r>0&&(n[r]&192)==128;)--r;return{output:n.subarray(0,r).toString(`utf8`),truncated:!0}}function L(e,t){if(!t)return e.length===1?e[0]:void 0;let n=e.filter(e=>e.name===t||e.id===t);if(n.length===0)throw Error(`Custom Function "${t}" was not found in the manifest.`);if(n.length>1)throw Error(`Custom Function selector "${t}" is ambiguous. Pass its manifest ID instead.`);return n[0]}async function R(a,h){n(this.process);try{let n=o(this,{...h?{directory:h}:{},...a.manifest?{manifest:a.manifest}:{}});if(!this.fs.existsSync(n.manifestPath)){let e=this.process.cwd();throw Error(r({cwd:e,manifestPath:n.manifestPath,discoveredManifestPaths:c(this,e),command:`run`}))}let u=i(this.fs.readFileSync(n.manifestPath,`utf8`));if(u.functions.length===0)throw Error(`The Custom Function manifest does not define any functions.`);let g=!a.noInteractive&&!!(this.process.stdin.isTTY&&this.process.stderr.isTTY),_=L(u.functions,a.function);if(!_&&g){let e=await new l(this).select(`Custom Function to run:`,u.functions.map((e,t)=>({name:e.id?`${e.name} (${e.id})`:e.name,value:String(t)})),`0`);_=u.functions[Number(e)]}if(!_)throw Error(`Select a Custom Function with --function in a non-interactive invocation.`);let{config:y,sourcePath:x}=s(n.manifestPath,_,t(a.variables),t=>e(this,n.manifestDirectory,t));if(!y.testPayloads||y.testPayloads.length===0)throw Error(`Custom Function "${y.name}" has no test payloads. Add test-payload or test-payloads to its manifest entry.`);let S=this.fs.existsSync(n.denoConfigPath)?{denoConfigPath:n.denoConfigPath}:{},C=y.testPayloads.map(e=>({testPayload:e,invocation:N(y,e,{...S,allowNetwork:a.allowNetwork})})),w=await d(`deno`,[`--version`],{cwd:n.manifestDirectory},this);if(w.error?.code===`ENOENT`)throw Error(`Deno 2.x is required. Install it from ${p}`);if(w.code!==0)throw Error(`Deno was found, but its version could not be determined.`);let T=f(w.stdout);if(T.level===`error`)throw Error(T.message);T.level===`warning`&&this.logger.warn(T.message);let E=await d(`deno`,[`info`,`--json`,...S.denoConfigPath?[`--config=${S.denoConfigPath}`]:[`--no-config`],x],{cwd:n.manifestDirectory},this);if(E.code!==0)throw Error(`Could not inspect Custom Function runtime imports: ${E.stderr.trim()||`Deno exited with code ${E.code}`}`);let O=m(E.stdout);if(O.length>0)throw Error(`Custom Functions must be self-contained. Local or import-map runtime dependencies are not deployed: ${O.join(`, `)}`);this.logger.warn(v.yellow(`Local simulator: sdk.fetch calls are logged and return HTTP 200 without sending a request; KV state starts empty for each payload.`)),a.allowNetwork?this.logger.warn(v.yellow(`Network enabled: native fetch can make real requests to ${y.allowedHosts?.length?y.allowedHosts.join(`, `):`localhost`}.`)):y.allowedHosts?.length&&this.logger.warn(v.yellow(`Native network access is disabled. Pass --allowNetwork to permit calls to allowed-hosts.`));let k=!1;for(let[e,{invocation:t,testPayload:r}]of C.entries()){let i=r.payloadType??`payload ${e+1}`;this.logger.info(`\n${v.bold(`Running "${y.name}" (${i})`)}`);let a=await d(`deno`,t.args,{cwd:n.manifestDirectory,input:t.input,env:t.env,timeoutMs:t.timeoutMs,maxOutputBytes:D+Math.max(0,...Object.values(y.env??{}).map(e=>b.byteLength(e)))},this),o=y.env??{},s=I(F(a.stdout,o,a.stdoutTruncated)),c=I(F(a.stderr,o,a.stderrTruncated));if(s.output&&this.process.stdout.write(s.output.endsWith(`
|
|
89
89
|
`)?s.output:`${s.output}\n`),c.output&&this.process.stderr.write(c.output.endsWith(`
|
|
90
90
|
`)?c.output:`${c.output}\n`),(a.outputTruncated||s.truncated||c.truncated)&&this.logger.warn(v.yellow(`Simulator output was truncated after ${D} bytes per stream.`)),a.code===0)this.logger.info(v.green(`Passed "${y.name}" (${i})`));else{k=!0;let e=a.timedOut?`timed out after ${t.timeoutMs}ms`:a.inputError?`could not send the fixture to Deno: ${a.inputError.message}`:a.error?`could not start Deno: ${a.error.message}`:a.signal?`was terminated with ${a.signal}`:`exited with code ${a.code}`;this.logger.error(v.red(`Failed "${y.name}" (${i}): ${e}`))}}k&&(this.process.exitCode=1)}catch(e){throw e instanceof u&&this.process.exit(130),e}}export{R as run};
|
|
91
|
-
//# sourceMappingURL=impl-
|
|
91
|
+
//# sourceMappingURL=impl-CRif3TpB2.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impl-DhXzxQDN2.mjs","names":[],"sources":["../src/lib/custom-functions/local-simulator.ts","../src/commands/custom-functions/run/impl.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { stripVTControlCharacters } from 'node:util';\n\nimport {\n DSR_DATAPOINT_CUSTOM_FUNCTION_PAYLOAD_SCHEMA,\n DSR_REQUEST_ENRICHER_CUSTOM_FUNCTION_PAYLOAD_SCHEMA,\n GENERAL_CUSTOM_FUNCTION_PAYLOAD_SCHEMA,\n} from '@transcend-io/custom-function-types';\nimport { CustomFunctionPayloadType, CustomFunctionType } from '@transcend-io/privacy-types';\nimport Ajv from 'ajv';\n\nimport { validateCustomFunctionExecutionContext } from './execution-context.js';\nimport type { CustomFunctionManifestConfig } from './manifest.js';\n\n/** Value injected when production-only identifiers are absent from a fixture. */\nexport const LOCAL_SIMULATOR_IDENTIFIER = 'example-identifier';\n\n/** Synthetic data silo used by local DSR simulations. */\nexport const LOCAL_SIMULATOR_DATA_SILO_ID = '00000000-0000-4000-8000-000000000000';\n\n/** Default local execution timeout. */\nexport const LOCAL_SIMULATOR_TIMEOUT_MS = 30_000;\n\n/** Maximum stdout and stderr retained from one local invocation. */\nexport const LOCAL_SIMULATOR_MAX_OUTPUT_BYTES = 1024 * 1024;\n\n/** Isolated dependency cache readable by simulated functions. */\nexport const LOCAL_SIMULATOR_DENO_DIR = join(tmpdir(), 'transcend-custom-functions-deno');\n\nconst ajv = new Ajv({ allErrors: true, strict: false });\nconst payloadValidators = {\n general: ajv.compile(GENERAL_CUSTOM_FUNCTION_PAYLOAD_SCHEMA),\n datapoint: ajv.compile(DSR_DATAPOINT_CUSTOM_FUNCTION_PAYLOAD_SCHEMA),\n enricher: ajv.compile(DSR_REQUEST_ENRICHER_CUSTOM_FUNCTION_PAYLOAD_SCHEMA),\n};\n\n/** Complete local Deno process invocation. */\nexport interface LocalSimulatorInvocation {\n /** Deno CLI arguments. */\n args: string[];\n /** JSON sent privately over stdin. */\n input: string;\n /** Minimal environment exposed to the process. */\n env: NodeJS.ProcessEnv;\n /** Maximum execution time. */\n timeoutMs: number;\n}\n\n/**\n * Runtime wrapper modeled after Sombra's Deno executor.\n *\n * The local SDK intentionally simulates customer-ingress calls rather than\n * sending authenticated requests. Native fetch remains governed by Deno's\n * allow-net permissions.\n */\nconst LOCAL_SIMULATOR_SOURCE = `\nconst input = JSON.parse(await new Response(Deno.stdin.readable).text());\nfor (const [name, value] of Object.entries(input.functionArgs.environment)) {\n Deno.env.set(name, value);\n}\n\nclass KV {\n constructor() {\n this.store = {};\n }\n\n get(key) {\n return Promise.resolve(key in this.store ? this.store[key] : null);\n }\n\n async set(key, value) {\n if (typeof value !== 'string') throw new Error('Value must be of type string');\n if (value.length > 2048) throw new Error('Cannot store value greater than 2048 bytes');\n if (key.length > 128) throw new Error('Key length cannot be greater than 128 bytes');\n if (!(key in this.store) && Object.keys(this.store).length >= 128) {\n throw new Error('Maximum number of keys allowed is 128');\n }\n this.store[key] = value;\n }\n\n keys() {\n return Promise.resolve(Object.keys(this.store));\n }\n\n has(key) {\n return Promise.resolve(key in this.store);\n }\n\n async del(key) {\n if (!(key in this.store)) return false;\n delete this.store[key];\n return true;\n }\n}\n\nclass SDK {\n constructor(nonce) {\n this.transcendNonce = nonce;\n this.customerIngressBaseUrl = 'local://customer-ingress';\n }\n\n nonce() {\n return this.transcendNonce;\n }\n\n setCustomerIngressUrl(newUrl) {\n this.customerIngressBaseUrl = newUrl;\n }\n\n async ping() {\n await this.fetch('/test', { method: 'GET' });\n }\n\n fetch(path, options = {}) {\n const method = options.method ?? 'GET';\n console.warn(\n \\`[simulator] sdk.fetch \\${method} \\${path} -> HTTP 200 (request not sent)\\`,\n );\n return Promise.resolve(new Response(null, { status: 200, statusText: 'OK' }));\n }\n}\n\ntry {\n const custom = await import(\n \\`data:application/typescript;base64,\\${input.base64Function}\\`\n );\n if (!(input.functionToRun in custom)) {\n throw new Error(\n \\`Custom Function does not export \"\\${input.functionToRun}\" for this payload\\`,\n );\n }\n await custom[input.functionToRun]({\n ...input.functionArgs,\n sdk: new SDK(input.functionArgs.nonce),\n kv: new KV(),\n });\n Deno.exit(0);\n} catch (error) {\n console.error(error);\n Deno.exit(1);\n}\n`;\n\n/**\n * Add values that Sombra normally injects into test payloads.\n *\n * @param config - Selected manifest function\n * @param payload - Parsed test fixture\n * @param payloadType - Optional DSR export selector\n * @returns Prepared local handler payload\n */\nexport function prepareLocalSimulatorPayload(\n config: Pick<CustomFunctionManifestConfig, 'dataSiloId' | 'name' | 'type'>,\n payload: object,\n payloadType?: CustomFunctionPayloadType,\n): object {\n const record = payload as {\n /** Runtime core identifier. */\n coreIdentifier?: { value: string };\n /** DSR metadata. */\n extras?: Record<string, unknown>;\n };\n const extras = record.extras ?? {};\n const profile = extras['profile'] as { identifier?: unknown } | undefined;\n const type = config.type ?? CustomFunctionType.General;\n const isDataPoint =\n type === CustomFunctionType.Dsr && payloadType !== CustomFunctionPayloadType.RequestEnricher;\n const preparedProfile =\n isDataPoint && profile?.identifier === '{{identifier}}'\n ? { ...profile, identifier: LOCAL_SIMULATOR_IDENTIFIER }\n : profile;\n const dataSilo = extras['dataSilo'] as Record<string, unknown> | undefined;\n const preparedExtras =\n type === CustomFunctionType.Dsr\n ? {\n ...extras,\n ...(preparedProfile ? { profile: preparedProfile } : {}),\n dataSilo: {\n title: config.name,\n description: '',\n link: '',\n ...dataSilo,\n id: config.dataSiloId ?? dataSilo?.['id'] ?? LOCAL_SIMULATOR_DATA_SILO_ID,\n },\n }\n : preparedProfile\n ? { ...extras, profile: preparedProfile }\n : extras;\n return {\n ...record,\n ...(Object.keys(preparedExtras).length > 0 ? { extras: preparedExtras } : {}),\n coreIdentifier: record.coreIdentifier ?? { value: LOCAL_SIMULATOR_IDENTIFIER },\n };\n}\n\n/**\n * Validate a fixture with the same published schemas used by `check`.\n *\n * @param config - Selected manifest function\n * @param testPayload - Fixture and optional DSR export selector\n */\nfunction validateLocalSimulatorPayload(\n config: CustomFunctionManifestConfig,\n testPayload: NonNullable<CustomFunctionManifestConfig['testPayloads']>[number],\n): void {\n const type = config.type ?? CustomFunctionType.General;\n const validate =\n type !== CustomFunctionType.Dsr\n ? payloadValidators.general\n : testPayload.payloadType === CustomFunctionPayloadType.RequestEnricher\n ? payloadValidators.enricher\n : payloadValidators.datapoint;\n if (!validate(testPayload.payload)) {\n const details = (validate.errors ?? [])\n .map((error) => `${error.instancePath || '/'} ${error.message ?? 'is invalid'}`)\n .join('; ');\n throw new Error(`Invalid test payload for \"${config.name}\": ${details}`);\n }\n}\n\n/**\n * Build one constrained Deno invocation for a test fixture.\n *\n * @param config - Selected manifest function\n * @param testPayload - Fixture and optional DSR export selector\n * @param options - Discovered Deno configuration\n * @returns Process arguments, input, environment, and timeout\n */\nexport function buildLocalSimulatorInvocation(\n config: CustomFunctionManifestConfig,\n testPayload: NonNullable<CustomFunctionManifestConfig['testPayloads']>[number],\n options: {\n /** Existing deno.json or deno.jsonc path. */\n denoConfigPath?: string;\n /** Permit real native fetch calls to manifest allowed hosts. */\n allowNetwork?: boolean;\n } = {},\n): LocalSimulatorInvocation {\n validateLocalSimulatorPayload(config, testPayload);\n const environment = config.env ?? {};\n const envNames = Object.keys(environment);\n const allowedHosts = config.allowedHosts ?? [];\n validateCustomFunctionExecutionContext(config);\n const allowNetArgs = options.allowNetwork\n ? allowedHosts.length === 0\n ? ['--allow-net=localhost']\n : allowedHosts[0] === '*'\n ? ['--allow-net']\n : [`--allow-net=${allowedHosts.join(',')}`]\n : [];\n const type = config.type ?? CustomFunctionType.General;\n const functionToRun =\n type === CustomFunctionType.Dsr &&\n testPayload.payloadType === CustomFunctionPayloadType.RequestEnricher\n ? 'enricher'\n : 'default';\n const runnerUrl = `data:application/javascript;base64,${Buffer.from(\n LOCAL_SIMULATOR_SOURCE,\n ).toString('base64')}`;\n const args = [\n 'run',\n '--no-check',\n '--no-prompt',\n '--no-lock',\n '--node-modules-dir=none',\n '--vendor=false',\n `--allow-read=${LOCAL_SIMULATOR_DENO_DIR}`,\n ...(envNames.length > 0 ? [`--allow-env=${envNames.join(',')}`] : []),\n ...(options.denoConfigPath ? [`--config=${options.denoConfigPath}`] : ['--no-config']),\n ...allowNetArgs,\n ...(config.allowThirdPartyImports ? [] : ['--no-remote', '--no-npm']),\n runnerUrl,\n ];\n return {\n args,\n input: JSON.stringify({\n base64Function: Buffer.from(config.code).toString('base64'),\n functionToRun,\n functionArgs: {\n environment,\n payload: prepareLocalSimulatorPayload(config, testPayload.payload, testPayload.payloadType),\n nonce: 'local-simulator',\n },\n }),\n env: {\n ...environment,\n DENO_DIR: LOCAL_SIMULATOR_DENO_DIR,\n DENO_TLS_CA_STORE: 'system',\n NO_COLOR: '1',\n },\n timeoutMs:\n config.timeoutMs && config.timeoutMs > 0\n ? Math.min(config.timeoutMs, LOCAL_SIMULATOR_TIMEOUT_MS)\n : LOCAL_SIMULATOR_TIMEOUT_MS,\n };\n}\n\n/**\n * Remove terminal controls and opaque data URLs from local output.\n *\n * @param value - Untrusted terminal text\n * @returns Plain printable text\n */\nfunction sanitizeLocalSimulatorText(value: string): string {\n return Array.from(\n stripVTControlCharacters(\n value.replace(\n /data:application\\/(?:javascript|typescript);base64,[A-Za-z\\d+/=]+/gu,\n '<local-module>',\n ),\n ).replace(/\\r(?!\\n)/gu, '\\n'),\n )\n .filter((character) => {\n const code = character.codePointAt(0)!;\n return (\n code === 9 || code === 10 || (code >= 32 && code !== 127 && !(code >= 128 && code <= 159))\n );\n })\n .join('');\n}\n\n/**\n * Redact configured environment values from captured local output.\n *\n * @param output - Captured stdout or stderr\n * @param environment - User-defined environment\n * @param sourceTruncated - Whether capture stopped before the stream ended\n * @returns Redacted output\n */\nexport function redactLocalSimulatorOutput(\n output: string,\n environment: Record<string, string> = {},\n sourceTruncated = false,\n): string {\n const values = Object.values(environment)\n .filter((value) => value.length > 0)\n .map(sanitizeLocalSimulatorText)\n .sort((left, right) => right.length - left.length);\n let sanitized = sanitizeLocalSimulatorText(output);\n if (sourceTruncated) {\n const trailingFragmentLength = Math.max(\n 0,\n ...values.map((value) => {\n const maximum = Math.min(value.length - 1, sanitized.length);\n for (let length = maximum; length > 0; length -= 1) {\n if (sanitized.endsWith(value.slice(0, length))) {\n return length;\n }\n }\n return 0;\n }),\n );\n if (trailingFragmentLength > 0) {\n sanitized = sanitized.slice(0, -trailingFragmentLength);\n }\n }\n return values.reduce((redacted, value) => redacted.split(value).join('[REDACTED]'), sanitized);\n}\n\n/**\n * Truncate sanitized output without splitting a UTF-8 code point.\n *\n * @param output - Sanitized and redacted output\n * @param maxBytes - Maximum output size\n * @returns Bounded output and whether truncation occurred\n */\nexport function truncateLocalSimulatorOutput(\n output: string,\n maxBytes = LOCAL_SIMULATOR_MAX_OUTPUT_BYTES,\n): { output: string; truncated: boolean } {\n const bytes = Buffer.from(output);\n if (bytes.length <= maxBytes) {\n return { output, truncated: false };\n }\n let end = maxBytes;\n while (end > 0 && (bytes[end]! & 0b1100_0000) === 0b1000_0000) {\n end -= 1;\n }\n return {\n output: bytes.subarray(0, end).toString('utf8'),\n truncated: true,\n };\n}\n","import { Buffer } from 'node:buffer';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { runCapturedProcess } from '../../../lib/cli/run-captured-process.js';\nimport {\n DENO_INSTALL_URL,\n getDenoRuntimeCompatibility,\n SUPPORTED_DENO_MAJOR_VERSION,\n} from '../../../lib/custom-functions/deno-runtime.js';\nimport {\n buildLocalSimulatorInvocation,\n LOCAL_SIMULATOR_MAX_OUTPUT_BYTES,\n redactLocalSimulatorOutput,\n truncateLocalSimulatorOutput,\n} from '../../../lib/custom-functions/local-simulator.js';\nimport {\n parseCustomFunctionsManifest,\n readCustomFunctionManifestEntry,\n type CustomFunctionManifestEntry,\n} from '../../../lib/custom-functions/manifest.js';\nimport { formatMissingManifestMessage } from '../../../lib/custom-functions/missing-manifest.js';\nimport { findNonSelfContainedRuntimeImports } from '../../../lib/custom-functions/module-graph.js';\nimport {\n discoverCustomFunctionManifests,\n discoverCustomFunctionProject,\n} from '../../../lib/custom-functions/project-discovery.js';\nimport { parseVariablesFromString } from '../../../lib/helpers/parseVariablesFromString.js';\nimport { assertPathPhysicallyContained } from '../../../lib/scaffolding/path-safety.js';\nimport { PromptCancelledError, ScaffoldPrompts } from '../../../lib/scaffolding/prompts.js';\n\n/** Flags accepted by `transcend custom-functions run`. */\nexport interface CustomFunctionRunFlags {\n /** Explicit manifest path. */\n manifest?: string;\n /** Exact function name. */\n function?: string;\n /** Manifest variable substitutions. */\n variables: string;\n /** Disable prompts. */\n noInteractive: boolean;\n /** Permit native network calls to allowed hosts. */\n allowNetwork: boolean;\n}\n\n/**\n * Select one function by exact name or ID.\n *\n * @param configs - Hydrated manifest functions\n * @param selector - Optional exact name or ID\n * @returns Selected function, or undefined when interactive selection is needed\n */\nfunction selectNamedFunction<Config extends Pick<CustomFunctionManifestEntry, 'id' | 'name'>>(\n configs: readonly Config[],\n selector: string | undefined,\n): Config | undefined {\n if (!selector) {\n return configs.length === 1 ? configs[0] : undefined;\n }\n const matches = configs.filter((config) => config.name === selector || config.id === selector);\n if (matches.length === 0) {\n throw new Error(`Custom Function \"${selector}\" was not found in the manifest.`);\n }\n if (matches.length > 1) {\n throw new Error(\n `Custom Function selector \"${selector}\" is ambiguous. Pass its manifest ID instead.`,\n );\n }\n return matches[0];\n}\n\n/**\n * Run one manifest function in the credential-free local Deno simulator.\n *\n * @param this - CLI context\n * @param flags - Selection and manifest flags\n * @param directory - Optional project directory\n */\nexport async function run(\n this: LocalContext,\n flags: CustomFunctionRunFlags,\n directory?: string,\n): Promise<void> {\n doneInputValidation(this.process);\n try {\n const state = discoverCustomFunctionProject(this, {\n ...(directory ? { directory } : {}),\n ...(flags.manifest ? { manifest: flags.manifest } : {}),\n });\n if (!this.fs.existsSync(state.manifestPath)) {\n const cwd = this.process.cwd();\n throw new Error(\n formatMissingManifestMessage({\n cwd,\n manifestPath: state.manifestPath,\n discoveredManifestPaths: discoverCustomFunctionManifests(this, cwd),\n command: 'run',\n }),\n );\n }\n\n const parsedManifest = parseCustomFunctionsManifest(\n this.fs.readFileSync(state.manifestPath, 'utf8'),\n );\n if (parsedManifest.functions.length === 0) {\n throw new Error('The Custom Function manifest does not define any functions.');\n }\n const interactive =\n !flags.noInteractive && Boolean(this.process.stdin.isTTY && this.process.stderr.isTTY);\n let selectedEntry = selectNamedFunction(parsedManifest.functions, flags.function);\n if (!selectedEntry && interactive) {\n const prompts = new ScaffoldPrompts(this);\n const selectedIndex = await prompts.select(\n 'Custom Function to run:',\n parsedManifest.functions.map((entry, index) => ({\n name: entry.id ? `${entry.name} (${entry.id})` : entry.name,\n value: String(index),\n })),\n '0',\n );\n selectedEntry = parsedManifest.functions[Number(selectedIndex)];\n }\n if (!selectedEntry) {\n throw new Error('Select a Custom Function with --function in a non-interactive invocation.');\n }\n const { config: selected, sourcePath } = readCustomFunctionManifestEntry(\n state.manifestPath,\n selectedEntry,\n parseVariablesFromString(flags.variables),\n (path) => assertPathPhysicallyContained(this, state.manifestDirectory, path),\n );\n if (!selected.testPayloads || selected.testPayloads.length === 0) {\n throw new Error(\n `Custom Function \"${selected.name}\" has no test payloads. Add test-payload or test-payloads to its manifest entry.`,\n );\n }\n const denoConfig = this.fs.existsSync(state.denoConfigPath)\n ? { denoConfigPath: state.denoConfigPath }\n : {};\n const simulations = selected.testPayloads.map((testPayload) => ({\n testPayload,\n invocation: buildLocalSimulatorInvocation(selected, testPayload, {\n ...denoConfig,\n allowNetwork: flags.allowNetwork,\n }),\n }));\n\n const denoVersion = await runCapturedProcess(\n 'deno',\n ['--version'],\n { cwd: state.manifestDirectory },\n this,\n );\n if (denoVersion.error?.code === 'ENOENT') {\n throw new Error(\n `Deno ${SUPPORTED_DENO_MAJOR_VERSION}.x is required. Install it from ${DENO_INSTALL_URL}`,\n );\n }\n if (denoVersion.code !== 0) {\n throw new Error('Deno was found, but its version could not be determined.');\n }\n const compatibility = getDenoRuntimeCompatibility(denoVersion.stdout);\n if (compatibility.level === 'error') {\n throw new Error(compatibility.message);\n }\n if (compatibility.level === 'warning') {\n this.logger.warn(compatibility.message);\n }\n const moduleGraph = await runCapturedProcess(\n 'deno',\n [\n 'info',\n '--json',\n ...(denoConfig.denoConfigPath\n ? [`--config=${denoConfig.denoConfigPath}`]\n : ['--no-config']),\n sourcePath,\n ],\n { cwd: state.manifestDirectory },\n this,\n );\n if (moduleGraph.code !== 0) {\n throw new Error(\n `Could not inspect Custom Function runtime imports: ${\n moduleGraph.stderr.trim() || `Deno exited with code ${moduleGraph.code}`\n }`,\n );\n }\n const unsupportedImports = findNonSelfContainedRuntimeImports(moduleGraph.stdout);\n if (unsupportedImports.length > 0) {\n throw new Error(\n `Custom Functions must be self-contained. Local or import-map runtime dependencies are not deployed: ${unsupportedImports.join(\n ', ',\n )}`,\n );\n }\n\n this.logger.warn(\n colors.yellow(\n 'Local simulator: sdk.fetch calls are logged and return HTTP 200 without sending a request; KV state starts empty for each payload.',\n ),\n );\n if (flags.allowNetwork) {\n this.logger.warn(\n colors.yellow(\n `Network enabled: native fetch can make real requests to ${\n selected.allowedHosts?.length ? selected.allowedHosts.join(', ') : 'localhost'\n }.`,\n ),\n );\n } else if (selected.allowedHosts?.length) {\n this.logger.warn(\n colors.yellow(\n 'Native network access is disabled. Pass --allowNetwork to permit calls to allowed-hosts.',\n ),\n );\n }\n let failed = false;\n for (const [index, { invocation, testPayload }] of simulations.entries()) {\n const label = testPayload.payloadType ?? `payload ${index + 1}`;\n this.logger.info(`\\n${colors.bold(`Running \"${selected.name}\" (${label})`)}`);\n const result = await runCapturedProcess(\n 'deno',\n invocation.args,\n {\n cwd: state.manifestDirectory,\n input: invocation.input,\n env: invocation.env,\n timeoutMs: invocation.timeoutMs,\n maxOutputBytes:\n LOCAL_SIMULATOR_MAX_OUTPUT_BYTES +\n Math.max(\n 0,\n ...Object.values(selected.env ?? {}).map((value) => Buffer.byteLength(value)),\n ),\n },\n this,\n );\n const environment = selected.env ?? {};\n const stdout = truncateLocalSimulatorOutput(\n redactLocalSimulatorOutput(result.stdout, environment, result.stdoutTruncated),\n );\n const stderr = truncateLocalSimulatorOutput(\n redactLocalSimulatorOutput(result.stderr, environment, result.stderrTruncated),\n );\n if (stdout.output) {\n this.process.stdout.write(\n stdout.output.endsWith('\\n') ? stdout.output : `${stdout.output}\\n`,\n );\n }\n if (stderr.output) {\n this.process.stderr.write(\n stderr.output.endsWith('\\n') ? stderr.output : `${stderr.output}\\n`,\n );\n }\n if (result.outputTruncated || stdout.truncated || stderr.truncated) {\n this.logger.warn(\n colors.yellow(\n `Simulator output was truncated after ${LOCAL_SIMULATOR_MAX_OUTPUT_BYTES} bytes per stream.`,\n ),\n );\n }\n if (result.code === 0) {\n this.logger.info(colors.green(`Passed \"${selected.name}\" (${label})`));\n } else {\n failed = true;\n const detail = result.timedOut\n ? `timed out after ${invocation.timeoutMs}ms`\n : result.inputError\n ? `could not send the fixture to Deno: ${result.inputError.message}`\n : result.error\n ? `could not start Deno: ${result.error.message}`\n : result.signal\n ? `was terminated with ${result.signal}`\n : `exited with code ${result.code}`;\n this.logger.error(colors.red(`Failed \"${selected.name}\" (${label}): ${detail}`));\n }\n }\n if (failed) {\n this.process.exitCode = 1;\n }\n } catch (error) {\n if (error instanceof PromptCancelledError) {\n this.process.exit(130);\n }\n throw error;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"impl-CRif3TpB2.mjs","names":[],"sources":["../src/lib/custom-functions/local-simulator.ts","../src/commands/custom-functions/run/impl.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { stripVTControlCharacters } from 'node:util';\n\nimport {\n DSR_DATAPOINT_CUSTOM_FUNCTION_PAYLOAD_SCHEMA,\n DSR_REQUEST_ENRICHER_CUSTOM_FUNCTION_PAYLOAD_SCHEMA,\n GENERAL_CUSTOM_FUNCTION_PAYLOAD_SCHEMA,\n} from '@transcend-io/custom-function-types';\nimport { CustomFunctionPayloadType, CustomFunctionType } from '@transcend-io/privacy-types';\nimport Ajv from 'ajv';\n\nimport { validateCustomFunctionExecutionContext } from './execution-context.js';\nimport type { CustomFunctionManifestConfig } from './manifest.js';\n\n/** Value injected when production-only identifiers are absent from a fixture. */\nexport const LOCAL_SIMULATOR_IDENTIFIER = 'example-identifier';\n\n/** Synthetic data silo used by local DSR simulations. */\nexport const LOCAL_SIMULATOR_DATA_SILO_ID = '00000000-0000-4000-8000-000000000000';\n\n/** Default local execution timeout. */\nexport const LOCAL_SIMULATOR_TIMEOUT_MS = 30_000;\n\n/** Maximum stdout and stderr retained from one local invocation. */\nexport const LOCAL_SIMULATOR_MAX_OUTPUT_BYTES = 1024 * 1024;\n\n/** Isolated dependency cache readable by simulated functions. */\nexport const LOCAL_SIMULATOR_DENO_DIR = join(tmpdir(), 'transcend-custom-functions-deno');\n\nconst ajv = new Ajv({ allErrors: true, strict: false });\nconst payloadValidators = {\n general: ajv.compile(GENERAL_CUSTOM_FUNCTION_PAYLOAD_SCHEMA),\n datapoint: ajv.compile(DSR_DATAPOINT_CUSTOM_FUNCTION_PAYLOAD_SCHEMA),\n enricher: ajv.compile(DSR_REQUEST_ENRICHER_CUSTOM_FUNCTION_PAYLOAD_SCHEMA),\n};\n\n/** Complete local Deno process invocation. */\nexport interface LocalSimulatorInvocation {\n /** Deno CLI arguments. */\n args: string[];\n /** JSON sent privately over stdin. */\n input: string;\n /** Minimal environment exposed to the process. */\n env: NodeJS.ProcessEnv;\n /** Maximum execution time. */\n timeoutMs: number;\n}\n\n/**\n * Runtime wrapper modeled after Sombra's Deno executor.\n *\n * The local SDK intentionally simulates customer-ingress calls rather than\n * sending authenticated requests. Native fetch remains governed by Deno's\n * allow-net permissions.\n */\nconst LOCAL_SIMULATOR_SOURCE = `\nconst input = JSON.parse(await new Response(Deno.stdin.readable).text());\nfor (const [name, value] of Object.entries(input.functionArgs.environment)) {\n Deno.env.set(name, value);\n}\n\nclass KV {\n constructor() {\n this.store = {};\n }\n\n get(key) {\n return Promise.resolve(key in this.store ? this.store[key] : null);\n }\n\n async set(key, value) {\n if (typeof value !== 'string') throw new Error('Value must be of type string');\n if (value.length > 2048) throw new Error('Cannot store value greater than 2048 bytes');\n if (key.length > 128) throw new Error('Key length cannot be greater than 128 bytes');\n if (!(key in this.store) && Object.keys(this.store).length >= 128) {\n throw new Error('Maximum number of keys allowed is 128');\n }\n this.store[key] = value;\n }\n\n keys() {\n return Promise.resolve(Object.keys(this.store));\n }\n\n has(key) {\n return Promise.resolve(key in this.store);\n }\n\n async del(key) {\n if (!(key in this.store)) return false;\n delete this.store[key];\n return true;\n }\n}\n\nclass SDK {\n constructor(nonce) {\n this.transcendNonce = nonce;\n this.customerIngressBaseUrl = 'local://customer-ingress';\n }\n\n nonce() {\n return this.transcendNonce;\n }\n\n setCustomerIngressUrl(newUrl) {\n this.customerIngressBaseUrl = newUrl;\n }\n\n async ping() {\n await this.fetch('/test', { method: 'GET' });\n }\n\n fetch(path, options = {}) {\n const method = options.method ?? 'GET';\n console.warn(\n \\`[simulator] sdk.fetch \\${method} \\${path} -> HTTP 200 (request not sent)\\`,\n );\n return Promise.resolve(new Response(null, { status: 200, statusText: 'OK' }));\n }\n}\n\ntry {\n const custom = await import(\n \\`data:application/typescript;base64,\\${input.base64Function}\\`\n );\n if (!(input.functionToRun in custom)) {\n throw new Error(\n \\`Custom Function does not export \"\\${input.functionToRun}\" for this payload\\`,\n );\n }\n await custom[input.functionToRun]({\n ...input.functionArgs,\n sdk: new SDK(input.functionArgs.nonce),\n kv: new KV(),\n });\n Deno.exit(0);\n} catch (error) {\n console.error(error);\n Deno.exit(1);\n}\n`;\n\n/**\n * Add values that Sombra normally injects into test payloads.\n *\n * @param config - Selected manifest function\n * @param payload - Parsed test fixture\n * @param payloadType - Optional DSR export selector\n * @returns Prepared local handler payload\n */\nexport function prepareLocalSimulatorPayload(\n config: Pick<CustomFunctionManifestConfig, 'dataSiloId' | 'name' | 'type'>,\n payload: object,\n payloadType?: CustomFunctionPayloadType,\n): object {\n const record = payload as {\n /** Runtime core identifier. */\n coreIdentifier?: { value: string };\n /** DSR metadata. */\n extras?: Record<string, unknown>;\n };\n const extras = record.extras ?? {};\n const profile = extras['profile'] as { identifier?: unknown } | undefined;\n const type = config.type ?? CustomFunctionType.General;\n const isDataPoint =\n type === CustomFunctionType.Dsr && payloadType !== CustomFunctionPayloadType.RequestEnricher;\n const preparedProfile =\n isDataPoint && profile?.identifier === '{{identifier}}'\n ? { ...profile, identifier: LOCAL_SIMULATOR_IDENTIFIER }\n : profile;\n const dataSilo = extras['dataSilo'] as Record<string, unknown> | undefined;\n const preparedExtras =\n type === CustomFunctionType.Dsr\n ? {\n ...extras,\n ...(preparedProfile ? { profile: preparedProfile } : {}),\n dataSilo: {\n title: config.name,\n description: '',\n link: '',\n ...dataSilo,\n id: config.dataSiloId ?? dataSilo?.['id'] ?? LOCAL_SIMULATOR_DATA_SILO_ID,\n },\n }\n : preparedProfile\n ? { ...extras, profile: preparedProfile }\n : extras;\n return {\n ...record,\n ...(Object.keys(preparedExtras).length > 0 ? { extras: preparedExtras } : {}),\n coreIdentifier: record.coreIdentifier ?? { value: LOCAL_SIMULATOR_IDENTIFIER },\n };\n}\n\n/**\n * Validate a fixture with the same published schemas used by `check`.\n *\n * @param config - Selected manifest function\n * @param testPayload - Fixture and optional DSR export selector\n */\nfunction validateLocalSimulatorPayload(\n config: CustomFunctionManifestConfig,\n testPayload: NonNullable<CustomFunctionManifestConfig['testPayloads']>[number],\n): void {\n const type = config.type ?? CustomFunctionType.General;\n const validate =\n type !== CustomFunctionType.Dsr\n ? payloadValidators.general\n : testPayload.payloadType === CustomFunctionPayloadType.RequestEnricher\n ? payloadValidators.enricher\n : payloadValidators.datapoint;\n if (!validate(testPayload.payload)) {\n const details = (validate.errors ?? [])\n .map((error) => `${error.instancePath || '/'} ${error.message ?? 'is invalid'}`)\n .join('; ');\n throw new Error(`Invalid test payload for \"${config.name}\": ${details}`);\n }\n}\n\n/**\n * Build one constrained Deno invocation for a test fixture.\n *\n * @param config - Selected manifest function\n * @param testPayload - Fixture and optional DSR export selector\n * @param options - Discovered Deno configuration\n * @returns Process arguments, input, environment, and timeout\n */\nexport function buildLocalSimulatorInvocation(\n config: CustomFunctionManifestConfig,\n testPayload: NonNullable<CustomFunctionManifestConfig['testPayloads']>[number],\n options: {\n /** Existing deno.json or deno.jsonc path. */\n denoConfigPath?: string;\n /** Permit real native fetch calls to manifest allowed hosts. */\n allowNetwork?: boolean;\n } = {},\n): LocalSimulatorInvocation {\n validateLocalSimulatorPayload(config, testPayload);\n const environment = config.env ?? {};\n const envNames = Object.keys(environment);\n const allowedHosts = config.allowedHosts ?? [];\n validateCustomFunctionExecutionContext(config);\n const allowNetArgs = options.allowNetwork\n ? allowedHosts.length === 0\n ? ['--allow-net=localhost']\n : allowedHosts[0] === '*'\n ? ['--allow-net']\n : [`--allow-net=${allowedHosts.join(',')}`]\n : [];\n const type = config.type ?? CustomFunctionType.General;\n const functionToRun =\n type === CustomFunctionType.Dsr &&\n testPayload.payloadType === CustomFunctionPayloadType.RequestEnricher\n ? 'enricher'\n : 'default';\n const runnerUrl = `data:application/javascript;base64,${Buffer.from(\n LOCAL_SIMULATOR_SOURCE,\n ).toString('base64')}`;\n const args = [\n 'run',\n '--no-check',\n '--no-prompt',\n '--no-lock',\n '--node-modules-dir=none',\n '--vendor=false',\n `--allow-read=${LOCAL_SIMULATOR_DENO_DIR}`,\n ...(envNames.length > 0 ? [`--allow-env=${envNames.join(',')}`] : []),\n ...(options.denoConfigPath ? [`--config=${options.denoConfigPath}`] : ['--no-config']),\n ...allowNetArgs,\n ...(config.allowThirdPartyImports ? [] : ['--no-remote', '--no-npm']),\n runnerUrl,\n ];\n return {\n args,\n input: JSON.stringify({\n base64Function: Buffer.from(config.code).toString('base64'),\n functionToRun,\n functionArgs: {\n environment,\n payload: prepareLocalSimulatorPayload(config, testPayload.payload, testPayload.payloadType),\n nonce: 'local-simulator',\n },\n }),\n env: {\n ...environment,\n DENO_DIR: LOCAL_SIMULATOR_DENO_DIR,\n DENO_TLS_CA_STORE: 'system',\n NO_COLOR: '1',\n },\n timeoutMs:\n config.timeoutMs && config.timeoutMs > 0\n ? Math.min(config.timeoutMs, LOCAL_SIMULATOR_TIMEOUT_MS)\n : LOCAL_SIMULATOR_TIMEOUT_MS,\n };\n}\n\n/**\n * Remove terminal controls and opaque data URLs from local output.\n *\n * @param value - Untrusted terminal text\n * @returns Plain printable text\n */\nfunction sanitizeLocalSimulatorText(value: string): string {\n return Array.from(\n stripVTControlCharacters(\n value.replace(\n /data:application\\/(?:javascript|typescript);base64,[A-Za-z\\d+/=]+/gu,\n '<local-module>',\n ),\n ).replace(/\\r(?!\\n)/gu, '\\n'),\n )\n .filter((character) => {\n const code = character.codePointAt(0)!;\n return (\n code === 9 || code === 10 || (code >= 32 && code !== 127 && !(code >= 128 && code <= 159))\n );\n })\n .join('');\n}\n\n/**\n * Redact configured environment values from captured local output.\n *\n * @param output - Captured stdout or stderr\n * @param environment - User-defined environment\n * @param sourceTruncated - Whether capture stopped before the stream ended\n * @returns Redacted output\n */\nexport function redactLocalSimulatorOutput(\n output: string,\n environment: Record<string, string> = {},\n sourceTruncated = false,\n): string {\n const values = Object.values(environment)\n .filter((value) => value.length > 0)\n .map(sanitizeLocalSimulatorText)\n .sort((left, right) => right.length - left.length);\n let sanitized = sanitizeLocalSimulatorText(output);\n if (sourceTruncated) {\n const trailingFragmentLength = Math.max(\n 0,\n ...values.map((value) => {\n const maximum = Math.min(value.length - 1, sanitized.length);\n for (let length = maximum; length > 0; length -= 1) {\n if (sanitized.endsWith(value.slice(0, length))) {\n return length;\n }\n }\n return 0;\n }),\n );\n if (trailingFragmentLength > 0) {\n sanitized = sanitized.slice(0, -trailingFragmentLength);\n }\n }\n return values.reduce((redacted, value) => redacted.split(value).join('[REDACTED]'), sanitized);\n}\n\n/**\n * Truncate sanitized output without splitting a UTF-8 code point.\n *\n * @param output - Sanitized and redacted output\n * @param maxBytes - Maximum output size\n * @returns Bounded output and whether truncation occurred\n */\nexport function truncateLocalSimulatorOutput(\n output: string,\n maxBytes = LOCAL_SIMULATOR_MAX_OUTPUT_BYTES,\n): { output: string; truncated: boolean } {\n const bytes = Buffer.from(output);\n if (bytes.length <= maxBytes) {\n return { output, truncated: false };\n }\n let end = maxBytes;\n while (end > 0 && (bytes[end]! & 0b1100_0000) === 0b1000_0000) {\n end -= 1;\n }\n return {\n output: bytes.subarray(0, end).toString('utf8'),\n truncated: true,\n };\n}\n","import { Buffer } from 'node:buffer';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { runCapturedProcess } from '../../../lib/cli/run-captured-process.js';\nimport {\n DENO_INSTALL_URL,\n getDenoRuntimeCompatibility,\n SUPPORTED_DENO_MAJOR_VERSION,\n} from '../../../lib/custom-functions/deno-runtime.js';\nimport {\n buildLocalSimulatorInvocation,\n LOCAL_SIMULATOR_MAX_OUTPUT_BYTES,\n redactLocalSimulatorOutput,\n truncateLocalSimulatorOutput,\n} from '../../../lib/custom-functions/local-simulator.js';\nimport {\n parseCustomFunctionsManifest,\n readCustomFunctionManifestEntry,\n type CustomFunctionManifestEntry,\n} from '../../../lib/custom-functions/manifest.js';\nimport { formatMissingManifestMessage } from '../../../lib/custom-functions/missing-manifest.js';\nimport { findNonSelfContainedRuntimeImports } from '../../../lib/custom-functions/module-graph.js';\nimport {\n discoverCustomFunctionManifests,\n discoverCustomFunctionProject,\n} from '../../../lib/custom-functions/project-discovery.js';\nimport { parseVariablesFromString } from '../../../lib/helpers/parseVariablesFromString.js';\nimport { assertPathPhysicallyContained } from '../../../lib/scaffolding/path-safety.js';\nimport { PromptCancelledError, ScaffoldPrompts } from '../../../lib/scaffolding/prompts.js';\n\n/** Flags accepted by `transcend custom-functions run`. */\nexport interface CustomFunctionRunFlags {\n /** Explicit manifest path. */\n manifest?: string;\n /** Exact function name. */\n function?: string;\n /** Manifest variable substitutions. */\n variables: string;\n /** Disable prompts. */\n noInteractive: boolean;\n /** Permit native network calls to allowed hosts. */\n allowNetwork: boolean;\n}\n\n/**\n * Select one function by exact name or ID.\n *\n * @param configs - Hydrated manifest functions\n * @param selector - Optional exact name or ID\n * @returns Selected function, or undefined when interactive selection is needed\n */\nfunction selectNamedFunction<Config extends Pick<CustomFunctionManifestEntry, 'id' | 'name'>>(\n configs: readonly Config[],\n selector: string | undefined,\n): Config | undefined {\n if (!selector) {\n return configs.length === 1 ? configs[0] : undefined;\n }\n const matches = configs.filter((config) => config.name === selector || config.id === selector);\n if (matches.length === 0) {\n throw new Error(`Custom Function \"${selector}\" was not found in the manifest.`);\n }\n if (matches.length > 1) {\n throw new Error(\n `Custom Function selector \"${selector}\" is ambiguous. Pass its manifest ID instead.`,\n );\n }\n return matches[0];\n}\n\n/**\n * Run one manifest function in the credential-free local Deno simulator.\n *\n * @param this - CLI context\n * @param flags - Selection and manifest flags\n * @param directory - Optional project directory\n */\nexport async function run(\n this: LocalContext,\n flags: CustomFunctionRunFlags,\n directory?: string,\n): Promise<void> {\n doneInputValidation(this.process);\n try {\n const state = discoverCustomFunctionProject(this, {\n ...(directory ? { directory } : {}),\n ...(flags.manifest ? { manifest: flags.manifest } : {}),\n });\n if (!this.fs.existsSync(state.manifestPath)) {\n const cwd = this.process.cwd();\n throw new Error(\n formatMissingManifestMessage({\n cwd,\n manifestPath: state.manifestPath,\n discoveredManifestPaths: discoverCustomFunctionManifests(this, cwd),\n command: 'run',\n }),\n );\n }\n\n const parsedManifest = parseCustomFunctionsManifest(\n this.fs.readFileSync(state.manifestPath, 'utf8'),\n );\n if (parsedManifest.functions.length === 0) {\n throw new Error('The Custom Function manifest does not define any functions.');\n }\n const interactive =\n !flags.noInteractive && Boolean(this.process.stdin.isTTY && this.process.stderr.isTTY);\n let selectedEntry = selectNamedFunction(parsedManifest.functions, flags.function);\n if (!selectedEntry && interactive) {\n const prompts = new ScaffoldPrompts(this);\n const selectedIndex = await prompts.select(\n 'Custom Function to run:',\n parsedManifest.functions.map((entry, index) => ({\n name: entry.id ? `${entry.name} (${entry.id})` : entry.name,\n value: String(index),\n })),\n '0',\n );\n selectedEntry = parsedManifest.functions[Number(selectedIndex)];\n }\n if (!selectedEntry) {\n throw new Error('Select a Custom Function with --function in a non-interactive invocation.');\n }\n const { config: selected, sourcePath } = readCustomFunctionManifestEntry(\n state.manifestPath,\n selectedEntry,\n parseVariablesFromString(flags.variables),\n (path) => assertPathPhysicallyContained(this, state.manifestDirectory, path),\n );\n if (!selected.testPayloads || selected.testPayloads.length === 0) {\n throw new Error(\n `Custom Function \"${selected.name}\" has no test payloads. Add test-payload or test-payloads to its manifest entry.`,\n );\n }\n const denoConfig = this.fs.existsSync(state.denoConfigPath)\n ? { denoConfigPath: state.denoConfigPath }\n : {};\n const simulations = selected.testPayloads.map((testPayload) => ({\n testPayload,\n invocation: buildLocalSimulatorInvocation(selected, testPayload, {\n ...denoConfig,\n allowNetwork: flags.allowNetwork,\n }),\n }));\n\n const denoVersion = await runCapturedProcess(\n 'deno',\n ['--version'],\n { cwd: state.manifestDirectory },\n this,\n );\n if (denoVersion.error?.code === 'ENOENT') {\n throw new Error(\n `Deno ${SUPPORTED_DENO_MAJOR_VERSION}.x is required. Install it from ${DENO_INSTALL_URL}`,\n );\n }\n if (denoVersion.code !== 0) {\n throw new Error('Deno was found, but its version could not be determined.');\n }\n const compatibility = getDenoRuntimeCompatibility(denoVersion.stdout);\n if (compatibility.level === 'error') {\n throw new Error(compatibility.message);\n }\n if (compatibility.level === 'warning') {\n this.logger.warn(compatibility.message);\n }\n const moduleGraph = await runCapturedProcess(\n 'deno',\n [\n 'info',\n '--json',\n ...(denoConfig.denoConfigPath\n ? [`--config=${denoConfig.denoConfigPath}`]\n : ['--no-config']),\n sourcePath,\n ],\n { cwd: state.manifestDirectory },\n this,\n );\n if (moduleGraph.code !== 0) {\n throw new Error(\n `Could not inspect Custom Function runtime imports: ${\n moduleGraph.stderr.trim() || `Deno exited with code ${moduleGraph.code}`\n }`,\n );\n }\n const unsupportedImports = findNonSelfContainedRuntimeImports(moduleGraph.stdout);\n if (unsupportedImports.length > 0) {\n throw new Error(\n `Custom Functions must be self-contained. Local or import-map runtime dependencies are not deployed: ${unsupportedImports.join(\n ', ',\n )}`,\n );\n }\n\n this.logger.warn(\n colors.yellow(\n 'Local simulator: sdk.fetch calls are logged and return HTTP 200 without sending a request; KV state starts empty for each payload.',\n ),\n );\n if (flags.allowNetwork) {\n this.logger.warn(\n colors.yellow(\n `Network enabled: native fetch can make real requests to ${\n selected.allowedHosts?.length ? selected.allowedHosts.join(', ') : 'localhost'\n }.`,\n ),\n );\n } else if (selected.allowedHosts?.length) {\n this.logger.warn(\n colors.yellow(\n 'Native network access is disabled. Pass --allowNetwork to permit calls to allowed-hosts.',\n ),\n );\n }\n let failed = false;\n for (const [index, { invocation, testPayload }] of simulations.entries()) {\n const label = testPayload.payloadType ?? `payload ${index + 1}`;\n this.logger.info(`\\n${colors.bold(`Running \"${selected.name}\" (${label})`)}`);\n const result = await runCapturedProcess(\n 'deno',\n invocation.args,\n {\n cwd: state.manifestDirectory,\n input: invocation.input,\n env: invocation.env,\n timeoutMs: invocation.timeoutMs,\n maxOutputBytes:\n LOCAL_SIMULATOR_MAX_OUTPUT_BYTES +\n Math.max(\n 0,\n ...Object.values(selected.env ?? {}).map((value) => Buffer.byteLength(value)),\n ),\n },\n this,\n );\n const environment = selected.env ?? {};\n const stdout = truncateLocalSimulatorOutput(\n redactLocalSimulatorOutput(result.stdout, environment, result.stdoutTruncated),\n );\n const stderr = truncateLocalSimulatorOutput(\n redactLocalSimulatorOutput(result.stderr, environment, result.stderrTruncated),\n );\n if (stdout.output) {\n this.process.stdout.write(\n stdout.output.endsWith('\\n') ? stdout.output : `${stdout.output}\\n`,\n );\n }\n if (stderr.output) {\n this.process.stderr.write(\n stderr.output.endsWith('\\n') ? stderr.output : `${stderr.output}\\n`,\n );\n }\n if (result.outputTruncated || stdout.truncated || stderr.truncated) {\n this.logger.warn(\n colors.yellow(\n `Simulator output was truncated after ${LOCAL_SIMULATOR_MAX_OUTPUT_BYTES} bytes per stream.`,\n ),\n );\n }\n if (result.code === 0) {\n this.logger.info(colors.green(`Passed \"${selected.name}\" (${label})`));\n } else {\n failed = true;\n const detail = result.timedOut\n ? `timed out after ${invocation.timeoutMs}ms`\n : result.inputError\n ? `could not send the fixture to Deno: ${result.inputError.message}`\n : result.error\n ? `could not start Deno: ${result.error.message}`\n : result.signal\n ? `was terminated with ${result.signal}`\n : `exited with code ${result.code}`;\n this.logger.error(colors.red(`Failed \"${selected.name}\" (${label}): ${detail}`));\n }\n }\n if (failed) {\n this.process.exitCode = 1;\n }\n } catch (error) {\n if (error instanceof PromptCancelledError) {\n this.process.exit(130);\n }\n throw error;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./paths-J5KScOaQ.mjs";import{o as t}from"./project-discovery-CWRjlFnC.mjs";import{t as n}from"./parseVariablesFromString-6TYW65LF.mjs";import{t as r}from"./validateTranscendAuth-
|
|
2
|
-
//# sourceMappingURL=impl-
|
|
1
|
+
import{i as e}from"./paths-J5KScOaQ.mjs";import{o as t}from"./project-discovery-CWRjlFnC.mjs";import{t as n}from"./parseVariablesFromString-6TYW65LF.mjs";import{t as r}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as i}from"./done-input-validation-LiTaCEzF.mjs";import{t as a}from"./missing-manifest-D8y1VL4p.mjs";import{c as o,s,t as c}from"./project-discovery-g29vd44a.mjs";import{t as l}from"./command-output-BJcDRXNr.mjs";import{n as u}from"./command-output-BRfF3YFv.mjs";import{CustomFunctionPayloadType as d,CustomFunctionType as f}from"@transcend-io/privacy-types";import p from"colors";import{mapSeries as m}from"@transcend-io/utils";import{buildTranscendGraphQLClient as h,createSombraGotInstance as g,fetchAllCustomFunctions as _,resolveEffectiveSombraId as v,resolveExistingCustomFunction as y,syncCustomFunction as b}from"@transcend-io/sdk";async function x({auth:x,sombraAuth:S,transcendUrl:C,manifest:w,variables:T,dryRun:E,json:D,promote:O,force:k,skipTests:A,updateManifest:j,sombraId:M},N){i(this.process);let P=this.process.cwd(),{manifestDirectory:F,manifestPath:I}=e(P,{...N?{directory:N}:{},...w?{manifest:w}:{}});if(!this.fs.existsSync(I)){let e=a({cwd:P,manifestPath:I,discoveredManifestPaths:c(this,P),command:`push`});this.logger.error(p.red(e)),this.process.exit(1)}let L=r(x,this);Array.isArray(L)&&(this.logger.error(p.red(`transcend custom-functions push does not support a list of API keys — pass a single API key.`)),this.process.exit(1));let R=L,z=l(this.logger,D),B=n(T);z.info(p.magenta(`Reading manifest "${I}"...`));let V=s(I,B,e=>t(this,F,e));z.info(p.green(`Found ${V.length} custom function(s) in "${I}"`));let H=h(C,R),U=await _(H,{logger:z}),W=new Map,G=async(e,t)=>{let n=`${e??``}\u0000${t??``}`,r=W.get(n);if(r)return r;z.info(p.magenta(`Connecting to the ${e?`Sombra gateway "${e}"`:`primary Sombra gateway`} to sign code...`));let i=await g(C,R,{logger:z,sombraApiKey:t,...e?{sombraId:e}:{}});return W.set(n,i),i},K=e=>{if(!e.sombraAuthEnv)return S;let t=this.process.env[e.sombraAuthEnv];if(!t)throw Error(`Custom function "${e.name}" sets sombra-auth-env: ${e.sombraAuthEnv}, but that environment variable is not set. Export it (e.g. from a CI secret) before pushing.`);return t},q=[];if(await m(V,async e=>{try{let t=v(e,y(U,e),M),n=await b(H,{input:e,sombra:E?void 0:await G(t,K(e)),defaultSombraId:M,existing:U,promote:O,dryRun:E,force:k,...!A&&e.testPayloads!==void 0?{testPayloads:e.testPayloads}:{},logger:z});q.push({name:e.name,result:n});let r=n.versionNumber?` (version ${n.versionNumber})`:``,i=n.changedFields.length>0?` [${n.changedFields.join(`, `)}]`:``;switch(n.outcome){case`created`:n.createdDataSilo&&n.dataSiloId&&z.info(p.green(`Created DSR integration (data silo ${n.dataSiloId}) for "${e.name}"`)),z.info(p.green(`Created custom function "${e.name}"${r}`));break;case`updated`:z.info(p.green(`Pushed new revision to "${e.name}"${r}${i}${n.promoted?` and promoted to active`:` as a draft`}`));break;case`metadata-updated`:z.info(p.green(`Updated metadata for "${e.name}"${i} — code unchanged, no new revision`));break;case`skipped`:z.info(p.yellow(`Skipped "${e.name}" — no changes detected (env variable values cannot be diffed; use --force if only values changed)`));break;case`would-create`:z.info(p.cyan(`[dry run] Would create custom function "${e.name}"${e.type===f.Dsr&&!e.dataSiloId?` and its DSR integration (data silo)`:``}`));break;case`would-update`:z.info(p.cyan(`[dry run] Would push a new revision to "${e.name}"${i}`));break;case`test-failed`:{let t=(n.testResults??[]).filter(({passed:e})=>!e);z.error(p.red(`Rejected "${e.name}" — ${t.length} of ${n.testResults?.length??0} test run(s) failed`)),t.forEach(({payloadType:e,result:t})=>{let n=e?`[${e}] `:``;z.error(p.red(` ${n}${t.error?t.error.message:`failed with exit code ${t.exitCode}`}`)),t.logs.forEach(({file:e,message:t})=>{z.error(p.red(` [${e}] ${t}`))})}),n.createdDataSilo&&z.error(p.red(` The DSR integration (data silo) created for "${e.name}" was rolled back.`));break}}if(!A&&(e.testPayloads===void 0||e.testPayloads.length===0)&&(n.outcome===`created`||n.outcome===`updated`)&&z.warn(p.yellow(`Custom function "${e.name}" was pushed without a test run — add a test-payload to its manifest entry to enable test-before-promote.`)),!A&&e.type===f.Dsr&&e.testPayloads!==void 0&&e.testPayloads.length>0&&(n.outcome===`created`||n.outcome===`updated`)){let t=new Set(e.testPayloads.map(({payloadType:e})=>e??d.DataPoint));if(t.size===1){let[n]=t,r=n===d.DataPoint?d.RequestEnricher:d.DataPoint;z.warn(p.yellow(`DSR custom function "${e.name}" only tests its ${n} export — if it also implements the ${r} export, add a test payload with payload-type: ${r} so both entry points are tested on every push.`))}}}catch(t){q.push({name:e.name,error:t}),z.error(p.red(`Failed to sync custom function "${e.name}": ${t.message}`))}}),j&&!E){let e=o(I,V.map((e,t)=>{let n=q[t]?.result;if(!n)return;let r={...!e.id&&n.customFunctionId?{id:n.customFunctionId}:{},...!e.dataSiloId&&n.dataSiloId?{dataSiloId:n.dataSiloId}:{}};return Object.keys(r).length>0?r:void 0}));e>0&&z.info(p.green(`Wrote assigned id(s) back to ${e} manifest entr(ies) in "${I}" — commit this change so future pushes match by ID.`))}let J=u(I,E,q);if(D)this.process.stdout.write(`${JSON.stringify(J)}\n`);else{let{summary:e}=J;z.info(p.magenta(`Custom function sync complete: ${e.created} created, ${e.updated} updated, ${e.metadataUpdated} metadata-only, ${e.skipped} skipped, ${e.rejected} rejected (test failed), ${e.failed} failed${E?` (dry run)`:``}`))}J.status===`failed`&&this.process.exit(1)}export{x as push};
|
|
2
|
+
//# sourceMappingURL=impl-CWINXCFq2.mjs.map
|