@transcend-io/cli 10.27.5 → 10.28.0
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 +193 -24
- package/dist/app-DCY8E776.mjs +148 -0
- package/dist/app-DCY8E776.mjs.map +1 -0
- package/dist/{approvePrivacyRequests-B842tXn4.mjs → approvePrivacyRequests-80SV_94y.mjs} +2 -2
- package/dist/{approvePrivacyRequests-B842tXn4.mjs.map → approvePrivacyRequests-80SV_94y.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-CRrUU89C.mjs → buildExamples-2YDkSvtA.mjs} +2 -2
- package/dist/{buildExamples-CRrUU89C.mjs.map → buildExamples-2YDkSvtA.mjs.map} +1 -1
- package/dist/{buildXdiSyncEndpoint-B9seJTxP.mjs → buildXdiSyncEndpoint-B3zUrI16.mjs} +2 -2
- package/dist/{buildXdiSyncEndpoint-B9seJTxP.mjs.map → buildXdiSyncEndpoint-B3zUrI16.mjs.map} +1 -1
- package/dist/{bulkRestartRequests-CE7cDUMd.mjs → bulkRestartRequests-BLb8OJmf.mjs} +2 -2
- package/dist/{bulkRestartRequests-CE7cDUMd.mjs.map → bulkRestartRequests-BLb8OJmf.mjs.map} +1 -1
- package/dist/{bulkRetryEnrichers-BcSANZPC.mjs → bulkRetryEnrichers-BA9cboSe.mjs} +2 -2
- package/dist/{bulkRetryEnrichers-BcSANZPC.mjs.map → bulkRetryEnrichers-BA9cboSe.mjs.map} +1 -1
- package/dist/{cancelPrivacyRequests-BKibbagv.mjs → cancelPrivacyRequests-BEyOBJ2r.mjs} +2 -2
- package/dist/{cancelPrivacyRequests-BKibbagv.mjs.map → cancelPrivacyRequests-BEyOBJ2r.mjs.map} +1 -1
- package/dist/{codecs-zRkskjaJ.mjs → codecs-BsQFAFGT.mjs} +1 -1
- package/dist/{codecs-zRkskjaJ.mjs.map → codecs-BsQFAFGT.mjs.map} +1 -1
- package/dist/{collectCsvFilesOrExit-Dg5U3Qx_.mjs → collectCsvFilesOrExit-BqnmK63h.mjs} +1 -1
- package/dist/{collectCsvFilesOrExit-Dg5U3Qx_.mjs.map → collectCsvFilesOrExit-BqnmK63h.mjs.map} +1 -1
- package/dist/{collectParquetFilesOrExit-BlG2RRSC.mjs → collectParquetFilesOrExit-BiksFI-Q.mjs} +1 -1
- package/dist/{collectParquetFilesOrExit-BlG2RRSC.mjs.map → collectParquetFilesOrExit-BiksFI-Q.mjs.map} +1 -1
- package/dist/{command-DKNKpgUB.mjs → command-eIenZMOx.mjs} +2 -2
- package/dist/{command-DKNKpgUB.mjs.map → command-eIenZMOx.mjs.map} +1 -1
- package/dist/commands/admin/chunk-csv/worker.mjs +1 -1
- package/dist/commands/admin/parquet-to-csv/worker.mjs +1 -1
- package/dist/{consentManagersToBusinessEntities-Rv-ajWya.mjs → consentManagersToBusinessEntities-O4KBox9u.mjs} +1 -1
- package/dist/{consentManagersToBusinessEntities-Rv-ajWya.mjs.map → consentManagersToBusinessEntities-O4KBox9u.mjs.map} +1 -1
- package/dist/{constants-CdgK1myP.mjs → constants-BG53Mbi9.mjs} +2 -2
- package/dist/{constants-CdgK1myP.mjs.map → constants-BG53Mbi9.mjs.map} +1 -1
- package/dist/{constants-FbK2iR--.mjs → constants-BMAOvdcA.mjs} +1 -1
- package/dist/{constants-FbK2iR--.mjs.map → constants-BMAOvdcA.mjs.map} +1 -1
- package/dist/{constants-B6wESCW2.mjs → constants-BpQ5awGp.mjs} +2 -2
- package/dist/{constants-B6wESCW2.mjs.map → constants-BpQ5awGp.mjs.map} +1 -1
- package/dist/{constants-BuoISmXP.mjs → constants-C1seVfCu.mjs} +1 -1
- package/dist/{constants-BuoISmXP.mjs.map → constants-C1seVfCu.mjs.map} +1 -1
- package/dist/{context-4GAUnhTE.mjs → context-CZYrQfAn.mjs} +1 -1
- package/dist/{context-4GAUnhTE.mjs.map → context-CZYrQfAn.mjs.map} +1 -1
- package/dist/{createPoolingCommandUi-vTsGgYZT.mjs → createPoolingCommandUi-C39R_zo3.mjs} +2 -2
- package/dist/{createPoolingCommandUi-vTsGgYZT.mjs.map → createPoolingCommandUi-C39R_zo3.mjs.map} +1 -1
- package/dist/{dataFlowsToDataSilos-DRuAfwIn.mjs → dataFlowsToDataSilos-CLSHb1GA.mjs} +1 -1
- package/dist/{dataFlowsToDataSilos-DRuAfwIn.mjs.map → dataFlowsToDataSilos-CLSHb1GA.mjs.map} +1 -1
- package/dist/deno-runtime-QqwBDKXX.mjs +2 -0
- package/dist/deno-runtime-QqwBDKXX.mjs.map +1 -0
- package/dist/{done-input-validation-BFgMCQWH.mjs → done-input-validation-Cjk7a3jX.mjs} +1 -1
- package/dist/{done-input-validation-BFgMCQWH.mjs.map → done-input-validation-Cjk7a3jX.mjs.map} +1 -1
- package/dist/{downloadPrivacyRequestFiles-Dn3VexN2.mjs → downloadPrivacyRequestFiles-CLFgQItk.mjs} +2 -2
- package/dist/{downloadPrivacyRequestFiles-Dn3VexN2.mjs.map → downloadPrivacyRequestFiles-CLFgQItk.mjs.map} +1 -1
- package/dist/{extractClientError-DeS63kje.mjs → extractClientError-C_6ly7Gw.mjs} +1 -1
- package/dist/{extractClientError-DeS63kje.mjs.map → extractClientError-C_6ly7Gw.mjs.map} +1 -1
- package/dist/{fetchAllRequests-DUQGTJjx.mjs → fetchAllRequests-CEDKdq0c.mjs} +2 -2
- package/dist/{fetchAllRequests-DUQGTJjx.mjs.map → fetchAllRequests-CEDKdq0c.mjs.map} +1 -1
- package/dist/{formatPolicyBundleVersionSummary-Bo7DYxoy.mjs → formatPolicyBundleVersionSummary-CrFtcPwS.mjs} +1 -1
- package/dist/{formatPolicyBundleVersionSummary-Bo7DYxoy.mjs.map → formatPolicyBundleVersionSummary-CrFtcPwS.mjs.map} +1 -1
- package/dist/{fuzzyMatchColumns-BDD4a2W0.mjs → fuzzyMatchColumns-OTsFJ21f.mjs} +2 -2
- package/dist/{fuzzyMatchColumns-BDD4a2W0.mjs.map → fuzzyMatchColumns-OTsFJ21f.mjs.map} +1 -1
- package/dist/{generateCrossAccountApiKeys-QhnLqtUN.mjs → generateCrossAccountApiKeys-D6O_Qm3Y.mjs} +2 -2
- package/dist/{generateCrossAccountApiKeys-QhnLqtUN.mjs.map → generateCrossAccountApiKeys-D6O_Qm3Y.mjs.map} +1 -1
- package/dist/{impl-CrY1za0t.mjs → impl-6m7GXUAe.mjs} +2 -2
- package/dist/{impl-CrY1za0t.mjs.map → impl-6m7GXUAe.mjs.map} +1 -1
- package/dist/{impl-D33Zr0vh2.mjs → impl-B--lr5RJ2.mjs} +2 -2
- package/dist/{impl-D33Zr0vh2.mjs.map → impl-B--lr5RJ2.mjs.map} +1 -1
- package/dist/{impl-QeWNZCg4.mjs → impl-B3_hrFPX.mjs} +2 -2
- package/dist/{impl-QeWNZCg4.mjs.map → impl-B3_hrFPX.mjs.map} +1 -1
- package/dist/{impl-CbijbA-M2.mjs → impl-BFJtKA2o2.mjs} +2 -2
- package/dist/{impl-CbijbA-M2.mjs.map → impl-BFJtKA2o2.mjs.map} +1 -1
- package/dist/{impl-GnxjtYL7.mjs → impl-BJlKQJdS2.mjs} +2 -2
- package/dist/impl-BJlKQJdS2.mjs.map +1 -0
- package/dist/{impl-_rrZ0KXo.mjs → impl-BNPgYSBT.mjs} +2 -2
- package/dist/{impl-_rrZ0KXo.mjs.map → impl-BNPgYSBT.mjs.map} +1 -1
- package/dist/{impl-s5h7dIlv2.mjs → impl-BWVe4VGF2.mjs} +2 -2
- package/dist/{impl-s5h7dIlv2.mjs.map → impl-BWVe4VGF2.mjs.map} +1 -1
- package/dist/{impl-DiyWNLJq.mjs → impl-BYGNx-8W2.mjs} +2 -2
- package/dist/impl-BYGNx-8W2.mjs.map +1 -0
- package/dist/impl-BcJ019T2.mjs +2 -0
- package/dist/impl-BcJ019T2.mjs.map +1 -0
- package/dist/{impl-CMYYX3Kz.mjs → impl-BewF8tB6.mjs} +2 -2
- package/dist/{impl-CMYYX3Kz.mjs.map → impl-BewF8tB6.mjs.map} +1 -1
- package/dist/{impl-DQG3PiAW2.mjs → impl-Bq6g_xYv.mjs} +2 -2
- package/dist/impl-Bq6g_xYv.mjs.map +1 -0
- package/dist/{impl-DRimS_G8.mjs → impl-BqrSLoig.mjs} +2 -2
- package/dist/{impl-DRimS_G8.mjs.map → impl-BqrSLoig.mjs.map} +1 -1
- package/dist/{impl-CccuY3Za.mjs → impl-Bs-drNBf.mjs} +2 -2
- package/dist/{impl-CccuY3Za.mjs.map → impl-Bs-drNBf.mjs.map} +1 -1
- package/dist/impl-BsC1KVxS.mjs +2 -0
- package/dist/impl-BsC1KVxS.mjs.map +1 -0
- package/dist/{impl-BgxjEv88.mjs → impl-BvNZqLrT.mjs} +2 -2
- package/dist/{impl-BgxjEv88.mjs.map → impl-BvNZqLrT.mjs.map} +1 -1
- package/dist/{impl-BkyqCY72.mjs → impl-BwRcpAno.mjs} +2 -2
- package/dist/{impl-BkyqCY72.mjs.map → impl-BwRcpAno.mjs.map} +1 -1
- package/dist/{impl-BddyFp_q.mjs → impl-BySmbxEt.mjs} +2 -2
- package/dist/{impl-BddyFp_q.mjs.map → impl-BySmbxEt.mjs.map} +1 -1
- package/dist/{impl-BPn_YPIq2.mjs → impl-C50tdWlL2.mjs} +2 -2
- package/dist/{impl-BPn_YPIq2.mjs.map → impl-C50tdWlL2.mjs.map} +1 -1
- package/dist/{impl-CusKk_JR2.mjs → impl-C5dzaDga2.mjs} +2 -2
- package/dist/{impl-CusKk_JR2.mjs.map → impl-C5dzaDga2.mjs.map} +1 -1
- package/dist/impl-C8BmxFQ2.mjs +2 -0
- package/dist/impl-C8BmxFQ2.mjs.map +1 -0
- package/dist/{impl-CBC5K-IH.mjs → impl-CDtUusmg.mjs} +2 -2
- package/dist/{impl-CBC5K-IH.mjs.map → impl-CDtUusmg.mjs.map} +1 -1
- package/dist/{impl-Dpes0u_6.mjs → impl-CE56-wQh.mjs} +2 -2
- package/dist/{impl-Dpes0u_6.mjs.map → impl-CE56-wQh.mjs.map} +1 -1
- package/dist/{impl-DzJG5HaX.mjs → impl-CEmXPEq22.mjs} +2 -2
- package/dist/impl-CEmXPEq22.mjs.map +1 -0
- package/dist/{impl-CZ-KvZE02.mjs → impl-CHmjV-Pa.mjs} +2 -2
- package/dist/impl-CHmjV-Pa.mjs.map +1 -0
- package/dist/{impl-CXdy0YMX.mjs → impl-CQGeH47F.mjs} +2 -2
- package/dist/{impl-CXdy0YMX.mjs.map → impl-CQGeH47F.mjs.map} +1 -1
- package/dist/{impl-DG9RwTkA2.mjs → impl-CTIWliTx.mjs} +2 -2
- package/dist/impl-CTIWliTx.mjs.map +1 -0
- package/dist/{impl-DbPLuDc22.mjs → impl-CWh9H7mL.mjs} +2 -2
- package/dist/impl-CWh9H7mL.mjs.map +1 -0
- package/dist/{impl-BQTw6jpw.mjs → impl-CXUJ1eRC.mjs} +2 -2
- package/dist/{impl-BQTw6jpw.mjs.map → impl-CXUJ1eRC.mjs.map} +1 -1
- package/dist/{impl-xRwX5ZLK.mjs → impl-CfPXYgT42.mjs} +2 -2
- package/dist/impl-CfPXYgT42.mjs.map +1 -0
- package/dist/{impl-CLVMZXJo.mjs → impl-CiYKuCHV.mjs} +2 -2
- package/dist/{impl-CLVMZXJo.mjs.map → impl-CiYKuCHV.mjs.map} +1 -1
- package/dist/{impl-BoCD0t4j.mjs → impl-CqF9xIIy.mjs} +2 -2
- package/dist/{impl-BoCD0t4j.mjs.map → impl-CqF9xIIy.mjs.map} +1 -1
- package/dist/{impl-CVChVd63.mjs → impl-Cx3T0Iei.mjs} +2 -2
- package/dist/{impl-CVChVd63.mjs.map → impl-Cx3T0Iei.mjs.map} +1 -1
- package/dist/impl-CzxvoiGW.mjs +3 -0
- package/dist/impl-CzxvoiGW.mjs.map +1 -0
- package/dist/impl-D-SQJc3t.mjs +2 -0
- package/dist/impl-D-SQJc3t.mjs.map +1 -0
- package/dist/{impl-BPjGRqOL2.mjs → impl-D23kJPAQ2.mjs} +2 -2
- package/dist/{impl-BPjGRqOL2.mjs.map → impl-D23kJPAQ2.mjs.map} +1 -1
- package/dist/{impl-uKjAibIR.mjs → impl-DF8RGVlT.mjs} +2 -2
- package/dist/{impl-uKjAibIR.mjs.map → impl-DF8RGVlT.mjs.map} +1 -1
- package/dist/{impl-PYtpY5hs2.mjs → impl-DHfYO9T52.mjs} +2 -2
- package/dist/{impl-PYtpY5hs2.mjs.map → impl-DHfYO9T52.mjs.map} +1 -1
- package/dist/{impl-p0AyZWFL.mjs → impl-DIPvFKiP.mjs} +2 -2
- package/dist/{impl-p0AyZWFL.mjs.map → impl-DIPvFKiP.mjs.map} +1 -1
- package/dist/{impl-CzbVqbm0.mjs → impl-DJLlcqSg.mjs} +2 -2
- package/dist/{impl-CzbVqbm0.mjs.map → impl-DJLlcqSg.mjs.map} +1 -1
- package/dist/{impl-3IyENr9T.mjs → impl-DOoR93T6.mjs} +2 -2
- package/dist/{impl-3IyENr9T.mjs.map → impl-DOoR93T6.mjs.map} +1 -1
- package/dist/{impl-BiBNqcob.mjs → impl-DXNcD7CZ.mjs} +2 -2
- package/dist/{impl-BiBNqcob.mjs.map → impl-DXNcD7CZ.mjs.map} +1 -1
- package/dist/{impl-nJ7LzilX2.mjs → impl-DYf10-BD2.mjs} +2 -2
- package/dist/{impl-nJ7LzilX2.mjs.map → impl-DYf10-BD2.mjs.map} +1 -1
- package/dist/{impl-wf0PvJms.mjs → impl-DYwojWvN.mjs} +2 -2
- package/dist/{impl-wf0PvJms.mjs.map → impl-DYwojWvN.mjs.map} +1 -1
- package/dist/{impl-CH40t5qf.mjs → impl-DbZ1cYoR.mjs} +2 -2
- package/dist/{impl-CH40t5qf.mjs.map → impl-DbZ1cYoR.mjs.map} +1 -1
- package/dist/{impl-DbF7uw7f2.mjs → impl-Dib6Fff12.mjs} +2 -2
- package/dist/{impl-DbF7uw7f2.mjs.map → impl-Dib6Fff12.mjs.map} +1 -1
- package/dist/{impl-4rLX5Wah2.mjs → impl-Dk6TZKrp2.mjs} +2 -2
- package/dist/{impl-4rLX5Wah2.mjs.map → impl-Dk6TZKrp2.mjs.map} +1 -1
- package/dist/{impl-Cq5wI-kP.mjs → impl-Dm-Fkr392.mjs} +2 -2
- package/dist/impl-Dm-Fkr392.mjs.map +1 -0
- package/dist/{impl-BsEYMBx2.mjs → impl-DpuhHpuk.mjs} +2 -2
- package/dist/{impl-BsEYMBx2.mjs.map → impl-DpuhHpuk.mjs.map} +1 -1
- package/dist/{impl-DlaWf-oS2.mjs → impl-Drql0g72.mjs} +2 -2
- package/dist/impl-Drql0g72.mjs.map +1 -0
- package/dist/{impl-_tY0CJdZ.mjs → impl-DzNk41xd.mjs} +2 -2
- package/dist/{impl-_tY0CJdZ.mjs.map → impl-DzNk41xd.mjs.map} +1 -1
- package/dist/impl-FLj_mWLO.mjs +2 -0
- package/dist/impl-FLj_mWLO.mjs.map +1 -0
- package/dist/{impl-DxXWaXFU.mjs → impl-GHukPBnk.mjs} +2 -2
- package/dist/{impl-DxXWaXFU.mjs.map → impl-GHukPBnk.mjs.map} +1 -1
- package/dist/{impl-V_ffkzbd2.mjs → impl-KKrDTraf.mjs} +2 -2
- package/dist/impl-KKrDTraf.mjs.map +1 -0
- package/dist/{impl-BbWzTCSd2.mjs → impl-M3Eu4QjS.mjs} +2 -2
- package/dist/impl-M3Eu4QjS.mjs.map +1 -0
- package/dist/{impl-BlFBTc6f.mjs → impl-VPBEqV0w2.mjs} +2 -2
- package/dist/impl-VPBEqV0w2.mjs.map +1 -0
- package/dist/{impl-DWBQKUuq.mjs → impl-amV0wRWk.mjs} +2 -2
- package/dist/{impl-DWBQKUuq.mjs.map → impl-amV0wRWk.mjs.map} +1 -1
- package/dist/impl-m3QXCc6n.mjs +91 -0
- package/dist/impl-m3QXCc6n.mjs.map +1 -0
- package/dist/{impl-Ba8naMzu.mjs → impl-syp5hclX.mjs} +2 -2
- package/dist/{impl-Ba8naMzu.mjs.map → impl-syp5hclX.mjs.map} +1 -1
- package/dist/{impl-9TDsbGfF2.mjs → impl-zZFaSmxd2.mjs} +2 -2
- package/dist/{impl-9TDsbGfF2.mjs.map → impl-zZFaSmxd2.mjs.map} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{initializeCliRuntime-B7zDhMok.mjs → initializeCliRuntime-802-P8MC.mjs} +1 -1
- package/dist/{initializeCliRuntime-B7zDhMok.mjs.map → initializeCliRuntime-802-P8MC.mjs.map} +1 -1
- package/dist/{inquirer-DNa31Mkx.mjs → inquirer-DkFTQU00.mjs} +2 -2
- package/dist/{inquirer-DNa31Mkx.mjs.map → inquirer-DkFTQU00.mjs.map} +1 -1
- package/dist/{listFiles-DrxRhlZ2.mjs → listFiles-CWHAdKY-.mjs} +1 -1
- package/dist/{listFiles-DrxRhlZ2.mjs.map → listFiles-CWHAdKY-.mjs.map} +1 -1
- package/dist/logger-9T6vva73.mjs +2 -0
- package/dist/logger-9T6vva73.mjs.map +1 -0
- package/dist/manifest-DVuW_vvO.mjs +2 -0
- package/dist/manifest-DVuW_vvO.mjs.map +1 -0
- package/dist/{mapConsentCsvRowsToInputs-DA7BRD7M.mjs → mapConsentCsvRowsToInputs-MMPZwzrV.mjs} +1 -1
- package/dist/{mapConsentCsvRowsToInputs-DA7BRD7M.mjs.map → mapConsentCsvRowsToInputs-MMPZwzrV.mjs.map} +1 -1
- package/dist/{markRequestDataSiloIdsCompleted-CK7PNwTz.mjs → markRequestDataSiloIdsCompleted-PKCcn5wQ.mjs} +2 -2
- package/dist/{markRequestDataSiloIdsCompleted-CK7PNwTz.mjs.map → markRequestDataSiloIdsCompleted-PKCcn5wQ.mjs.map} +1 -1
- package/dist/{markSilentPrivacyRequests-Cb-J9ckA.mjs → markSilentPrivacyRequests-7l9I99pe.mjs} +2 -2
- package/dist/{markSilentPrivacyRequests-Cb-J9ckA.mjs.map → markSilentPrivacyRequests-7l9I99pe.mjs.map} +1 -1
- package/dist/{mergeTranscendInputs-CkpitZbH.mjs → mergeTranscendInputs-CWHXH0kF.mjs} +2 -2
- package/dist/{mergeTranscendInputs-CkpitZbH.mjs.map → mergeTranscendInputs-CWHXH0kF.mjs.map} +1 -1
- package/dist/missing-manifest-BKj1j-jg.mjs +2 -0
- package/dist/missing-manifest-BKj1j-jg.mjs.map +1 -0
- package/dist/module-graph-DBC7ZvyA.mjs +2 -0
- package/dist/module-graph-DBC7ZvyA.mjs.map +1 -0
- package/dist/{notifyPrivacyRequestsAdditionalTime-it1FA62W.mjs → notifyPrivacyRequestsAdditionalTime-BPIYuCov.mjs} +2 -2
- package/dist/{notifyPrivacyRequestsAdditionalTime-it1FA62W.mjs.map → notifyPrivacyRequestsAdditionalTime-BPIYuCov.mjs.map} +1 -1
- package/dist/{parquetToCsvOneFile-Dtz90qfJ.mjs → parquetToCsvOneFile-CSVdrLvq.mjs} +2 -2
- package/dist/{parquetToCsvOneFile-Dtz90qfJ.mjs.map → parquetToCsvOneFile-CSVdrLvq.mjs.map} +1 -1
- package/dist/{parseAttributesFromString-BxJcnKmn.mjs → parseAttributesFromString-C5-KGkPH.mjs} +2 -2
- package/dist/{parseAttributesFromString-BxJcnKmn.mjs.map → parseAttributesFromString-C5-KGkPH.mjs.map} +1 -1
- package/dist/parseVariablesFromString-Cr3x2uq3.mjs +2 -0
- package/dist/parseVariablesFromString-Cr3x2uq3.mjs.map +1 -0
- package/dist/{policyEngineCliError-BnBghLd1.mjs → policyEngineCliError-DY8V-qkK.mjs} +1 -1
- package/dist/{policyEngineCliError-BnBghLd1.mjs.map → policyEngineCliError-DY8V-qkK.mjs.map} +1 -1
- package/dist/{printResult-oXnpZu_9.mjs → printResult-esxW3HhT.mjs} +2 -2
- package/dist/{printResult-oXnpZu_9.mjs.map → printResult-esxW3HhT.mjs.map} +1 -1
- package/dist/project-plan-apply-C2DfikVN.mjs +3 -0
- package/dist/project-plan-apply-C2DfikVN.mjs.map +1 -0
- package/dist/{pullAllDatapoints-XqreMBT5.mjs → pullAllDatapoints-H92qjLSx.mjs} +2 -2
- package/dist/{pullAllDatapoints-XqreMBT5.mjs.map → pullAllDatapoints-H92qjLSx.mjs.map} +1 -1
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DuPDOm6f.mjs → pullChunkedCustomSiloOutstandingIdentifiers-BrDmPbvc.mjs} +2 -2
- package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DuPDOm6f.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-BrDmPbvc.mjs.map} +1 -1
- package/dist/{pullConsentManagerMetrics-Dk5IejaY.mjs → pullConsentManagerMetrics-Cvex-gpd.mjs} +2 -2
- package/dist/{pullConsentManagerMetrics-Dk5IejaY.mjs.map → pullConsentManagerMetrics-Cvex-gpd.mjs.map} +1 -1
- package/dist/{pullManualEnrichmentIdentifiersToCsv-CAD1navz.mjs → pullManualEnrichmentIdentifiersToCsv-qjdNA75O.mjs} +2 -2
- package/dist/{pullManualEnrichmentIdentifiersToCsv-CAD1navz.mjs.map → pullManualEnrichmentIdentifiersToCsv-qjdNA75O.mjs.map} +1 -1
- package/dist/{pullTranscendConfiguration-NcFjHE8k.mjs → pullTranscendConfiguration-CD7Frn8z.mjs} +2 -2
- package/dist/{pullTranscendConfiguration-NcFjHE8k.mjs.map → pullTranscendConfiguration-CD7Frn8z.mjs.map} +1 -1
- package/dist/{pullUnstructuredSubDataPointRecommendations-Cf4irXl4.mjs → pullUnstructuredSubDataPointRecommendations-Dmh_-r95.mjs} +2 -2
- package/dist/{pullUnstructuredSubDataPointRecommendations-Cf4irXl4.mjs.map → pullUnstructuredSubDataPointRecommendations-Dmh_-r95.mjs.map} +1 -1
- package/dist/{pushCronIdentifiersFromCsv-BGaJycWo.mjs → pushCronIdentifiersFromCsv-DjeY7TtK.mjs} +2 -2
- package/dist/{pushCronIdentifiersFromCsv-BGaJycWo.mjs.map → pushCronIdentifiersFromCsv-DjeY7TtK.mjs.map} +1 -1
- package/dist/{pushManualEnrichmentIdentifiersFromCsv-B9okRkhL.mjs → pushManualEnrichmentIdentifiersFromCsv-BDtMo13j.mjs} +2 -2
- package/dist/{pushManualEnrichmentIdentifiersFromCsv-B9okRkhL.mjs.map → pushManualEnrichmentIdentifiersFromCsv-BDtMo13j.mjs.map} +1 -1
- package/dist/{readCsv-CmRYYFJc.mjs → readCsv-Cr_1t8F5.mjs} +1 -1
- package/dist/{readCsv-CmRYYFJc.mjs.map → readCsv-Cr_1t8F5.mjs.map} +1 -1
- package/dist/{readTranscendYaml-DtJz9mor.mjs → readTranscendYaml-STYnRzq-.mjs} +3 -3
- package/dist/readTranscendYaml-STYnRzq-.mjs.map +1 -0
- package/dist/{removeUnverifiedRequestIdentifiers-DJhxiy_D.mjs → removeUnverifiedRequestIdentifiers-B9uPApVR.mjs} +2 -2
- package/dist/{removeUnverifiedRequestIdentifiers-DJhxiy_D.mjs.map → removeUnverifiedRequestIdentifiers-B9uPApVR.mjs.map} +1 -1
- package/dist/{renderTable-DKXvortp.mjs → renderTable-DKTZbMjY.mjs} +1 -1
- package/dist/{renderTable-DKXvortp.mjs.map → renderTable-DKTZbMjY.mjs.map} +1 -1
- package/dist/{request-CCCU2SdV.mjs → request-B1yRTdG-.mjs} +1 -1
- package/dist/{request-CCCU2SdV.mjs.map → request-B1yRTdG-.mjs.map} +1 -1
- package/dist/{resolveBundleIdByName-By5Vl8Iz.mjs → resolveBundleIdByName-DuxWYrDF.mjs} +2 -2
- package/dist/{resolveBundleIdByName-By5Vl8Iz.mjs.map → resolveBundleIdByName-DuxWYrDF.mjs.map} +1 -1
- package/dist/{resolvePolicyBundleVersion-DO7IvEwb.mjs → resolvePolicyBundleVersion-DhXZKwb4.mjs} +2 -2
- package/dist/{resolvePolicyBundleVersion-DO7IvEwb.mjs.map → resolvePolicyBundleVersion-DhXZKwb4.mjs.map} +1 -1
- package/dist/{retryRequestDataSilos-6JfyZclD.mjs → retryRequestDataSilos-D9dBtbdl.mjs} +2 -2
- package/dist/{retryRequestDataSilos-6JfyZclD.mjs.map → retryRequestDataSilos-D9dBtbdl.mjs.map} +1 -1
- package/dist/run-captured-process-CpZBh0lG.mjs +2 -0
- package/dist/run-captured-process-CpZBh0lG.mjs.map +1 -0
- package/dist/{runOpa-Q2r3qPsi.mjs → runOpa-CkKAwsvB.mjs} +2 -2
- package/dist/{runOpa-Q2r3qPsi.mjs.map → runOpa-CkKAwsvB.mjs.map} +1 -1
- package/dist/scaffold-planning-DMACXSnX.mjs +121 -0
- package/dist/scaffold-planning-DMACXSnX.mjs.map +1 -0
- package/dist/scaffold-templates-CsHM1y80.mjs +84 -0
- package/dist/scaffold-templates-CsHM1y80.mjs.map +1 -0
- package/dist/{skipPreflightJobs-xpbtJ3dK.mjs → skipPreflightJobs-Beia_iB6.mjs} +2 -2
- package/dist/{skipPreflightJobs-xpbtJ3dK.mjs.map → skipPreflightJobs-Beia_iB6.mjs.map} +1 -1
- package/dist/{skipRequestDataSilos-B7RA6I3Z.mjs → skipRequestDataSilos-BSNLacnR.mjs} +2 -2
- package/dist/{skipRequestDataSilos-B7RA6I3Z.mjs.map → skipRequestDataSilos-BSNLacnR.mjs.map} +1 -1
- package/dist/{streamPrivacyRequestsToCsv-DT31SP6w.mjs → streamPrivacyRequestsToCsv-Cksb9D49.mjs} +2 -2
- package/dist/{streamPrivacyRequestsToCsv-DT31SP6w.mjs.map → streamPrivacyRequestsToCsv-Cksb9D49.mjs.map} +1 -1
- package/dist/{syncCodePackages-ozt9aBXf.mjs → syncCodePackages-DsC1tE8B.mjs} +2 -2
- package/dist/{syncCodePackages-ozt9aBXf.mjs.map → syncCodePackages-DsC1tE8B.mjs.map} +1 -1
- package/dist/{updateConsentManagerVersionToLatest-CCzWEBEj.mjs → updateConsentManagerVersionToLatest-CaEkTnlL.mjs} +2 -2
- package/dist/{updateConsentManagerVersionToLatest-CCzWEBEj.mjs.map → updateConsentManagerVersionToLatest-CaEkTnlL.mjs.map} +1 -1
- package/dist/{uploadConsents-CDqFNWX_.mjs → uploadConsents-CNyuYx0o.mjs} +2 -2
- package/dist/{uploadConsents-CDqFNWX_.mjs.map → uploadConsents-CNyuYx0o.mjs.map} +1 -1
- package/dist/{uploadPrivacyRequestsFromCsv-CVpBFaYB.mjs → uploadPrivacyRequestsFromCsv-BdTQOZnF.mjs} +2 -2
- package/dist/{uploadPrivacyRequestsFromCsv-CVpBFaYB.mjs.map → uploadPrivacyRequestsFromCsv-BdTQOZnF.mjs.map} +1 -1
- package/dist/{validateTranscendAuth-3guZJPKH.mjs → validateTranscendAuth-CnHMn77m.mjs} +2 -2
- package/dist/{validateTranscendAuth-3guZJPKH.mjs.map → validateTranscendAuth-CnHMn77m.mjs.map} +1 -1
- package/dist/{writeCsv-rhlEBjYp.mjs → writeCsv-D46aDkGf.mjs} +1 -1
- package/dist/{writeCsv-rhlEBjYp.mjs.map → writeCsv-D46aDkGf.mjs.map} +1 -1
- package/package.json +10 -5
- package/dist/app-dIu3pdTM.mjs +0 -148
- package/dist/app-dIu3pdTM.mjs.map +0 -1
- package/dist/impl-BbWzTCSd2.mjs.map +0 -1
- package/dist/impl-BlFBTc6f.mjs.map +0 -1
- package/dist/impl-BqiclSRZ.mjs +0 -2
- package/dist/impl-BqiclSRZ.mjs.map +0 -1
- package/dist/impl-CZ-KvZE02.mjs.map +0 -1
- package/dist/impl-CclEOdC32.mjs +0 -2
- package/dist/impl-CclEOdC32.mjs.map +0 -1
- package/dist/impl-Cq5wI-kP.mjs.map +0 -1
- package/dist/impl-DG9RwTkA2.mjs.map +0 -1
- package/dist/impl-DQG3PiAW2.mjs.map +0 -1
- package/dist/impl-DbPLuDc22.mjs.map +0 -1
- package/dist/impl-DiyWNLJq.mjs.map +0 -1
- package/dist/impl-DlaWf-oS2.mjs.map +0 -1
- package/dist/impl-DzJG5HaX.mjs.map +0 -1
- package/dist/impl-GYM4LDKp2.mjs +0 -2
- package/dist/impl-GYM4LDKp2.mjs.map +0 -1
- package/dist/impl-GnxjtYL7.mjs.map +0 -1
- package/dist/impl-V_ffkzbd2.mjs.map +0 -1
- package/dist/impl-xRwX5ZLK.mjs.map +0 -1
- package/dist/logger-CB_h_zbj.mjs +0 -2
- package/dist/logger-CB_h_zbj.mjs.map +0 -1
- package/dist/parseVariablesFromString-cu5gPC3M.mjs +0 -2
- package/dist/parseVariablesFromString-cu5gPC3M.mjs.map +0 -1
- package/dist/readTranscendYaml-DtJz9mor.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pushManualEnrichmentIdentifiersFromCsv-
|
|
1
|
+
{"version":3,"file":"pushManualEnrichmentIdentifiersFromCsv-BDtMo13j.mjs","names":[],"sources":["../src/lib/manual-enrichment/enrichPrivacyRequest.ts","../src/lib/manual-enrichment/pushManualEnrichmentIdentifiersFromCsv.ts"],"sourcesContent":["import { splitCsvToList } from '@transcend-io/utils';\nimport colors from 'colors';\nimport type { Got } from 'got';\nimport * as t from 'io-ts';\nimport { uniq } from 'lodash-es';\n\nimport { logger } from '../../logger.js';\n\nconst ADMIN_URL = 'https://app.transcend.io/privacy-requests/incoming-requests/';\n/**\n * Minimal set required to mark as completed\n */\nexport const EnrichPrivacyRequest = t.record(t.string, t.string);\n\n/** Type override */\nexport type EnrichPrivacyRequest = t.TypeOf<typeof EnrichPrivacyRequest>;\n\n/**\n * Upload identifiers to a privacy request or mark request as\n *\n * @param sombra - Sombra instance configured to make requests\n * @param request - Request to enricher\n * @param enricherId - The ID of the enricher being uploaded to\n * @param index - Index of request ID\n * @returns True if enriched successfully, false if skipped, throws error if failed\n */\nexport async function enrichPrivacyRequest(\n sombra: Got,\n { id: rawId, ...rest }: EnrichPrivacyRequest,\n enricherId: string,\n index?: number,\n): Promise<boolean> {\n if (!rawId) {\n // error\n const msg = `Request ID must be provided to enricher request.${\n index ? ` Found error in row: ${index}` : ''\n }`;\n logger.error(colors.red(msg));\n throw new Error(msg);\n }\n\n const id = rawId.toLowerCase();\n\n // Pull out the identifiers\n const enrichedIdentifiers = Object.entries(rest).reduce(\n (acc, [key, value]) => {\n const values = uniq(splitCsvToList(value));\n return values.length === 0\n ? acc\n : Object.assign(acc, {\n [key]: uniq(splitCsvToList(value)).map((val) => ({\n value: key === 'email' ? val.toLowerCase() : val,\n })),\n });\n },\n {} as Record<string, string[]>,\n );\n\n // Make the GraphQL request\n try {\n await sombra\n .post('v1/enrich-identifiers', {\n headers: {\n 'x-transcend-request-id': id,\n 'x-transcend-enricher-id': enricherId,\n },\n json: {\n enrichedIdentifiers,\n },\n })\n .json();\n\n logger.error(colors.green(`Successfully enriched request: ${ADMIN_URL}${id}`));\n return true;\n } catch (err) {\n // skip if already enriched\n if (\n typeof err.response.body === 'string' &&\n err.response.body.includes('Cannot update a resolved RequestEnricher')\n ) {\n logger.warn(\n colors.magenta(\n `Skipped enrichment for request: ${ADMIN_URL}${id}, request is no longer in the enriching phase.`,\n ),\n );\n return false;\n }\n\n // error\n logger.error(\n colors.red(\n `Failed to enricher identifiers for request with id: ${ADMIN_URL}${id} - ${err.message} - ${err.response.body}`,\n ),\n );\n throw err;\n }\n}\n","import {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n makeGraphQLRequest,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { UPDATE_PRIVACY_REQUEST } from '../graphql/index.js';\nimport { readCsv } from '../requests/index.js';\nimport { enrichPrivacyRequest, EnrichPrivacyRequest } from './enrichPrivacyRequest.js';\n\n/**\n * Push a CSV of enriched requests back into Transcend\n *\n * @param options - Options\n * @returns Number of items processed\n */\nexport async function pushManualEnrichmentIdentifiersFromCsv({\n file,\n auth,\n sombraAuth,\n enricherId,\n markSilent,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** ID of enricher being uploaded to */\n enricherId: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Mark requests in silent mode before enriching */\n markSilent?: boolean;\n}): Promise<number> {\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, EnrichPrivacyRequest);\n\n // Notify Transcend\n logger.info(colors.magenta(`Enriching \"${activeResults.length}\" privacy requests.`));\n\n let successCount = 0;\n let skippedCount = 0;\n let errorCount = 0;\n\n await map(\n activeResults,\n async (request, index) => {\n try {\n // Mark requests in silent mode before a certain date\n if (markSilent) {\n await makeGraphQLRequest(client, UPDATE_PRIVACY_REQUEST, {\n variables: {\n input: {\n id: request.id,\n isSilent: true,\n },\n },\n logger,\n });\n\n logger.info(colors.magenta(`Mark request as silent mode - ${request.id}`));\n }\n\n const result = await enrichPrivacyRequest(sombra, request, enricherId, index);\n if (result) {\n successCount += 1;\n } else {\n skippedCount += 1;\n }\n } catch {\n errorCount += 1;\n }\n },\n { concurrency },\n );\n\n logger.info(colors.green(`Successfully notified Transcend! \\n Success count: ${successCount}.`));\n\n if (skippedCount > 0) {\n logger.info(colors.magenta(`Skipped count: ${skippedCount}.`));\n }\n\n if (errorCount > 0) {\n logger.info(colors.red(`Error Count: ${errorCount}.`));\n throw new Error(`Failed to enrich: ${errorCount} requests.`);\n }\n\n return activeResults.length;\n}\n"],"mappings":"qaAQA,MAAM,EAAY,+DAIL,EAAuB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAchE,eAAsB,EACpB,EACA,CAAE,GAAI,EAAO,GAAG,GAChB,EACA,EACkB,CAClB,GAAI,CAAC,EAAO,CAEV,IAAM,EAAM,mDACV,EAAQ,wBAAwB,IAAU,KAG5C,MADA,EAAO,MAAM,EAAO,IAAI,EAAI,CAAC,CACnB,MAAM,EAAI,CAGtB,IAAM,EAAK,EAAM,aAAa,CAGxB,EAAsB,OAAO,QAAQ,EAAK,CAAC,QAC9C,EAAK,CAAC,EAAK,KACK,EAAK,EAAe,EAAM,CAC5B,CAAC,SAAW,EACrB,EACA,OAAO,OAAO,EAAK,EAChB,GAAM,EAAK,EAAe,EAAM,CAAC,CAAC,IAAK,IAAS,CAC/C,MAAO,IAAQ,QAAU,EAAI,aAAa,CAAG,EAC9C,EAAE,CACJ,CAAC,CAER,EAAE,CACH,CAGD,GAAI,CAcF,OAbA,MAAM,EACH,KAAK,wBAAyB,CAC7B,QAAS,CACP,yBAA0B,EAC1B,0BAA2B,EAC5B,CACD,KAAM,CACJ,sBACD,CACF,CAAC,CACD,MAAM,CAET,EAAO,MAAM,EAAO,MAAM,kCAAkC,IAAY,IAAK,CAAC,CACvE,SACA,EAAK,CAEZ,GACE,OAAO,EAAI,SAAS,MAAS,UAC7B,EAAI,SAAS,KAAK,SAAS,2CAA2C,CAOtE,OALA,EAAO,KACL,EAAO,QACL,mCAAmC,IAAY,EAAG,gDACnD,CACF,CACM,GAST,MALA,EAAO,MACL,EAAO,IACL,uDAAuD,IAAY,EAAG,KAAK,EAAI,QAAQ,KAAK,EAAI,SAAS,OAC1G,CACF,CACK,GC1EV,eAAsB,EAAuC,CAC3D,OACA,OACA,aACA,aACA,aACA,cAAc,IACd,eAAe,GAgBG,CAElB,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CACI,EAAS,EAA4B,EAAc,EAAK,CAG9D,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAC1D,IAAM,EAAgB,EAAQ,EAAM,EAAqB,CAGzD,EAAO,KAAK,EAAO,QAAQ,cAAc,EAAc,OAAO,qBAAqB,CAAC,CAEpF,IAAI,EAAe,EACf,EAAe,EACf,EAAa,EAwCjB,GAtCA,MAAM,EACJ,EACA,MAAO,EAAS,IAAU,CACxB,GAAI,CAEE,IACF,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,GAAI,EAAQ,GACZ,SAAU,GACX,CACF,CACD,SACD,CAAC,CAEF,EAAO,KAAK,EAAO,QAAQ,iCAAiC,EAAQ,KAAK,CAAC,EAIxE,MADiB,EAAqB,EAAQ,EAAS,EAAY,EAAM,CAE3E,GAAgB,EAEhB,GAAgB,OAEZ,CACN,GAAc,IAGlB,CAAE,cAAa,CAChB,CAED,EAAO,KAAK,EAAO,MAAM,sDAAsD,EAAa,GAAG,CAAC,CAE5F,EAAe,GACjB,EAAO,KAAK,EAAO,QAAQ,kBAAkB,EAAa,GAAG,CAAC,CAG5D,EAAa,EAEf,MADA,EAAO,KAAK,EAAO,IAAI,gBAAgB,EAAW,GAAG,CAAC,CAC5C,MAAM,qBAAqB,EAAW,YAAY,CAG9D,OAAO,EAAc"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{readFileSync as e}from"node:fs";import{decodeCodec as t}from"@transcend-io/type-utils";import*as n from"io-ts";import{parse as r}from"csv-parse/sync";function i(e,i,a={columns:!0}){let o=r(e,a);return t(n.array(i),o).map(e=>Object.entries(e).reduce((e,[t,n])=>Object.assign(e,{[t.replace(/[^a-z_.+\-A-Z -~]/g,``)]:n}),{}))}function a(t,n,r={columns:!0}){return i(e(t,`utf-8`),n,r)}export{a as n,i as t};
|
|
2
|
-
//# sourceMappingURL=readCsv-
|
|
2
|
+
//# sourceMappingURL=readCsv-Cr_1t8F5.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readCsv-
|
|
1
|
+
{"version":3,"file":"readCsv-Cr_1t8F5.mjs","names":[],"sources":["../src/lib/requests/readCsv.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport type { Options } from 'csv-parse';\nimport { parse } from 'csv-parse/sync';\nimport * as t from 'io-ts';\n\n/**\n * Parse CSV contents and validate their shape.\n *\n * @param contents - CSV contents.\n * @param codec - The codec to validate against. This is the codec for individual, non-header, rows\n * @param options - CSV parse options\n * @returns The JSON data\n */\nexport function parseCsv<T extends t.Any>(\n contents: string,\n codec: T,\n options: Options = { columns: true },\n): t.TypeOf<T>[] {\n const fileContent = parse(contents, options);\n\n // validate codec\n const data = decodeCodec(t.array(codec), fileContent);\n\n // remove any special characters from object keys\n const parsed = data.map((datum) =>\n Object.entries(datum).reduce(\n (acc, [key, value]) =>\n Object.assign(acc, {\n [key.replace(/[^a-z_.+\\-A-Z -~]/g, '')]: value,\n }),\n {} as T,\n ),\n );\n return parsed;\n}\n\n/**\n * Read in a CSV and validate its shape.\n *\n * @param pathToFile - Path to file.\n * @param codec - The codec to validate against. This is the codec for individual, non-header, rows.\n * @param options - CSV parse options.\n * @returns The JSON data.\n */\nexport function readCsv<T extends t.Any>(\n pathToFile: string,\n codec: T,\n options: Options = { columns: true },\n): t.TypeOf<T>[] {\n return parseCsv(readFileSync(pathToFile, 'utf-8'), codec, options);\n}\n"],"mappings":"6JAeA,SAAgB,EACd,EACA,EACA,EAAmB,CAAE,QAAS,GAAM,CACrB,CACf,IAAM,EAAc,EAAM,EAAU,EAAQ,CAe5C,OAZa,EAAY,EAAE,MAAM,EAAM,CAAE,EAGtB,CAAC,IAAK,GACvB,OAAO,QAAQ,EAAM,CAAC,QACnB,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,EAAI,QAAQ,qBAAsB,GAAG,EAAG,EAC1C,CAAC,CACJ,EAAE,CACH,CAEU,CAWf,SAAgB,EACd,EACA,EACA,EAAmB,CAAE,QAAS,GAAM,CACrB,CACf,OAAO,EAAS,EAAa,EAAY,QAAQ,CAAE,EAAO,EAAQ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{dt as e}from"./codecs-
|
|
2
|
-
Make sure you are passing all
|
|
1
|
+
import{dt as e}from"./codecs-BsQFAFGT.mjs";import{readFileSync as t,writeFileSync as n}from"node:fs";import{decodeCodec as r}from"@transcend-io/type-utils";import i from"js-yaml";const a=/<<parameters\.(.+?)>>/,o=`parameters`;function s(e,t,n=``){let r=Object.entries(t).reduce((e,[t,n])=>e.split(`<<${o}.${t}>>`).join(n),e);if(a.test(r)){let[,e]=a.exec(r)||[];throw Error(`Found variable that was not set: ${e}.
|
|
2
|
+
Make sure you are passing all variables through the --variables=${e}:value-for-variable flag.
|
|
3
3
|
${n}`)}return r}function c(t,n={},a){let o=s(t,n,a?`Also check that there are no extra variables defined in your yaml: ${a}`:``);return r(e,i.load(o))}function l(t){return i.dump(r(e,t))}function u(e,n={}){return c(t(e,`utf-8`),n,e)}function d(e,t){n(e,l(t))}export{s as a,u as i,a as n,l as o,c as r,d as s,o as t};
|
|
4
|
-
//# sourceMappingURL=readTranscendYaml-
|
|
4
|
+
//# sourceMappingURL=readTranscendYaml-STYnRzq-.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readTranscendYaml-STYnRzq-.mjs","names":[],"sources":["../src/lib/readTranscendYaml.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\n\nimport { decodeCodec, ObjByString } from '@transcend-io/type-utils';\nimport yaml from 'js-yaml';\n\nimport { TranscendInput } from '../codecs.js';\n\nexport const VARIABLE_PARAMETERS_REGEXP = /<<parameters\\.(.+?)>>/;\nexport const VARIABLE_PARAMETERS_NAME = 'parameters';\n\n/**\n * Function that replaces variables in a text file.\n * Throws error if there are variables that have not been replaced\n *\n * @param input - Input text\n * @param variables - Variables to replace\n * @param extraErrorMessage - Additional error message text\n * @returns Output text\n */\nexport function replaceVariablesInYaml(\n input: string,\n variables: ObjByString,\n extraErrorMessage = '',\n): string {\n const contents = Object.entries(variables).reduce(\n (replaced, [name, value]) =>\n replaced.split(`<<${VARIABLE_PARAMETERS_NAME}.${name}>>`).join(value),\n input,\n );\n\n // Throw error if unfilled parameters\n if (VARIABLE_PARAMETERS_REGEXP.test(contents)) {\n const [, name] = VARIABLE_PARAMETERS_REGEXP.exec(contents) || [];\n throw new Error(\n `Found variable that was not set: ${name}.\nMake sure you are passing all variables through the --variables=${name}:value-for-variable flag.\n${extraErrorMessage}`,\n );\n }\n\n return contents;\n}\n\n/**\n * Parse YAML contents and validate that their shape matches the codec API.\n *\n * @param contents - YAML contents.\n * @param variables - Variables to fill in\n * @param sourcePath - Optional source path included in parameter errors.\n * @returns The parsed contents, type-checked.\n */\nexport function parseTranscendYaml(\n contents: string,\n variables: ObjByString = {},\n sourcePath?: string,\n): TranscendInput {\n const replacedVariables = replaceVariablesInYaml(\n contents,\n variables,\n sourcePath\n ? `Also check that there are no extra variables defined in your yaml: ${sourcePath}`\n : '',\n );\n\n return decodeCodec(TranscendInput, yaml.load(replacedVariables));\n}\n\n/**\n * Serialize a validated Transcend configuration as YAML.\n *\n * @param input - The input to serialize.\n * @returns YAML contents.\n */\nexport function serializeTranscendYaml(input: TranscendInput): string {\n return yaml.dump(decodeCodec(TranscendInput, input));\n}\n\n/**\n * Read in the contents of a YAML file and validate that its shape matches the codec API.\n *\n * @param filePath - Path to YAML file.\n * @param variables - Variables to fill in.\n * @returns The parsed contents, type-checked.\n */\nexport function readTranscendYaml(filePath: string, variables: ObjByString = {}): TranscendInput {\n return parseTranscendYaml(readFileSync(filePath, 'utf-8'), variables, filePath);\n}\n\n/**\n * Write a Transcend configuration to disk.\n *\n * @param filePath - Path to YAML file.\n * @param input - The input to write out.\n */\nexport function writeTranscendYaml(filePath: string, input: TranscendInput): void {\n writeFileSync(filePath, serializeTranscendYaml(input));\n}\n"],"mappings":"mLAOA,MAAa,EAA6B,wBAC7B,EAA2B,aAWxC,SAAgB,EACd,EACA,EACA,EAAoB,GACZ,CACR,IAAM,EAAW,OAAO,QAAQ,EAAU,CAAC,QACxC,EAAU,CAAC,EAAM,KAChB,EAAS,MAAM,KAAK,EAAyB,GAAG,EAAK,IAAI,CAAC,KAAK,EAAM,CACvE,EACD,CAGD,GAAI,EAA2B,KAAK,EAAS,CAAE,CAC7C,GAAM,EAAG,GAAQ,EAA2B,KAAK,EAAS,EAAI,EAAE,CAChE,MAAU,MACR,oCAAoC,EAAK;kEACmB,EAAK;EACrE,IACG,CAGH,OAAO,EAWT,SAAgB,EACd,EACA,EAAyB,EAAE,CAC3B,EACgB,CAChB,IAAM,EAAoB,EACxB,EACA,EACA,EACI,sEAAsE,IACtE,GACL,CAED,OAAO,EAAY,EAAgB,EAAK,KAAK,EAAkB,CAAC,CASlE,SAAgB,EAAuB,EAA+B,CACpE,OAAO,EAAK,KAAK,EAAY,EAAgB,EAAM,CAAC,CAUtD,SAAgB,EAAkB,EAAkB,EAAyB,EAAE,CAAkB,CAC/F,OAAO,EAAmB,EAAa,EAAU,QAAQ,CAAE,EAAW,EAAS,CASjF,SAAgB,EAAmB,EAAkB,EAA6B,CAChF,EAAc,EAAU,EAAuB,EAAM,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=removeUnverifiedRequestIdentifiers-
|
|
1
|
+
import{a as e}from"./constants-BG53Mbi9.mjs";import{t}from"./logger-9T6vva73.mjs";import{r as n}from"./fetchAllRequests-CEDKdq0c.mjs";import{RequestStatus as r}from"@transcend-io/privacy-types";import i from"colors";import{REMOVE_REQUEST_IDENTIFIERS as a,buildTranscendGraphQLClient as o,fetchAllRequestIdentifierMetadata as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d,identifierNames:f,auth:p,concurrency:m=20,transcendUrl:h=e}){let g=o(h,p),_=new Date().getTime(),v=new u.SingleBar({},u.Presets.shades_classic),y=await n(g,{actions:d,statuses:[r.Enriching]});t.info(i.magenta(`Fetched requests in preflight/enriching state.`));let b=0,x=0;v.start(y.length,0),await l(y,async e=>{let n=(await s(g,{filterBy:{requestId:e.id},logger:t})).filter(({isVerifiedAtLeastOnce:e,name:t})=>e===!1&&f.includes(t)).map(({id:e})=>e);n.length>0&&(await c(g,a,{variables:{input:{requestId:e.id,requestIdentifierIds:n}},logger:t}),x+=n.length),b+=1,v.update(b)},{concurrency:m}),v.stop();let S=new Date().getTime()-_;return t.info(i.green(`Successfully cleared out unverified identifiers "${S/1e3}" seconds for ${b} requests, ${x} identifiers were cleared out!`)),y.length}export{d as t};
|
|
2
|
+
//# sourceMappingURL=removeUnverifiedRequestIdentifiers-B9uPApVR.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeUnverifiedRequestIdentifiers-
|
|
1
|
+
{"version":3,"file":"removeUnverifiedRequestIdentifiers-B9uPApVR.mjs","names":[],"sources":["../src/lib/requests/removeUnverifiedRequestIdentifiers.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllRequestIdentifierMetadata,\n makeGraphQLRequest,\n REMOVE_REQUEST_IDENTIFIERS,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Remove a set of unverified request identifier\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function removeUnverifiedRequestIdentifiers({\n requestActions,\n identifierNames,\n auth,\n concurrency = 20,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** The set of identifier names to remove */\n identifierNames: string[];\n /** Concurrency to upload requests in parallel */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n // Notify Transcend\n logger.info(colors.magenta('Fetched requests in preflight/enriching state.'));\n\n let total = 0;\n let processed = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToRestart) => {\n const requestIdentifiers = await fetchAllRequestIdentifierMetadata(client, {\n filterBy: { requestId: requestToRestart.id },\n logger,\n });\n const clearOut = requestIdentifiers\n .filter(\n ({ isVerifiedAtLeastOnce, name }) =>\n isVerifiedAtLeastOnce === false && identifierNames.includes(name),\n )\n .map(({ id }) => id);\n\n if (clearOut.length > 0) {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, REMOVE_REQUEST_IDENTIFIERS, {\n variables: {\n input: {\n requestId: requestToRestart.id,\n requestIdentifierIds: clearOut,\n },\n },\n logger,\n });\n processed += clearOut.length;\n }\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\n );\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully cleared out unverified identifiers \"${\n totalTime / 1000\n }\" seconds for ${total} requests, ${processed} identifiers were cleared out!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"6bAqBA,eAAsB,EAAmC,CACvD,iBACA,kBACA,OACA,cAAc,GACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,iDAAiD,CAAC,CAE7E,IAAI,EAAQ,EACR,EAAY,EAChB,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAqB,CAK1B,IAAM,GAAW,MAJgB,EAAkC,EAAQ,CACzE,SAAU,CAAE,UAAW,EAAiB,GAAI,CAC5C,SACD,CAAC,EAEC,QACE,CAAE,wBAAuB,UACxB,IAA0B,IAAS,EAAgB,SAAS,EAAK,CACpE,CACA,KAAK,CAAE,QAAS,EAAG,CAElB,EAAS,OAAS,IACpB,MAAM,EAGH,EAAQ,EAA4B,CACrC,UAAW,CACT,MAAO,CACL,UAAW,EAAiB,GAC5B,qBAAsB,EACvB,CACF,CACD,SACD,CAAC,CACF,GAAa,EAAS,QAGxB,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SACF,CAAG,EASvB,OAPA,EAAO,KACL,EAAO,MACL,oDACE,EAAY,IACb,gBAAgB,EAAM,aAAa,EAAU,gCAC/C,CACF,CACM,EAAY"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
function e(e,t){let n=e.map((e,n)=>Math.max(e.length,...t.map(e=>(e[n]??``).length))),r=e=>e.map((e,t)=>e.padEnd(n[t]??e.length)).join(` `),i=n.map(e=>`-`.repeat(e)).join(` `);return[r(e),i,...t.map(e=>r(e))].join(`
|
|
2
2
|
`)}export{e as t};
|
|
3
|
-
//# sourceMappingURL=renderTable-
|
|
3
|
+
//# sourceMappingURL=renderTable-DKTZbMjY.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderTable-
|
|
1
|
+
{"version":3,"file":"renderTable-DKTZbMjY.mjs","names":[],"sources":["../src/commands/policy/helpers/renderTable.ts"],"sourcesContent":["/**\n * Renders rows as a simple fixed-width text table.\n *\n * @param headers - Column headers\n * @param rows - Table rows\n * @returns Formatted table string\n */\nexport function renderTable(headers: string[], rows: string[][]): string {\n const widths = headers.map((header, index) =>\n Math.max(header.length, ...rows.map((row) => (row[index] ?? '').length)),\n );\n\n const formatRow = (cells: string[]): string =>\n cells.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join(' ');\n\n const divider = widths.map((width) => '-'.repeat(width)).join(' ');\n return [formatRow(headers), divider, ...rows.map((row) => formatRow(row))].join('\\n');\n}\n"],"mappings":"AAOA,SAAgB,EAAY,EAAmB,EAA0B,CACvE,IAAM,EAAS,EAAQ,KAAK,EAAQ,IAClC,KAAK,IAAI,EAAO,OAAQ,GAAG,EAAK,IAAK,IAAS,EAAI,IAAU,IAAI,OAAO,CAAC,CACzE,CAEK,EAAa,GACjB,EAAM,KAAK,EAAM,IAAU,EAAK,OAAO,EAAO,IAAU,EAAK,OAAO,CAAC,CAAC,KAAK,KAAK,CAE5E,EAAU,EAAO,IAAK,GAAU,IAAI,OAAO,EAAM,CAAC,CAAC,KAAK,KAAK,CACnE,MAAO,CAAC,EAAU,EAAQ,CAAE,EAAS,GAAG,EAAK,IAAK,GAAQ,EAAU,EAAI,CAAC,CAAC,CAAC,KAAK;EAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-
|
|
1
|
+
{"version":3,"file":"request-B1yRTdG-.mjs","names":[],"sources":["../src/lib/graphql/gqls/request.ts"],"sourcesContent":["import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const REQUESTS_COUNT = gql`\n query TranscendCliRequestsCount($filterBy: RequestFiltersInput!) {\n requests(filterBy: $filterBy, first: 0, useMaster: false) {\n totalCount\n }\n }\n`;\n\nexport const REQUESTS = gql`\n query TranscendCliRequests($first: Int!, $after: String, $filterBy: RequestFiltersInput!) {\n requests(\n filterBy: $filterBy\n first: $first\n after: $after\n orderBy: [{ field: createdAt, direction: ASC }, { field: id, direction: ASC }]\n useMaster: false\n ) {\n nodes {\n id\n createdAt\n email\n link\n status\n details\n isTest\n locale\n origin\n isSilent\n coreIdentifier\n daysRemaining\n successfullyCompletedAt\n type\n subjectType\n country\n countrySubDivision\n purpose {\n title\n name\n consent\n enrichedPreferences {\n topic\n selectValues {\n id\n name\n preferenceOption {\n id\n slug\n title {\n defaultMessage\n }\n }\n }\n selectValue {\n id\n name\n }\n selectValue {\n id\n name\n }\n preferenceTopic {\n title {\n defaultMessage\n }\n id\n slug\n }\n name\n id\n booleanValue\n }\n }\n attributeValues {\n id\n name\n attributeKey {\n id\n name\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n`;\n\nexport const APPROVE_PRIVACY_REQUEST = gql`\n mutation TranscendCliApprovePrivacyRequest($input: CommunicationInput!) {\n approveRequest(input: $input) {\n request {\n id\n }\n }\n }\n`;\nexport const CANCEL_PRIVACY_REQUEST = gql`\n mutation TranscendCliCancelPrivacyRequest($input: CommunicationInput!) {\n cancelRequest(input: $input) {\n request {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_PRIVACY_REQUEST = gql`\n mutation TranscendCliUpdatePrivacyRequest($input: UpdateRequestInput!) {\n updateRequest(input: $input) {\n request {\n id\n }\n }\n }\n`;\n\nexport const NOTIFY_ADDITIONAL_TIME = gql`\n mutation TranscendCliNotifyAdditionalTime($input: AdditionalTimeInput!) {\n notifyAdditionalTime(input: $input) {\n clientMutationId\n }\n }\n`;\n"],"mappings":"sCAIA,MAAa,EAAiB,CAAG;;;;;;EAQpB,EAAW,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiFd,EAA0B,CAAG;;;;;;;;EAS7B,EAAyB,CAAG;;;;;;;;EAU5B,EAAyB,CAAG;;;;;;;;EAU5B,EAAyB,CAAG"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./printResult-
|
|
2
|
-
//# sourceMappingURL=resolveBundleIdByName-
|
|
1
|
+
import{n as e}from"./printResult-esxW3HhT.mjs";async function t(t,n){let r=0;for(;;){let i=await e(t.get(`v1/policy-engine/policy-bundles`,{searchParams:{limit:100,offset:r}}).json()),a=i.nodes.find(e=>e.bundleName===n);if(a)return a;if(r+=i.nodes.length,r>=i.totalCount||i.nodes.length===0)return}}async function n(e,n){return(await t(e,n))?.id}export{n,t};
|
|
2
|
+
//# sourceMappingURL=resolveBundleIdByName-DuxWYrDF.mjs.map
|
package/dist/{resolveBundleIdByName-By5Vl8Iz.mjs.map → resolveBundleIdByName-DuxWYrDF.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveBundleIdByName-
|
|
1
|
+
{"version":3,"file":"resolveBundleIdByName-DuxWYrDF.mjs","names":[],"sources":["../src/commands/policy/helpers/resolveBundleIdByName.ts"],"sourcesContent":["import type { Got } from 'got';\n\nimport type { PolicyBundle, PolicyBundleListResponse } from '../types.js';\nimport { policyEngineRequest } from './formatPolicyEngineRequestError.js';\n\n/**\n * Resolves a bundle name to its parent record by scanning offset-paginated listings.\n *\n * @param client - Policy Engine REST client\n * @param bundleName - Bundle name to resolve\n * @returns Matching bundle when found\n */\nexport async function resolveBundleByName(\n client: Got,\n bundleName: string,\n): Promise<PolicyBundle | undefined> {\n const limit = 100;\n let offset = 0;\n\n while (true) {\n const body = await policyEngineRequest(\n client\n .get('v1/policy-engine/policy-bundles', {\n searchParams: { limit, offset },\n })\n .json<PolicyBundleListResponse>(),\n );\n\n const match = body.nodes.find((bundle) => bundle.bundleName === bundleName);\n if (match) {\n return match;\n }\n\n offset += body.nodes.length;\n if (offset >= body.totalCount || body.nodes.length === 0) {\n return undefined;\n }\n }\n}\n\n/**\n * Resolves a bundle name to its UUID by scanning offset-paginated bundle listings.\n *\n * @param client - Policy Engine REST client\n * @param bundleName - Bundle name to resolve\n * @returns Bundle UUID when found\n */\nexport async function resolveBundleIdByName(\n client: Got,\n bundleName: string,\n): Promise<string | undefined> {\n const bundle = await resolveBundleByName(client, bundleName);\n return bundle?.id;\n}\n"],"mappings":"+CAYA,eAAsB,EACpB,EACA,EACmC,CACnC,IACI,EAAS,EAEb,OAAa,CACX,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,kCAAmC,CACtC,aAAc,CAAE,UAAO,SAAQ,CAChC,CAAC,CACD,MAAgC,CACpC,CAEK,EAAQ,EAAK,MAAM,KAAM,GAAW,EAAO,aAAe,EAAW,CAC3E,GAAI,EACF,OAAO,EAIT,GADA,GAAU,EAAK,MAAM,OACjB,GAAU,EAAK,YAAc,EAAK,MAAM,SAAW,EACrD,QAYN,eAAsB,EACpB,EACA,EAC6B,CAE7B,OAAO,MADc,EAAoB,EAAQ,EAAW,GAC7C"}
|
package/dist/{resolvePolicyBundleVersion-DO7IvEwb.mjs → resolvePolicyBundleVersion-DhXZKwb4.mjs}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./printResult-
|
|
2
|
-
//# sourceMappingURL=resolvePolicyBundleVersion-
|
|
1
|
+
import{n as e}from"./printResult-esxW3HhT.mjs";async function t(t,n){let r=[],i;for(;;){let a={limit:100};i&&(a.after=i);let o=await e(t.get(`v1/policy-engine/policy-bundles/${n}/versions`,{searchParams:a}).json());if(r.push(...o.nodes),!o.pageInfo.hasNextPage||!o.pageInfo.endCursor)break;i=o.pageInfo.endCursor}return r}function n(e,t){return new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime()}async function r(e,r,i){let a=await t(e,r);if(a.length===0)throw Error(`No versions found for this policy bundle.`);if(i.version){let e=a.find(e=>e.version===i.version);if(!e)throw Error(`Version "${i.version}" was not found for this policy bundle.`);return e}return a.sort(n)[0]}export{r as t};
|
|
2
|
+
//# sourceMappingURL=resolvePolicyBundleVersion-DhXZKwb4.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolvePolicyBundleVersion-
|
|
1
|
+
{"version":3,"file":"resolvePolicyBundleVersion-DhXZKwb4.mjs","names":[],"sources":["../src/commands/policy/helpers/resolvePolicyBundleVersion.ts"],"sourcesContent":["import type { Got } from 'got';\n\nimport type { PolicyBundleVersion, PolicyBundleVersionListResponse } from '../types.js';\nimport { policyEngineRequest } from './formatPolicyEngineRequestError.js';\n\n/** Options for resolving a policy bundle version. */\nexport interface ResolvePolicyBundleVersionOptions {\n /** Caller-supplied version label; omitted to pick the latest by createdAt */\n version?: string;\n}\n\n/**\n * Lists all versions for a bundle, following cursor pagination.\n *\n * @param client - Policy Engine REST client\n * @param bundleId - Parent bundle UUID\n * @returns All uploaded versions\n */\nasync function listAllPolicyBundleVersions(\n client: Got,\n bundleId: string,\n): Promise<PolicyBundleVersion[]> {\n const limit = 100;\n const versions: PolicyBundleVersion[] = [];\n let after: string | undefined;\n\n while (true) {\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 versions.push(...body.nodes);\n\n if (!body.pageInfo.hasNextPage || !body.pageInfo.endCursor) {\n break;\n }\n after = body.pageInfo.endCursor;\n }\n\n return versions;\n}\n\n/**\n * Compares two version records by createdAt, newest first.\n *\n * @param left - First version\n * @param right - Second version\n * @returns Sort order for descending createdAt\n */\nfunction compareVersionsByCreatedAtDesc(\n left: PolicyBundleVersion,\n right: PolicyBundleVersion,\n): number {\n return new Date(right.createdAt).getTime() - new Date(left.createdAt).getTime();\n}\n\n/**\n * Resolves a version label to a version record, or picks the latest by createdAt.\n *\n * @param client - Policy Engine REST client\n * @param bundleId - Parent bundle UUID\n * @param options - Version lookup options\n * @returns Matching or latest version record\n */\nexport async function resolvePolicyBundleVersion(\n client: Got,\n bundleId: string,\n options: ResolvePolicyBundleVersionOptions,\n): Promise<PolicyBundleVersion> {\n const versions = await listAllPolicyBundleVersions(client, bundleId);\n\n if (versions.length === 0) {\n throw new Error('No versions found for this policy bundle.');\n }\n\n if (options.version) {\n const match = versions.find((entry) => entry.version === options.version);\n if (!match) {\n throw new Error(`Version \"${options.version}\" was not found for this policy bundle.`);\n }\n return match;\n }\n\n return versions.sort(compareVersionsByCreatedAtDesc)[0];\n}\n"],"mappings":"+CAkBA,eAAe,EACb,EACA,EACgC,CAChC,IACM,EAAkC,EAAE,CACtC,EAEJ,OAAa,CACX,IAAM,EAAgD,CAAE,UAAO,CAC3D,IACF,EAAa,MAAQ,GAGvB,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,mCAAmC,EAAS,WAAY,CAC3D,eACD,CAAC,CACD,MAAuC,CAC3C,CAID,GAFA,EAAS,KAAK,GAAG,EAAK,MAAM,CAExB,CAAC,EAAK,SAAS,aAAe,CAAC,EAAK,SAAS,UAC/C,MAEF,EAAQ,EAAK,SAAS,UAGxB,OAAO,EAUT,SAAS,EACP,EACA,EACQ,CACR,OAAO,IAAI,KAAK,EAAM,UAAU,CAAC,SAAS,CAAG,IAAI,KAAK,EAAK,UAAU,CAAC,SAAS,CAWjF,eAAsB,EACpB,EACA,EACA,EAC8B,CAC9B,IAAM,EAAW,MAAM,EAA4B,EAAQ,EAAS,CAEpE,GAAI,EAAS,SAAW,EACtB,MAAU,MAAM,4CAA4C,CAG9D,GAAI,EAAQ,QAAS,CACnB,IAAM,EAAQ,EAAS,KAAM,GAAU,EAAM,UAAY,EAAQ,QAAQ,CACzE,GAAI,CAAC,EACH,MAAU,MAAM,YAAY,EAAQ,QAAQ,yCAAyC,CAEvF,OAAO,EAGT,OAAO,EAAS,KAAK,EAA+B,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=retryRequestDataSilos-
|
|
1
|
+
import{a as e}from"./constants-BG53Mbi9.mjs";import{t}from"./logger-9T6vva73.mjs";import{r as n}from"./fetchAllRequests-CEDKdq0c.mjs";import{RequestStatus as r}from"@transcend-io/privacy-types";import i from"colors";import{RETRY_REQUEST_DATA_SILO as a,buildTranscendGraphQLClient as o,fetchRequestDataSilo as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d,dataSiloId:f,auth:p,concurrency:m=20,transcendUrl:h=e}){let g=o(h,p),_=new Date().getTime(),v=new u.SingleBar({},u.Presets.shades_classic),y=await n(g,{actions:d,statuses:[r.Compiling,r.Approving]});t.info(i.magenta(`Retrying requests for Data Silo: "${f}", restarting "${y.length}" requests.`));let b=0,x=0;v.start(y.length,0),await l(y,async e=>{try{await c(g,a,{variables:{requestDataSiloId:(await s(g,{logger:t,filterBy:{requestId:e.id,dataSiloId:f}})).id},logger:t})}catch(e){if(!e.message.includes(`Failed to find RequestDataSilo`))throw e;x+=1}b+=1,v.update(b)},{concurrency:m}),v.stop();let S=new Date().getTime()-_;return t.info(i.green(`Successfully notified Transcend in "${S/1e3}" seconds for ${b} requests, ${x} requests were skipped because data silo was not attached to the request!`)),y.length}export{d as t};
|
|
2
|
+
//# sourceMappingURL=retryRequestDataSilos-D9dBtbdl.mjs.map
|
package/dist/{retryRequestDataSilos-6JfyZclD.mjs.map → retryRequestDataSilos-D9dBtbdl.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryRequestDataSilos-
|
|
1
|
+
{"version":3,"file":"retryRequestDataSilos-D9dBtbdl.mjs","names":[],"sources":["../src/lib/requests/retryRequestDataSilos.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n makeGraphQLRequest,\n RETRY_REQUEST_DATA_SILO,\n fetchRequestDataSilo,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Retry a set of RequestDataSilos\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function retryRequestDataSilos({\n requestActions,\n dataSiloId,\n auth,\n concurrency = 20,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Concurrency to upload requests in parallel */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Compiling, RequestStatus.Approving],\n });\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Retrying requests for Data Silo: \"${dataSiloId}\", restarting \"${allRequests.length}\" requests.`,\n ),\n );\n\n let total = 0;\n let skipped = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToRestart) => {\n try {\n const requestDataSilo = await fetchRequestDataSilo(client, {\n logger,\n filterBy: { requestId: requestToRestart.id, dataSiloId },\n });\n\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, RETRY_REQUEST_DATA_SILO, {\n variables: { requestDataSiloId: requestDataSilo.id },\n logger,\n });\n } catch (err) {\n // some requests may not have this data silo connected\n if (!err.message.includes('Failed to find RequestDataSilo')) {\n throw err;\n }\n skipped += 1;\n }\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\n );\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully notified Transcend in \"${\n totalTime / 1000\n }\" seconds for ${total} requests, ${skipped} requests were skipped because data silo was not attached to the request!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"6aAqBA,eAAsB,EAAsB,CAC1C,iBACA,aACA,OACA,cAAc,GACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAW,EAAc,UAAU,CAC7D,CAAC,CAGF,EAAO,KACL,EAAO,QACL,qCAAqC,EAAW,iBAAiB,EAAY,OAAO,aACrF,CACF,CAED,IAAI,EAAQ,EACR,EAAU,EACd,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAqB,CAC1B,GAAI,CAMF,MAAM,EAGH,EAAQ,EAAyB,CAClC,UAAW,CAAE,mBAAmB,MATJ,EAAqB,EAAQ,CACzD,SACA,SAAU,CAAE,UAAW,EAAiB,GAAI,aAAY,CACzD,CAAC,EAMgD,GAAI,CACpD,SACD,CAAC,OACK,EAAK,CAEZ,GAAI,CAAC,EAAI,QAAQ,SAAS,iCAAiC,CACzD,MAAM,EAER,GAAW,EAGb,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SACF,CAAG,EASvB,OAPA,EAAO,KACL,EAAO,MACL,uCACE,EAAY,IACb,gBAAgB,EAAM,aAAa,EAAQ,2EAC7C,CACF,CACM,EAAY"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{spawn as e}from"node:child_process";import{Buffer as t}from"node:buffer";const n=(n,r,i,a)=>new Promise(o=>{let s=e(n,[...r],{cwd:i.cwd,env:{...i.env??a.process.env,PATH:a.process.env.PATH,NO_COLOR:`1`},stdio:`pipe`}),c=``,l=``,u=!1,d=!1,f=!1,p,m=!1,h,g=i.timeoutMs?setTimeout(()=>{f=!0,s.kill(`SIGTERM`),h=setTimeout(()=>s.kill(`SIGKILL`),1e3)},i.timeoutMs):void 0,_=e=>{m||(m=!0,g&&clearTimeout(g),h&&clearTimeout(h),o({...e,...f?{timedOut:!0}:{},...p?{inputError:p}:{},...u||d?{outputTruncated:!0}:{},...u?{stdoutTruncated:!0}:{},...d?{stderrTruncated:!0}:{}}))},v=(e,n,r)=>{if(!i.maxOutputBytes)return e+n;let a=i.maxOutputBytes-t.byteLength(e),o=t.from(n);if(a<=0)return r(),e;if(o.length>a){r();let t=a;for(;t>0&&(o[t]&192)==128;)--t;return e+o.subarray(0,t).toString(`utf8`)}return e+n};s.stdout.setEncoding(`utf8`),s.stderr.setEncoding(`utf8`),s.stdout.on(`data`,e=>{c=v(c,e,()=>{u=!0})}),s.stderr.on(`data`,e=>{l=v(l,e,()=>{d=!0})}),s.stdin.on(`error`,e=>{p=e}),s.once(`error`,e=>{_({code:1,stdout:c,stderr:l,error:e})}),s.once(`close`,(e,t)=>{_({code:f||p?1:e??1,stdout:c,stderr:l,...t?{signal:t}:{}})});try{i.input===void 0?s.stdin.end():s.stdin.end(i.input)}catch(e){p=e,s.kill(`SIGTERM`)}});export{n as t};
|
|
2
|
+
//# sourceMappingURL=run-captured-process-CpZBh0lG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-captured-process-CpZBh0lG.mjs","names":[],"sources":["../src/lib/cli/run-captured-process.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport { spawn } from 'node:child_process';\n\nimport type { LocalContext } from '../../context.js';\n\n/** Captured subprocess result. */\nexport interface CapturedProcessResult {\n /** Process exit code. */\n code: number;\n /** Captured standard output. */\n stdout: string;\n /** Captured standard error. */\n stderr: string;\n /** Signal that terminated the process, when present. */\n signal?: NodeJS.Signals;\n /** Whether the configured timeout elapsed. */\n timedOut?: boolean;\n /** Error encountered while writing standard input. */\n inputError?: NodeJS.ErrnoException;\n /** Whether stdout or stderr exceeded the configured capture limit. */\n outputTruncated?: boolean;\n /** Whether stdout exceeded the configured capture limit. */\n stdoutTruncated?: boolean;\n /** Whether stderr exceeded the configured capture limit. */\n stderrTruncated?: boolean;\n /** Spawn error, when the executable did not start. */\n error?: NodeJS.ErrnoException;\n}\n\n/** Captured subprocess runner. */\nexport type CapturedProcessRunner = (\n command: string,\n args: readonly string[],\n options: {\n /** Working directory. */\n cwd: string;\n /** Optional standard input. */\n input?: string;\n /** Child environment; PATH is retained so the executable can be resolved. */\n env?: NodeJS.ProcessEnv;\n /** Optional process timeout. */\n timeoutMs?: number;\n /** Maximum bytes retained from each output stream. */\n maxOutputBytes?: number;\n },\n context: LocalContext,\n) => Promise<CapturedProcessResult>;\n\n/**\n * Capture a subprocess without forwarding its output.\n *\n * @param command - Executable\n * @param args - Arguments\n * @param options - CWD and optional standard input\n * @param context - CLI context\n * @returns Captured result\n */\nexport const runCapturedProcess: CapturedProcessRunner = (command, args, options, context) =>\n new Promise((resolveResult) => {\n const child = spawn(command, [...args], {\n cwd: options.cwd,\n env: {\n ...(options.env ?? context.process.env),\n PATH: context.process.env.PATH,\n NO_COLOR: '1',\n },\n stdio: 'pipe',\n });\n let stdout = '';\n let stderr = '';\n let stdoutTruncated = false;\n let stderrTruncated = false;\n let timedOut = false;\n let inputError: NodeJS.ErrnoException | undefined;\n let settled = false;\n let forceKillTimer: NodeJS.Timeout | undefined;\n const timeoutTimer = options.timeoutMs\n ? setTimeout(() => {\n timedOut = true;\n child.kill('SIGTERM');\n forceKillTimer = setTimeout(() => child.kill('SIGKILL'), 1000);\n }, options.timeoutMs)\n : undefined;\n const finish = (result: CapturedProcessResult): void => {\n if (settled) {\n return;\n }\n settled = true;\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n }\n if (forceKillTimer) {\n clearTimeout(forceKillTimer);\n }\n resolveResult({\n ...result,\n ...(timedOut ? { timedOut: true } : {}),\n ...(inputError ? { inputError } : {}),\n ...(stdoutTruncated || stderrTruncated ? { outputTruncated: true } : {}),\n ...(stdoutTruncated ? { stdoutTruncated: true } : {}),\n ...(stderrTruncated ? { stderrTruncated: true } : {}),\n });\n };\n const appendOutput = (output: string, chunk: string, markTruncated: () => void): string => {\n if (!options.maxOutputBytes) {\n return output + chunk;\n }\n const remaining = options.maxOutputBytes - Buffer.byteLength(output);\n const bytes = Buffer.from(chunk);\n if (remaining <= 0) {\n markTruncated();\n return output;\n }\n if (bytes.length > remaining) {\n markTruncated();\n let end = remaining;\n while (end > 0 && (bytes[end]! & 0b1100_0000) === 0b1000_0000) {\n end -= 1;\n }\n return output + bytes.subarray(0, end).toString('utf8');\n }\n return output + chunk;\n };\n child.stdout.setEncoding('utf8');\n child.stderr.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n stdout = appendOutput(stdout, chunk, () => {\n stdoutTruncated = true;\n });\n });\n child.stderr.on('data', (chunk: string) => {\n stderr = appendOutput(stderr, chunk, () => {\n stderrTruncated = true;\n });\n });\n child.stdin.on('error', (error: NodeJS.ErrnoException) => {\n inputError = error;\n });\n child.once('error', (error: NodeJS.ErrnoException) => {\n finish({\n code: 1,\n stdout,\n stderr,\n error,\n });\n });\n child.once('close', (code, signal) => {\n finish({\n code: timedOut || inputError ? 1 : (code ?? 1),\n stdout,\n stderr,\n ...(signal ? { signal } : {}),\n });\n });\n try {\n if (options.input === undefined) {\n child.stdin.end();\n } else {\n child.stdin.end(options.input);\n }\n } catch (error) {\n inputError = error as NodeJS.ErrnoException;\n child.kill('SIGTERM');\n }\n });\n"],"mappings":"gFAyDA,MAAa,GAA6C,EAAS,EAAM,EAAS,IAChF,IAAI,QAAS,GAAkB,CAC7B,IAAM,EAAQ,EAAM,EAAS,CAAC,GAAG,EAAK,CAAE,CACtC,IAAK,EAAQ,IACb,IAAK,CACH,GAAI,EAAQ,KAAO,EAAQ,QAAQ,IACnC,KAAM,EAAQ,QAAQ,IAAI,KAC1B,SAAU,IACX,CACD,MAAO,OACR,CAAC,CACE,EAAS,GACT,EAAS,GACT,EAAkB,GAClB,EAAkB,GAClB,EAAW,GACX,EACA,EAAU,GACV,EACE,EAAe,EAAQ,UACzB,eAAiB,CACf,EAAW,GACX,EAAM,KAAK,UAAU,CACrB,EAAiB,eAAiB,EAAM,KAAK,UAAU,CAAE,IAAK,EAC7D,EAAQ,UAAU,CACrB,IAAA,GACE,EAAU,GAAwC,CAClD,IAGJ,EAAU,GACN,GACF,aAAa,EAAa,CAExB,GACF,aAAa,EAAe,CAE9B,EAAc,CACZ,GAAG,EACH,GAAI,EAAW,CAAE,SAAU,GAAM,CAAG,EAAE,CACtC,GAAI,EAAa,CAAE,aAAY,CAAG,EAAE,CACpC,GAAI,GAAmB,EAAkB,CAAE,gBAAiB,GAAM,CAAG,EAAE,CACvE,GAAI,EAAkB,CAAE,gBAAiB,GAAM,CAAG,EAAE,CACpD,GAAI,EAAkB,CAAE,gBAAiB,GAAM,CAAG,EAAE,CACrD,CAAC,GAEE,GAAgB,EAAgB,EAAe,IAAsC,CACzF,GAAI,CAAC,EAAQ,eACX,OAAO,EAAS,EAElB,IAAM,EAAY,EAAQ,eAAiB,EAAO,WAAW,EAAO,CAC9D,EAAQ,EAAO,KAAK,EAAM,CAChC,GAAI,GAAa,EAEf,OADA,GAAe,CACR,EAET,GAAI,EAAM,OAAS,EAAW,CAC5B,GAAe,CACf,IAAI,EAAM,EACV,KAAO,EAAM,IAAM,EAAM,GAAQ,MAAiB,KAChD,IAEF,OAAO,EAAS,EAAM,SAAS,EAAG,EAAI,CAAC,SAAS,OAAO,CAEzD,OAAO,EAAS,GAElB,EAAM,OAAO,YAAY,OAAO,CAChC,EAAM,OAAO,YAAY,OAAO,CAChC,EAAM,OAAO,GAAG,OAAS,GAAkB,CACzC,EAAS,EAAa,EAAQ,MAAa,CACzC,EAAkB,IAClB,EACF,CACF,EAAM,OAAO,GAAG,OAAS,GAAkB,CACzC,EAAS,EAAa,EAAQ,MAAa,CACzC,EAAkB,IAClB,EACF,CACF,EAAM,MAAM,GAAG,QAAU,GAAiC,CACxD,EAAa,GACb,CACF,EAAM,KAAK,QAAU,GAAiC,CACpD,EAAO,CACL,KAAM,EACN,SACA,SACA,QACD,CAAC,EACF,CACF,EAAM,KAAK,SAAU,EAAM,IAAW,CACpC,EAAO,CACL,KAAM,GAAY,EAAa,EAAK,GAAQ,EAC5C,SACA,SACA,GAAI,EAAS,CAAE,SAAQ,CAAG,EAAE,CAC7B,CAAC,EACF,CACF,GAAI,CACE,EAAQ,QAAU,IAAA,GACpB,EAAM,MAAM,KAAK,CAEjB,EAAM,MAAM,IAAI,EAAQ,MAAM,OAEzB,EAAO,CACd,EAAa,EACb,EAAM,KAAK,UAAU,GAEvB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./constants-
|
|
2
|
-
//# sourceMappingURL=runOpa-
|
|
1
|
+
import{r as e}from"./constants-BMAOvdcA.mjs";import{spawn as t,spawnSync as n}from"node:child_process";function r(t=n){let r=t(`opa`,[`version`],{stdio:`ignore`});if(r.error||r.status!==0)throw Error(e)}function i(n,r={}){return new Promise((i,a)=>{let o=t(`opa`,n,{cwd:r.cwd,stdio:`inherit`});o.on(`error`,t=>{if(t.code===`ENOENT`){a(Error(e));return}a(t)}),o.on(`close`,e=>i(e??1))})}function a(n,r={}){return new Promise((i,a)=>{let o=t(`opa`,n,{cwd:r.cwd,stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``;o.stdout?.on(`data`,e=>{s+=e.toString()}),o.stderr?.on(`data`,e=>{c+=e.toString()}),o.on(`error`,t=>{if(t.code===`ENOENT`){a(Error(e));return}a(t)}),o.on(`close`,e=>i({code:e??1,stdout:s,stderr:c}))})}export{i as n,r,a as t};
|
|
2
|
+
//# sourceMappingURL=runOpa-CkKAwsvB.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runOpa-
|
|
1
|
+
{"version":3,"file":"runOpa-CkKAwsvB.mjs","names":[],"sources":["../src/commands/policy/helpers/assertOpaInstalled.ts","../src/commands/policy/helpers/runOpa.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\n\nimport { OPA_INSTALL_HINT } from '../constants.js';\n\n/** Options used to suppress output from the availability check. */\ninterface OpaSpawnOptions {\n /** Discard child process output. */\n stdio: 'ignore';\n}\n\n/** Synchronously invokes a command for availability checks. */\ntype SpawnSync = (\n command: string,\n args: string[],\n options: OpaSpawnOptions,\n) => Pick<ReturnType<typeof spawnSync>, 'error' | 'status'>;\n\n/**\n * Ensures the `opa` binary is available on PATH.\n *\n * @param runSpawnSync - Child process runner dependency\n * @throws Error when `opa` is not installed\n */\nexport function assertOpaInstalled(runSpawnSync: SpawnSync = spawnSync): void {\n const result = runSpawnSync('opa', ['version'], { stdio: 'ignore' });\n if (result.error || result.status !== 0) {\n throw new Error(OPA_INSTALL_HINT);\n }\n}\n","import { spawn } from 'node:child_process';\n\nimport { OPA_INSTALL_HINT } from '../constants.js';\n\n/** Result of an OPA CLI invocation with captured output. */\nexport interface RunOpaCaptureResult {\n /** Child process exit code */\n code: number;\n /** Captured stdout */\n stdout: string;\n /** Captured stderr */\n stderr: string;\n}\n\n/**\n * Runs an OPA CLI command and streams stdout/stderr to the current process.\n *\n * @param args - Arguments passed to the `opa` binary\n * @param options - Optional working directory\n * @returns The child process exit code\n */\nexport function runOpa(args: string[], options: { cwd?: string } = {}): Promise<number> {\n return new Promise<number>((resolve, reject) => {\n const child = spawn('opa', args, {\n cwd: options.cwd,\n stdio: 'inherit',\n });\n\n child.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n reject(new Error(OPA_INSTALL_HINT));\n return;\n }\n reject(err);\n });\n child.on('close', (code) => resolve(code ?? 1));\n });\n}\n\n/**\n * Runs an OPA CLI command and captures stdout/stderr.\n *\n * @param args - Arguments passed to the `opa` binary\n * @param options - Optional working directory\n * @returns Exit code and captured output\n */\nexport function runOPACapture(\n args: string[],\n options: { cwd?: string } = {},\n): Promise<RunOpaCaptureResult> {\n return new Promise<RunOpaCaptureResult>((resolve, reject) => {\n const child = spawn('opa', args, {\n cwd: options.cwd,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n child.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n reject(new Error(OPA_INSTALL_HINT));\n return;\n }\n reject(err);\n });\n child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }));\n });\n}\n"],"mappings":"uGAuBA,SAAgB,EAAmB,EAA0B,EAAiB,CAC5E,IAAM,EAAS,EAAa,MAAO,CAAC,UAAU,CAAE,CAAE,MAAO,SAAU,CAAC,CACpE,GAAI,EAAO,OAAS,EAAO,SAAW,EACpC,MAAU,MAAM,EAAiB,CCLrC,SAAgB,EAAO,EAAgB,EAA4B,EAAE,CAAmB,CACtF,OAAO,IAAI,SAAiB,EAAS,IAAW,CAC9C,IAAM,EAAQ,EAAM,MAAO,EAAM,CAC/B,IAAK,EAAQ,IACb,MAAO,UACR,CAAC,CAEF,EAAM,GAAG,QAAU,GAAQ,CACzB,GAAK,EAA8B,OAAS,SAAU,CACpD,EAAW,MAAM,EAAiB,CAAC,CACnC,OAEF,EAAO,EAAI,EACX,CACF,EAAM,GAAG,QAAU,GAAS,EAAQ,GAAQ,EAAE,CAAC,EAC/C,CAUJ,SAAgB,EACd,EACA,EAA4B,EAAE,CACA,CAC9B,OAAO,IAAI,SAA8B,EAAS,IAAW,CAC3D,IAAM,EAAQ,EAAM,MAAO,EAAM,CAC/B,IAAK,EAAQ,IACb,MAAO,CAAC,SAAU,OAAQ,OAAO,CAClC,CAAC,CAEE,EAAS,GACT,EAAS,GAEb,EAAM,QAAQ,GAAG,OAAS,GAAkB,CAC1C,GAAU,EAAM,UAAU,EAC1B,CACF,EAAM,QAAQ,GAAG,OAAS,GAAkB,CAC1C,GAAU,EAAM,UAAU,EAC1B,CAEF,EAAM,GAAG,QAAU,GAAQ,CACzB,GAAK,EAA8B,OAAS,SAAU,CACpD,EAAW,MAAM,EAAiB,CAAC,CACnC,OAEF,EAAO,EAAI,EACX,CACF,EAAM,GAAG,QAAU,GAAS,EAAQ,CAAE,KAAM,GAAQ,EAAG,SAAQ,SAAQ,CAAC,CAAC,EACzE"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import{n as e}from"./scaffold-templates-CsHM1y80.mjs";import{d as t,f as n,h as r,l as i,m as a,n as o,p as s,u as c}from"./deno-runtime-QqwBDKXX.mjs";import{r as l,t as u}from"./manifest-DVuW_vvO.mjs";import{n as d}from"./project-plan-apply-C2DfikVN.mjs";import{basename as f,dirname as p,isAbsolute as m,join as h,relative as g,resolve as _,sep as v}from"node:path";import y from"colors";import{createHash as b}from"node:crypto";import{createTwoFilesPatch as x}from"diff";import{applyEdits as S,createScanner as C,modify as w,parse as T}from"jsonc-parser";var E=`# Project setup and CI
|
|
2
|
+
|
|
3
|
+
## Initialize
|
|
4
|
+
|
|
5
|
+
Run:
|
|
6
|
+
|
|
7
|
+
\`\`\`sh
|
|
8
|
+
transcend custom-functions init
|
|
9
|
+
\`\`\`
|
|
10
|
+
|
|
11
|
+
The default target is \`transcend/custom-functions\`. Interactive setup offers:
|
|
12
|
+
|
|
13
|
+
- \`transcend-functions.yml\`
|
|
14
|
+
- strict, target-scoped Deno configuration and a check task
|
|
15
|
+
- target-scoped VS Code Deno settings and extension recommendation
|
|
16
|
+
- this Agent Skill
|
|
17
|
+
- credential-free GitHub Actions validation
|
|
18
|
+
|
|
19
|
+
Review the complete plan before applying it. Existing JSONC settings and comments should be preserved. Do not overwrite unrelated repository configuration.
|
|
20
|
+
|
|
21
|
+
## Deno
|
|
22
|
+
|
|
23
|
+
Local validation requires Deno 2 (2.4.5 recommended). The generated \`custom-functions:check\` Deno task delegates to the CLI so it runs the same manifest, export, type, lint, and format checks. A different Deno 2 version may produce a production-parity warning; other major versions are unsupported. If Deno is missing or unsupported, direct the developer to the official installation instructions; do not install or switch runtimes without permission.
|
|
24
|
+
|
|
25
|
+
## CI
|
|
26
|
+
|
|
27
|
+
The generated GitHub Actions workflow is a secure reference implementation: it uses read-only repository permissions, pinned actions, a tested Deno 2.4.5 version, a pinned Transcend CLI version, and no Transcend credentials.
|
|
28
|
+
|
|
29
|
+
Adapt it to existing repository conventions instead of creating a parallel CI system. For another CI provider, preserve this validation recipe:
|
|
30
|
+
|
|
31
|
+
1. Trigger when the Custom Function manifest, source, payloads, or Deno configuration changes.
|
|
32
|
+
2. Install Deno 2.
|
|
33
|
+
3. Install a pinned \`@transcend-io/cli\` version.
|
|
34
|
+
4. Run:
|
|
35
|
+
|
|
36
|
+
\`\`\`sh
|
|
37
|
+
transcend custom-functions check "<custom-function-directory>" \\
|
|
38
|
+
--manifest="<manifest-path>" \\
|
|
39
|
+
--noInteractive \\
|
|
40
|
+
--json
|
|
41
|
+
\`\`\`
|
|
42
|
+
|
|
43
|
+
Do not add deployment credentials to validation-only jobs.
|
|
44
|
+
`,ee='# Writing Custom Functions\n\n## Add a function\n\nInitialize the project first, then scaffold a function:\n\n```sh\ntranscend custom-functions new\n```\n\nChoose the smallest matching template:\n\n- `general` for a General Custom Function\n- `dsr-datapoint` for the DSR data-point handler\n- `dsr-enricher` for the DSR request enricher\n- `dsr-both` when both DSR exports are required\n\nInspect the generated source, manifest entry, and payloads before implementing. Keep the generated export shape unless the manifest and fixtures change with it.\n\n## Type contracts\n\nImport `CustomFunction` as a type from `@transcend-io/custom-function-types`:\n\n- General functions default-export a handler using `CustomFunction.GeneralArgument`.\n- DSR data-point functions default-export a handler using `CustomFunction.Argument`.\n- DSR request enrichers export `enricher` using `CustomFunction.EnricherArgument`.\n\nHandlers receive `payload`, `environment`, `sdk`, and `kv`. Use:\n\n- `payload` for trigger data\n- `environment` for configured values\n- `sdk` for Transcend and external HTTP calls\n- `kv` for small persistent strings\n\nCheck `response.ok` for every `sdk.fetch` call. Include the response status and useful response details in failures without exposing secrets.\n\n## Manifest and fixtures\n\n- Use `<<parameters.ENV_NAME>>` placeholders for secret values, matching each placeholder name to its environment key.\n- Add every external network destination to `allowed-hosts`. Transcend SDK routes do not require an allowed-host entry.\n- Set `allow-third-party-imports` only when the implementation needs undeclared third-party modules.\n- Keep each function self-contained in its entry source file. Local runtime imports are not deployed; remote and `npm:` imports follow `allow-third-party-imports`.\n- Keep fixtures minimal but realistic, with at least one case for every implemented export.\n- Match DSR fixtures to `DATA_POINT` and `REQUEST_ENRICHER`. Do not hardcode values such as the data silo identity that the push workflow supplies.\n\n## Run locally\n\nExercise every configured fixture and show `console.log` output:\n\n```sh\ntranscend custom-functions run "<custom-function-directory>" \\\n --function="<function-name>" \\\n --variables=TRANSCEND_API_KEY:placeholder\n```\n\nThe local simulator mirrors Deno permissions, payload preparation, export selection, timeouts, environment isolation, and KV limits. It starts KV empty for each fixture and simulates `sdk.fetch` with a logged HTTP 200 response without making a request. Pass every `<<parameters.name>>` value through `--variables="name:value"`. Native network calls are denied unless the user explicitly passes `--allowNetwork`; those real requests can have side effects. Treat the simulator as a fast development loop, not proof of production behavior.\n\n## Validate and deploy\n\nRun:\n\n```sh\ntranscend custom-functions check "<custom-function-directory>" \\\n --variables=TRANSCEND_API_KEY:placeholder\ntranscend custom-functions push \\\n --file="<custom-function-directory>/transcend-functions.yml" \\\n --auth="$TRANSCEND_API_KEY" \\\n --variables="TRANSCEND_API_KEY:$TRANSCEND_API_KEY" \\\n --dryRun\n```\n\nRun, check, and push require every manifest variable. Placeholder values are sufficient for local validation; pass real secrets only when they are needed for authenticated push tests or deployment. Fix every check failure before pushing. Keep a revision as a draft with `--promote=false`. After the first successful push, use `--updateManifest` to record assigned IDs for stable future matching.\n',D=`---
|
|
45
|
+
name: transcend-custom-functions
|
|
46
|
+
description: Sets up, implements, validates, and deploys Transcend Custom Functions. Use when working with transcend-functions.yml, General or DSR handlers, test payloads, Deno configuration, Custom Function CI, or transcend custom-functions CLI commands.
|
|
47
|
+
compatibility: Requires Deno 2.x (2.4.5 recommended) for local validation and the Transcend CLI.
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
# Transcend Custom Functions
|
|
51
|
+
|
|
52
|
+
Use the CLI for deterministic scaffolding and validation. Use this skill for the repository-specific implementation and integration decisions that remain.
|
|
53
|
+
|
|
54
|
+
## Workflow
|
|
55
|
+
|
|
56
|
+
1. Locate \`transcend-functions.yml\`. The default project is \`transcend/custom-functions\`.
|
|
57
|
+
2. For project setup, Deno, editor support, or CI, read [references/setup.md](references/setup.md).
|
|
58
|
+
3. For handlers, manifest entries, test payloads, validation, or deployment, read [references/writing-custom-functions.md](references/writing-custom-functions.md).
|
|
59
|
+
4. Follow existing repository conventions and preserve unrelated configuration.
|
|
60
|
+
5. Use \`transcend custom-functions run <custom-function-directory>\` while developing, then run \`transcend custom-functions check <custom-function-directory>\` before considering the work complete.
|
|
61
|
+
|
|
62
|
+
## Documentation
|
|
63
|
+
|
|
64
|
+
- Every Transcend CLI command and subcommand provides contextual help with \`transcend <command> --help\`.
|
|
65
|
+
- Use the [Transcend CLI README](https://github.com/transcend-io/tools/tree/main/packages/cli#readme) for command documentation and examples.
|
|
66
|
+
- Use the [Transcend documentation index](https://docs.transcend.io/llms.txt) to find current product documentation.
|
|
67
|
+
|
|
68
|
+
## Guardrails
|
|
69
|
+
|
|
70
|
+
- Never commit credentials. Keep secrets in parameter placeholders and the repository's secret store.
|
|
71
|
+
- Do not invent third-party API endpoints, authentication behavior, or field mappings. Inspect available documentation and existing code; ask for missing requirements.
|
|
72
|
+
- Keep source and test-payload paths relative to the manifest.
|
|
73
|
+
- Custom Functions run on Deno 2.4.5. Avoid Node-only APIs.
|
|
74
|
+
`;const O=`transcend-custom-functions`,k=[{path:`SKILL.md`,contents:D},{path:`references/setup.md`,contents:E},{path:`references/writing-custom-functions.md`,contents:ee}];function A(e){let t=e.hasSkill?`Use the \`${O}\` skill to`:`Ask your coding agent to`,r=`transcend custom-functions check ${n(e.targetDirectory,e.manifestPath)} --noInteractive`;return e.hasGithubWorkflow?`${t} review the Custom Function setup in \`${e.targetDirectory}\`, adapt the generated GitHub Actions workflow to this repository's conventions, and run \`${r}\`.`:`${t} review the Custom Function setup in \`${e.targetDirectory}\` and add equivalent CI for this repository: install Deno 2 and \`@transcend-io/cli@${e.cliVersion}\`, then run \`${r}\`.`}function j(e){let t=e.hasSkill?`Use the \`${O}\` skill to`:`Ask your coding agent to`,i=s(e.variableNames),a=`transcend custom-functions check ${n(e.targetDirectory,e.manifestPath)}${i}`,o=`transcend custom-functions run ${n(e.targetDirectory,e.manifestPath)} --function=${r(e.displayName)}${i}`;return`${t} implement \`${e.displayName}\` in \`${e.sourcePath}\`, replace the example fixtures with realistic cases, run \`${o}\` to exercise it locally, and finish with \`${a}\`.`}function M(e,t){return a(e,t)}function N(e,t){return t.kind===`link`?{kind:`link`,target:`${M(e,t.path)} -> ${t.target}`,description:t.description}:{kind:t.before===null?`create`:`merge`,target:M(e,t.path),description:t.description}}function te(e,t){return{version:e.version,command:e.command,applied:t.applied,dryRun:t.dryRun,targetDirectory:e.targetDirectory,manifestPath:e.manifestPath,changes:e.changes.map(e=>N(t.cwd,e)),warnings:e.warnings,nextSteps:e.nextSteps,aiHandoff:t.aiHandoff}}function ne(e,t){let n=[y.bold(`Custom Function plan`),` ${y.dim(`Target:`)} ${y.cyan(M(t,e.targetDirectory))}`,` ${y.dim(`Manifest:`)} ${y.cyan(M(t,e.manifestPath))}`,``];return e.changes.length===0?n.push(y.dim(`No changes needed.`)):(n.push(y.bold(`Changes`)),e.changes.forEach(e=>{let r=N(t,e),i={create:y.green(r.kind.padEnd(7)),merge:y.cyan(r.kind.padEnd(7)),link:y.magenta(r.kind.padEnd(7))}[r.kind];if(n.push(` ${i} ${r.target}`),e.kind===`file`&&e.before!==null){let r=M(t,e.path),i=x(r,r,e.before,e.after,``,``,{context:3});n.push(...i.trimEnd().split(`
|
|
75
|
+
`).map(e=>` ${e}`))}})),e.unchanged.length>0&&(n.push(``,y.bold(`Left unchanged`)),e.unchanged.forEach(e=>n.push(` ${y.dim(M(t,e))}`))),e.warnings.length>0&&(n.push(``,y.bold(y.yellow(`Warnings`))),e.warnings.forEach(e=>n.push(` ${y.yellow(e)}`))),`${n.join(`
|
|
76
|
+
`)}\n`}function re(e){let{snapshot:t,after:n,description:r,createOnly:i}=e;if(i&&t.contents!==null)throw Error(`Refusing to overwrite existing file: ${t.path}`);if(t.contents!==n)return{kind:`file`,path:t.path,before:t.contents,after:n,description:r,...t.mode===void 0?{}:{mode:t.mode},...i===void 0?{}:{createOnly:i}}}function P(e){return e.replace(/([!*?[\]\\])/gu,`\\$1`)}function ie(e){let t=e.match(/# managed-by: @transcend-io\/cli; content-sha256: ([a-f0-9]{64})\s*$/u);if(!t||t.index===void 0)return!1;let n=e.slice(0,t.index).trimEnd();return b(`sha256`).update(n).digest(`hex`)===t[1]}function ae(e){let{cliVersion:t,targetDirectory:n,manifestPath:r}=e,i=e.contentDirectory??n,a=i===`.`?``:`${P(i.replace(/\/+$/u,``))}/`,s=[`${a}functions/**`,`${a}test-payloads/**`,P(r),`${a}deno.json*`,...(e.watchedPaths??[]).map(P)].filter((e,t,n)=>n.indexOf(e)===t).map(e=>` - ${JSON.stringify(e)}`).join(`
|
|
77
|
+
`),c=`# Generated by transcend custom-functions init.
|
|
78
|
+
name: Transcend Custom Functions
|
|
79
|
+
|
|
80
|
+
on:
|
|
81
|
+
pull_request:
|
|
82
|
+
paths:
|
|
83
|
+
${s}
|
|
84
|
+
push:
|
|
85
|
+
paths:
|
|
86
|
+
${s}
|
|
87
|
+
|
|
88
|
+
permissions:
|
|
89
|
+
contents: read
|
|
90
|
+
|
|
91
|
+
jobs:
|
|
92
|
+
check:
|
|
93
|
+
runs-on: ubuntu-latest
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
96
|
+
- uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5
|
|
97
|
+
with:
|
|
98
|
+
deno-version: ${o}
|
|
99
|
+
- name: Install the Transcend CLI
|
|
100
|
+
run: npm install --global @transcend-io/cli@${t}
|
|
101
|
+
- name: Validate Custom Functions
|
|
102
|
+
env:
|
|
103
|
+
CUSTOM_FUNCTION_DIRECTORY: ${JSON.stringify(n)}
|
|
104
|
+
CUSTOM_FUNCTION_MANIFEST: ${JSON.stringify(r)}
|
|
105
|
+
run: >-
|
|
106
|
+
transcend custom-functions check "$CUSTOM_FUNCTION_DIRECTORY"
|
|
107
|
+
--manifest="$CUSTOM_FUNCTION_MANIFEST"
|
|
108
|
+
--variables=TRANSCEND_API_KEY:placeholder
|
|
109
|
+
--noInteractive
|
|
110
|
+
--json
|
|
111
|
+
`,l=b(`sha256`).update(c.trimEnd()).digest(`hex`);return`${c.trimEnd()}\n\n# managed-by: @transcend-io/cli; content-sha256: ${l}\n`}const F={CloseBraceToken:2,CloseBracketToken:4,LineCommentTrivia:12,BlockCommentTrivia:13,LineBreakTrivia:14,Trivia:15,EOF:17};function I(e,t){let n=[],r=T(e,n,{allowTrailingComma:!0,disallowComments:!1});if(n.length>0||typeof r!=`object`||!r||Array.isArray(r))throw Error(`Cannot safely merge ${t}; fix its JSONC syntax or apply the patch manually.`);return r}function L(e){let t=e.match(/\n([ \t]+)"/)?.[1]??` `;return{tabSize:t.includes(` `)?1:t.length,insertSpaces:!t.includes(` `),eol:e.includes(`\r
|
|
112
|
+
`)?`\r
|
|
113
|
+
`:`
|
|
114
|
+
`}}function R(e){let t=C(e,!1),n=[],r=t.scan();for(;r!==F.EOF;)(r===F.LineCommentTrivia||r===F.BlockCommentTrivia)&&n.push(e.slice(t.getTokenOffset(),t.getTokenOffset()+t.getTokenLength())),r=t.scan();return n}function z(e){let t=C(e,!1),n=-1,r=t.scan();for(;r!==F.EOF;){if(r===F.LineCommentTrivia){let e=n===t.getTokenStartLine(),i=t.scan();for(;i===F.Trivia||i===F.LineBreakTrivia||i===F.LineCommentTrivia||i===F.BlockCommentTrivia;)i=t.scan();if(e&&(i===F.CloseBraceToken||i===F.CloseBracketToken))return!0;r=i;continue}r!==F.Trivia&&r!==F.LineBreakTrivia&&r!==F.BlockCommentTrivia&&(n=t.getTokenStartLine()),r=t.scan()}return!1}function B(e,t,n){let r=e??`{}
|
|
115
|
+
`;if(I(r,n),e!==null&&z(e))throw Error(`Cannot prove comment-preserving edits for ${n}; apply the displayed patch manually.`);let i=R(r),a=L(r);t.forEach(({path:e,value:t})=>{r=S(r,w(r,e,t,{formattingOptions:{...a,insertFinalNewline:!0,keepLines:!0}}))});let o=R(r);if(i.length!==o.length||i.some((e,t)=>o[t]!==e))throw Error(`A comment would move or disappear in ${n}; apply the patch manually.`);return I(r,n),r.endsWith(a.eol)?r:`${r}${a.eol}`}function V(e,t){let n=Array.isArray(e)?e.filter(e=>typeof e==`string`):[];return[...n,...t.filter(e=>!n.includes(e))]}function H(e,t,r=`transcend-functions.yml`,i={}){let a=I(e??`{}
|
|
116
|
+
`,`Deno configuration`),o=a.compilerOptions&&typeof a.compilerOptions==`object`&&!Array.isArray(a.compilerOptions)?a.compilerOptions:{},s=a.lint&&typeof a.lint==`object`&&!Array.isArray(a.lint)?a.lint:{},c=a.fmt&&typeof a.fmt==`object`&&!Array.isArray(a.fmt)?a.fmt:{},l=a.tasks&&typeof a.tasks==`object`&&!Array.isArray(a.tasks)?a.tasks:{},u=`custom-functions:check`,d=`transcend custom-functions check ${n(`.`,r)} --noInteractive`,f=`transcend custom-functions check ${n(`.`,r)} --variables=TRANSCEND_API_KEY:placeholder --noInteractive`;if(l[u]!==void 0&&l[u]!==`deno check functions/**/*.ts && deno lint functions/ && deno fmt --check functions/ test-payloads/`&&l[u]!==d&&l[u]!==f)throw Error(`Deno task "${u}" already has a different command; apply the patch manually.`);return B(e,[{path:[`imports`,`@transcend-io/custom-function-types`],value:`npm:@transcend-io/custom-function-types@${t}`},{path:[`compilerOptions`,`strict`],value:!0},{path:[`compilerOptions`,`lib`],value:V(o.lib,[`deno.ns`,`dom`,`dom.iterable`,`esnext`])},{path:[`lint`,`include`],value:V(s.include,[`functions/`,...i.sources??[]])},{path:[`fmt`,`include`],value:V(c.include,[`functions/`,`test-payloads/`,r,...i.sources??[],...i.payloads??[]])},{path:[`fmt`,`singleQuote`],value:!0},{path:[`fmt`,`lineWidth`],value:100},{path:[`tasks`,u],value:f}],`Deno configuration`)}function U(e,t,n){let r=I(e??`{}
|
|
117
|
+
`,`editor settings`),i=g(t,n).split(v).join(`/`)||`.`;return B(e,[{path:[`deno.enable`],value:!0},{path:[`deno.enablePaths`],value:V(r[`deno.enablePaths`],[i])}],`editor settings`)}function W(e){return B(e,[{path:[`recommendations`],value:V(I(e??`{}
|
|
118
|
+
`,`editor extension recommendations`).recommendations,[`denoland.vscode-deno`])}],`editor extension recommendations`)}function G(e){let t=JSON.stringify(e)??``;return[...new Set(Array.from(t.matchAll(/<<parameters\.([^>]+)>>/gu),e=>e[1]))]}function K(e){return e.projectRoot}function q(e,n){let r=K(e),i=new Set([e.manifestPath]),a=new Set(n.features);if(a.has(d.Deno)&&i.add(e.denoConfigPath),a.has(d.Editor)&&(i.add(h(r,`.vscode`,`settings.json`)),i.add(h(r,`.vscode`,`extensions.json`))),a.has(d.Skill)){let n=t(e.existingSkillDirectories);k.forEach(({path:e})=>{i.add(h(r,n.canonical,O,e))}),n.aliases.forEach(e=>{let t=h(r,e,O);i.add(t),k.forEach(({path:e})=>{i.add(h(t,e))})}),e.existingSkillDirectories.forEach(({path:e})=>{k.forEach(({path:t})=>{i.add(h(r,e,O,t))})})}return a.has(d.Ci)&&i.add(h(r,`.github`,`workflows`,`transcend-custom-functions.yml`)),[...i].sort((e,t)=>e.localeCompare(t))}function oe(e,t){return[e.manifestPath,h(e.manifestDirectory,t.sourceFile.path),...t.payloadFiles.map(t=>h(e.manifestDirectory,t.path))].sort((e,t)=>e.localeCompare(t))}function J(e,t){let n=e.snapshots[t];if(!n)throw Error(`Missing preflight snapshot for ${t}`);return n}function Y(e,t){let n=J(e,t);if(n.kind===`directory`||n.kind===`link`)throw Error(`Expected a regular file or absent path: ${t}`);return n.kind===`file`?{path:t,contents:n.contents,mode:n.mode}:{path:t,contents:null}}function X(e,t){let n=g(e,t);if(n===`..`||n.startsWith(`..${v}`)||m(n))throw Error(`Refusing to modify path outside project root: ${t}`)}function Z(e,t){let n=K(e);X(e.targetDirectory,e.manifestPath),t.forEach(e=>X(n,e));let r=new Map(e.relativePaths.map(e=>[e.toLocaleLowerCase(`en-US`),e]));t.forEach(t=>{let n=g(e.manifestDirectory,t).split(v).join(`/`);if(n.startsWith(`../`))return;let i=n.split(`/`);for(let e=1;e<=i.length;e+=1){let t=i.slice(0,e).join(`/`),n=r.get(t.toLocaleLowerCase(`en-US`));if(n&&n!==t)throw Error(`Case-insensitive path collision: "${t}" conflicts with "${n}".`)}})}function Q(e,t,n){let r=re({snapshot:Y(t,n.path),after:n.contents,description:n.description,...n.createOnly===void 0?{}:{createOnly:n.createOnly}});r?e.changes.push(r):e.unchanged.push(n.path)}function se(e,n){let r=K(n.state),a=t(n.state.existingSkillDirectories),o=h(r,a.canonical,O),s=k.map(e=>({path:e.path,contents:i(e.contents,`@transcend-io/cli`)})),l=(t,r)=>{s.forEach(i=>{let a=h(t,i.path),o=Y(n,a);if(o.contents!==null&&o.contents!==i.contents&&!c(o.contents,`@transcend-io/cli`))throw Error(`Refusing to replace user-managed skill: ${a}. Apply the skill update manually.`);Q(e,n,{path:a,contents:i.contents,description:`${r}: ${i.path}`})})};l(o,`Install Custom Function skill file`),a.aliases.forEach(t=>{let i=h(r,t,O),a=J(n,i),c=g(p(i),o);if(a.kind===`link`&&a.target===c){e.unchanged.push(i);return}if(a.kind===`directory`){l(i,`Update Custom Function skill copy in ${t}`);return}if(a.kind!==`absent`)throw Error(`Refusing to replace unexpected skill target: ${i}`);let u={kind:`link`,path:i,target:c,fallbackFiles:s,description:`Expose the canonical skill in ${t}`};e.changes.push(u)}),n.state.existingSkillDirectories.map(({path:e})=>e).filter(e=>e!==a.canonical&&!a.aliases.includes(e)).forEach(t=>{let i=h(r,t,O),a=Y(n,h(i,`SKILL.md`));a.contents!==null&&c(a.contents,`@transcend-io/cli`)?l(i,`Update existing managed skill in ${t}`):a.contents?.includes(`managed-by: @transcend-io/cli`)&&(e.unchanged.push(h(i,`SKILL.md`)),e.warnings.push(`Existing customized managed skill was left unchanged: ${i}`))})}function ce(e,t){let{state:r}=e,i=n(r.targetDirectory,r.manifestPath,r.invocationDirectory),a={version:1,command:`init`,rootDirectory:K(r),targetDirectory:r.targetDirectory,manifestPath:r.manifestPath,changes:[],unchanged:[],warnings:[],nextSteps:[`transcend custom-functions new ${i}`,`transcend custom-functions check ${i}`]},o=Y(e,r.manifestPath),s=o.contents===null?void 0:l(o.contents);o.contents===null?Q(a,e,{path:r.manifestPath,contents:`# Custom Functions managed as code.
|
|
119
|
+
functions: []
|
|
120
|
+
`,description:`Create the Custom Function manifest`}):a.unchanged.push(r.manifestPath);let c=new Set(t.features);if(c.has(d.Deno)){let t=Y(e,r.denoConfigPath),n=(s?.functions??[]).map(({code:e})=>e).filter(e=>!e.includes(`<<parameters.`)),i=(s?.functions??[]).flatMap(e=>[...e[`test-payload`]?[e[`test-payload`]]:[],...(e[`test-payloads`]??[]).map(({payload:e})=>e)]).filter(e=>!e.includes(`<<parameters.`));Q(a,e,{path:r.denoConfigPath,contents:H(t.contents,e.contractVersion,f(r.manifestPath),{sources:n,payloads:i}),description:`Merge strict target-scoped Deno authoring configuration`})}let u=K(r);if(c.has(d.Editor)){let t=h(u,`.vscode`,`settings.json`),n=h(u,`.vscode`,`extensions.json`),i=Y(e,t),o=Y(e,n);Q(a,e,{path:t,contents:U(i.contents,u,r.targetDirectory),description:`Scope Deno language support to Custom Functions`}),Q(a,e,{path:n,contents:W(o.contents),description:`Recommend the Deno editor extension`})}if(c.has(d.Skill)&&se(a,e),c.has(d.Ci))if(!r.repositoryRoot||!r.usesGithub)a.warnings.push(`GitHub Actions setup was selected, but this target is not inside a detected GitHub repository.`);else{let t=h(r.repositoryRoot,`.github`,`workflows`,`transcend-custom-functions.yml`),n=g(r.repositoryRoot,r.targetDirectory).split(v).join(`/`)||`.`,i=g(r.repositoryRoot,r.manifestDirectory).split(v).join(`/`)||`.`,o=g(r.repositoryRoot,r.manifestPath).split(v).join(`/`),c=(s?.functions??[]).flatMap(e=>[e.code,...e[`test-payload`]?[e[`test-payload`]]:[],...(e[`test-payloads`]??[]).map(({payload:e})=>e)]).filter(e=>!e.includes(`<<parameters.`)).map(e=>g(r.repositoryRoot,_(r.manifestDirectory,e)).split(v).join(`/`)),l=ae({cliVersion:e.cliVersion,targetDirectory:n,contentDirectory:i,manifestPath:o,watchedPaths:c}),u=Y(e,t);u.contents===null?Q(a,e,{path:t,contents:l,description:`Add credential-free Custom Function checks`,createOnly:!0}):u.contents===l?a.unchanged.push(t):ie(u.contents)?Q(a,e,{path:t,contents:l,description:`Update managed Custom Function checks`}):(a.unchanged.push(t),a.warnings.push(`Existing GitHub Actions workflow was left unchanged: ${t}`))}return Z(r,a.changes.map(({path:e})=>e)),a}function le(e,t){let{state:i}=e,o=Y(e,i.manifestPath).contents;if(o===null)throw Error(`Custom Function manifest does not exist: ${i.manifestPath}`);let c=t.generated.sourceFile.path.split(v).join(`/`),d=i.relativePaths.find(e=>e.toLocaleLowerCase(`en-US`)===c.toLocaleLowerCase(`en-US`));if(d)throw Error(`Custom Function name "${t.generated.displayName}" maps to ${c}, which conflicts with existing path ${d}. Choose another name.`);let f=l(o).functions.find(e=>_(i.manifestDirectory,e.code)===_(i.manifestDirectory,c));if(f)throw Error(`Custom Function name "${t.generated.displayName}" maps to source used by "${f.name}". Choose another name.`);let p={version:1,command:`new`,rootDirectory:i.manifestDirectory,targetDirectory:i.targetDirectory,manifestPath:i.manifestPath,changes:[],unchanged:[],warnings:[],nextSteps:[]},m=u(o,t.generated.manifestEntry);Q(p,e,{path:i.manifestPath,contents:m,description:`Register ${t.generated.displayName} in the manifest`}),[t.generated.sourceFile,...t.generated.payloadFiles].forEach(n=>{Q(p,e,{path:h(i.manifestDirectory,n.path),contents:n.contents,description:n===t.generated.sourceFile?`Create ${t.generated.displayName} source`:`Create ${t.generated.displayName} test payload`,createOnly:!0})});let g=h(i.manifestDirectory,t.generated.sourceFile.path),y=n(i.targetDirectory,i.manifestPath,i.invocationDirectory),b=G(t.generated.manifestEntry),x=s(b);return p.nextSteps=[`Edit ${r(a(i.invocationDirectory,g))}`,`transcend custom-functions run ${y} --function=${r(t.generated.displayName)}${x}`,`transcend custom-functions check ${y}${x}`,`transcend custom-functions push --file=${r(a(i.invocationDirectory,i.manifestPath))} --dryRun${x}`],b.length>0&&p.warnings.push(`Supply ${b.join(`, `)} through --variables when running or pushing; never commit secret values.`),Z(i,p.changes.map(({path:e})=>e)),p}function $(t,n){return e(t,n)}export{G as a,M as c,j as d,O as f,q as i,ne as l,ce as n,$ as o,oe as r,te as s,le as t,A as u};
|
|
121
|
+
//# sourceMappingURL=scaffold-planning-DMACXSnX.mjs.map
|