@transcend-io/cli 10.27.4 → 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.
Files changed (409) hide show
  1. package/README.md +193 -24
  2. package/dist/app-DCY8E776.mjs +148 -0
  3. package/dist/app-DCY8E776.mjs.map +1 -0
  4. package/dist/{approvePrivacyRequests-QMPJYI3X.mjs → approvePrivacyRequests-80SV_94y.mjs} +2 -2
  5. package/dist/{approvePrivacyRequests-QMPJYI3X.mjs.map → approvePrivacyRequests-80SV_94y.mjs.map} +1 -1
  6. package/dist/bin/bash-complete.mjs +1 -1
  7. package/dist/bin/cli.mjs +1 -1
  8. package/dist/bin/cli.mjs.map +1 -1
  9. package/dist/bin/deprecated-command.mjs +3 -3
  10. package/dist/bin/deprecated-command.mjs.map +1 -1
  11. package/dist/{buildExamples-BkyOPD_E.mjs → buildExamples-2YDkSvtA.mjs} +2 -2
  12. package/dist/{buildExamples-BkyOPD_E.mjs.map → buildExamples-2YDkSvtA.mjs.map} +1 -1
  13. package/dist/{buildXdiSyncEndpoint-5HFin8GM.mjs → buildXdiSyncEndpoint-B3zUrI16.mjs} +2 -2
  14. package/dist/{buildXdiSyncEndpoint-5HFin8GM.mjs.map → buildXdiSyncEndpoint-B3zUrI16.mjs.map} +1 -1
  15. package/dist/{bulkRestartRequests-CYTUjpuK.mjs → bulkRestartRequests-BLb8OJmf.mjs} +2 -2
  16. package/dist/{bulkRestartRequests-CYTUjpuK.mjs.map → bulkRestartRequests-BLb8OJmf.mjs.map} +1 -1
  17. package/dist/{bulkRetryEnrichers-xpffnBsW.mjs → bulkRetryEnrichers-BA9cboSe.mjs} +2 -2
  18. package/dist/{bulkRetryEnrichers-xpffnBsW.mjs.map → bulkRetryEnrichers-BA9cboSe.mjs.map} +1 -1
  19. package/dist/{cancelPrivacyRequests-B-QuIjkC.mjs → cancelPrivacyRequests-BEyOBJ2r.mjs} +2 -2
  20. package/dist/{cancelPrivacyRequests-B-QuIjkC.mjs.map → cancelPrivacyRequests-BEyOBJ2r.mjs.map} +1 -1
  21. package/dist/{codecs-DJFlZLGT.mjs → codecs-BsQFAFGT.mjs} +1 -1
  22. package/dist/{codecs-DJFlZLGT.mjs.map → codecs-BsQFAFGT.mjs.map} +1 -1
  23. package/dist/collectCsvFilesOrExit-BqnmK63h.mjs +2 -0
  24. package/dist/collectCsvFilesOrExit-BqnmK63h.mjs.map +1 -0
  25. package/dist/collectParquetFilesOrExit-BiksFI-Q.mjs +2 -0
  26. package/dist/collectParquetFilesOrExit-BiksFI-Q.mjs.map +1 -0
  27. package/dist/{command-_zwStiyM.mjs → command-eIenZMOx.mjs} +2 -2
  28. package/dist/{command-_zwStiyM.mjs.map → command-eIenZMOx.mjs.map} +1 -1
  29. package/dist/commands/admin/chunk-csv/worker.mjs +1 -1
  30. package/dist/commands/admin/parquet-to-csv/worker.mjs +1 -1
  31. package/dist/consentManagersToBusinessEntities-O4KBox9u.mjs +2 -0
  32. package/dist/consentManagersToBusinessEntities-O4KBox9u.mjs.map +1 -0
  33. package/dist/{constants-DyD22MtN.mjs → constants-BG53Mbi9.mjs} +2 -2
  34. package/dist/{constants-DyD22MtN.mjs.map → constants-BG53Mbi9.mjs.map} +1 -1
  35. package/dist/{constants-FbK2iR--.mjs → constants-BMAOvdcA.mjs} +1 -1
  36. package/dist/{constants-FbK2iR--.mjs.map → constants-BMAOvdcA.mjs.map} +1 -1
  37. package/dist/{constants-BgCEW975.mjs → constants-BpQ5awGp.mjs} +2 -2
  38. package/dist/{constants-BgCEW975.mjs.map → constants-BpQ5awGp.mjs.map} +1 -1
  39. package/dist/{constants-C9xZJ9YW.mjs → constants-C1seVfCu.mjs} +1 -1
  40. package/dist/{constants-C9xZJ9YW.mjs.map → constants-C1seVfCu.mjs.map} +1 -1
  41. package/dist/context-CZYrQfAn.mjs +2 -0
  42. package/dist/context-CZYrQfAn.mjs.map +1 -0
  43. package/dist/createPoolingCommandUi-C39R_zo3.mjs +14 -0
  44. package/dist/createPoolingCommandUi-C39R_zo3.mjs.map +1 -0
  45. package/dist/{dataFlowsToDataSilos-DRuAfwIn.mjs → dataFlowsToDataSilos-CLSHb1GA.mjs} +1 -1
  46. package/dist/{dataFlowsToDataSilos-DRuAfwIn.mjs.map → dataFlowsToDataSilos-CLSHb1GA.mjs.map} +1 -1
  47. package/dist/deno-runtime-QqwBDKXX.mjs +2 -0
  48. package/dist/deno-runtime-QqwBDKXX.mjs.map +1 -0
  49. package/dist/done-input-validation-Cjk7a3jX.mjs +2 -0
  50. package/dist/done-input-validation-Cjk7a3jX.mjs.map +1 -0
  51. package/dist/{downloadPrivacyRequestFiles-W5pXxfeu.mjs → downloadPrivacyRequestFiles-CLFgQItk.mjs} +2 -2
  52. package/dist/{downloadPrivacyRequestFiles-W5pXxfeu.mjs.map → downloadPrivacyRequestFiles-CLFgQItk.mjs.map} +1 -1
  53. package/dist/{extractClientError-X9wJVqGq.mjs → extractClientError-C_6ly7Gw.mjs} +1 -1
  54. package/dist/{extractClientError-X9wJVqGq.mjs.map → extractClientError-C_6ly7Gw.mjs.map} +1 -1
  55. package/dist/{fetchAllRequests-DP24WqrP.mjs → fetchAllRequests-CEDKdq0c.mjs} +2 -2
  56. package/dist/{fetchAllRequests-DP24WqrP.mjs.map → fetchAllRequests-CEDKdq0c.mjs.map} +1 -1
  57. package/dist/{formatPolicyBundleVersionSummary-Bo7DYxoy.mjs → formatPolicyBundleVersionSummary-CrFtcPwS.mjs} +1 -1
  58. package/dist/{formatPolicyBundleVersionSummary-Bo7DYxoy.mjs.map → formatPolicyBundleVersionSummary-CrFtcPwS.mjs.map} +1 -1
  59. package/dist/{fuzzyMatchColumns-C1STZ_T1.mjs → fuzzyMatchColumns-OTsFJ21f.mjs} +2 -2
  60. package/dist/{fuzzyMatchColumns-C1STZ_T1.mjs.map → fuzzyMatchColumns-OTsFJ21f.mjs.map} +1 -1
  61. package/dist/{generateCrossAccountApiKeys-BTuoFxxy.mjs → generateCrossAccountApiKeys-D6O_Qm3Y.mjs} +2 -2
  62. package/dist/{generateCrossAccountApiKeys-BTuoFxxy.mjs.map → generateCrossAccountApiKeys-D6O_Qm3Y.mjs.map} +1 -1
  63. package/dist/impl-6m7GXUAe.mjs +2 -0
  64. package/dist/impl-6m7GXUAe.mjs.map +1 -0
  65. package/dist/impl-B--lr5RJ2.mjs +2 -0
  66. package/dist/impl-B--lr5RJ2.mjs.map +1 -0
  67. package/dist/impl-B3_hrFPX.mjs +3 -0
  68. package/dist/impl-B3_hrFPX.mjs.map +1 -0
  69. package/dist/impl-BFJtKA2o2.mjs +2 -0
  70. package/dist/{impl-DOoJoSO22.mjs.map → impl-BFJtKA2o2.mjs.map} +1 -1
  71. package/dist/{impl-DSE-RmED.mjs → impl-BJlKQJdS2.mjs} +2 -2
  72. package/dist/impl-BJlKQJdS2.mjs.map +1 -0
  73. package/dist/impl-BNPgYSBT.mjs +3 -0
  74. package/dist/impl-BNPgYSBT.mjs.map +1 -0
  75. package/dist/impl-BWVe4VGF2.mjs +2 -0
  76. package/dist/{impl-D8FcLfAL2.mjs.map → impl-BWVe4VGF2.mjs.map} +1 -1
  77. package/dist/impl-BYGNx-8W2.mjs +2 -0
  78. package/dist/impl-BYGNx-8W2.mjs.map +1 -0
  79. package/dist/impl-BcJ019T2.mjs +2 -0
  80. package/dist/impl-BcJ019T2.mjs.map +1 -0
  81. package/dist/{impl-C2Irk48l.mjs → impl-BewF8tB6.mjs} +2 -2
  82. package/dist/{impl-C2Irk48l.mjs.map → impl-BewF8tB6.mjs.map} +1 -1
  83. package/dist/impl-Bq6g_xYv.mjs +2 -0
  84. package/dist/impl-Bq6g_xYv.mjs.map +1 -0
  85. package/dist/impl-BqrSLoig.mjs +2 -0
  86. package/dist/impl-BqrSLoig.mjs.map +1 -0
  87. package/dist/impl-Bs-drNBf.mjs +12 -0
  88. package/dist/impl-Bs-drNBf.mjs.map +1 -0
  89. package/dist/impl-BsC1KVxS.mjs +2 -0
  90. package/dist/impl-BsC1KVxS.mjs.map +1 -0
  91. package/dist/impl-BvNZqLrT.mjs +3 -0
  92. package/dist/impl-BvNZqLrT.mjs.map +1 -0
  93. package/dist/{impl-CIncREux.mjs → impl-BwRcpAno.mjs} +2 -2
  94. package/dist/impl-BwRcpAno.mjs.map +1 -0
  95. package/dist/impl-BySmbxEt.mjs +3 -0
  96. package/dist/impl-BySmbxEt.mjs.map +1 -0
  97. package/dist/impl-C50tdWlL2.mjs +2 -0
  98. package/dist/{impl-q66XVeBW2.mjs.map → impl-C50tdWlL2.mjs.map} +1 -1
  99. package/dist/impl-C5dzaDga2.mjs +2 -0
  100. package/dist/{impl-jVkU5ZQe2.mjs.map → impl-C5dzaDga2.mjs.map} +1 -1
  101. package/dist/impl-C8BmxFQ2.mjs +2 -0
  102. package/dist/impl-C8BmxFQ2.mjs.map +1 -0
  103. package/dist/impl-CDtUusmg.mjs +2 -0
  104. package/dist/impl-CDtUusmg.mjs.map +1 -0
  105. package/dist/impl-CE56-wQh.mjs +2 -0
  106. package/dist/{impl-CFB9lqIN.mjs.map → impl-CE56-wQh.mjs.map} +1 -1
  107. package/dist/impl-CEmXPEq22.mjs +2 -0
  108. package/dist/impl-CEmXPEq22.mjs.map +1 -0
  109. package/dist/impl-CHmjV-Pa.mjs +2 -0
  110. package/dist/impl-CHmjV-Pa.mjs.map +1 -0
  111. package/dist/impl-CQGeH47F.mjs +2 -0
  112. package/dist/impl-CQGeH47F.mjs.map +1 -0
  113. package/dist/impl-CTIWliTx.mjs +2 -0
  114. package/dist/impl-CTIWliTx.mjs.map +1 -0
  115. package/dist/impl-CWh9H7mL.mjs +2 -0
  116. package/dist/impl-CWh9H7mL.mjs.map +1 -0
  117. package/dist/impl-CXUJ1eRC.mjs +2 -0
  118. package/dist/impl-CXUJ1eRC.mjs.map +1 -0
  119. package/dist/impl-CfPXYgT42.mjs +2 -0
  120. package/dist/impl-CfPXYgT42.mjs.map +1 -0
  121. package/dist/impl-CiYKuCHV.mjs +2 -0
  122. package/dist/impl-CiYKuCHV.mjs.map +1 -0
  123. package/dist/impl-CqF9xIIy.mjs +3 -0
  124. package/dist/impl-CqF9xIIy.mjs.map +1 -0
  125. package/dist/impl-Cx3T0Iei.mjs +2 -0
  126. package/dist/impl-Cx3T0Iei.mjs.map +1 -0
  127. package/dist/impl-CzxvoiGW.mjs +3 -0
  128. package/dist/impl-CzxvoiGW.mjs.map +1 -0
  129. package/dist/impl-D-SQJc3t.mjs +2 -0
  130. package/dist/impl-D-SQJc3t.mjs.map +1 -0
  131. package/dist/impl-D23kJPAQ2.mjs +3 -0
  132. package/dist/{impl-CNzXdBVG2.mjs.map → impl-D23kJPAQ2.mjs.map} +1 -1
  133. package/dist/impl-DF8RGVlT.mjs +2 -0
  134. package/dist/impl-DF8RGVlT.mjs.map +1 -0
  135. package/dist/impl-DHfYO9T52.mjs +2 -0
  136. package/dist/impl-DHfYO9T52.mjs.map +1 -0
  137. package/dist/impl-DIPvFKiP.mjs +2 -0
  138. package/dist/impl-DIPvFKiP.mjs.map +1 -0
  139. package/dist/impl-DJLlcqSg.mjs +5 -0
  140. package/dist/impl-DJLlcqSg.mjs.map +1 -0
  141. package/dist/impl-DOoR93T6.mjs +2 -0
  142. package/dist/impl-DOoR93T6.mjs.map +1 -0
  143. package/dist/impl-DXNcD7CZ.mjs +2 -0
  144. package/dist/impl-DXNcD7CZ.mjs.map +1 -0
  145. package/dist/impl-DYf10-BD2.mjs +2 -0
  146. package/dist/impl-DYf10-BD2.mjs.map +1 -0
  147. package/dist/impl-DYwojWvN.mjs +2 -0
  148. package/dist/impl-DYwojWvN.mjs.map +1 -0
  149. package/dist/impl-DbZ1cYoR.mjs +2 -0
  150. package/dist/impl-DbZ1cYoR.mjs.map +1 -0
  151. package/dist/impl-Dib6Fff12.mjs +2 -0
  152. package/dist/{impl-BRm1_RUu2.mjs.map → impl-Dib6Fff12.mjs.map} +1 -1
  153. package/dist/impl-Dk6TZKrp2.mjs +2 -0
  154. package/dist/impl-Dk6TZKrp2.mjs.map +1 -0
  155. package/dist/impl-Dm-Fkr392.mjs +2 -0
  156. package/dist/impl-Dm-Fkr392.mjs.map +1 -0
  157. package/dist/impl-DpuhHpuk.mjs +7 -0
  158. package/dist/{impl-DvSnW_IA.mjs.map → impl-DpuhHpuk.mjs.map} +1 -1
  159. package/dist/impl-Drql0g72.mjs +2 -0
  160. package/dist/impl-Drql0g72.mjs.map +1 -0
  161. package/dist/impl-DzNk41xd.mjs +5 -0
  162. package/dist/impl-DzNk41xd.mjs.map +1 -0
  163. package/dist/impl-FLj_mWLO.mjs +2 -0
  164. package/dist/impl-FLj_mWLO.mjs.map +1 -0
  165. package/dist/impl-GHukPBnk.mjs +2 -0
  166. package/dist/impl-GHukPBnk.mjs.map +1 -0
  167. package/dist/impl-KKrDTraf.mjs +2 -0
  168. package/dist/impl-KKrDTraf.mjs.map +1 -0
  169. package/dist/impl-M3Eu4QjS.mjs +2 -0
  170. package/dist/impl-M3Eu4QjS.mjs.map +1 -0
  171. package/dist/{impl-Ca064LmU.mjs → impl-VPBEqV0w2.mjs} +3 -3
  172. package/dist/impl-VPBEqV0w2.mjs.map +1 -0
  173. package/dist/impl-amV0wRWk.mjs +2 -0
  174. package/dist/{impl-BtLxw8E7.mjs.map → impl-amV0wRWk.mjs.map} +1 -1
  175. package/dist/impl-m3QXCc6n.mjs +91 -0
  176. package/dist/impl-m3QXCc6n.mjs.map +1 -0
  177. package/dist/impl-syp5hclX.mjs +2 -0
  178. package/dist/impl-syp5hclX.mjs.map +1 -0
  179. package/dist/impl-zZFaSmxd2.mjs +2 -0
  180. package/dist/impl-zZFaSmxd2.mjs.map +1 -0
  181. package/dist/index.d.mts +79 -15
  182. package/dist/index.d.mts.map +1 -1
  183. package/dist/index.mjs +3 -3
  184. package/dist/index.mjs.map +1 -1
  185. package/dist/initializeCliRuntime-802-P8MC.mjs +2 -0
  186. package/dist/initializeCliRuntime-802-P8MC.mjs.map +1 -0
  187. package/dist/{inquirer-B0OF_nRe.mjs → inquirer-DkFTQU00.mjs} +2 -2
  188. package/dist/{inquirer-B0OF_nRe.mjs.map → inquirer-DkFTQU00.mjs.map} +1 -1
  189. package/dist/listFiles-CWHAdKY-.mjs +2 -0
  190. package/dist/listFiles-CWHAdKY-.mjs.map +1 -0
  191. package/dist/logger-9T6vva73.mjs +2 -0
  192. package/dist/logger-9T6vva73.mjs.map +1 -0
  193. package/dist/manifest-DVuW_vvO.mjs +2 -0
  194. package/dist/manifest-DVuW_vvO.mjs.map +1 -0
  195. package/dist/mapConsentCsvRowsToInputs-MMPZwzrV.mjs +2 -0
  196. package/dist/mapConsentCsvRowsToInputs-MMPZwzrV.mjs.map +1 -0
  197. package/dist/{markRequestDataSiloIdsCompleted-CcJGKOn4.mjs → markRequestDataSiloIdsCompleted-PKCcn5wQ.mjs} +2 -2
  198. package/dist/{markRequestDataSiloIdsCompleted-CcJGKOn4.mjs.map → markRequestDataSiloIdsCompleted-PKCcn5wQ.mjs.map} +1 -1
  199. package/dist/{markSilentPrivacyRequests-CVxwueuH.mjs → markSilentPrivacyRequests-7l9I99pe.mjs} +2 -2
  200. package/dist/{markSilentPrivacyRequests-CVxwueuH.mjs.map → markSilentPrivacyRequests-7l9I99pe.mjs.map} +1 -1
  201. package/dist/{mergeTranscendInputs-DjPe49yR.mjs → mergeTranscendInputs-CWHXH0kF.mjs} +2 -2
  202. package/dist/{mergeTranscendInputs-DjPe49yR.mjs.map → mergeTranscendInputs-CWHXH0kF.mjs.map} +1 -1
  203. package/dist/missing-manifest-BKj1j-jg.mjs +2 -0
  204. package/dist/missing-manifest-BKj1j-jg.mjs.map +1 -0
  205. package/dist/module-graph-DBC7ZvyA.mjs +2 -0
  206. package/dist/module-graph-DBC7ZvyA.mjs.map +1 -0
  207. package/dist/{notifyPrivacyRequestsAdditionalTime-D1gLyndO.mjs → notifyPrivacyRequestsAdditionalTime-BPIYuCov.mjs} +2 -2
  208. package/dist/{notifyPrivacyRequestsAdditionalTime-D1gLyndO.mjs.map → notifyPrivacyRequestsAdditionalTime-BPIYuCov.mjs.map} +1 -1
  209. package/dist/{parquetToCsvOneFile-0O4iLz0t.mjs → parquetToCsvOneFile-CSVdrLvq.mjs} +2 -2
  210. package/dist/{parquetToCsvOneFile-0O4iLz0t.mjs.map → parquetToCsvOneFile-CSVdrLvq.mjs.map} +1 -1
  211. package/dist/{parseAttributesFromString-CYcxsS3n.mjs → parseAttributesFromString-C5-KGkPH.mjs} +2 -2
  212. package/dist/{parseAttributesFromString-CYcxsS3n.mjs.map → parseAttributesFromString-C5-KGkPH.mjs.map} +1 -1
  213. package/dist/parseVariablesFromString-Cr3x2uq3.mjs +2 -0
  214. package/dist/parseVariablesFromString-Cr3x2uq3.mjs.map +1 -0
  215. package/dist/{policyEngineCliError-BnBghLd1.mjs → policyEngineCliError-DY8V-qkK.mjs} +1 -1
  216. package/dist/{policyEngineCliError-BnBghLd1.mjs.map → policyEngineCliError-DY8V-qkK.mjs.map} +1 -1
  217. package/dist/{printResult-oXnpZu_9.mjs → printResult-esxW3HhT.mjs} +2 -2
  218. package/dist/{printResult-oXnpZu_9.mjs.map → printResult-esxW3HhT.mjs.map} +1 -1
  219. package/dist/project-plan-apply-C2DfikVN.mjs +3 -0
  220. package/dist/project-plan-apply-C2DfikVN.mjs.map +1 -0
  221. package/dist/{pullAllDatapoints-DJno8LkB.mjs → pullAllDatapoints-H92qjLSx.mjs} +2 -2
  222. package/dist/{pullAllDatapoints-DJno8LkB.mjs.map → pullAllDatapoints-H92qjLSx.mjs.map} +1 -1
  223. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-BCblZfOb.mjs → pullChunkedCustomSiloOutstandingIdentifiers-BrDmPbvc.mjs} +2 -2
  224. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-BCblZfOb.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-BrDmPbvc.mjs.map} +1 -1
  225. package/dist/{pullConsentManagerMetrics-C41UhU8u.mjs → pullConsentManagerMetrics-Cvex-gpd.mjs} +2 -2
  226. package/dist/{pullConsentManagerMetrics-C41UhU8u.mjs.map → pullConsentManagerMetrics-Cvex-gpd.mjs.map} +1 -1
  227. package/dist/{pullManualEnrichmentIdentifiersToCsv-BYjAq9G5.mjs → pullManualEnrichmentIdentifiersToCsv-qjdNA75O.mjs} +2 -2
  228. package/dist/{pullManualEnrichmentIdentifiersToCsv-BYjAq9G5.mjs.map → pullManualEnrichmentIdentifiersToCsv-qjdNA75O.mjs.map} +1 -1
  229. package/dist/{pullTranscendConfiguration-DbRVLKq5.mjs → pullTranscendConfiguration-CD7Frn8z.mjs} +2 -2
  230. package/dist/{pullTranscendConfiguration-DbRVLKq5.mjs.map → pullTranscendConfiguration-CD7Frn8z.mjs.map} +1 -1
  231. package/dist/{pullUnstructuredSubDataPointRecommendations-B9xIDPf2.mjs → pullUnstructuredSubDataPointRecommendations-Dmh_-r95.mjs} +2 -2
  232. package/dist/{pullUnstructuredSubDataPointRecommendations-B9xIDPf2.mjs.map → pullUnstructuredSubDataPointRecommendations-Dmh_-r95.mjs.map} +1 -1
  233. package/dist/pushCronIdentifiersFromCsv-DjeY7TtK.mjs +2 -0
  234. package/dist/{pushCronIdentifiersFromCsv-DIZF-QXC.mjs.map → pushCronIdentifiersFromCsv-DjeY7TtK.mjs.map} +1 -1
  235. package/dist/pushManualEnrichmentIdentifiersFromCsv-BDtMo13j.mjs +2 -0
  236. package/dist/{pushManualEnrichmentIdentifiersFromCsv-Ch5-jHbY.mjs.map → pushManualEnrichmentIdentifiersFromCsv-BDtMo13j.mjs.map} +1 -1
  237. package/dist/readCsv-Cr_1t8F5.mjs +2 -0
  238. package/dist/readCsv-Cr_1t8F5.mjs.map +1 -0
  239. package/dist/readTranscendYaml-STYnRzq-.mjs +4 -0
  240. package/dist/readTranscendYaml-STYnRzq-.mjs.map +1 -0
  241. package/dist/{removeUnverifiedRequestIdentifiers-CHupDNvu.mjs → removeUnverifiedRequestIdentifiers-B9uPApVR.mjs} +2 -2
  242. package/dist/{removeUnverifiedRequestIdentifiers-CHupDNvu.mjs.map → removeUnverifiedRequestIdentifiers-B9uPApVR.mjs.map} +1 -1
  243. package/dist/{renderTable-DKXvortp.mjs → renderTable-DKTZbMjY.mjs} +1 -1
  244. package/dist/{renderTable-DKXvortp.mjs.map → renderTable-DKTZbMjY.mjs.map} +1 -1
  245. package/dist/{request-BIplTb3L.mjs → request-B1yRTdG-.mjs} +1 -1
  246. package/dist/{request-BIplTb3L.mjs.map → request-B1yRTdG-.mjs.map} +1 -1
  247. package/dist/{resolveBundleIdByName-By5Vl8Iz.mjs → resolveBundleIdByName-DuxWYrDF.mjs} +2 -2
  248. package/dist/{resolveBundleIdByName-By5Vl8Iz.mjs.map → resolveBundleIdByName-DuxWYrDF.mjs.map} +1 -1
  249. package/dist/{resolvePolicyBundleVersion-DO7IvEwb.mjs → resolvePolicyBundleVersion-DhXZKwb4.mjs} +2 -2
  250. package/dist/{resolvePolicyBundleVersion-DO7IvEwb.mjs.map → resolvePolicyBundleVersion-DhXZKwb4.mjs.map} +1 -1
  251. package/dist/{retryRequestDataSilos-DlAldSyR.mjs → retryRequestDataSilos-D9dBtbdl.mjs} +2 -2
  252. package/dist/{retryRequestDataSilos-DlAldSyR.mjs.map → retryRequestDataSilos-D9dBtbdl.mjs.map} +1 -1
  253. package/dist/run-captured-process-CpZBh0lG.mjs +2 -0
  254. package/dist/run-captured-process-CpZBh0lG.mjs.map +1 -0
  255. package/dist/runOpa-CkKAwsvB.mjs +2 -0
  256. package/dist/runOpa-CkKAwsvB.mjs.map +1 -0
  257. package/dist/scaffold-planning-DMACXSnX.mjs +121 -0
  258. package/dist/scaffold-planning-DMACXSnX.mjs.map +1 -0
  259. package/dist/scaffold-templates-CsHM1y80.mjs +84 -0
  260. package/dist/scaffold-templates-CsHM1y80.mjs.map +1 -0
  261. package/dist/{skipPreflightJobs-C4trcphf.mjs → skipPreflightJobs-Beia_iB6.mjs} +2 -2
  262. package/dist/{skipPreflightJobs-C4trcphf.mjs.map → skipPreflightJobs-Beia_iB6.mjs.map} +1 -1
  263. package/dist/{skipRequestDataSilos-D6babS9E.mjs → skipRequestDataSilos-BSNLacnR.mjs} +2 -2
  264. package/dist/{skipRequestDataSilos-D6babS9E.mjs.map → skipRequestDataSilos-BSNLacnR.mjs.map} +1 -1
  265. package/dist/{streamPrivacyRequestsToCsv-CMzC_73c.mjs → streamPrivacyRequestsToCsv-Cksb9D49.mjs} +2 -2
  266. package/dist/{streamPrivacyRequestsToCsv-CMzC_73c.mjs.map → streamPrivacyRequestsToCsv-Cksb9D49.mjs.map} +1 -1
  267. package/dist/{syncCodePackages-Dhm5jI6B.mjs → syncCodePackages-DsC1tE8B.mjs} +2 -2
  268. package/dist/{syncCodePackages-Dhm5jI6B.mjs.map → syncCodePackages-DsC1tE8B.mjs.map} +1 -1
  269. package/dist/{updateConsentManagerVersionToLatest-CFYnN3Gk.mjs → updateConsentManagerVersionToLatest-CaEkTnlL.mjs} +2 -2
  270. package/dist/{updateConsentManagerVersionToLatest-CFYnN3Gk.mjs.map → updateConsentManagerVersionToLatest-CaEkTnlL.mjs.map} +1 -1
  271. package/dist/{uploadConsents-C5sG51Dk.mjs → uploadConsents-CNyuYx0o.mjs} +2 -2
  272. package/dist/{uploadConsents-C5sG51Dk.mjs.map → uploadConsents-CNyuYx0o.mjs.map} +1 -1
  273. package/dist/{uploadPrivacyRequestsFromCsv-BnzI39-b.mjs → uploadPrivacyRequestsFromCsv-BdTQOZnF.mjs} +2 -2
  274. package/dist/{uploadPrivacyRequestsFromCsv-BnzI39-b.mjs.map → uploadPrivacyRequestsFromCsv-BdTQOZnF.mjs.map} +1 -1
  275. package/dist/validateTranscendAuth-CnHMn77m.mjs +2 -0
  276. package/dist/validateTranscendAuth-CnHMn77m.mjs.map +1 -0
  277. package/dist/{writeCsv-DMw5OmWp.mjs → writeCsv-D46aDkGf.mjs} +1 -1
  278. package/dist/{writeCsv-DMw5OmWp.mjs.map → writeCsv-D46aDkGf.mjs.map} +1 -1
  279. package/package.json +11 -6
  280. package/dist/app-9G6prJ34.mjs +0 -148
  281. package/dist/app-9G6prJ34.mjs.map +0 -1
  282. package/dist/collectCsvFilesOrExit-BPo8Mjy7.mjs +0 -2
  283. package/dist/collectCsvFilesOrExit-BPo8Mjy7.mjs.map +0 -1
  284. package/dist/collectParquetFilesOrExit-DVS9_OSv.mjs +0 -2
  285. package/dist/collectParquetFilesOrExit-DVS9_OSv.mjs.map +0 -1
  286. package/dist/consentManagersToBusinessEntities-rf8_xu71.mjs +0 -5
  287. package/dist/consentManagersToBusinessEntities-rf8_xu71.mjs.map +0 -1
  288. package/dist/context-Br0NHHOk.mjs +0 -2
  289. package/dist/context-Br0NHHOk.mjs.map +0 -1
  290. package/dist/createExtraKeyHandler-DSN5zA2f.mjs +0 -14
  291. package/dist/createExtraKeyHandler-DSN5zA2f.mjs.map +0 -1
  292. package/dist/done-input-validation-DL31vk7g.mjs +0 -2
  293. package/dist/done-input-validation-DL31vk7g.mjs.map +0 -1
  294. package/dist/impl-4BsLrbMs.mjs +0 -2
  295. package/dist/impl-4BsLrbMs.mjs.map +0 -1
  296. package/dist/impl-7pxeoDZg.mjs +0 -5
  297. package/dist/impl-7pxeoDZg.mjs.map +0 -1
  298. package/dist/impl-8VwlDfF2.mjs +0 -2
  299. package/dist/impl-8VwlDfF2.mjs.map +0 -1
  300. package/dist/impl-8wGX5Vf32.mjs +0 -2
  301. package/dist/impl-8wGX5Vf32.mjs.map +0 -1
  302. package/dist/impl-93xjb93p.mjs +0 -2
  303. package/dist/impl-93xjb93p.mjs.map +0 -1
  304. package/dist/impl-B2eZGemA.mjs +0 -2
  305. package/dist/impl-B2eZGemA.mjs.map +0 -1
  306. package/dist/impl-B6butj0_2.mjs +0 -2
  307. package/dist/impl-B6butj0_2.mjs.map +0 -1
  308. package/dist/impl-BRm1_RUu2.mjs +0 -2
  309. package/dist/impl-BauzMfVC2.mjs +0 -2
  310. package/dist/impl-BauzMfVC2.mjs.map +0 -1
  311. package/dist/impl-BmQR1Pae.mjs +0 -3
  312. package/dist/impl-BmQR1Pae.mjs.map +0 -1
  313. package/dist/impl-BnzPrDmM.mjs +0 -2
  314. package/dist/impl-BnzPrDmM.mjs.map +0 -1
  315. package/dist/impl-BohgbWOH.mjs +0 -2
  316. package/dist/impl-BohgbWOH.mjs.map +0 -1
  317. package/dist/impl-BqTimIMI.mjs +0 -2
  318. package/dist/impl-BqTimIMI.mjs.map +0 -1
  319. package/dist/impl-BtLxw8E7.mjs +0 -2
  320. package/dist/impl-BtiWdLEm2.mjs +0 -2
  321. package/dist/impl-BtiWdLEm2.mjs.map +0 -1
  322. package/dist/impl-Bur_bNXN.mjs +0 -2
  323. package/dist/impl-Bur_bNXN.mjs.map +0 -1
  324. package/dist/impl-BwuWn3TM.mjs +0 -2
  325. package/dist/impl-BwuWn3TM.mjs.map +0 -1
  326. package/dist/impl-BxQE7dL92.mjs +0 -2
  327. package/dist/impl-BxQE7dL92.mjs.map +0 -1
  328. package/dist/impl-BygKSE0s2.mjs +0 -2
  329. package/dist/impl-BygKSE0s2.mjs.map +0 -1
  330. package/dist/impl-C3f_H_77.mjs +0 -3
  331. package/dist/impl-C3f_H_77.mjs.map +0 -1
  332. package/dist/impl-CDQ82oJL2.mjs +0 -2
  333. package/dist/impl-CDQ82oJL2.mjs.map +0 -1
  334. package/dist/impl-CFB9lqIN.mjs +0 -2
  335. package/dist/impl-CIncREux.mjs.map +0 -1
  336. package/dist/impl-CMpVsG1a.mjs +0 -2
  337. package/dist/impl-CMpVsG1a.mjs.map +0 -1
  338. package/dist/impl-CNzXdBVG2.mjs +0 -3
  339. package/dist/impl-CZG9gzzR.mjs +0 -3
  340. package/dist/impl-CZG9gzzR.mjs.map +0 -1
  341. package/dist/impl-Ca064LmU.mjs.map +0 -1
  342. package/dist/impl-CaiSz_JT2.mjs +0 -2
  343. package/dist/impl-CaiSz_JT2.mjs.map +0 -1
  344. package/dist/impl-ChP6AAtL.mjs +0 -3
  345. package/dist/impl-ChP6AAtL.mjs.map +0 -1
  346. package/dist/impl-Chska4J8.mjs +0 -3
  347. package/dist/impl-Chska4J8.mjs.map +0 -1
  348. package/dist/impl-CkoQHhc8.mjs +0 -12
  349. package/dist/impl-CkoQHhc8.mjs.map +0 -1
  350. package/dist/impl-Cl3hf0Pd.mjs +0 -2
  351. package/dist/impl-Cl3hf0Pd.mjs.map +0 -1
  352. package/dist/impl-Cm5zP_mL2.mjs +0 -2
  353. package/dist/impl-Cm5zP_mL2.mjs.map +0 -1
  354. package/dist/impl-CnrK11Gr2.mjs +0 -2
  355. package/dist/impl-CnrK11Gr2.mjs.map +0 -1
  356. package/dist/impl-D0-ioxpZ.mjs +0 -2
  357. package/dist/impl-D0-ioxpZ.mjs.map +0 -1
  358. package/dist/impl-D8FcLfAL2.mjs +0 -2
  359. package/dist/impl-DBK5c6d0.mjs +0 -2
  360. package/dist/impl-DBK5c6d0.mjs.map +0 -1
  361. package/dist/impl-DBny72kx2.mjs +0 -2
  362. package/dist/impl-DBny72kx2.mjs.map +0 -1
  363. package/dist/impl-DLWhxaMi.mjs +0 -2
  364. package/dist/impl-DLWhxaMi.mjs.map +0 -1
  365. package/dist/impl-DMMWwLyN2.mjs +0 -2
  366. package/dist/impl-DMMWwLyN2.mjs.map +0 -1
  367. package/dist/impl-DOoJoSO22.mjs +0 -2
  368. package/dist/impl-DSE-RmED.mjs.map +0 -1
  369. package/dist/impl-DTaYnwjN.mjs +0 -2
  370. package/dist/impl-DTaYnwjN.mjs.map +0 -1
  371. package/dist/impl-DUn2j-1O.mjs +0 -2
  372. package/dist/impl-DUn2j-1O.mjs.map +0 -1
  373. package/dist/impl-DVjCdEx9.mjs +0 -2
  374. package/dist/impl-DVjCdEx9.mjs.map +0 -1
  375. package/dist/impl-DmODS2cY.mjs +0 -2
  376. package/dist/impl-DmODS2cY.mjs.map +0 -1
  377. package/dist/impl-DoJDjUsd2.mjs +0 -2
  378. package/dist/impl-DoJDjUsd2.mjs.map +0 -1
  379. package/dist/impl-DvSnW_IA.mjs +0 -7
  380. package/dist/impl-HNBTIl1R.mjs +0 -2
  381. package/dist/impl-HNBTIl1R.mjs.map +0 -1
  382. package/dist/impl-W7FHn0mS.mjs +0 -2
  383. package/dist/impl-W7FHn0mS.mjs.map +0 -1
  384. package/dist/impl-Xrph1kvG2.mjs +0 -2
  385. package/dist/impl-Xrph1kvG2.mjs.map +0 -1
  386. package/dist/impl-jVkU5ZQe2.mjs +0 -2
  387. package/dist/impl-q66XVeBW2.mjs +0 -2
  388. package/dist/impl-xIb20rTt.mjs +0 -2
  389. package/dist/impl-xIb20rTt.mjs.map +0 -1
  390. package/dist/listFiles-C5kubvdN.mjs +0 -2
  391. package/dist/listFiles-C5kubvdN.mjs.map +0 -1
  392. package/dist/logger-Ckep4QXn.mjs +0 -2
  393. package/dist/logger-Ckep4QXn.mjs.map +0 -1
  394. package/dist/parseVariablesFromString-B4TUkJRF.mjs +0 -2
  395. package/dist/parseVariablesFromString-B4TUkJRF.mjs.map +0 -1
  396. package/dist/pushCronIdentifiersFromCsv-DIZF-QXC.mjs +0 -2
  397. package/dist/pushManualEnrichmentIdentifiersFromCsv-Ch5-jHbY.mjs +0 -2
  398. package/dist/readCsv--FfP8n-H.mjs +0 -2
  399. package/dist/readCsv--FfP8n-H.mjs.map +0 -1
  400. package/dist/readTranscendYaml-bL1qFPqv.mjs +0 -4
  401. package/dist/readTranscendYaml-bL1qFPqv.mjs.map +0 -1
  402. package/dist/runOpa-D511z37u.mjs +0 -2
  403. package/dist/runOpa-D511z37u.mjs.map +0 -1
  404. package/dist/uploadCookiesFromCsv-BgrbBl1Y.mjs +0 -2
  405. package/dist/uploadCookiesFromCsv-BgrbBl1Y.mjs.map +0 -1
  406. package/dist/uploadDataFlowsFromCsv-CJMs2KA1.mjs +0 -2
  407. package/dist/uploadDataFlowsFromCsv-CJMs2KA1.mjs.map +0 -1
  408. package/dist/validateTranscendAuth-CAO5ktnu.mjs +0 -2
  409. package/dist/validateTranscendAuth-CAO5ktnu.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"generateCrossAccountApiKeys-BTuoFxxy.mjs","names":[],"sources":["../src/lib/api-keys/generateCrossAccountApiKeys.ts"],"sourcesContent":["import { ScopeName } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClientGeneric,\n loginUser,\n createApiKey,\n fetchAllApiKeys,\n deleteApiKey,\n assumeRole,\n} from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { StoredApiKey } from '../../codecs.js';\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\n\nexport interface ApiKeyGenerateError {\n /** Name of instance */\n organizationName: string;\n /** Error */\n error: string;\n /** Organization ID API key is for */\n organizationId: string;\n}\n\n/**\n * Generate API keys across multiple transcend accounts\n *\n * @param options - Options\n * @returns Number of API keys created\n */\nexport async function generateCrossAccountApiKeys({\n email,\n password,\n scopes,\n apiKeyTitle,\n parentOrganizationId,\n deleteExistingApiKey = true,\n createNewApiKey = true,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** Email address of user generating API keys */\n email: string;\n /** Password of user generating API keys */\n password: string;\n /** Filter for organizations that match this parent organization ID */\n parentOrganizationId?: string;\n /** Title of the API create to create */\n apiKeyTitle: string;\n /** Title of the API create to create */\n scopes: ScopeName[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** When true delete existing API keys with that title, if set to false an API key exists with that title, an error is thrown */\n deleteExistingApiKey?: boolean;\n /** When true, generate new API keys, otherwise only will delete past API keys */\n createNewApiKey?: boolean;\n}): Promise<{\n /** Successfully generated */\n apiKeys: StoredApiKey[];\n /** Error results */\n errors: ApiKeyGenerateError[];\n}> {\n // Create GraphQL client\n const client = await buildTranscendGraphQLClientGeneric(transcendUrl, {});\n\n // Login the user\n logger.info(colors.magenta('Logging in using email and password.'));\n const { roles, loginCookie } = await loginUser(client, { email, password, logger });\n logger.info(\n colors.green(\n `Successfully logged in and found ${roles.length} role${roles.length === 1 ? '' : 's'}!`,\n ),\n );\n\n // Filter down by parentOrganizationId\n const filteredRoles = parentOrganizationId\n ? roles.filter(\n (role) =>\n role.organization.id === parentOrganizationId ||\n role.organization.parentOrganizationId === parentOrganizationId,\n )\n : roles;\n\n // Save cookie to call route subsequent times\n client.setHeaders({\n Cookie: loginCookie,\n });\n\n // Save the resulting API keys\n const results: StoredApiKey[] = [];\n const errors: ApiKeyGenerateError[] = [];\n\n // Generate API keys\n logger.info(\n colors.magenta(`Generating API keys with title: ${apiKeyTitle}, scopes: ${scopes.join(',')}.`),\n );\n\n // Map over each role\n await mapSeries(filteredRoles, async (role) => {\n try {\n // Log into the other instance\n await assumeRole(client, { roleId: role.id, email, logger });\n\n // Grab API keys with that title\n logger.info(\n colors.magenta(\n `Checking if API key already exists in organization \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n\n // Delete existing API key\n const [apiKeyWithTitle] = await fetchAllApiKeys(client, {\n logger,\n filterBy: { titles: [apiKeyTitle] },\n });\n if (apiKeyWithTitle && deleteExistingApiKey) {\n logger.info(\n colors.yellow(\n `Deleting existing API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n await deleteApiKey(client, { id: apiKeyWithTitle.id, logger });\n logger.info(\n colors.green(\n `Successfully deleted API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n } else if (apiKeyWithTitle) {\n // throw error if one exists but not configured to delete\n throw new Error(`API key already exists with title: \"${apiKeyTitle}\"`);\n }\n\n // Create the API key\n if (createNewApiKey) {\n logger.info(\n colors.magenta(\n `Creating API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n const { apiKey } = await createApiKey(client, {\n input: { title: apiKeyTitle, scopes },\n logger,\n });\n results.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n apiKey,\n });\n logger.info(\n colors.green(\n `Successfully created API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n } else {\n // Delete only\n results.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n apiKey: '',\n });\n }\n } catch (err) {\n logger.error(\n colors.red(\n `Failed to create API key in organization \"${role.organization.name}\"! - ${err.message}`,\n ),\n );\n errors.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n error: err.message,\n });\n }\n });\n logger.info(\n colors.green(\n `Successfully created ${results.length} API key${results.length === 1 ? '' : 's'}`,\n ),\n );\n\n if (errors.length > 0) {\n logger.error(\n colors.red(`Failed to create ${errors.length} API key${errors.length === 1 ? '' : 's'}!`),\n );\n }\n\n return { errors, apiKeys: results };\n}\n"],"mappings":"uTA+BA,eAAsB,EAA4B,CAChD,QACA,WACA,SACA,cACA,uBACA,uBAAuB,GACvB,kBAAkB,GAClB,eAAe,GAuBd,CAED,IAAM,EAAS,MAAM,EAAmC,EAAc,EAAE,CAAC,CAGzE,EAAO,KAAK,EAAO,QAAQ,uCAAuC,CAAC,CACnE,GAAM,CAAE,QAAO,eAAgB,MAAM,EAAU,EAAQ,CAAE,QAAO,WAAU,SAAQ,CAAC,CACnF,EAAO,KACL,EAAO,MACL,oCAAoC,EAAM,OAAO,OAAO,EAAM,SAAW,EAAI,GAAK,IAAI,GACvF,CACF,CAGD,IAAM,EAAgB,EAClB,EAAM,OACH,GACC,EAAK,aAAa,KAAO,GACzB,EAAK,aAAa,uBAAyB,EAC9C,CACD,EAGJ,EAAO,WAAW,CAChB,OAAQ,EACT,CAAC,CAGF,IAAM,EAA0B,EAAE,CAC5B,EAAgC,EAAE,CAgGxC,OA7FA,EAAO,KACL,EAAO,QAAQ,mCAAmC,EAAY,YAAY,EAAO,KAAK,IAAI,CAAC,GAAG,CAC/F,CAGD,MAAM,EAAU,EAAe,KAAO,IAAS,CAC7C,GAAI,CAEF,MAAM,EAAW,EAAQ,CAAE,OAAQ,EAAK,GAAI,QAAO,SAAQ,CAAC,CAG5D,EAAO,KACL,EAAO,QACL,uDAAuD,EAAK,aAAa,KAAK,iBAAiB,EAAY,IAC5G,CACF,CAGD,GAAM,CAAC,GAAmB,MAAM,EAAgB,EAAQ,CACtD,SACA,SAAU,CAAE,OAAQ,CAAC,EAAY,CAAE,CACpC,CAAC,CACF,GAAI,GAAmB,EACrB,EAAO,KACL,EAAO,OACL,iCAAiC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACtF,CACF,CACD,MAAM,EAAa,EAAQ,CAAE,GAAI,EAAgB,GAAI,SAAQ,CAAC,CAC9D,EAAO,KACL,EAAO,MACL,oCAAoC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACzF,CACF,SACQ,EAET,MAAU,MAAM,uCAAuC,EAAY,GAAG,CAIxE,GAAI,EAAiB,CACnB,EAAO,KACL,EAAO,QACL,wBAAwB,EAAK,aAAa,KAAK,iBAAiB,EAAY,IAC7E,CACF,CACD,GAAM,CAAE,UAAW,MAAM,EAAa,EAAQ,CAC5C,MAAO,CAAE,MAAO,EAAa,SAAQ,CACrC,SACD,CAAC,CACF,EAAQ,KAAK,CACX,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,SACD,CAAC,CACF,EAAO,KACL,EAAO,MACL,oCAAoC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACzF,CACF,MAGD,EAAQ,KAAK,CACX,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,OAAQ,GACT,CAAC,OAEG,EAAK,CACZ,EAAO,MACL,EAAO,IACL,6CAA6C,EAAK,aAAa,KAAK,OAAO,EAAI,UAChF,CACF,CACD,EAAO,KAAK,CACV,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,MAAO,EAAI,QACZ,CAAC,GAEJ,CACF,EAAO,KACL,EAAO,MACL,wBAAwB,EAAQ,OAAO,UAAU,EAAQ,SAAW,EAAI,GAAK,MAC9E,CACF,CAEG,EAAO,OAAS,GAClB,EAAO,MACL,EAAO,IAAI,oBAAoB,EAAO,OAAO,UAAU,EAAO,SAAW,EAAI,GAAK,IAAI,GAAG,CAC1F,CAGI,CAAE,SAAQ,QAAS,EAAS"}
1
+ {"version":3,"file":"generateCrossAccountApiKeys-D6O_Qm3Y.mjs","names":[],"sources":["../src/lib/api-keys/generateCrossAccountApiKeys.ts"],"sourcesContent":["import { ScopeName } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClientGeneric,\n loginUser,\n createApiKey,\n fetchAllApiKeys,\n deleteApiKey,\n assumeRole,\n} from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { StoredApiKey } from '../../codecs.js';\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\n\nexport interface ApiKeyGenerateError {\n /** Name of instance */\n organizationName: string;\n /** Error */\n error: string;\n /** Organization ID API key is for */\n organizationId: string;\n}\n\n/**\n * Generate API keys across multiple transcend accounts\n *\n * @param options - Options\n * @returns Number of API keys created\n */\nexport async function generateCrossAccountApiKeys({\n email,\n password,\n scopes,\n apiKeyTitle,\n parentOrganizationId,\n deleteExistingApiKey = true,\n createNewApiKey = true,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** Email address of user generating API keys */\n email: string;\n /** Password of user generating API keys */\n password: string;\n /** Filter for organizations that match this parent organization ID */\n parentOrganizationId?: string;\n /** Title of the API create to create */\n apiKeyTitle: string;\n /** Title of the API create to create */\n scopes: ScopeName[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** When true delete existing API keys with that title, if set to false an API key exists with that title, an error is thrown */\n deleteExistingApiKey?: boolean;\n /** When true, generate new API keys, otherwise only will delete past API keys */\n createNewApiKey?: boolean;\n}): Promise<{\n /** Successfully generated */\n apiKeys: StoredApiKey[];\n /** Error results */\n errors: ApiKeyGenerateError[];\n}> {\n // Create GraphQL client\n const client = await buildTranscendGraphQLClientGeneric(transcendUrl, {});\n\n // Login the user\n logger.info(colors.magenta('Logging in using email and password.'));\n const { roles, loginCookie } = await loginUser(client, { email, password, logger });\n logger.info(\n colors.green(\n `Successfully logged in and found ${roles.length} role${roles.length === 1 ? '' : 's'}!`,\n ),\n );\n\n // Filter down by parentOrganizationId\n const filteredRoles = parentOrganizationId\n ? roles.filter(\n (role) =>\n role.organization.id === parentOrganizationId ||\n role.organization.parentOrganizationId === parentOrganizationId,\n )\n : roles;\n\n // Save cookie to call route subsequent times\n client.setHeaders({\n Cookie: loginCookie,\n });\n\n // Save the resulting API keys\n const results: StoredApiKey[] = [];\n const errors: ApiKeyGenerateError[] = [];\n\n // Generate API keys\n logger.info(\n colors.magenta(`Generating API keys with title: ${apiKeyTitle}, scopes: ${scopes.join(',')}.`),\n );\n\n // Map over each role\n await mapSeries(filteredRoles, async (role) => {\n try {\n // Log into the other instance\n await assumeRole(client, { roleId: role.id, email, logger });\n\n // Grab API keys with that title\n logger.info(\n colors.magenta(\n `Checking if API key already exists in organization \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n\n // Delete existing API key\n const [apiKeyWithTitle] = await fetchAllApiKeys(client, {\n logger,\n filterBy: { titles: [apiKeyTitle] },\n });\n if (apiKeyWithTitle && deleteExistingApiKey) {\n logger.info(\n colors.yellow(\n `Deleting existing API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n await deleteApiKey(client, { id: apiKeyWithTitle.id, logger });\n logger.info(\n colors.green(\n `Successfully deleted API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n } else if (apiKeyWithTitle) {\n // throw error if one exists but not configured to delete\n throw new Error(`API key already exists with title: \"${apiKeyTitle}\"`);\n }\n\n // Create the API key\n if (createNewApiKey) {\n logger.info(\n colors.magenta(\n `Creating API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n const { apiKey } = await createApiKey(client, {\n input: { title: apiKeyTitle, scopes },\n logger,\n });\n results.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n apiKey,\n });\n logger.info(\n colors.green(\n `Successfully created API key in \"${role.organization.name}\" with title: \"${apiKeyTitle}\".`,\n ),\n );\n } else {\n // Delete only\n results.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n apiKey: '',\n });\n }\n } catch (err) {\n logger.error(\n colors.red(\n `Failed to create API key in organization \"${role.organization.name}\"! - ${err.message}`,\n ),\n );\n errors.push({\n organizationName: role.organization.name,\n organizationId: role.organization.id,\n error: err.message,\n });\n }\n });\n logger.info(\n colors.green(\n `Successfully created ${results.length} API key${results.length === 1 ? '' : 's'}`,\n ),\n );\n\n if (errors.length > 0) {\n logger.error(\n colors.red(`Failed to create ${errors.length} API key${errors.length === 1 ? '' : 's'}!`),\n );\n }\n\n return { errors, apiKeys: results };\n}\n"],"mappings":"uTA+BA,eAAsB,EAA4B,CAChD,QACA,WACA,SACA,cACA,uBACA,uBAAuB,GACvB,kBAAkB,GAClB,eAAe,GAuBd,CAED,IAAM,EAAS,MAAM,EAAmC,EAAc,EAAE,CAAC,CAGzE,EAAO,KAAK,EAAO,QAAQ,uCAAuC,CAAC,CACnE,GAAM,CAAE,QAAO,eAAgB,MAAM,EAAU,EAAQ,CAAE,QAAO,WAAU,SAAQ,CAAC,CACnF,EAAO,KACL,EAAO,MACL,oCAAoC,EAAM,OAAO,OAAO,EAAM,SAAW,EAAI,GAAK,IAAI,GACvF,CACF,CAGD,IAAM,EAAgB,EAClB,EAAM,OACH,GACC,EAAK,aAAa,KAAO,GACzB,EAAK,aAAa,uBAAyB,EAC9C,CACD,EAGJ,EAAO,WAAW,CAChB,OAAQ,EACT,CAAC,CAGF,IAAM,EAA0B,EAAE,CAC5B,EAAgC,EAAE,CAgGxC,OA7FA,EAAO,KACL,EAAO,QAAQ,mCAAmC,EAAY,YAAY,EAAO,KAAK,IAAI,CAAC,GAAG,CAC/F,CAGD,MAAM,EAAU,EAAe,KAAO,IAAS,CAC7C,GAAI,CAEF,MAAM,EAAW,EAAQ,CAAE,OAAQ,EAAK,GAAI,QAAO,SAAQ,CAAC,CAG5D,EAAO,KACL,EAAO,QACL,uDAAuD,EAAK,aAAa,KAAK,iBAAiB,EAAY,IAC5G,CACF,CAGD,GAAM,CAAC,GAAmB,MAAM,EAAgB,EAAQ,CACtD,SACA,SAAU,CAAE,OAAQ,CAAC,EAAY,CAAE,CACpC,CAAC,CACF,GAAI,GAAmB,EACrB,EAAO,KACL,EAAO,OACL,iCAAiC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACtF,CACF,CACD,MAAM,EAAa,EAAQ,CAAE,GAAI,EAAgB,GAAI,SAAQ,CAAC,CAC9D,EAAO,KACL,EAAO,MACL,oCAAoC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACzF,CACF,SACQ,EAET,MAAU,MAAM,uCAAuC,EAAY,GAAG,CAIxE,GAAI,EAAiB,CACnB,EAAO,KACL,EAAO,QACL,wBAAwB,EAAK,aAAa,KAAK,iBAAiB,EAAY,IAC7E,CACF,CACD,GAAM,CAAE,UAAW,MAAM,EAAa,EAAQ,CAC5C,MAAO,CAAE,MAAO,EAAa,SAAQ,CACrC,SACD,CAAC,CACF,EAAQ,KAAK,CACX,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,SACD,CAAC,CACF,EAAO,KACL,EAAO,MACL,oCAAoC,EAAK,aAAa,KAAK,iBAAiB,EAAY,IACzF,CACF,MAGD,EAAQ,KAAK,CACX,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,OAAQ,GACT,CAAC,OAEG,EAAK,CACZ,EAAO,MACL,EAAO,IACL,6CAA6C,EAAK,aAAa,KAAK,OAAO,EAAI,UAChF,CACF,CACD,EAAO,KAAK,CACV,iBAAkB,EAAK,aAAa,KACpC,eAAgB,EAAK,aAAa,GAClC,MAAO,EAAI,QACZ,CAAC,GAEJ,CACF,EAAO,KACL,EAAO,MACL,wBAAwB,EAAQ,OAAO,UAAU,EAAQ,SAAW,EAAI,GAAK,MAC9E,CACF,CAEG,EAAO,OAAS,GAClB,EAAO,MACL,EAAO,IAAI,oBAAoB,EAAO,OAAO,UAAU,EAAO,SAAW,EAAI,GAAK,IAAI,GAAG,CAC1F,CAGI,CAAE,SAAQ,QAAS,EAAS"}
@@ -0,0 +1,2 @@
1
+ import{n as e,r as t}from"./runOpa-CkKAwsvB.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";import r from"node:path";import i from"colors";async function a({pkg:a,input:o,bundle:s}){n(this.process),t();let c=r.resolve(o);if(!this.fs.existsSync(c))throw Error(`Input file not found: ${c}`);let l=[`eval`,`--format`,`pretty`,`--input`,c];s&&l.push(`-b`,r.resolve(s)),l.push(a),this.logger.info(i.green(`Evaluating ${a} with input ${c}...`));let u=await e(l);u!==0&&this.process.exit(u)}export{a as _eval};
2
+ //# sourceMappingURL=impl-6m7GXUAe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-6m7GXUAe.mjs","names":[],"sources":["../src/commands/policy/eval/impl.ts"],"sourcesContent":["import path from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { assertOpaInstalled, runOpa } from '../helpers/index.js';\n\n/** CLI flags for `transcend policy eval`. */\nexport interface EvalCommandFlags {\n /** OPA package/query to evaluate (e.g. `data.transcend.decision`) */\n pkg: string;\n /** Path to a JSON envelope input file */\n input: string;\n /** Optional local policy bundle directory */\n bundle?: string;\n}\n\n/**\n * Evaluate one envelope against a local policy bundle via `opa eval`.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function _eval(\n this: LocalContext,\n { pkg, input, bundle }: EvalCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n assertOpaInstalled();\n\n const inputPath = path.resolve(input);\n if (!this.fs.existsSync(inputPath)) {\n throw new Error(`Input file not found: ${inputPath}`);\n }\n\n const args = ['eval', '--format', 'pretty', '--input', inputPath];\n if (bundle) {\n args.push('-b', path.resolve(bundle));\n }\n args.push(pkg);\n\n this.logger.info(colors.green(`Evaluating ${pkg} with input ${inputPath}...`));\n\n const exitCode = await runOpa(args);\n if (exitCode !== 0) {\n this.process.exit(exitCode);\n }\n}\n"],"mappings":"yJAwBA,eAAsB,EAEpB,CAAE,MAAK,QAAO,UACC,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAoB,CAEpB,IAAM,EAAY,EAAK,QAAQ,EAAM,CACrC,GAAI,CAAC,KAAK,GAAG,WAAW,EAAU,CAChC,MAAU,MAAM,yBAAyB,IAAY,CAGvD,IAAM,EAAO,CAAC,OAAQ,WAAY,SAAU,UAAW,EAAU,CAC7D,GACF,EAAK,KAAK,KAAM,EAAK,QAAQ,EAAO,CAAC,CAEvC,EAAK,KAAK,EAAI,CAEd,KAAK,OAAO,KAAK,EAAO,MAAM,cAAc,EAAI,cAAc,EAAU,KAAK,CAAC,CAE9E,IAAM,EAAW,MAAM,EAAO,EAAK,CAC/B,IAAa,GACf,KAAK,QAAQ,KAAK,EAAS"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./cancelPrivacyRequests-BEyOBJ2r.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,actions:r,statuses:i=[],requestIds:a,silentModeBefore:o,createdAtBefore:s,createdAtAfter:c,updatedAtBefore:l,updatedAtAfter:u,cancellationTitle:d,transcendUrl:f,concurrency:p}){t(this.process),await e({transcendUrl:f,requestActions:r,auth:n,cancellationTitle:d,requestIds:a,statuses:i,concurrency:p,silentModeBefore:o?new Date(o):void 0,createdAtBefore:s?new Date(s):void 0,createdAtAfter:c?new Date(c):void 0,updatedAtBefore:l?new Date(l):void 0,updatedAtAfter:u?new Date(u):void 0})}export{n as cancel};
2
+ //# sourceMappingURL=impl-B--lr5RJ2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-B--lr5RJ2.mjs","names":[],"sources":["../src/commands/request/cancel/impl.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { cancelPrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface CancelCommandFlags {\n auth: string;\n actions: RequestAction[];\n statuses?: RequestStatus[];\n requestIds?: string[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n cancellationTitle: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function cancel(\n this: LocalContext,\n {\n auth,\n actions,\n statuses = [],\n requestIds,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n cancellationTitle,\n transcendUrl,\n concurrency,\n }: CancelCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await cancelPrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n cancellationTitle,\n requestIds,\n statuses,\n concurrency,\n silentModeBefore: silentModeBefore ? new Date(silentModeBefore) : undefined,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n updatedAtBefore: updatedAtBefore ? new Date(updatedAtBefore) : undefined,\n updatedAtAfter: updatedAtAfter ? new Date(updatedAtAfter) : undefined,\n });\n}\n"],"mappings":"6GAqBA,eAAsB,EAEpB,CACE,OACA,UACA,WAAW,EAAE,CACb,aACA,mBACA,kBACA,iBACA,kBACA,iBACA,oBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAsB,CAC1B,eACA,eAAgB,EAChB,OACA,oBACA,aACA,WACA,cACA,iBAAkB,EAAmB,IAAI,KAAK,EAAiB,CAAG,IAAA,GAClE,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC7D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import{r as e}from"./policyEngineCliError-DY8V-qkK.mjs";import{i as t,n,t as r}from"./printResult-esxW3HhT.mjs";import{t as i}from"./resolveBundleIdByName-DuxWYrDF.mjs";import{t as a}from"./resolvePolicyBundleVersion-DhXZKwb4.mjs";import{t as o}from"./done-input-validation-Cjk7a3jX.mjs";import s from"node:path";import c from"got";import l from"colors";function u(e,t){return`${e}-${t}.tar.gz`}function d(e,t){return[`bundleName ${e.bundleName}`,`version ${e.version}`,`output ${t}`,`sha256 ${e.sha256}`,`sizeBytes ${e.sizeBytes}`,`uploadedAt ${e.uploadedAt}`,`activatedAt ${e.activatedAt??`-`}`].join(`
2
+ `)}async function f({"bundle-name":f,version:p,output:m,auth:h,"transcend-url":g,json:_,debug:v=!1}){o(this.process),e(v);let y=t(g,h),b=await i(y,f);if(!b)throw Error(`Policy bundle "${f}" was not found for this organization.`);let x;if(p)x=(await a(y,b.id,{version:p})).id;else{if(!b.activeVersionId)throw Error(`Policy bundle "${f}" has no active version.`);x=b.activeVersionId}this.logger.info(l.green(p?`Fetching download URL for bundle "${f}" version "${p}"...`:`Fetching download URL for active version of bundle "${f}"...`));let S=await n(y.get(`v1/policy-engine/policy-bundles/${b.id}/versions/${x}`).json());if(_){r(this.process.stdout,{json:!0,data:S});return}let C=s.resolve(m??u(f,S.version));this.logger.info(l.green(`Downloading policy bundle to ${C}...`));let w;try{w=await c(S.downloadUrl).buffer()}catch(e){throw Error(`Failed to download policy bundle from the presigned URL: ${e instanceof Error?e.message:String(e)}`,{cause:e})}let T=s.dirname(C);this.fs.mkdirSync(T,{recursive:!0}),this.fs.writeFileSync(C,w),r(this.process.stdout,{json:!1,data:S,renderTable:()=>d(S,C)}),this.logger.info(l.green(`Policy bundle downloaded successfully.`))}export{f as download};
3
+ //# sourceMappingURL=impl-B3_hrFPX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-B3_hrFPX.mjs","names":[],"sources":["../src/commands/policy/download/impl.ts"],"sourcesContent":["import path from 'node:path';\n\nimport colors from 'colors';\nimport got from 'got';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { EMPTY_CELL } from '../constants.js';\nimport {\n buildPolicyEngineClient,\n policyEngineRequest,\n printResult,\n resolveBundleByName,\n resolvePolicyBundleVersion,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { GetPolicyBundleVersionResponse } from '../types.js';\n\n/** CLI flags for `transcend policy download`. */\nexport interface DownloadCommandFlags {\n /** Tenant-unique bundle name */\n 'bundle-name': string;\n /**\n * Caller-supplied version label to download.\n * When omitted, downloads the bundle's currently active version.\n */\n version?: string;\n /** Destination file path; defaults to `{bundleName}-{version}.tar.gz` */\n output?: string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Print metadata + presigned URL as JSON without writing a file */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Builds the default output path for a downloaded policy bundle.\n *\n * @param bundleName - Tenant-unique bundle name\n * @param version - Caller-supplied version label\n * @returns Relative path `{bundleName}-{version}.tar.gz`\n */\nexport function defaultPolicyDownloadOutputPath(bundleName: string, version: string): string {\n return `${bundleName}-${version}.tar.gz`;\n}\n\n/**\n * Formats download metadata for human-readable CLI output.\n *\n * @param body - Version metadata from the Policy Engine API\n * @param outputPath - Destination path written (or that would be written)\n * @returns Summary lines\n */\nfunction formatDownloadSummary(body: GetPolicyBundleVersionResponse, outputPath: string): string {\n return [\n `bundleName ${body.bundleName}`,\n `version ${body.version}`,\n `output ${outputPath}`,\n `sha256 ${body.sha256}`,\n `sizeBytes ${body.sizeBytes}`,\n `uploadedAt ${body.uploadedAt}`,\n `activatedAt ${body.activatedAt ?? EMPTY_CELL}`,\n ].join('\\n');\n}\n\n/**\n * Download a compiled policy bundle version to disk.\n *\n * Resolves `--bundle-name` and an optional `--version` to IDs, fetches a\n * short-lived presigned S3 URL from the monolith, then downloads the `.tar.gz`\n * bytes directly from S3 (the monolith does not proxy the artifact).\n *\n * When `--version` is omitted, downloads the bundle's currently active version.\n * If the bundle has no active version, exits with an error.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function download(\n this: LocalContext,\n {\n 'bundle-name': bundleName,\n version,\n output,\n auth,\n 'transcend-url': transcendUrl,\n json,\n debug = false,\n }: DownloadCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n\n const bundle = await resolveBundleByName(client, bundleName);\n if (!bundle) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n\n let versionId: string;\n if (version) {\n const resolvedVersion = await resolvePolicyBundleVersion(client, bundle.id, { version });\n versionId = resolvedVersion.id;\n } else {\n if (!bundle.activeVersionId) {\n throw new Error(`Policy bundle \"${bundleName}\" has no active version.`);\n }\n versionId = bundle.activeVersionId;\n }\n\n this.logger.info(\n colors.green(\n version\n ? `Fetching download URL for bundle \"${bundleName}\" version \"${version}\"...`\n : `Fetching download URL for active version of bundle \"${bundleName}\"...`,\n ),\n );\n\n const body = await policyEngineRequest(\n client\n .get(`v1/policy-engine/policy-bundles/${bundle.id}/versions/${versionId}`)\n .json<GetPolicyBundleVersionResponse>(),\n );\n\n if (json) {\n printResult(this.process.stdout, {\n json: true,\n data: body,\n });\n return;\n }\n\n const outputPath = path.resolve(\n output ?? defaultPolicyDownloadOutputPath(bundleName, body.version),\n );\n\n this.logger.info(colors.green(`Downloading policy bundle to ${outputPath}...`));\n\n let bundleBytes: Uint8Array;\n try {\n bundleBytes = await got(body.downloadUrl).buffer();\n } catch (err) {\n throw new Error(\n `Failed to download policy bundle from the presigned URL: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err },\n );\n }\n\n const outputDir = path.dirname(outputPath);\n this.fs.mkdirSync(outputDir, { recursive: true });\n this.fs.writeFileSync(outputPath, bundleBytes);\n\n printResult(this.process.stdout, {\n json: false,\n data: body,\n renderTable: () => formatDownloadSummary(body, outputPath),\n });\n\n this.logger.info(colors.green('Policy bundle downloaded successfully.'));\n}\n"],"mappings":"kWA8CA,SAAgB,EAAgC,EAAoB,EAAyB,CAC3F,MAAO,GAAG,EAAW,GAAG,EAAQ,SAUlC,SAAS,EAAsB,EAAsC,EAA4B,CAC/F,MAAO,CACL,eAAe,EAAK,aACpB,eAAe,EAAK,UACpB,eAAe,IACf,eAAe,EAAK,SACpB,eAAe,EAAK,YACpB,eAAe,EAAK,aACpB,eAAe,EAAK,aAAA,MACrB,CAAC,KAAK;EAAK,CAgBd,eAAsB,EAEpB,CACE,cAAe,EACf,UACA,SACA,OACA,gBAAiB,EACjB,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CAEpD,EAAS,MAAM,EAAoB,EAAQ,EAAW,CAC5D,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,IAAI,EACJ,GAAI,EAEF,GAAY,MADkB,EAA2B,EAAQ,EAAO,GAAI,CAAE,UAAS,CAAC,EAC5D,OACvB,CACL,GAAI,CAAC,EAAO,gBACV,MAAU,MAAM,kBAAkB,EAAW,0BAA0B,CAEzE,EAAY,EAAO,gBAGrB,KAAK,OAAO,KACV,EAAO,MACL,EACI,qCAAqC,EAAW,aAAa,EAAQ,MACrE,uDAAuD,EAAW,MACvE,CACF,CAED,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,mCAAmC,EAAO,GAAG,YAAY,IAAY,CACzE,MAAsC,CAC1C,CAED,GAAI,EAAM,CACR,EAAY,KAAK,QAAQ,OAAQ,CAC/B,KAAM,GACN,KAAM,EACP,CAAC,CACF,OAGF,IAAM,EAAa,EAAK,QACtB,GAAU,EAAgC,EAAY,EAAK,QAAQ,CACpE,CAED,KAAK,OAAO,KAAK,EAAO,MAAM,gCAAgC,EAAW,KAAK,CAAC,CAE/E,IAAI,EACJ,GAAI,CACF,EAAc,MAAM,EAAI,EAAK,YAAY,CAAC,QAAQ,OAC3C,EAAK,CACZ,MAAU,MACR,4DACE,aAAe,MAAQ,EAAI,QAAU,OAAO,EAAI,GAElD,CAAE,MAAO,EAAK,CACf,CAGH,IAAM,EAAY,EAAK,QAAQ,EAAW,CAC1C,KAAK,GAAG,UAAU,EAAW,CAAE,UAAW,GAAM,CAAC,CACjD,KAAK,GAAG,cAAc,EAAY,EAAY,CAE9C,EAAY,KAAK,QAAQ,OAAQ,CAC/B,KAAM,GACN,KAAM,EACN,gBAAmB,EAAsB,EAAM,EAAW,CAC3D,CAAC,CAEF,KAAK,OAAO,KAAK,EAAO,MAAM,yCAAyC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./downloadPrivacyRequestFiles-CLFgQItk.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";import{RequestStatus as n}from"@transcend-io/privacy-types";async function r({auth:r,transcendUrl:i,folderPath:a,requestIds:o,statuses:s=[n.Approving,n.Downloadable],concurrency:c,createdAtBefore:l,createdAtAfter:u,updatedAtBefore:d,updatedAtAfter:f,approveAfterDownload:p}){t(this.process),await e({transcendUrl:i,auth:r,folderPath:a,requestIds:o,statuses:s,concurrency:c,createdAtBefore:l,createdAtAfter:u,updatedAtBefore:d,updatedAtAfter:f,approveAfterDownload:p})}export{r as downloadFiles};
2
+ //# sourceMappingURL=impl-BFJtKA2o2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DOoJoSO22.mjs","names":[],"sources":["../src/commands/request/download-files/impl.ts"],"sourcesContent":["import { RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { downloadPrivacyRequestFiles } from '../../../lib/requests/index.js';\n\nexport interface DownloadFilesCommandFlags {\n auth: string;\n sombraAuth?: string;\n concurrency: number;\n requestIds?: string[];\n statuses?: RequestStatus[];\n folderPath: string;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n approveAfterDownload: boolean;\n transcendUrl: string;\n}\n\nexport async function downloadFiles(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n folderPath,\n requestIds,\n statuses = [RequestStatus.Approving, RequestStatus.Downloadable],\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n approveAfterDownload,\n }: DownloadFilesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await downloadPrivacyRequestFiles({\n transcendUrl,\n auth,\n folderPath,\n requestIds,\n statuses,\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n approveAfterDownload,\n });\n}\n"],"mappings":"+KAqBA,eAAsB,EAEpB,CACE,OACA,eACA,aACA,aACA,WAAW,CAAC,EAAc,UAAW,EAAc,aAAa,CAChE,cACA,kBACA,iBACA,kBACA,iBACA,wBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAA4B,CAChC,eACA,OACA,aACA,aACA,WACA,cACA,kBACA,iBACA,kBACA,iBACA,uBACD,CAAC"}
1
+ {"version":3,"file":"impl-BFJtKA2o2.mjs","names":[],"sources":["../src/commands/request/download-files/impl.ts"],"sourcesContent":["import { RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { downloadPrivacyRequestFiles } from '../../../lib/requests/index.js';\n\nexport interface DownloadFilesCommandFlags {\n auth: string;\n sombraAuth?: string;\n concurrency: number;\n requestIds?: string[];\n statuses?: RequestStatus[];\n folderPath: string;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n approveAfterDownload: boolean;\n transcendUrl: string;\n}\n\nexport async function downloadFiles(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n folderPath,\n requestIds,\n statuses = [RequestStatus.Approving, RequestStatus.Downloadable],\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n approveAfterDownload,\n }: DownloadFilesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await downloadPrivacyRequestFiles({\n transcendUrl,\n auth,\n folderPath,\n requestIds,\n statuses,\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n approveAfterDownload,\n });\n}\n"],"mappings":"+KAqBA,eAAsB,EAEpB,CACE,OACA,eACA,aACA,aACA,WAAW,CAAC,EAAc,UAAW,EAAc,aAAa,CAChE,cACA,kBACA,iBACA,kBACA,iBACA,wBAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAA4B,CAChC,eACA,OACA,aACA,aACA,WACA,cACA,kBACA,iBACA,kBACA,iBACA,uBACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./constants-DyD22MtN.mjs";import{t}from"./logger-Ckep4QXn.mjs";import{n}from"./syncCodePackages-Dhm5jI6B.mjs";import{t as r}from"./done-input-validation-DL31vk7g.mjs";import{t as i}from"./constants-BgCEW975.mjs";import a from"fast-glob";import o from"colors";import{getEntries as s}from"@transcend-io/type-utils";import{buildTranscendGraphQLClient as c}from"@transcend-io/sdk";import{execSync as l}from"child_process";async function u({scanPath:e,ignoreDirs:n=[],repositoryName:r}){return(await Promise.all(s(i).map(async([i,s])=>{let{ignoreDirs:c,supportedFiles:l,scanFunction:u}=s,d=[...n,...c].filter(e=>e.length>0);try{let n=await a(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(o.magenta(`Scanning: ${n.length} files of type ${i}`));let s=n.map(t=>u(t).map(n=>({...n,relativePath:t.replace(`${e}/`,``)}))).flat();return t.info(o.green(`Found: ${s.length} packages and ${s.map(({softwareDevelopmentKits:e=[]})=>e).flat().length} sdks`)),s.map(e=>({...e,type:i,repositoryName:r}))}catch(e){throw Error(`Error scanning globs ${l} with error: ${e}`)}}))).flat()}const d=`A repository name must be provided. You can specify using --repositoryName=$REPO_NAME or by ensuring the command "git config --get remote.origin.url" returns the name of the repository`;async function f({auth:i,scanPath:a,ignoreDirs:s,repositoryName:f,transcendUrl:p}){r(this.process.exit);let m=f;if(!m)try{let e=l(`cd ${a} && git config --get remote.origin.url`).toString(`utf-8`).trim();[m]=e.includes(`https:`)?e.split(`/`).slice(3).join(`/`).split(`.`):(e.split(`:`).pop()||``).split(`.`),m||(t.error(o.red(d)),this.process.exit(1))}catch(e){t.error(o.red(`${d} - Got error: ${e.message}`)),this.process.exit(1)}let h=c(p,i),g=await u({scanPath:a,ignoreDirs:s,repositoryName:m});await n(h,g);let _=new URL(e);_.pathname=`/code-scanning/code-packages`,t.info(o.green(`Scan found ${g.length} packages at ${a}! View results at '${_.href}'`))}export{f as scanPackages};
2
- //# sourceMappingURL=impl-DSE-RmED.mjs.map
1
+ import{t as e}from"./constants-BG53Mbi9.mjs";import{t}from"./logger-9T6vva73.mjs";import{n}from"./syncCodePackages-DsC1tE8B.mjs";import{t as r}from"./done-input-validation-Cjk7a3jX.mjs";import{t as i}from"./constants-BpQ5awGp.mjs";import a from"fast-glob";import o from"colors";import{getEntries as s}from"@transcend-io/type-utils";import{buildTranscendGraphQLClient as c}from"@transcend-io/sdk";import{execSync as l}from"child_process";async function u({scanPath:e,ignoreDirs:n=[],repositoryName:r}){return(await Promise.all(s(i).map(async([i,s])=>{let{ignoreDirs:c,supportedFiles:l,scanFunction:u}=s,d=[...n,...c].filter(e=>e.length>0);try{let n=await a(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(o.magenta(`Scanning: ${n.length} files of type ${i}`));let s=n.map(t=>u(t).map(n=>({...n,relativePath:t.replace(`${e}/`,``)}))).flat();return t.info(o.green(`Found: ${s.length} packages and ${s.map(({softwareDevelopmentKits:e=[]})=>e).flat().length} sdks`)),s.map(e=>({...e,type:i,repositoryName:r}))}catch(e){throw Error(`Error scanning globs ${l} with error: ${e}`)}}))).flat()}const d=`A repository name must be provided. You can specify using --repositoryName=$REPO_NAME or by ensuring the command "git config --get remote.origin.url" returns the name of the repository`;async function f({auth:t,scanPath:i,ignoreDirs:a,repositoryName:s,transcendUrl:f}){r(this.process);let p=s;if(!p)try{let e=l(`cd ${i} && git config --get remote.origin.url`).toString(`utf-8`).trim();[p]=e.includes(`https:`)?e.split(`/`).slice(3).join(`/`).split(`.`):(e.split(`:`).pop()||``).split(`.`),p||(this.logger.error(o.red(d)),this.process.exit(1))}catch(e){this.logger.error(o.red(`${d} - Got error: ${e.message}`)),this.process.exit(1)}let m=c(f,t),h=await u({scanPath:i,ignoreDirs:a,repositoryName:p});await n(m,h);let g=new URL(e);g.pathname=`/code-scanning/code-packages`,this.logger.info(o.green(`Scan found ${h.length} packages at ${i}! View results at '${g.href}'`))}export{f as scanPackages};
2
+ //# sourceMappingURL=impl-BJlKQJdS2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BJlKQJdS2.mjs","names":[],"sources":["../src/lib/code-scanning/findCodePackagesInFolder.ts","../src/commands/inventory/scan-packages/impl.ts"],"sourcesContent":["import { getEntries } from '@transcend-io/type-utils';\nimport colors from 'colors';\nimport fastGlob from 'fast-glob';\n\nimport { CodePackageInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { CODE_SCANNING_CONFIGS } from './constants.js';\n\n/**\n * Helper to scan and discovery all of the code packages within a folder\n *\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findCodePackagesInFolder({\n scanPath,\n ignoreDirs = [],\n repositoryName,\n}: {\n /** The name of the github repository reporting packages for */\n repositoryName: string;\n /** Where to look for package.json files */\n scanPath: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs?: string[];\n}): Promise<CodePackageInput[]> {\n const allCodePackages = await Promise.all(\n getEntries(CODE_SCANNING_CONFIGS).map(async ([codePackageType, config]) => {\n const { ignoreDirs: configIgnoreDirs, supportedFiles, scanFunction } = config;\n const dirsToIgnore = [...ignoreDirs, ...configIgnoreDirs].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${supportedFiles.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(\n colors.magenta(`Scanning: ${filesToScan.length} files of type ${codePackageType}`),\n );\n const allPackages = filesToScan\n .map((filePath) =>\n scanFunction(filePath).map((result) => ({\n ...result,\n relativePath: filePath.replace(`${scanPath}/`, ''),\n })),\n )\n .flat();\n logger.info(\n colors.green(\n `Found: ${allPackages.length} packages and ${\n allPackages.map(({ softwareDevelopmentKits = [] }) => softwareDevelopmentKits).flat()\n .length\n } sdks`,\n ),\n );\n\n return allPackages.map(\n (pkg): CodePackageInput => ({\n ...pkg,\n type: codePackageType,\n repositoryName,\n }),\n );\n } catch (error) {\n throw new Error(`Error scanning globs ${supportedFiles} with error: ${error}`);\n }\n }),\n );\n\n return allCodePackages.flat();\n}\n","import { execSync } from 'child_process';\n\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findCodePackagesInFolder } from '../../../lib/code-scanning/index.js';\nimport { syncCodePackages } from '../../../lib/graphql/index.js';\n\nconst REPO_ERROR =\n 'A repository name must be provided. ' +\n 'You can specify using --repositoryName=$REPO_NAME or by ensuring the ' +\n 'command \"git config --get remote.origin.url\" returns the name of the repository';\n\nexport interface ScanPackagesCommandFlags {\n auth: string;\n scanPath: string;\n ignoreDirs?: string[];\n repositoryName?: string;\n transcendUrl: string;\n}\n\nexport async function scanPackages(\n this: LocalContext,\n { auth, scanPath, ignoreDirs, repositoryName, transcendUrl }: ScanPackagesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Ensure repository name is specified\n let gitRepositoryName = repositoryName;\n if (!gitRepositoryName) {\n try {\n const name = execSync(`cd ${scanPath} && git config --get remote.origin.url`);\n // Trim and parse the URL\n const url = name.toString('utf-8').trim();\n [gitRepositoryName] = !url.includes('https:')\n ? (url.split(':').pop() || '').split('.')\n : url.split('/').slice(3).join('/').split('.');\n if (!gitRepositoryName) {\n this.logger.error(colors.red(REPO_ERROR));\n this.process.exit(1);\n }\n } catch (err) {\n this.logger.error(colors.red(`${REPO_ERROR} - Got error: ${err.message}`));\n this.process.exit(1);\n }\n }\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Scan the codebase to discovery packages\n const results = await findCodePackagesInFolder({\n scanPath,\n ignoreDirs,\n repositoryName: gitRepositoryName,\n });\n\n // Report scan to Transcend\n await syncCodePackages(client, results);\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/code-scanning/code-packages';\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Scan found ${results.length} packages at ${scanPath}! ` + `View results at '${newUrl.href}'`,\n ),\n );\n}\n"],"mappings":"qbAcA,eAAsB,EAAyB,CAC7C,WACA,aAAa,EAAE,CACf,kBAQ8B,CA4C9B,OAAO,MA3CuB,QAAQ,IACpC,EAAW,EAAsB,CAAC,IAAI,MAAO,CAAC,EAAiB,KAAY,CACzE,GAAM,CAAE,WAAY,EAAkB,iBAAgB,gBAAiB,EACjE,EAAe,CAAC,GAAG,EAAY,GAAG,EAAiB,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CACzF,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KACL,EAAO,QAAQ,aAAa,EAAY,OAAO,iBAAiB,IAAkB,CACnF,CACD,IAAM,EAAc,EACjB,IAAK,GACJ,EAAa,EAAS,CAAC,IAAK,IAAY,CACtC,GAAG,EACH,aAAc,EAAS,QAAQ,GAAG,EAAS,GAAI,GAAG,CACnD,EAAE,CACJ,CACA,MAAM,CAUT,OATA,EAAO,KACL,EAAO,MACL,UAAU,EAAY,OAAO,gBAC3B,EAAY,KAAK,CAAE,0BAA0B,EAAE,IAAO,EAAwB,CAAC,MAAM,CAClF,OACJ,OACF,CACF,CAEM,EAAY,IAChB,IAA2B,CAC1B,GAAG,EACH,KAAM,EACN,iBACD,EACF,OACM,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAe,eAAe,IAAQ,GAEhF,CACH,EAEsB,MAAM,CC1D/B,MAAM,EACJ,2LAYF,eAAsB,EAEpB,CAAE,OAAM,WAAU,aAAY,iBAAgB,gBAC/B,CACf,EAAoB,KAAK,QAAQ,CAGjC,IAAI,EAAoB,EACxB,GAAI,CAAC,EACH,GAAI,CAGF,IAAM,EAFO,EAAS,MAAM,EAAS,wCAErB,CAAC,SAAS,QAAQ,CAAC,MAAM,CACzC,CAAC,GAAsB,EAAI,SAAS,SAAS,CAEzC,EAAI,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,EAD3C,EAAI,MAAM,IAAI,CAAC,KAAK,EAAI,IAAI,MAAM,IAAI,CAEtC,IACH,KAAK,OAAO,MAAM,EAAO,IAAI,EAAW,CAAC,CACzC,KAAK,QAAQ,KAAK,EAAE,QAEf,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,GAAG,EAAW,gBAAgB,EAAI,UAAU,CAAC,CAC1E,KAAK,QAAQ,KAAK,EAAE,CAKxB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAU,MAAM,EAAyB,CAC7C,WACA,aACA,eAAgB,EACjB,CAAC,CAGF,MAAM,EAAiB,EAAQ,EAAQ,CAEvC,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,+BAGlB,KAAK,OAAO,KACV,EAAO,MACL,cAAc,EAAQ,OAAO,eAAe,EAAS,qBAA0B,EAAO,KAAK,GAC5F,CACF"}
@@ -0,0 +1,3 @@
1
+ import{n as e,r as t,t as n}from"./runOpa-CkKAwsvB.mjs";import{n as r}from"./inquirer-DkFTQU00.mjs";import{t as i}from"./done-input-validation-Cjk7a3jX.mjs";import a from"node:path";import o from"colors";async function s({dir:s}){i(this.process),t();let c=a.resolve(s);this.logger.info(o.green(`Linting policy bundle in ${c}...`));let l=await e([`check`,`--strict`,c]);l!==0&&this.process.exit(l);let{stdout:u}=await n([`fmt`,`--list`,c]),d=u.trim().split(`
2
+ `).filter(e=>e.length>0);if(d.length>0){this.logger.error(o.red(`Policy files are not formatted:`)),d.forEach(e=>{this.logger.error(o.red(` - ${e}`))}),this.logger.error(``),await e([`fmt`,`--diff`,c]),this.process.stdin.isTTY||(this.logger.error(o.red(`Cannot format policy files in a non-interactive environment.`)),this.process.exit(1)),await r({message:`Format the unformatted policy files listed above?`})||this.process.exit(1);let t=await e([`fmt`,`-w`,c]);t!==0&&this.process.exit(t),this.logger.info(o.green(`Policy files formatted.`)),this.logger.info(o.green(`Policy lint passed.`));return}this.logger.info(o.green(`Policy lint passed.`))}export{s as lint};
3
+ //# sourceMappingURL=impl-BNPgYSBT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BNPgYSBT.mjs","names":[],"sources":["../src/commands/policy/lint/impl.ts"],"sourcesContent":["import path from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport { assertOpaInstalled, runOpa, runOPACapture } from '../helpers/index.js';\n\n/** CLI flags for `transcend policy lint`. */\nexport interface LintCommandFlags {\n /** Directory containing Rego policy files */\n dir: string;\n}\n\n/**\n * Local Rego lint via `opa check` and optional interactive formatting via `opa fmt`.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function lint(this: LocalContext, { dir }: LintCommandFlags): Promise<void> {\n doneInputValidation(this.process);\n\n assertOpaInstalled();\n const resolvedDir = path.resolve(dir);\n\n this.logger.info(colors.green(`Linting policy bundle in ${resolvedDir}...`));\n\n const checkCode = await runOpa(['check', '--strict', resolvedDir]);\n if (checkCode !== 0) {\n this.process.exit(checkCode);\n }\n\n const { stdout } = await runOPACapture(['fmt', '--list', resolvedDir]);\n const unformattedFiles = stdout\n .trim()\n .split('\\n')\n .filter((file) => file.length > 0);\n\n if (unformattedFiles.length > 0) {\n this.logger.error(colors.red('Policy files are not formatted:'));\n unformattedFiles.forEach((file) => {\n this.logger.error(colors.red(` - ${file}`));\n });\n this.logger.error('');\n await runOpa(['fmt', '--diff', resolvedDir]);\n\n if (!this.process.stdin.isTTY) {\n this.logger.error(colors.red('Cannot format policy files in a non-interactive environment.'));\n this.process.exit(1);\n }\n\n const shouldFormat = await inquirerConfirmBoolean({\n message: 'Format the unformatted policy files listed above?',\n });\n if (!shouldFormat) {\n this.process.exit(1);\n }\n\n const fmtWriteCode = await runOpa(['fmt', '-w', resolvedDir]);\n if (fmtWriteCode !== 0) {\n this.process.exit(fmtWriteCode);\n }\n\n this.logger.info(colors.green('Policy files formatted.'));\n this.logger.info(colors.green('Policy lint passed.'));\n return;\n }\n\n this.logger.info(colors.green('Policy lint passed.'));\n}\n"],"mappings":"4MAqBA,eAAsB,EAAyB,CAAE,OAAwC,CACvF,EAAoB,KAAK,QAAQ,CAEjC,GAAoB,CACpB,IAAM,EAAc,EAAK,QAAQ,EAAI,CAErC,KAAK,OAAO,KAAK,EAAO,MAAM,4BAA4B,EAAY,KAAK,CAAC,CAE5E,IAAM,EAAY,MAAM,EAAO,CAAC,QAAS,WAAY,EAAY,CAAC,CAC9D,IAAc,GAChB,KAAK,QAAQ,KAAK,EAAU,CAG9B,GAAM,CAAE,UAAW,MAAM,EAAc,CAAC,MAAO,SAAU,EAAY,CAAC,CAChE,EAAmB,EACtB,MAAM,CACN,MAAM;EAAK,CACX,OAAQ,GAAS,EAAK,OAAS,EAAE,CAEpC,GAAI,EAAiB,OAAS,EAAG,CAC/B,KAAK,OAAO,MAAM,EAAO,IAAI,kCAAkC,CAAC,CAChE,EAAiB,QAAS,GAAS,CACjC,KAAK,OAAO,MAAM,EAAO,IAAI,OAAO,IAAO,CAAC,EAC5C,CACF,KAAK,OAAO,MAAM,GAAG,CACrB,MAAM,EAAO,CAAC,MAAO,SAAU,EAAY,CAAC,CAEvC,KAAK,QAAQ,MAAM,QACtB,KAAK,OAAO,MAAM,EAAO,IAAI,+DAA+D,CAAC,CAC7F,KAAK,QAAQ,KAAK,EAAE,EAMjB,MAHsB,EAAuB,CAChD,QAAS,oDACV,CAAC,EAEA,KAAK,QAAQ,KAAK,EAAE,CAGtB,IAAM,EAAe,MAAM,EAAO,CAAC,MAAO,KAAM,EAAY,CAAC,CACzD,IAAiB,GACnB,KAAK,QAAQ,KAAK,EAAa,CAGjC,KAAK,OAAO,KAAK,EAAO,MAAM,0BAA0B,CAAC,CACzD,KAAK,OAAO,KAAK,EAAO,MAAM,sBAAsB,CAAC,CACrD,OAGF,KAAK,OAAO,KAAK,EAAO,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./approvePrivacyRequests-80SV_94y.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,actions:r,origins:i,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l,transcendUrl:u,concurrency:d}){t(this.process),await e({transcendUrl:u,requestActions:r,auth:n,requestOrigins:i,concurrency:d,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l})}export{n as approve};
2
+ //# sourceMappingURL=impl-BWVe4VGF2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-D8FcLfAL2.mjs","names":[],"sources":["../src/commands/request/approve/impl.ts"],"sourcesContent":["import { RequestAction, RequestOrigin } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { approvePrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface ApproveCommandFlags {\n auth: string;\n actions: RequestAction[];\n origins?: RequestOrigin[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function approve(\n this: LocalContext,\n {\n auth,\n actions,\n origins,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n transcendUrl,\n concurrency,\n }: ApproveCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await approvePrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n requestOrigins: origins,\n concurrency,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"8GAmBA,eAAsB,EAEpB,CACE,OACA,UACA,UACA,mBACA,kBACA,iBACA,kBACA,iBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAuB,CAC3B,eACA,eAAgB,EAChB,OACA,eAAgB,EAChB,cACA,mBACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
1
+ {"version":3,"file":"impl-BWVe4VGF2.mjs","names":[],"sources":["../src/commands/request/approve/impl.ts"],"sourcesContent":["import { RequestAction, RequestOrigin } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { approvePrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface ApproveCommandFlags {\n auth: string;\n actions: RequestAction[];\n origins?: RequestOrigin[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function approve(\n this: LocalContext,\n {\n auth,\n actions,\n origins,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n transcendUrl,\n concurrency,\n }: ApproveCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await approvePrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n requestOrigins: origins,\n concurrency,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"8GAmBA,eAAsB,EAEpB,CACE,OACA,UACA,UACA,mBACA,kBACA,iBACA,kBACA,iBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAuB,CAC3B,eACA,eAAgB,EAChB,OACA,eAAgB,EAChB,cACA,mBACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{i as e}from"./enums-OiLcZ26O.mjs";import{r as t}from"./constants-BG53Mbi9.mjs";import{n,t as r}from"./command-eIenZMOx.mjs";import{o as i}from"./readTranscendYaml-STYnRzq-.mjs";import{n as a}from"./pullTranscendConfiguration-CD7Frn8z.mjs";import{t as o}from"./validateTranscendAuth-CnHMn77m.mjs";import{t as s}from"./done-input-validation-Cjk7a3jX.mjs";import c from"node:path";import l from"colors";import{buildTranscendGraphQLClient as u}from"@transcend-io/sdk";import{mapSeries as d}from"@transcend-io/utils";async function f({auth:f,resources:p=n,file:m,transcendUrl:h,dataSiloIds:g=[],integrationNames:_=[],trackerStatuses:v=r,pageSize:y,skipDatapoints:b,skipSubDatapoints:x,includeGuessedCategories:S,debug:C}){s(this.process);let w=await o(f,this),T=p.includes(`all`)?Object.values(e):p;if(typeof w==`string`){try{let e=await a(u(h,w),{dataSiloIds:g,integrationNames:_,resources:T,pageSize:y,debug:C,skipDatapoints:b,skipSubDatapoints:x,includeGuessedCategories:S,trackerStatuses:v});this.logger.info(l.magenta(`Writing configuration to file "${m}"...`)),this.fs.writeFileSync(m,i(e))}catch(e){this.logger.error(l.red(`An error occurred syncing the schema: ${C?e.stack:e.message}`)),this.process.exit(1)}this.logger.info(l.green(`Successfully synced yaml file to disk at ${m}! View at ${t}`))}else{if(!this.fs.lstatSync(m).isDirectory())throw Error(`File is expected to be a folder when passing in a list of API keys to pull from. e.g. --file=./working/`);let e=[];await d(w,async(t,n)=>{let r=`[${n+1}/${w.length}][${t.organizationName}] `;this.logger.info(l.magenta(`~~~\n\n${r}Attempting to pull configuration...\n\n~~~`));let o=u(h,t.apiKey);try{let e=await a(o,{dataSiloIds:g,integrationNames:_,resources:T,pageSize:y,debug:C,skipDatapoints:b,skipSubDatapoints:x,includeGuessedCategories:S,trackerStatuses:v}),n=c.join(m,`${t.organizationName}.yml`);this.logger.info(l.magenta(`Writing configuration to file "${n}"...`)),this.fs.writeFileSync(n,i(e)),this.logger.info(l.green(`${r}Successfully pulled configuration!`))}catch(n){this.logger.error(l.red(`${r}Failed to sync configuration. - ${n.message}`)),e.push(t.organizationName)}}),e.length>0&&(this.logger.info(l.red(`Sync encountered errors for "${e.join(`,`)}". View output above for more information, or check out ${t}`)),this.process.exit(1))}}export{f as pull};
2
+ //# sourceMappingURL=impl-BYGNx-8W2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BYGNx-8W2.mjs","names":[],"sources":["../src/commands/inventory/pull/impl.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { ADMIN_DASH_INTEGRATIONS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { TranscendPullResource } from '../../../enums.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { pullTranscendConfiguration } from '../../../lib/graphql/index.js';\nimport { serializeTranscendYaml } from '../../../lib/readTranscendYaml.js';\nimport { DEFAULT_CONSENT_TRACKER_STATUSES, DEFAULT_TRANSCEND_PULL_RESOURCES } from './command.js';\n\nexport interface PullCommandFlags {\n auth: string;\n resources?: (TranscendPullResource | 'all')[];\n file: string;\n transcendUrl: string;\n dataSiloIds?: string[];\n integrationNames?: string[];\n trackerStatuses?: ConsentTrackerStatus[];\n pageSize: number;\n skipDatapoints: boolean;\n skipSubDatapoints: boolean;\n includeGuessedCategories: boolean;\n debug: boolean;\n}\n\nexport async function pull(\n this: LocalContext,\n {\n auth,\n resources = DEFAULT_TRANSCEND_PULL_RESOURCES,\n file,\n transcendUrl,\n dataSiloIds = [],\n integrationNames = [],\n trackerStatuses = DEFAULT_CONSENT_TRACKER_STATUSES,\n pageSize,\n skipDatapoints,\n skipSubDatapoints,\n includeGuessedCategories,\n debug,\n }: PullCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth, this);\n\n const resourcesToPull: TranscendPullResource[] = resources.includes('all')\n ? Object.values(TranscendPullResource)\n : (resources as TranscendPullResource[]);\n\n // Sync to Disk\n if (typeof apiKeyOrList === 'string') {\n try {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, apiKeyOrList);\n\n const configuration = await pullTranscendConfiguration(client, {\n dataSiloIds,\n integrationNames,\n resources: resourcesToPull,\n pageSize,\n debug,\n skipDatapoints,\n skipSubDatapoints,\n includeGuessedCategories,\n trackerStatuses,\n });\n\n this.logger.info(colors.magenta(`Writing configuration to file \"${file}\"...`));\n this.fs.writeFileSync(file, serializeTranscendYaml(configuration));\n } catch (err) {\n this.logger.error(\n colors.red(`An error occurred syncing the schema: ${debug ? err.stack : err.message}`),\n );\n this.process.exit(1);\n }\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Successfully synced yaml file to disk at ${file}! View at ${ADMIN_DASH_INTEGRATIONS}`,\n ),\n );\n } else {\n if (!this.fs.lstatSync(file).isDirectory()) {\n throw new Error(\n 'File is expected to be a folder when passing in a list of API keys to pull from. e.g. --file=./working/',\n );\n }\n\n const encounteredErrors: string[] = [];\n await mapSeries(apiKeyOrList, async (apiKey, ind) => {\n const prefix = `[${ind + 1}/${apiKeyOrList.length}][${apiKey.organizationName}] `;\n this.logger.info(\n colors.magenta(`~~~\\n\\n${prefix}Attempting to pull configuration...\\n\\n~~~`),\n );\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, apiKey.apiKey);\n\n try {\n const configuration = await pullTranscendConfiguration(client, {\n dataSiloIds,\n integrationNames,\n resources: resourcesToPull,\n pageSize,\n debug,\n skipDatapoints,\n skipSubDatapoints,\n includeGuessedCategories,\n trackerStatuses,\n });\n\n const filePath = path.join(file, `${apiKey.organizationName}.yml`);\n this.logger.info(colors.magenta(`Writing configuration to file \"${filePath}\"...`));\n this.fs.writeFileSync(filePath, serializeTranscendYaml(configuration));\n\n this.logger.info(colors.green(`${prefix}Successfully pulled configuration!`));\n } catch (err) {\n this.logger.error(colors.red(`${prefix}Failed to sync configuration. - ${err.message}`));\n encounteredErrors.push(apiKey.organizationName);\n }\n });\n\n if (encounteredErrors.length > 0) {\n this.logger.info(\n colors.red(\n `Sync encountered errors for \"${encounteredErrors.join(\n ',',\n )}\". View output above for more information, or check out ${ADMIN_DASH_INTEGRATIONS}`,\n ),\n );\n\n this.process.exit(1);\n }\n }\n}\n"],"mappings":"ugBA+BA,eAAsB,EAEpB,CACE,OACA,YAAY,EACZ,OACA,eACA,cAAc,EAAE,CAChB,mBAAmB,EAAE,CACrB,kBAAkB,EAClB,WACA,iBACA,oBACA,2BACA,SAEa,CACf,EAAoB,KAAK,QAAQ,CAGjC,IAAM,EAAe,MAAM,EAAsB,EAAM,KAAK,CAEtD,EAA2C,EAAU,SAAS,MAAM,CACtE,OAAO,OAAO,EAAsB,CACnC,EAGL,GAAI,OAAO,GAAiB,SAAU,CACpC,GAAI,CAIF,IAAM,EAAgB,MAAM,EAFb,EAA4B,EAAc,EAEI,CAAE,CAC7D,cACA,mBACA,UAAW,EACX,WACA,QACA,iBACA,oBACA,2BACA,kBACD,CAAC,CAEF,KAAK,OAAO,KAAK,EAAO,QAAQ,kCAAkC,EAAK,MAAM,CAAC,CAC9E,KAAK,GAAG,cAAc,EAAM,EAAuB,EAAc,CAAC,OAC3D,EAAK,CACZ,KAAK,OAAO,MACV,EAAO,IAAI,yCAAyC,EAAQ,EAAI,MAAQ,EAAI,UAAU,CACvF,CACD,KAAK,QAAQ,KAAK,EAAE,CAItB,KAAK,OAAO,KACV,EAAO,MACL,4CAA4C,EAAK,YAAY,IAC9D,CACF,KACI,CACL,GAAI,CAAC,KAAK,GAAG,UAAU,EAAK,CAAC,aAAa,CACxC,MAAU,MACR,0GACD,CAGH,IAAM,EAA8B,EAAE,CACtC,MAAM,EAAU,EAAc,MAAO,EAAQ,IAAQ,CACnD,IAAM,EAAS,IAAI,EAAM,EAAE,GAAG,EAAa,OAAO,IAAI,EAAO,iBAAiB,IAC9E,KAAK,OAAO,KACV,EAAO,QAAQ,UAAU,EAAO,4CAA4C,CAC7E,CAGD,IAAM,EAAS,EAA4B,EAAc,EAAO,OAAO,CAEvE,GAAI,CACF,IAAM,EAAgB,MAAM,EAA2B,EAAQ,CAC7D,cACA,mBACA,UAAW,EACX,WACA,QACA,iBACA,oBACA,2BACA,kBACD,CAAC,CAEI,EAAW,EAAK,KAAK,EAAM,GAAG,EAAO,iBAAiB,MAAM,CAClE,KAAK,OAAO,KAAK,EAAO,QAAQ,kCAAkC,EAAS,MAAM,CAAC,CAClF,KAAK,GAAG,cAAc,EAAU,EAAuB,EAAc,CAAC,CAEtE,KAAK,OAAO,KAAK,EAAO,MAAM,GAAG,EAAO,oCAAoC,CAAC,OACtE,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,GAAG,EAAO,kCAAkC,EAAI,UAAU,CAAC,CACxF,EAAkB,KAAK,EAAO,iBAAiB,GAEjD,CAEE,EAAkB,OAAS,IAC7B,KAAK,OAAO,KACV,EAAO,IACL,gCAAgC,EAAkB,KAChD,IACD,CAAC,0DAA0D,IAC7D,CACF,CAED,KAAK,QAAQ,KAAK,EAAE"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./parseVariablesFromString-Cr3x2uq3.mjs";import{t}from"./validateTranscendAuth-CnHMn77m.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";import{a as r,c as i,o as a}from"./manifest-DVuW_vvO.mjs";import{CustomFunctionPayloadType as o,CustomFunctionType as s}from"@transcend-io/privacy-types";import{dirname as c,resolve as l}from"node:path";import u from"colors";import{buildTranscendGraphQLClient as d,createSombraGotInstance as f,fetchAllCustomFunctions as p,resolveEffectiveSombraId as m,resolveExistingCustomFunction as h,syncCustomFunction as g}from"@transcend-io/sdk";import{mapSeries as _}from"@transcend-io/utils";async function v({auth:v,sombraAuth:y,transcendUrl:b,file:x=`./transcend-functions.yml`,variables:S,dryRun:C,promote:w,force:T,skipTests:E,updateManifest:D,sombraId:O}){if(n(this.process),!this.fs.existsSync(x)){let e=`./transcend/custom-functions/transcend-functions.yml`,t=this.fs.existsSync(e)?` Did you mean --file=${e}?`:` You can specify the file path using --file=./transcend-functions.yml`;this.logger.error(u.red(`The manifest file does not exist on disk: ${x}.${t}`)),this.process.exit(1)}let k=t(v,this);Array.isArray(k)&&(this.logger.error(u.red(`transcend custom-functions push does not support a list of API keys — pass a single API key.`)),this.process.exit(1));let A=k,j=e(S);this.logger.info(u.magenta(`Reading manifest "${x}"...`));let M=c(l(x)),N=r(x,j,e=>i(this,M,e));this.logger.info(u.green(`Found ${N.length} custom function(s) in "${x}"`));let P=d(b,A),F=await p(P,{logger:this.logger}),I=new Map,L=async(e,t)=>{let n=`${e??``}\u0000${t??``}`,r=I.get(n);if(r)return r;this.logger.info(u.magenta(`Connecting to the ${e?`Sombra gateway "${e}"`:`primary Sombra gateway`} to sign code...`));let i=await f(b,A,{logger:this.logger,sombraApiKey:t,...e?{sombraId:e}:{}});return I.set(n,i),i},R=e=>{if(!e.sombraAuthEnv)return y;let t=this.process.env[e.sombraAuthEnv];if(!t)throw Error(`Custom function "${e.name}" sets sombra-auth-env: ${e.sombraAuthEnv}, but that environment variable is not set. Export it (e.g. from a CI secret) before pushing.`);return t},z=[];if(await _(N,async e=>{try{let t=m(e,h(F,e),O),n=await g(P,{input:e,sombra:C?void 0:await L(t,R(e)),defaultSombraId:O,existing:F,promote:w,dryRun:C,force:T,...!E&&e.testPayloads!==void 0?{testPayloads:e.testPayloads}:{},logger:this.logger});z.push({name:e.name,result:n});let r=n.versionNumber?` (version ${n.versionNumber})`:``,i=n.changedFields.length>0?` [${n.changedFields.join(`, `)}]`:``;switch(n.outcome){case`created`:n.createdDataSilo&&n.dataSiloId&&this.logger.info(u.green(`Created DSR integration (data silo ${n.dataSiloId}) for "${e.name}"`)),this.logger.info(u.green(`Created custom function "${e.name}"${r}`));break;case`updated`:this.logger.info(u.green(`Pushed new revision to "${e.name}"${r}${i}${n.promoted?` and promoted to active`:` as a draft`}`));break;case`metadata-updated`:this.logger.info(u.green(`Updated metadata for "${e.name}"${i} — code unchanged, no new revision`));break;case`skipped`:this.logger.info(u.yellow(`Skipped "${e.name}" — no changes detected (env variable values cannot be diffed; use --force if only values changed)`));break;case`would-create`:this.logger.info(u.cyan(`[dry run] Would create custom function "${e.name}"${e.type===s.Dsr&&!e.dataSiloId?` and its DSR integration (data silo)`:``}`));break;case`would-update`:this.logger.info(u.cyan(`[dry run] Would push a new revision to "${e.name}"${i}`));break;case`test-failed`:{let t=(n.testResults??[]).filter(({passed:e})=>!e);this.logger.error(u.red(`Rejected "${e.name}" — ${t.length} of ${n.testResults?.length??0} test run(s) failed`)),t.forEach(({payloadType:e,result:t})=>{let n=e?`[${e}] `:``;this.logger.error(u.red(` ${n}${t.error?t.error.message:`failed with exit code ${t.exitCode}`}`)),t.logs.forEach(({file:e,message:t})=>{this.logger.error(u.red(` [${e}] ${t}`))})}),n.createdDataSilo&&this.logger.error(u.red(` The DSR integration (data silo) created for "${e.name}" was rolled back.`));break}}if(!E&&(e.testPayloads===void 0||e.testPayloads.length===0)&&(n.outcome===`created`||n.outcome===`updated`)&&this.logger.warn(u.yellow(`Custom function "${e.name}" was pushed without a test run — add a test-payload to its manifest entry to enable test-before-promote.`)),!E&&e.type===s.Dsr&&e.testPayloads!==void 0&&e.testPayloads.length>0&&(n.outcome===`created`||n.outcome===`updated`)){let t=new Set(e.testPayloads.map(({payloadType:e})=>e??o.DataPoint));if(t.size===1){let[n]=t,r=n===o.DataPoint?o.RequestEnricher:o.DataPoint;this.logger.warn(u.yellow(`DSR custom function "${e.name}" only tests its ${n} export — if it also implements the ${r} export, add a test payload with payload-type: ${r} so both entry points are tested on every push.`))}}}catch(t){z.push({name:e.name,error:t}),this.logger.error(u.red(`Failed to sync custom function "${e.name}": ${t.message}`))}}),D&&!C){let e=a(x,N.map((e,t)=>{let n=z[t]?.result;if(!n)return;let r={...!e.id&&n.customFunctionId?{id:n.customFunctionId}:{},...!e.dataSiloId&&n.dataSiloId?{dataSiloId:n.dataSiloId}:{}};return Object.keys(r).length>0?r:void 0}));e>0&&this.logger.info(u.green(`Wrote assigned id(s) back to ${e} manifest entr(ies) in "${x}" — commit this change so future pushes match by ID.`))}let B=e=>z.filter(({result:t})=>t?.outcome===e).length,V=z.filter(({error:e})=>e!==void 0),H=B(`test-failed`);this.logger.info(u.magenta(`Custom function sync complete: ${B(`created`)+B(`would-create`)} created, ${B(`updated`)+B(`would-update`)} updated, ${B(`metadata-updated`)} metadata-only, ${B(`skipped`)} skipped, ${H} rejected (test failed), ${V.length} failed${C?` (dry run)`:``}`)),(V.length>0||H>0)&&this.process.exit(1)}export{v as push};
2
+ //# sourceMappingURL=impl-BcJ019T2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BcJ019T2.mjs","names":[],"sources":["../src/commands/custom-functions/push/impl.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path';\n\nimport { CustomFunctionPayloadType, CustomFunctionType } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n fetchAllCustomFunctions,\n resolveEffectiveSombraId,\n resolveExistingCustomFunction,\n syncCustomFunction,\n type CustomFunctionSyncResult,\n} from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport {\n readCustomFunctionsManifest,\n writeCustomFunctionIdsToManifest,\n} from '../../../lib/custom-functions/manifest.js';\nimport { parseVariablesFromString } from '../../../lib/helpers/parseVariablesFromString.js';\nimport { assertPathPhysicallyContained } from '../../../lib/scaffolding/path-safety.js';\n\nexport interface CustomFunctionsPushCommandFlags {\n auth: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n variables: string;\n dryRun: boolean;\n promote: boolean;\n force: boolean;\n skipTests: boolean;\n updateManifest: boolean;\n sombraId?: string;\n}\n\nexport async function push(\n this: LocalContext,\n {\n auth,\n sombraAuth,\n transcendUrl,\n file = './transcend-functions.yml',\n variables,\n dryRun,\n promote,\n force,\n skipTests,\n updateManifest,\n sombraId,\n }: CustomFunctionsPushCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Read and validate the manifest before performing auth or network setup.\n if (!this.fs.existsSync(file)) {\n const scaffoldedManifest = './transcend/custom-functions/transcend-functions.yml';\n const suggestion = this.fs.existsSync(scaffoldedManifest)\n ? ` Did you mean --file=${scaffoldedManifest}?`\n : ' You can specify the file path using --file=./transcend-functions.yml';\n this.logger.error(\n colors.red(`The manifest file does not exist on disk: ${file}.${suggestion}`),\n );\n this.process.exit(1);\n }\n\n // This command operates on a single Transcend instance\n const apiKeyOrList = validateTranscendAuth(auth, this);\n if (Array.isArray(apiKeyOrList)) {\n this.logger.error(\n colors.red(\n 'transcend custom-functions push does not support a list of API keys — pass a single API key.',\n ),\n );\n this.process.exit(1);\n }\n const apiKey = apiKeyOrList as string;\n\n const vars = parseVariablesFromString(variables);\n this.logger.info(colors.magenta(`Reading manifest \"${file}\"...`));\n const manifestDirectory = dirname(resolve(file));\n const configs = readCustomFunctionsManifest(file, vars, (path) =>\n assertPathPhysicallyContained(this, manifestDirectory, path),\n );\n this.logger.info(colors.green(`Found ${configs.length} custom function(s) in \"${file}\"`));\n\n const client = buildTranscendGraphQLClient(transcendUrl, apiKey);\n\n // Fetch existing functions once to diff against\n const existing = await fetchAllCustomFunctions(client, { logger: this.logger });\n\n // Each custom function belongs to a single Sombra gateway whose keys sign\n // its code, so code must be signed against that specific gateway's customer\n // ingress. Cache one connection per distinct gateway + internal key across\n // the run.\n type SombraGot = Awaited<ReturnType<typeof createSombraGotInstance>>;\n const sombraByGateway = new Map<string, SombraGot>();\n const getSombraForGateway = async (\n gatewaySombraId: string | undefined,\n sombraApiKey: string | undefined,\n ): Promise<SombraGot> => {\n const key = `${gatewaySombraId ?? ''}\\u0000${sombraApiKey ?? ''}`;\n const cached = sombraByGateway.get(key);\n if (cached) {\n return cached;\n }\n this.logger.info(\n colors.magenta(\n `Connecting to the ${\n gatewaySombraId ? `Sombra gateway \"${gatewaySombraId}\"` : 'primary Sombra gateway'\n } to sign code...`,\n ),\n );\n const sombra = await createSombraGotInstance(transcendUrl, apiKey, {\n logger: this.logger,\n sombraApiKey,\n ...(gatewaySombraId ? { sombraId: gatewaySombraId } : {}),\n });\n sombraByGateway.set(key, sombra);\n return sombra;\n };\n\n /**\n * Resolve the Sombra internal key for a manifest entry: the env variable\n * named by `sombra-auth-env` when set (which must be exported), else the\n * `--sombraAuth` flag.\n *\n * @param input - The manifest entry\n * @returns The internal key to authenticate with, if any\n */\n const resolveEntrySombraAuth = (input: {\n /** Function name, for error messages */\n name: string;\n /** Env variable name holding the gateway's internal key */\n sombraAuthEnv?: string;\n }): string | undefined => {\n if (!input.sombraAuthEnv) {\n return sombraAuth;\n }\n const value = this.process.env[input.sombraAuthEnv];\n if (!value) {\n throw new Error(\n `Custom function \"${input.name}\" sets sombra-auth-env: ${input.sombraAuthEnv}, ` +\n 'but that environment variable is not set. Export it (e.g. from a CI secret) ' +\n 'before pushing.',\n );\n }\n return value;\n };\n\n // Sync each function in order\n const results: { name: string; result?: CustomFunctionSyncResult; error?: Error }[] = [];\n await mapSeries(configs, async (input) => {\n try {\n // Resolve the gateway this function belongs to: manifest sombra-id,\n // else the existing function's gateway, else --sombraId, else primary.\n // Also validates manifest-vs-existing gateway mismatches.\n const effectiveSombraId = resolveEffectiveSombraId(\n input,\n resolveExistingCustomFunction(existing, input),\n sombraId,\n );\n const result = await syncCustomFunction(client, {\n input,\n sombra: dryRun\n ? undefined\n : await getSombraForGateway(effectiveSombraId, resolveEntrySombraAuth(input)),\n defaultSombraId: sombraId,\n existing,\n promote,\n dryRun,\n force,\n // Test the freshly signed code before pushing; every payload must\n // pass or the function is rejected. Dry runs never sign, so nothing\n // is tested either.\n ...(!skipTests && input.testPayloads !== undefined\n ? { testPayloads: input.testPayloads }\n : {}),\n logger: this.logger,\n });\n results.push({ name: input.name, result });\n\n const suffix = result.versionNumber ? ` (version ${result.versionNumber})` : '';\n const changes =\n result.changedFields.length > 0 ? ` [${result.changedFields.join(', ')}]` : '';\n switch (result.outcome) {\n case 'created':\n if (result.createdDataSilo && result.dataSiloId) {\n this.logger.info(\n colors.green(\n `Created DSR integration (data silo ${result.dataSiloId}) for \"${input.name}\"`,\n ),\n );\n }\n this.logger.info(colors.green(`Created custom function \"${input.name}\"${suffix}`));\n break;\n case 'updated':\n this.logger.info(\n colors.green(\n `Pushed new revision to \"${input.name}\"${suffix}${changes}${\n result.promoted ? ' and promoted to active' : ' as a draft'\n }`,\n ),\n );\n break;\n case 'metadata-updated':\n this.logger.info(\n colors.green(\n `Updated metadata for \"${input.name}\"${changes} — code unchanged, no new revision`,\n ),\n );\n break;\n case 'skipped':\n this.logger.info(\n colors.yellow(\n `Skipped \"${input.name}\" — no changes detected ` +\n '(env variable values cannot be diffed; use --force if only values changed)',\n ),\n );\n break;\n case 'would-create':\n this.logger.info(\n colors.cyan(\n `[dry run] Would create custom function \"${input.name}\"${\n input.type === CustomFunctionType.Dsr && !input.dataSiloId\n ? ' and its DSR integration (data silo)'\n : ''\n }`,\n ),\n );\n break;\n case 'would-update':\n this.logger.info(\n colors.cyan(`[dry run] Would push a new revision to \"${input.name}\"${changes}`),\n );\n break;\n case 'test-failed': {\n const failed = (result.testResults ?? []).filter(({ passed }) => !passed);\n this.logger.error(\n colors.red(\n `Rejected \"${input.name}\" — ${failed.length} of ${\n result.testResults?.length ?? 0\n } test run(s) failed`,\n ),\n );\n failed.forEach(({ payloadType, result: execution }) => {\n const label = payloadType ? `[${payloadType}] ` : '';\n this.logger.error(\n colors.red(\n ` ${label}${\n execution.error\n ? execution.error.message\n : `failed with exit code ${execution.exitCode}`\n }`,\n ),\n );\n execution.logs.forEach(({ file: logFile, message }) => {\n this.logger.error(colors.red(` [${logFile}] ${message}`));\n });\n });\n if (result.createdDataSilo) {\n this.logger.error(\n colors.red(\n ` The DSR integration (data silo) created for \"${input.name}\" was rolled back.`,\n ),\n );\n }\n break;\n }\n }\n\n // Anything that reached the push path without a test payload was\n // promoted untested — call it out so payloads get added over time\n if (\n !skipTests &&\n (input.testPayloads === undefined || input.testPayloads.length === 0) &&\n (result.outcome === 'created' || result.outcome === 'updated')\n ) {\n this.logger.warn(\n colors.yellow(\n `Custom function \"${input.name}\" was pushed without a test run — add a ` +\n 'test-payload to its manifest entry to enable test-before-promote.',\n ),\n );\n }\n\n // DSR functions have two entry points (default export = DATA_POINT,\n // enricher export = REQUEST_ENRICHER); nudge toward covering both\n if (\n !skipTests &&\n input.type === CustomFunctionType.Dsr &&\n input.testPayloads !== undefined &&\n input.testPayloads.length > 0 &&\n (result.outcome === 'created' || result.outcome === 'updated')\n ) {\n const coveredTypes = new Set(\n input.testPayloads.map(\n ({ payloadType }) => payloadType ?? CustomFunctionPayloadType.DataPoint,\n ),\n );\n if (coveredTypes.size === 1) {\n const [covered] = coveredTypes;\n const uncovered =\n covered === CustomFunctionPayloadType.DataPoint\n ? CustomFunctionPayloadType.RequestEnricher\n : CustomFunctionPayloadType.DataPoint;\n this.logger.warn(\n colors.yellow(\n `DSR custom function \"${input.name}\" only tests its ${covered} export — if it ` +\n `also implements the ${uncovered} export, add a test payload with ` +\n `payload-type: ${uncovered} so both entry points are tested on every push.`,\n ),\n );\n }\n }\n } catch (err) {\n results.push({ name: input.name, error: err as Error });\n this.logger.error(\n colors.red(`Failed to sync custom function \"${input.name}\": ${(err as Error).message}`),\n );\n }\n });\n\n // Write assigned IDs back into the manifest so future pushes match by ID\n // instead of by (potentially non-unique) name, and DSR entries keep\n // pointing at their (possibly auto-created) integration\n if (updateManifest && !dryRun) {\n const idsByIndex = configs.map((input, index) => {\n const result = results[index]?.result;\n if (!result) {\n return undefined;\n }\n const ids = {\n ...(!input.id && result.customFunctionId ? { id: result.customFunctionId } : {}),\n ...(!input.dataSiloId && result.dataSiloId ? { dataSiloId: result.dataSiloId } : {}),\n };\n return Object.keys(ids).length > 0 ? ids : undefined;\n });\n const updatedCount = writeCustomFunctionIdsToManifest(file, idsByIndex);\n if (updatedCount > 0) {\n this.logger.info(\n colors.green(\n `Wrote assigned id(s) back to ${updatedCount} manifest entr(ies) in \"${file}\" — ` +\n 'commit this change so future pushes match by ID.',\n ),\n );\n }\n }\n\n // Summarize\n const count = (outcome: CustomFunctionSyncResult['outcome']): number =>\n results.filter(({ result }) => result?.outcome === outcome).length;\n const failures = results.filter(({ error }) => error !== undefined);\n const rejected = count('test-failed');\n this.logger.info(\n colors.magenta(\n `Custom function sync complete: ${count('created') + count('would-create')} created, ${\n count('updated') + count('would-update')\n } updated, ${count('metadata-updated')} metadata-only, ${count(\n 'skipped',\n )} skipped, ${rejected} rejected (test failed), ${failures.length} failed${\n dryRun ? ' (dry run)' : ''\n }`,\n ),\n );\n\n if (failures.length > 0 || rejected > 0) {\n this.process.exit(1);\n }\n}\n"],"mappings":"6oBAuCA,eAAsB,EAEpB,CACE,OACA,aACA,eACA,OAAO,4BACP,YACA,SACA,UACA,QACA,YACA,iBACA,YAEa,CAIf,GAHA,EAAoB,KAAK,QAAQ,CAG7B,CAAC,KAAK,GAAG,WAAW,EAAK,CAAE,CAC7B,IAAM,EAAqB,uDACrB,EAAa,KAAK,GAAG,WAAW,EAAmB,CACrD,wBAAwB,EAAmB,GAC3C,wEACJ,KAAK,OAAO,MACV,EAAO,IAAI,6CAA6C,EAAK,GAAG,IAAa,CAC9E,CACD,KAAK,QAAQ,KAAK,EAAE,CAItB,IAAM,EAAe,EAAsB,EAAM,KAAK,CAClD,MAAM,QAAQ,EAAa,GAC7B,KAAK,OAAO,MACV,EAAO,IACL,+FACD,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAEtB,IAAM,EAAS,EAET,EAAO,EAAyB,EAAU,CAChD,KAAK,OAAO,KAAK,EAAO,QAAQ,qBAAqB,EAAK,MAAM,CAAC,CACjE,IAAM,EAAoB,EAAQ,EAAQ,EAAK,CAAC,CAC1C,EAAU,EAA4B,EAAM,EAAO,GACvD,EAA8B,KAAM,EAAmB,EAAK,CAC7D,CACD,KAAK,OAAO,KAAK,EAAO,MAAM,SAAS,EAAQ,OAAO,0BAA0B,EAAK,GAAG,CAAC,CAEzF,IAAM,EAAS,EAA4B,EAAc,EAAO,CAG1D,EAAW,MAAM,EAAwB,EAAQ,CAAE,OAAQ,KAAK,OAAQ,CAAC,CAOzE,EAAkB,IAAI,IACtB,EAAsB,MAC1B,EACA,IACuB,CACvB,IAAM,EAAM,GAAG,GAAmB,GAAG,QAAQ,GAAgB,KACvD,EAAS,EAAgB,IAAI,EAAI,CACvC,GAAI,EACF,OAAO,EAET,KAAK,OAAO,KACV,EAAO,QACL,qBACE,EAAkB,mBAAmB,EAAgB,GAAK,yBAC3D,kBACF,CACF,CACD,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAQ,CACjE,OAAQ,KAAK,OACb,eACA,GAAI,EAAkB,CAAE,SAAU,EAAiB,CAAG,EAAE,CACzD,CAAC,CAEF,OADA,EAAgB,IAAI,EAAK,EAAO,CACzB,GAWH,EAA0B,GAKN,CACxB,GAAI,CAAC,EAAM,cACT,OAAO,EAET,IAAM,EAAQ,KAAK,QAAQ,IAAI,EAAM,eACrC,GAAI,CAAC,EACH,MAAU,MACR,oBAAoB,EAAM,KAAK,0BAA0B,EAAM,cAAc,+FAG9E,CAEH,OAAO,GAIH,EAAgF,EAAE,CA+KxF,GA9KA,MAAM,EAAU,EAAS,KAAO,IAAU,CACxC,GAAI,CAIF,IAAM,EAAoB,EACxB,EACA,EAA8B,EAAU,EAAM,CAC9C,EACD,CACK,EAAS,MAAM,EAAmB,EAAQ,CAC9C,QACA,OAAQ,EACJ,IAAA,GACA,MAAM,EAAoB,EAAmB,EAAuB,EAAM,CAAC,CAC/E,gBAAiB,EACjB,WACA,UACA,SACA,QAIA,GAAI,CAAC,GAAa,EAAM,eAAiB,IAAA,GACrC,CAAE,aAAc,EAAM,aAAc,CACpC,EAAE,CACN,OAAQ,KAAK,OACd,CAAC,CACF,EAAQ,KAAK,CAAE,KAAM,EAAM,KAAM,SAAQ,CAAC,CAE1C,IAAM,EAAS,EAAO,cAAgB,aAAa,EAAO,cAAc,GAAK,GACvE,EACJ,EAAO,cAAc,OAAS,EAAI,KAAK,EAAO,cAAc,KAAK,KAAK,CAAC,GAAK,GAC9E,OAAQ,EAAO,QAAf,CACE,IAAK,UACC,EAAO,iBAAmB,EAAO,YACnC,KAAK,OAAO,KACV,EAAO,MACL,sCAAsC,EAAO,WAAW,SAAS,EAAM,KAAK,GAC7E,CACF,CAEH,KAAK,OAAO,KAAK,EAAO,MAAM,4BAA4B,EAAM,KAAK,GAAG,IAAS,CAAC,CAClF,MACF,IAAK,UACH,KAAK,OAAO,KACV,EAAO,MACL,2BAA2B,EAAM,KAAK,GAAG,IAAS,IAChD,EAAO,SAAW,0BAA4B,gBAEjD,CACF,CACD,MACF,IAAK,mBACH,KAAK,OAAO,KACV,EAAO,MACL,yBAAyB,EAAM,KAAK,GAAG,EAAQ,oCAChD,CACF,CACD,MACF,IAAK,UACH,KAAK,OAAO,KACV,EAAO,OACL,YAAY,EAAM,KAAK,oGAExB,CACF,CACD,MACF,IAAK,eACH,KAAK,OAAO,KACV,EAAO,KACL,2CAA2C,EAAM,KAAK,GACpD,EAAM,OAAS,EAAmB,KAAO,CAAC,EAAM,WAC5C,uCACA,KAEP,CACF,CACD,MACF,IAAK,eACH,KAAK,OAAO,KACV,EAAO,KAAK,2CAA2C,EAAM,KAAK,GAAG,IAAU,CAChF,CACD,MACF,IAAK,cAAe,CAClB,IAAM,GAAU,EAAO,aAAe,EAAE,EAAE,QAAQ,CAAE,YAAa,CAAC,EAAO,CACzE,KAAK,OAAO,MACV,EAAO,IACL,aAAa,EAAM,KAAK,MAAM,EAAO,OAAO,MAC1C,EAAO,aAAa,QAAU,EAC/B,qBACF,CACF,CACD,EAAO,SAAS,CAAE,cAAa,OAAQ,KAAgB,CACrD,IAAM,EAAQ,EAAc,IAAI,EAAY,IAAM,GAClD,KAAK,OAAO,MACV,EAAO,IACL,KAAK,IACH,EAAU,MACN,EAAU,MAAM,QAChB,yBAAyB,EAAU,aAE1C,CACF,CACD,EAAU,KAAK,SAAS,CAAE,KAAM,EAAS,aAAc,CACrD,KAAK,OAAO,MAAM,EAAO,IAAI,QAAQ,EAAQ,IAAI,IAAU,CAAC,EAC5D,EACF,CACE,EAAO,iBACT,KAAK,OAAO,MACV,EAAO,IACL,kDAAkD,EAAM,KAAK,oBAC9D,CACF,CAEH,OAqBJ,GAdE,CAAC,IACA,EAAM,eAAiB,IAAA,IAAa,EAAM,aAAa,SAAW,KAClE,EAAO,UAAY,WAAa,EAAO,UAAY,YAEpD,KAAK,OAAO,KACV,EAAO,OACL,oBAAoB,EAAM,KAAK,2GAEhC,CACF,CAMD,CAAC,GACD,EAAM,OAAS,EAAmB,KAClC,EAAM,eAAiB,IAAA,IACvB,EAAM,aAAa,OAAS,IAC3B,EAAO,UAAY,WAAa,EAAO,UAAY,WACpD,CACA,IAAM,EAAe,IAAI,IACvB,EAAM,aAAa,KAChB,CAAE,iBAAkB,GAAe,EAA0B,UAC/D,CACF,CACD,GAAI,EAAa,OAAS,EAAG,CAC3B,GAAM,CAAC,GAAW,EACZ,EACJ,IAAY,EAA0B,UAClC,EAA0B,gBAC1B,EAA0B,UAChC,KAAK,OAAO,KACV,EAAO,OACL,wBAAwB,EAAM,KAAK,mBAAmB,EAAQ,sCACrC,EAAU,iDAChB,EAAU,iDAC9B,CACF,SAGE,EAAK,CACZ,EAAQ,KAAK,CAAE,KAAM,EAAM,KAAM,MAAO,EAAc,CAAC,CACvD,KAAK,OAAO,MACV,EAAO,IAAI,mCAAmC,EAAM,KAAK,KAAM,EAAc,UAAU,CACxF,GAEH,CAKE,GAAkB,CAAC,EAAQ,CAY7B,IAAM,EAAe,EAAiC,EAXnC,EAAQ,KAAK,EAAO,IAAU,CAC/C,IAAM,EAAS,EAAQ,IAAQ,OAC/B,GAAI,CAAC,EACH,OAEF,IAAM,EAAM,CACV,GAAI,CAAC,EAAM,IAAM,EAAO,iBAAmB,CAAE,GAAI,EAAO,iBAAkB,CAAG,EAAE,CAC/E,GAAI,CAAC,EAAM,YAAc,EAAO,WAAa,CAAE,WAAY,EAAO,WAAY,CAAG,EAAE,CACpF,CACD,OAAO,OAAO,KAAK,EAAI,CAAC,OAAS,EAAI,EAAM,IAAA,IAEyB,CAAC,CACnE,EAAe,GACjB,KAAK,OAAO,KACV,EAAO,MACL,gCAAgC,EAAa,0BAA0B,EAAK,sDAE7E,CACF,CAKL,IAAM,EAAS,GACb,EAAQ,QAAQ,CAAE,YAAa,GAAQ,UAAY,EAAQ,CAAC,OACxD,EAAW,EAAQ,QAAQ,CAAE,WAAY,IAAU,IAAA,GAAU,CAC7D,EAAW,EAAM,cAAc,CACrC,KAAK,OAAO,KACV,EAAO,QACL,kCAAkC,EAAM,UAAU,CAAG,EAAM,eAAe,CAAC,YACzE,EAAM,UAAU,CAAG,EAAM,eAAe,CACzC,YAAY,EAAM,mBAAmB,CAAC,kBAAkB,EACvD,UACD,CAAC,YAAY,EAAS,2BAA2B,EAAS,OAAO,SAChE,EAAS,aAAe,KAE3B,CACF,EAEG,EAAS,OAAS,GAAK,EAAW,IACpC,KAAK,QAAQ,KAAK,EAAE"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./readCsv--FfP8n-H.mjs";import{r as t}from"./uploadConsents-C5sG51Dk.mjs";import{t as n}from"./done-input-validation-DL31vk7g.mjs";import*as r from"io-ts";const i=r.intersection([r.type({userId:r.string,timestamp:r.string}),r.partial({confirmed:r.union([r.literal(`true`),r.literal(`false`)]),updated:r.union([r.literal(`true`),r.literal(`false`)]),prompted:r.union([r.literal(`true`),r.literal(`false`)]),metadata:r.string,usp:r.union([r.string,r.null]),gpp:r.union([r.string,r.null]),purposes:r.string})]);async function a({base64EncryptionKey:r,base64SigningKey:a,partition:o,file:s,consentUrl:c,concurrency:l}){n(this.process.exit),await t({base64EncryptionKey:r,base64SigningKey:a,preferences:e(s,i),partition:o,concurrency:l,transcendUrl:c})}export{a as uploadConsentPreferences};
2
- //# sourceMappingURL=impl-C2Irk48l.mjs.map
1
+ import{t as e}from"./readCsv-Cr_1t8F5.mjs";import{r as t}from"./uploadConsents-CNyuYx0o.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";import*as r from"io-ts";const i=r.intersection([r.type({userId:r.string,timestamp:r.string}),r.partial({confirmed:r.union([r.literal(`true`),r.literal(`false`)]),updated:r.union([r.literal(`true`),r.literal(`false`)]),prompted:r.union([r.literal(`true`),r.literal(`false`)]),metadata:r.string,usp:r.union([r.string,r.null]),gpp:r.union([r.string,r.null]),purposes:r.string})]);async function a({base64EncryptionKey:r,base64SigningKey:a,partition:o,file:s,consentUrl:c,concurrency:l}){n(this.process),await t({base64EncryptionKey:r,base64SigningKey:a,preferences:e(this.fs.readFileSync(s,`utf8`),i),partition:o,concurrency:l,transcendUrl:c})}export{a as uploadConsentPreferences};
2
+ //# sourceMappingURL=impl-BewF8tB6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-C2Irk48l.mjs","names":[],"sources":["../src/lib/consent-manager/types.ts","../src/commands/consent/upload-consent-preferences/impl.ts"],"sourcesContent":["import * as t from 'io-ts';\n\nexport const ConsentPreferenceUpload = t.intersection([\n t.type({\n /** User ID */\n userId: t.string,\n /** Has the consent been updated (including no-change confirmation) since default resolution */\n timestamp: t.string,\n }),\n t.partial({\n /** Was tracking consent confirmed by the user? If this is false, the consent was resolved from defaults & is not yet confirmed */\n confirmed: t.union([t.literal('true'), t.literal('false')]),\n /**\n * Has the consent been updated (including no-change confirmation) since default resolution\n */\n updated: t.union([t.literal('true'), t.literal('false')]),\n /**\n * Whether or not the UI has been shown to the end-user (undefined in older versions of airgap.js)\n */\n prompted: t.union([t.literal('true'), t.literal('false')]),\n /** Consent metadata */\n metadata: t.string,\n /** US Privacy (USP) String */\n usp: t.union([t.string, t.null]),\n /** IAB GPP String */\n gpp: t.union([t.string, t.null]),\n /**\n * Purpose map\n * This is a stringified JSON object with keys as purpose names and values as booleans or 'Auto'\n */\n purposes: t.string,\n }),\n]);\n\n/** Type override */\nexport type ConsentPreferenceUpload = t.TypeOf<typeof ConsentPreferenceUpload>;\n","import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { ConsentPreferenceUpload } from '../../../lib/consent-manager/types.js';\nimport { uploadConsents } from '../../../lib/consent-manager/uploadConsents.js';\nimport { readCsv } from '../../../lib/requests/index.js';\n\nexport interface UploadConsentPreferencesCommandFlags {\n base64EncryptionKey: string;\n base64SigningKey: string;\n partition: string;\n file: string;\n consentUrl: string;\n concurrency: number;\n}\n\nexport async function uploadConsentPreferences(\n this: LocalContext,\n {\n base64EncryptionKey,\n base64SigningKey,\n partition,\n file,\n consentUrl,\n concurrency,\n }: UploadConsentPreferencesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Load in preferences from csv\n const preferences = readCsv(file, ConsentPreferenceUpload);\n\n // Upload cookies\n await uploadConsents({\n base64EncryptionKey,\n base64SigningKey,\n preferences,\n partition,\n concurrency,\n transcendUrl: consentUrl,\n });\n}\n"],"mappings":"8KAEA,MAAa,EAA0B,EAAE,aAAa,CACpD,EAAE,KAAK,CAEL,OAAQ,EAAE,OAEV,UAAW,EAAE,OACd,CAAC,CACF,EAAE,QAAQ,CAER,UAAW,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAI3D,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAIzD,SAAU,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAE1D,SAAU,EAAE,OAEZ,IAAK,EAAE,MAAM,CAAC,EAAE,OAAQ,EAAE,KAAK,CAAC,CAEhC,IAAK,EAAE,MAAM,CAAC,EAAE,OAAQ,EAAE,KAAK,CAAC,CAKhC,SAAU,EAAE,OACb,CAAC,CACH,CAAC,CCjBF,eAAsB,EAEpB,CACE,sBACA,mBACA,YACA,OACA,aACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAMtC,MAAM,EAAe,CACnB,sBACA,mBACA,YANkB,EAAQ,EAAM,EAMrB,CACX,YACA,cACA,aAAc,EACf,CAAC"}
1
+ {"version":3,"file":"impl-BewF8tB6.mjs","names":[],"sources":["../src/lib/consent-manager/types.ts","../src/commands/consent/upload-consent-preferences/impl.ts"],"sourcesContent":["import * as t from 'io-ts';\n\nexport const ConsentPreferenceUpload = t.intersection([\n t.type({\n /** User ID */\n userId: t.string,\n /** Has the consent been updated (including no-change confirmation) since default resolution */\n timestamp: t.string,\n }),\n t.partial({\n /** Was tracking consent confirmed by the user? If this is false, the consent was resolved from defaults & is not yet confirmed */\n confirmed: t.union([t.literal('true'), t.literal('false')]),\n /**\n * Has the consent been updated (including no-change confirmation) since default resolution\n */\n updated: t.union([t.literal('true'), t.literal('false')]),\n /**\n * Whether or not the UI has been shown to the end-user (undefined in older versions of airgap.js)\n */\n prompted: t.union([t.literal('true'), t.literal('false')]),\n /** Consent metadata */\n metadata: t.string,\n /** US Privacy (USP) String */\n usp: t.union([t.string, t.null]),\n /** IAB GPP String */\n gpp: t.union([t.string, t.null]),\n /**\n * Purpose map\n * This is a stringified JSON object with keys as purpose names and values as booleans or 'Auto'\n */\n purposes: t.string,\n }),\n]);\n\n/** Type override */\nexport type ConsentPreferenceUpload = t.TypeOf<typeof ConsentPreferenceUpload>;\n","import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { ConsentPreferenceUpload } from '../../../lib/consent-manager/types.js';\nimport { uploadConsents } from '../../../lib/consent-manager/uploadConsents.js';\nimport { parseCsv } from '../../../lib/requests/readCsv.js';\n\nexport interface UploadConsentPreferencesCommandFlags {\n base64EncryptionKey: string;\n base64SigningKey: string;\n partition: string;\n file: string;\n consentUrl: string;\n concurrency: number;\n}\n\nexport async function uploadConsentPreferences(\n this: LocalContext,\n {\n base64EncryptionKey,\n base64SigningKey,\n partition,\n file,\n consentUrl,\n concurrency,\n }: UploadConsentPreferencesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Load in preferences from csv\n const preferences = parseCsv(this.fs.readFileSync(file, 'utf8'), ConsentPreferenceUpload);\n\n // Upload cookies\n await uploadConsents({\n base64EncryptionKey,\n base64SigningKey,\n preferences,\n partition,\n concurrency,\n transcendUrl: consentUrl,\n });\n}\n"],"mappings":"8KAEA,MAAa,EAA0B,EAAE,aAAa,CACpD,EAAE,KAAK,CAEL,OAAQ,EAAE,OAEV,UAAW,EAAE,OACd,CAAC,CACF,EAAE,QAAQ,CAER,UAAW,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAI3D,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAIzD,SAAU,EAAE,MAAM,CAAC,EAAE,QAAQ,OAAO,CAAE,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAE1D,SAAU,EAAE,OAEZ,IAAK,EAAE,MAAM,CAAC,EAAE,OAAQ,EAAE,KAAK,CAAC,CAEhC,IAAK,EAAE,MAAM,CAAC,EAAE,OAAQ,EAAE,KAAK,CAAC,CAKhC,SAAU,EAAE,OACb,CAAC,CACH,CAAC,CCjBF,eAAsB,EAEpB,CACE,sBACA,mBACA,YACA,OACA,aACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAMjC,MAAM,EAAe,CACnB,sBACA,mBACA,YANkB,EAAS,KAAK,GAAG,aAAa,EAAM,OAAO,CAAE,EAMpD,CACX,YACA,cACA,aAAc,EACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./skipRequestDataSilos-BSNLacnR.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,dataSiloId:r,status:i,statuses:a,transcendUrl:o,actionTypes:s}){t(this.process),await e({transcendUrl:o,auth:n,status:i,dataSiloId:r,requestStatuses:a,actionTypes:s})}export{n as skipRequestDataSilos};
2
+ //# sourceMappingURL=impl-Bq6g_xYv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-Bq6g_xYv.mjs","names":["skipRequestDataSilosHelper"],"sources":["../src/commands/request/system/skip-request-data-silos/impl.ts"],"sourcesContent":["import type {\n RequestAction,\n RequestDataSiloStatus,\n RequestStatus,\n} from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { skipRequestDataSilos as skipRequestDataSilosHelper } from '../../../../lib/requests/index.js';\n\nexport interface SkipRequestDataSilosCommandFlags {\n auth: string;\n dataSiloId: string;\n transcendUrl: string;\n statuses: RequestStatus[];\n status: (typeof RequestDataSiloStatus)['Skipped'] | (typeof RequestDataSiloStatus)['Resolved'];\n actionTypes?: RequestAction[];\n}\n\nexport async function skipRequestDataSilos(\n this: LocalContext,\n {\n auth,\n dataSiloId,\n status,\n statuses,\n transcendUrl,\n actionTypes,\n }: SkipRequestDataSilosCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await skipRequestDataSilosHelper({\n transcendUrl,\n auth,\n status,\n dataSiloId,\n requestStatuses: statuses,\n actionTypes,\n });\n}\n"],"mappings":"4GAmBA,eAAsB,EAEpB,CACE,OACA,aACA,SACA,WACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAMA,EAA2B,CAC/B,eACA,OACA,SACA,aACA,gBAAiB,EACjB,cACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{l as e}from"./constants-BG53Mbi9.mjs";import{t}from"./generateCrossAccountApiKeys-D6O_Qm3Y.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";async function r({email:r,password:i,apiKeyTitle:a,file:o,scopes:s,deleteExistingApiKey:c,createNewApiKey:l,parentOrganizationId:u,transcendUrl:d}){n(this.process);let{errors:f,apiKeys:p}=await t({transcendUrl:d,password:i,email:r,parentOrganizationId:u,deleteExistingApiKey:c,createNewApiKey:l,apiKeyTitle:a,scopes:s.map(t=>e[t].name)});this.fs.writeFileSync(o,`${JSON.stringify(p,null,2)}\n`),f.length>0&&this.process.exit(1)}export{r as generateApiKeys};
2
+ //# sourceMappingURL=impl-BqrSLoig.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BqrSLoig.mjs","names":[],"sources":["../src/commands/admin/generate-api-keys/impl.ts"],"sourcesContent":["import { ScopeName } from '@transcend-io/privacy-types';\n\nimport { SCOPES_BY_TITLE } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { generateCrossAccountApiKeys } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\n\n// Command flag interface\nexport interface GenerateApiKeysCommandFlags {\n email: string;\n password: string;\n apiKeyTitle: string;\n file: string;\n scopes: string[];\n deleteExistingApiKey: boolean;\n createNewApiKey: boolean;\n parentOrganizationId?: string;\n transcendUrl: string;\n}\n\n// Command implementation\nexport async function generateApiKeys(\n this: LocalContext,\n {\n email,\n password,\n apiKeyTitle,\n file,\n scopes,\n deleteExistingApiKey,\n createNewApiKey,\n parentOrganizationId,\n transcendUrl,\n }: GenerateApiKeysCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const scopeNames = scopes.map((scopeTitle) => SCOPES_BY_TITLE[scopeTitle].name as ScopeName);\n\n // Upload privacy requests\n const { errors, apiKeys } = await generateCrossAccountApiKeys({\n transcendUrl,\n password,\n email,\n parentOrganizationId,\n deleteExistingApiKey,\n createNewApiKey,\n apiKeyTitle,\n scopes: scopeNames,\n });\n\n // Write to disk\n this.fs.writeFileSync(file, `${JSON.stringify(apiKeys, null, 2)}\\n`);\n if (errors.length > 0) {\n this.process.exit(1);\n }\n}\n"],"mappings":"gKAqBA,eAAsB,EAEpB,CACE,QACA,WACA,cACA,OACA,SACA,uBACA,kBACA,uBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAKjC,GAAM,CAAE,SAAQ,WAAY,MAAM,EAA4B,CAC5D,eACA,WACA,QACA,uBACA,uBACA,kBACA,cACA,OAXiB,EAAO,IAAK,GAAe,EAAgB,GAAY,KAWtD,CACnB,CAAC,CAGF,KAAK,GAAG,cAAc,EAAM,GAAG,KAAK,UAAU,EAAS,KAAM,EAAE,CAAC,IAAI,CAChE,EAAO,OAAS,GAClB,KAAK,QAAQ,KAAK,EAAE"}
@@ -0,0 +1,12 @@
1
+ import{t as e}from"./readCsv-Cr_1t8F5.mjs";import{a as t}from"./writeCsv-D46aDkGf.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";import{chunk as r}from"lodash-es";import i from"node:path";import a from"colors";import{decodeCodec as o}from"@transcend-io/type-utils";import{DeletePreferenceRecordCliCsvRow as s,DeletePreferenceRecordsResponse as c,createSombraGotInstance as l,withTransientRetry as u}from"@transcend-io/sdk";import{map as d}from"@transcend-io/utils";import f from"cli-progress";async function p(e,{partition:t,identifierChunk:n,timestamp:r,logger:i}){try{let{failures:s}=o(c,await u(`Delete Preference Records`,()=>e.post(`v1/preferences/${t}/delete`,{json:{records:n.map(e=>({anchorIdentifier:e,timestamp:r.toISOString()}))}}).json(),{logger:i,maxAttempts:3,onRetry:(e,t,n)=>{i.warn(a.yellow(`Attempt ${e} to delete preference records failed: ${n}`))}}));return s.length>0?s.map(({index:e,error:t})=>({...n[e],error:t})):[]}catch(e){return n.map(t=>({...t,error:e.message}))}}async function m(e,{anchorIdentifiers:t,partition:n,timestamp:i,maxItemsInChunk:a,maxConcurrency:o,logger:s}){return(await d(r(t,a),async t=>await p(e,{partition:n,identifierChunk:t,timestamp:i,logger:s}),{concurrency:o})).flat()}async function h({auth:r,partition:o,sombraAuth:c,file:u=``,directory:p,transcendUrl:h,timestamp:g,maxConcurrency:_,maxItemsInChunk:v,receiptDirectory:y,fileConcurrency:b}){p&&u&&(this.logger.error(a.red(`Cannot provide both a directory and a file. Please provide only one.`)),this.process.exit(1)),!u&&!p&&(this.logger.error(a.red(`A file or directory must be provided. Please provide one using --file=./preferences.csv or --directory=./preferences`)),this.process.exit(1)),n(this.process);let x=[];if(p)try{let e=this.fs.readdirSync(p).filter(e=>e.endsWith(`.csv`));e.length===0&&(this.logger.error(a.red(`No CSV files found in directory: ${p}`)),this.process.exit(1)),x.push(...e.map(e=>i.join(p,e)))}catch(e){this.logger.error(a.red(`Failed to read directory: ${p}`)),this.logger.error(a.red(e.message)),this.process.exit(1)}else try{u.endsWith(`.csv`)||(this.logger.error(a.red(`File must be a CSV file`)),this.process.exit(1)),x.push(u)}catch(e){this.logger.error(a.red(`Failed to access file: ${u}`)),this.logger.error(a.red(e.message)),this.process.exit(1)}this.logger.debug(a.green(`Processing ${x.length} consent preferences files for partition: ${o}`)),this.logger.debug(`\nFiles to process: ${x.join(`, `)}\n`);let S=await l(h,r,{logger:this.logger,sombraApiKey:c,sombraUrl:this.process.env.SOMBRA_URL}),C=new f.SingleBar({format:`Deletion Progress |${a.cyan(`[{bar}]`)}| Duration: ${a.red(`{duration_formatted}`)} | {value}/{total} Files Processed `},f.Presets.shades_classic);C.start(x.length,0);let w=await d(x,async t=>{let n=await m(S,{partition:o,anchorIdentifiers:e(this.fs.readFileSync(t,`utf8`),s),timestamp:g,maxItemsInChunk:v,maxConcurrency:_,logger:this.logger});return C.increment(),n},{concurrency:b});C.stop();let T=w.flat(),E=``;T.length>0&&(E=i.join(y,`deletion-failures-${Date.now()}.csv`),t(E,T,!0)),this.logger.info(a.green(`
2
+
3
+ ==================================
4
+
5
+ `)),this.logger.info(a.green(`
6
+ #### Deletion Summary Report #####
7
+ `)),this.logger.info(a.green(`📁 Total Files Processed: ${x.length} \n❌ Errors: ${T.length} \n📝 Receipt Path: ${E||`N/A`}`)),this.logger.info(a.green(`
8
+
9
+ ==================================
10
+
11
+ `))}export{h as deletePreferenceRecords};
12
+ //# sourceMappingURL=impl-Bs-drNBf.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-Bs-drNBf.mjs","names":[],"sources":["../src/lib/preference-management/bulkDeletePreferenceRecords.ts","../src/commands/consent/delete-preference-records/impl.ts"],"sourcesContent":["import {\n DeletePreferenceRecordCliCsvRow,\n DeletePreferenceRecordsResponse,\n withTransientRetry,\n} from '@transcend-io/sdk';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport type { Got } from 'got';\nimport { chunk } from 'lodash-es';\n\nimport type { CliLogger } from '../../context.js';\nimport { logger } from '../../logger.js';\nimport { readCsv } from '../requests/index.js';\n\ninterface FailedResult extends DeletePreferenceRecordCliCsvRow {\n /** Error message describing the failure */\n error: string;\n}\n\ninterface DeletePreferenceRecordsRepositoryOptions {\n /** The partition to delete from */\n partition: string;\n /** Chunk of identifiers to delete */\n identifierChunk: DeletePreferenceRecordCliCsvRow[];\n /** the timestamp for the deletion operation */\n timestamp: Date;\n /** Command logger */\n logger: CliLogger;\n}\n\n/**\n * Options for deleting preference records\n */\ntype DeletePreferenceRecordsOptions = Omit<\n DeletePreferenceRecordsRepositoryOptions,\n 'identifierChunk' | 'logger'\n> & {\n /** The file path to read CSV rows from */\n filePath: string;\n /** Maximum items to include in each deletion chunk */\n maxItemsInChunk: number;\n /** Maximum concurrency for deletion requests */\n maxConcurrency: number;\n};\n\ntype DeletePreferenceRecordRowsOptions = Omit<DeletePreferenceRecordsOptions, 'filePath'> & {\n /** Decoded identifiers to delete */\n anchorIdentifiers: DeletePreferenceRecordCliCsvRow[];\n /** Command logger */\n logger: CliLogger;\n};\n\n/**\n *\n * Delete a chunk of preference records\n *\n * @param sombra - Sombra instance (must include auth headers)\n * @param options - Options for deletion\n * @param options.partition - The partition to delete from\n * @param options.identifierChunk - Chunk of identifiers to delete\n * @param options.timestamp - The timestamp for the deletion operation\n * @returns List of failed deletions\n */\nasync function deletePreferenceRecordsRepository(\n sombra: Got,\n {\n partition,\n identifierChunk: chunk,\n timestamp,\n logger: commandLogger,\n }: DeletePreferenceRecordsRepositoryOptions,\n): Promise<FailedResult[]> {\n try {\n const response = await withTransientRetry(\n 'Delete Preference Records',\n () =>\n sombra\n .post(`v1/preferences/${partition}/delete`, {\n json: {\n records: chunk.map((record) => ({\n anchorIdentifier: record,\n timestamp: timestamp.toISOString(),\n })),\n },\n })\n .json(),\n {\n logger: commandLogger,\n maxAttempts: 3,\n onRetry: (attempt, _err, msg) => {\n commandLogger.warn(\n colors.yellow(`Attempt ${attempt} to delete preference records failed: ${msg}`),\n );\n },\n },\n );\n const { failures } = decodeCodec(DeletePreferenceRecordsResponse, response);\n if (failures.length > 0) {\n return failures.map(({ index, error }) => ({\n ...chunk[index],\n error,\n }));\n }\n return [];\n } catch (err) {\n return chunk.map((record) => ({\n ...record,\n error: (err as Error).message,\n }));\n }\n}\n\n/**\n * Delete consent preferences for the managed consent database (delete endpoint)\n *\n * Uses POST /v1/preferences/{partition}/delete.\n *\n *\n * @param sombra - Sombra instance (must include auth headers)\n * @param options - Query options\n * @returns All nodes (only when onItems is not provided)\n */\nexport async function bulkDeletePreferenceRecords(\n sombra: Got,\n {\n partition,\n filePath,\n timestamp,\n maxItemsInChunk,\n maxConcurrency,\n }: DeletePreferenceRecordsOptions,\n): Promise<FailedResult[]> {\n const anchorIdentifiers = readCsv(filePath, DeletePreferenceRecordCliCsvRow);\n return bulkDeletePreferenceRecordsFromRows(sombra, {\n anchorIdentifiers,\n partition,\n timestamp,\n maxItemsInChunk,\n maxConcurrency,\n logger,\n });\n}\n\n/**\n * Delete decoded consent preference identifiers from the managed consent database.\n *\n * @param sombra - Sombra instance with authentication headers.\n * @param options - Decoded rows and deletion options.\n * @returns Failed deletions.\n */\nexport async function bulkDeletePreferenceRecordsFromRows(\n sombra: Got,\n {\n anchorIdentifiers,\n partition,\n timestamp,\n maxItemsInChunk,\n maxConcurrency,\n logger,\n }: DeletePreferenceRecordRowsOptions,\n): Promise<FailedResult[]> {\n const chunks = chunk(anchorIdentifiers, maxItemsInChunk);\n\n const failedResults = await map(\n chunks,\n async (identifierChunk) => {\n const failedResults = await deletePreferenceRecordsRepository(sombra, {\n partition,\n identifierChunk,\n timestamp,\n logger,\n });\n return failedResults;\n },\n { concurrency: maxConcurrency },\n );\n return failedResults.flat();\n}\n","import path from 'node:path';\n\nimport { createSombraGotInstance, DeletePreferenceRecordCliCsvRow } from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { writeCsv } from '../../../lib/helpers/index.js';\nimport { bulkDeletePreferenceRecordsFromRows } from '../../../lib/preference-management/index.js';\nimport { parseCsv } from '../../../lib/requests/readCsv.js';\n\nexport interface DeletePreferenceRecordsCommandFlags {\n /** Transcend API key for authentication */\n auth: string;\n /** Partition ID to delete preference records from */\n partition: string;\n /** Optional Sombra internal key for self-hosted instances */\n sombraAuth?: string;\n /** Path to the CSV file used to identify preference records to delete */\n file?: string;\n /** Path to the directory of CSV files to load preferences from */\n directory?: string;\n /** Base URL for the Transcend API */\n transcendUrl: string;\n /** The timestamp when the deletion operation is made. Used for logging purposes. */\n timestamp: Date;\n /** Maximum items to include in each deletion chunk */\n maxItemsInChunk: number;\n /** Maximum concurrency for deletion requests */\n maxConcurrency: number;\n /** Directory to write receipts of failed deletions to */\n receiptDirectory: string;\n /** Number of files to process concurrently when deleting preference records from multiple files */\n fileConcurrency: number;\n}\n\nexport async function deletePreferenceRecords(\n this: LocalContext,\n {\n auth,\n partition,\n sombraAuth,\n file = '',\n directory,\n transcendUrl,\n timestamp,\n maxConcurrency,\n maxItemsInChunk,\n receiptDirectory,\n fileConcurrency,\n }: DeletePreferenceRecordsCommandFlags,\n): Promise<void> {\n if (!!directory && !!file) {\n this.logger.error(\n colors.red('Cannot provide both a directory and a file. Please provide only one.'),\n );\n this.process.exit(1);\n }\n\n if (!file && !directory) {\n this.logger.error(\n colors.red(\n 'A file or directory must be provided. Please provide one using --file=./preferences.csv or --directory=./preferences',\n ),\n );\n this.process.exit(1);\n }\n doneInputValidation(this.process);\n\n const files: string[] = [];\n\n if (directory) {\n try {\n const filesInDirectory = this.fs.readdirSync(directory);\n const csvFiles = filesInDirectory.filter((file) => file.endsWith('.csv'));\n\n if (csvFiles.length === 0) {\n this.logger.error(colors.red(`No CSV files found in directory: ${directory}`));\n this.process.exit(1);\n }\n\n // Add full paths for each CSV file\n files.push(...csvFiles.map((file) => path.join(directory, file)));\n } catch (err) {\n this.logger.error(colors.red(`Failed to read directory: ${directory}`));\n this.logger.error(colors.red((err as Error).message));\n this.process.exit(1);\n }\n } else {\n try {\n // Verify file exists and is a CSV\n if (!file.endsWith('.csv')) {\n this.logger.error(colors.red('File must be a CSV file'));\n this.process.exit(1);\n }\n files.push(file);\n } catch (err) {\n this.logger.error(colors.red(`Failed to access file: ${file}`));\n this.logger.error(colors.red((err as Error).message));\n this.process.exit(1);\n }\n }\n\n this.logger.debug(\n colors.green(\n `Processing ${files.length} consent preferences files for partition: ${partition}`,\n ),\n );\n this.logger.debug(`\\nFiles to process: ${files.join(', ')}\\n`);\n\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, {\n logger: this.logger,\n sombraApiKey: sombraAuth,\n sombraUrl: this.process.env.SOMBRA_URL,\n });\n const globalProgressBar = new cliProgress.SingleBar(\n {\n format: `Deletion Progress |${colors.cyan('[{bar}]')}| Duration: ${colors.red(\n '{duration_formatted}',\n )} | {value}/{total} Files Processed `,\n },\n cliProgress.Presets.shades_classic,\n );\n globalProgressBar.start(files.length, 0);\n\n // Process batch of files with concurrency\n const failedResultsArrays = await map(\n files,\n async (filePath) => {\n const anchorIdentifiers = parseCsv(\n this.fs.readFileSync(filePath, 'utf8'),\n DeletePreferenceRecordCliCsvRow,\n );\n const result = await bulkDeletePreferenceRecordsFromRows(sombra, {\n partition,\n anchorIdentifiers,\n timestamp,\n maxItemsInChunk,\n maxConcurrency,\n logger: this.logger,\n });\n globalProgressBar.increment();\n return result;\n },\n { concurrency: fileConcurrency },\n );\n globalProgressBar.stop();\n const failedResults = failedResultsArrays.flat();\n\n // Check for failed results and write receipt if any\n let receiptPath = '';\n if (failedResults.length > 0) {\n receiptPath = path.join(receiptDirectory, `deletion-failures-${Date.now()}.csv`);\n writeCsv(receiptPath, failedResults, true);\n }\n\n this.logger.info(colors.green('\\n\\n ================================== \\n\\n'));\n this.logger.info(colors.green('\\n#### Deletion Summary Report #####\\n'));\n this.logger.info(\n colors.green(\n `📁 Total Files Processed: ${files.length} \\n` +\n `❌ Errors: ${failedResults.length} \\n` +\n `📝 Receipt Path: ${receiptPath || 'N/A'}`,\n ),\n );\n this.logger.info(colors.green('\\n\\n==================================\\n\\n'));\n}\n"],"mappings":"4fAgEA,eAAe,EACb,EACA,CACE,YACA,gBAAiB,EACjB,YACA,OAAQ,GAEe,CACzB,GAAI,CAwBF,GAAM,CAAE,YAAa,EAAY,EAAiC,MAvB3C,EACrB,gCAEE,EACG,KAAK,kBAAkB,EAAU,SAAU,CAC1C,KAAM,CACJ,QAAS,EAAM,IAAK,IAAY,CAC9B,iBAAkB,EAClB,UAAW,EAAU,aAAa,CACnC,EAAE,CACJ,CACF,CAAC,CACD,MAAM,CACX,CACE,OAAQ,EACR,YAAa,EACb,SAAU,EAAS,EAAM,IAAQ,CAC/B,EAAc,KACZ,EAAO,OAAO,WAAW,EAAQ,wCAAwC,IAAM,CAChF,EAEJ,CACF,CAC0E,CAO3E,OANI,EAAS,OAAS,EACb,EAAS,KAAK,CAAE,QAAO,YAAa,CACzC,GAAG,EAAM,GACT,QACD,EAAE,CAEE,EAAE,OACF,EAAK,CACZ,OAAO,EAAM,IAAK,IAAY,CAC5B,GAAG,EACH,MAAQ,EAAc,QACvB,EAAE,EA0CP,eAAsB,EACpB,EACA,CACE,oBACA,YACA,YACA,kBACA,iBACA,UAEuB,CAgBzB,OAAO,MAbqB,EAFb,EAAM,EAAmB,EAGhC,CACN,KAAO,IAOE,MANqB,EAAkC,EAAQ,CACpE,YACA,kBACA,YACA,SACD,CAAC,CAGJ,CAAE,YAAa,EAAgB,CAChC,EACoB,MAAM,CC3I7B,eAAsB,EAEpB,CACE,OACA,YACA,aACA,OAAO,GACP,YACA,eACA,YACA,iBACA,kBACA,mBACA,mBAEa,CACT,GAAe,IACnB,KAAK,OAAO,MACV,EAAO,IAAI,uEAAuE,CACnF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGlB,CAAC,GAAQ,CAAC,IACZ,KAAK,OAAO,MACV,EAAO,IACL,uHACD,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAEtB,EAAoB,KAAK,QAAQ,CAEjC,IAAM,EAAkB,EAAE,CAE1B,GAAI,EACF,GAAI,CAEF,IAAM,EADmB,KAAK,GAAG,YAAY,EACZ,CAAC,OAAQ,GAAS,EAAK,SAAS,OAAO,CAAC,CAErE,EAAS,SAAW,IACtB,KAAK,OAAO,MAAM,EAAO,IAAI,oCAAoC,IAAY,CAAC,CAC9E,KAAK,QAAQ,KAAK,EAAE,EAItB,EAAM,KAAK,GAAG,EAAS,IAAK,GAAS,EAAK,KAAK,EAAW,EAAK,CAAC,CAAC,OAC1D,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,6BAA6B,IAAY,CAAC,CACvE,KAAK,OAAO,MAAM,EAAO,IAAK,EAAc,QAAQ,CAAC,CACrD,KAAK,QAAQ,KAAK,EAAE,MAGtB,GAAI,CAEG,EAAK,SAAS,OAAO,GACxB,KAAK,OAAO,MAAM,EAAO,IAAI,0BAA0B,CAAC,CACxD,KAAK,QAAQ,KAAK,EAAE,EAEtB,EAAM,KAAK,EAAK,OACT,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,0BAA0B,IAAO,CAAC,CAC/D,KAAK,OAAO,MAAM,EAAO,IAAK,EAAc,QAAQ,CAAC,CACrD,KAAK,QAAQ,KAAK,EAAE,CAIxB,KAAK,OAAO,MACV,EAAO,MACL,cAAc,EAAM,OAAO,4CAA4C,IACxE,CACF,CACD,KAAK,OAAO,MAAM,uBAAuB,EAAM,KAAK,KAAK,CAAC,IAAI,CAG9D,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,OAAQ,KAAK,OACb,aAAc,EACd,UAAW,KAAK,QAAQ,IAAI,WAC7B,CAAC,CACI,EAAoB,IAAI,EAAY,UACxC,CACE,OAAQ,sBAAsB,EAAO,KAAK,UAAU,CAAC,cAAc,EAAO,IACxE,uBACD,CAAC,qCACH,CACD,EAAY,QAAQ,eACrB,CACD,EAAkB,MAAM,EAAM,OAAQ,EAAE,CAGxC,IAAM,EAAsB,MAAM,EAChC,EACA,KAAO,IAAa,CAKlB,IAAM,EAAS,MAAM,EAAoC,EAAQ,CAC/D,YACA,kBANwB,EACxB,KAAK,GAAG,aAAa,EAAU,OAAO,CACtC,EAIiB,CACjB,YACA,kBACA,iBACA,OAAQ,KAAK,OACd,CAAC,CAEF,OADA,EAAkB,WAAW,CACtB,GAET,CAAE,YAAa,EAAiB,CACjC,CACD,EAAkB,MAAM,CACxB,IAAM,EAAgB,EAAoB,MAAM,CAG5C,EAAc,GACd,EAAc,OAAS,IACzB,EAAc,EAAK,KAAK,EAAkB,qBAAqB,KAAK,KAAK,CAAC,MAAM,CAChF,EAAS,EAAa,EAAe,GAAK,EAG5C,KAAK,OAAO,KAAK,EAAO,MAAM;;;;EAA+C,CAAC,CAC9E,KAAK,OAAO,KAAK,EAAO,MAAM;;EAAyC,CAAC,CACxE,KAAK,OAAO,KACV,EAAO,MACL,6BAA6B,EAAM,OAAO,eAC3B,EAAc,OAAO,sBACd,GAAe,QACtC,CACF,CACD,KAAK,OAAO,KAAK,EAAO,MAAM;;;;EAA6C,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./skipPreflightJobs-Beia_iB6.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,transcendUrl:r,enricherIds:i}){t(this.process),await e({transcendUrl:r,auth:n,enricherIds:i})}export{n as skipPreflightJobs};
2
+ //# sourceMappingURL=impl-BsC1KVxS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BsC1KVxS.mjs","names":["skipPreflightJobsHelper"],"sources":["../src/commands/request/skip-preflight-jobs/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { skipPreflightJobs as skipPreflightJobsHelper } from '../../../lib/requests/index.js';\n\nexport interface SkipPreflightJobsCommandFlags {\n auth: string;\n enricherIds: string[];\n transcendUrl: string;\n}\n\nexport async function skipPreflightJobs(\n this: LocalContext,\n { auth, transcendUrl, enricherIds }: SkipPreflightJobsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await skipPreflightJobsHelper({\n transcendUrl,\n auth,\n enricherIds,\n });\n}\n"],"mappings":"yGAUA,eAAsB,EAEpB,CAAE,OAAM,eAAc,eACP,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAMA,EAAwB,CAC5B,eACA,OACA,cACD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import{r as e,t}from"./policyEngineCliError-DY8V-qkK.mjs";import{i as n,r,t as i}from"./printResult-esxW3HhT.mjs";import{t as a}from"./formatPolicyBundleVersionSummary-CrFtcPwS.mjs";import{n as o}from"./resolveBundleIdByName-DuxWYrDF.mjs";import{t as s}from"./done-input-validation-Cjk7a3jX.mjs";import c from"colors";async function l({"bundle-name":l,auth:u,"transcend-url":d,json:f,debug:p=!1}){s(this.process),e(p);let m=n(d,u),h=await o(m,l);if(!h)throw Error(`Policy bundle "${l}" was not found for this organization.`);this.logger.info(c.green(`Deactivating active version for bundle "${l}"...`));let g;try{g=await m.post(`v1/policy-engine/policy-bundles/${h}/deactivate`).json()}catch(e){if(e?.response?.statusCode===409)throw new t(`Policy bundle "${l}" has no active version.`,{cause:e});r(e)}i(this.process.stdout,{json:f,data:g,renderTable:()=>[`bundleId ${g.bundle.id}`,`bundleName ${g.bundle.bundleName}`,a(g.version)].join(`
2
+ `)}),this.logger.info(c.green(`Policy bundle version deactivated.`))}export{l as deactivate};
3
+ //# sourceMappingURL=impl-BvNZqLrT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BvNZqLrT.mjs","names":[],"sources":["../src/commands/policy/deactivate/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport {\n buildPolicyEngineClient,\n formatPolicyBundleVersionSummary,\n printResult,\n resolveBundleIdByName,\n setPolicyEngineCliDebug,\n throwPolicyEngineRequestError,\n PolicyEngineCliError,\n} from '../helpers/index.js';\nimport type { DeactivatePolicyBundleResponse } from '../types.js';\n\n/** CLI flags for `transcend policy deactivate`. */\nexport interface DeactivateCommandFlags {\n /** Logical bundle name to deactivate */\n 'bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Print raw JSON response */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Deactivate the currently active version of a policy bundle.\n *\n * Resolves `--bundle-name` to the parent bundle UUID internally, then calls the\n * Policy Engine deactivate endpoint. The bundle is addressed by name only -- the\n * UUID is never exposed to the operator.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function deactivate(\n this: LocalContext,\n {\n 'bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n json,\n debug = false,\n }: DeactivateCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n\n const resolvedBundleId = await resolveBundleIdByName(client, bundleName);\n if (!resolvedBundleId) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n\n this.logger.info(colors.green(`Deactivating active version for bundle \"${bundleName}\"...`));\n\n let body: DeactivatePolicyBundleResponse;\n try {\n body = await client\n .post(`v1/policy-engine/policy-bundles/${resolvedBundleId}/deactivate`)\n .json<DeactivatePolicyBundleResponse>();\n } catch (err) {\n // The monolith 409 references the internal bundle UUID; rewrite it to the\n // user-supplied bundle name so the error is actionable.\n const statusCode = (err as { response?: { statusCode?: number } })?.response?.statusCode;\n if (statusCode === 409) {\n throw new PolicyEngineCliError(`Policy bundle \"${bundleName}\" has no active version.`, {\n cause: err,\n });\n }\n throwPolicyEngineRequestError(err);\n }\n\n printResult(this.process.stdout, {\n json,\n data: body,\n renderTable: () =>\n [\n `bundleId ${body.bundle.id}`,\n `bundleName ${body.bundle.bundleName}`,\n formatPolicyBundleVersionSummary(body.version),\n ].join('\\n'),\n });\n\n this.logger.info(colors.green('Policy bundle version deactivated.'));\n}\n"],"mappings":"8TAuCA,eAAsB,EAEpB,CACE,cAAe,EACf,OACA,gBAAiB,EACjB,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CAEpD,EAAmB,MAAM,EAAsB,EAAQ,EAAW,CACxE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,KAAK,OAAO,KAAK,EAAO,MAAM,2CAA2C,EAAW,MAAM,CAAC,CAE3F,IAAI,EACJ,GAAI,CACF,EAAO,MAAM,EACV,KAAK,mCAAmC,EAAiB,aAAa,CACtE,MAAsC,OAClC,EAAK,CAIZ,GADoB,GAAgD,UAAU,aAC3D,IACjB,MAAM,IAAI,EAAqB,kBAAkB,EAAW,0BAA2B,CACrF,MAAO,EACR,CAAC,CAEJ,EAA8B,EAAI,CAGpC,EAAY,KAAK,QAAQ,OAAQ,CAC/B,OACA,KAAM,EACN,gBACE,CACE,eAAe,EAAK,OAAO,KAC3B,eAAe,EAAK,OAAO,aAC3B,EAAiC,EAAK,QAAQ,CAC/C,CAAC,KAAK;EAAK,CACf,CAAC,CAEF,KAAK,OAAO,KAAK,EAAO,MAAM,qCAAqC,CAAC"}
@@ -1,4 +1,4 @@
1
- import{t as e}from"./constants-DyD22MtN.mjs";import{t}from"./logger-Ckep4QXn.mjs";import{t as n}from"./done-input-validation-DL31vk7g.mjs";import{n as r}from"./constants-BgCEW975.mjs";import i from"fast-glob";import a from"colors";import{buildTranscendGraphQLClient as o,fetchActiveSiloDiscoPlugin as s,uploadSiloDiscoveryResults as c}from"@transcend-io/sdk";import{stringify as l}from"query-string";async function u({scanPath:e,fileGlobs:n,ignoreDirs:r,config:a}){let{ignoreDirs:o,supportedFiles:s,scanFunction:c}=a,l=n===``?s:s.concat(n.split(`,`)),d=[...r.split(`,`),...o].filter(e=>e.length>0);try{let n=await i(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(`Scanning: ${n.length} files`);let r=n.map(e=>c(e)).flat().map(e=>e.softwareDevelopmentKits||[]).flat(),a=[...new Set(r.map(e=>e.name))];return t.info(`Found: ${a.length} unique dependencies`),a.map(t=>({name:t,resourceId:`${e}/**/${t}`,useStrictClassifier:!0}))}catch(e){throw Error(`Error scanning globs ${u} with error: ${e}`)}}async function d({scanPath:i,dataSiloId:d,auth:f,fileGlobs:p,ignoreDirs:m,transcendUrl:h}){n(this.process.exit);let g=o(h,f),_=await s(g,{logger:t,filterBy:{dataSiloId:d}}),v=r[_.dataSilo.type];v||(t.error(a.red(`This plugin "${_.dataSilo.type}" is not supported for offline silo discovery.`)),this.process.exit(1));let y=await u({scanPath:i,fileGlobs:p,ignoreDirs:m,config:v});await c(g,{pluginId:_.id,results:y,logger:t});let b=new URL(e);b.pathname=`/data-map/data-inventory/silo-discovery/triage`,b.search=l({filters:JSON.stringify({pluginIds:[_.id]})}),t.info(a.green(`Scan found ${y.length} potential data silos at ${i}! View at '${b.href}'
1
+ import{t as e}from"./constants-BG53Mbi9.mjs";import{t}from"./logger-9T6vva73.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";import{n as r}from"./constants-BpQ5awGp.mjs";import i from"fast-glob";import a from"colors";import{buildTranscendGraphQLClient as o,fetchActiveSiloDiscoPlugin as s,uploadSiloDiscoveryResults as c}from"@transcend-io/sdk";import{stringify as l}from"query-string";async function u({scanPath:e,fileGlobs:n,ignoreDirs:r,config:a}){let{ignoreDirs:o,supportedFiles:s,scanFunction:c}=a,l=n===``?s:s.concat(n.split(`,`)),d=[...r.split(`,`),...o].filter(e=>e.length>0);try{let n=await i(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(`Scanning: ${n.length} files`);let r=n.map(e=>c(e)).flat().map(e=>e.softwareDevelopmentKits||[]).flat(),a=[...new Set(r.map(e=>e.name))];return t.info(`Found: ${a.length} unique dependencies`),a.map(t=>({name:t,resourceId:`${e}/**/${t}`,useStrictClassifier:!0}))}catch(e){throw Error(`Error scanning globs ${u} with error: ${e}`)}}async function d({scanPath:t,dataSiloId:i,auth:d,fileGlobs:f,ignoreDirs:p,transcendUrl:m}){n(this.process);let h=o(m,d),g=await s(h,{logger:this.logger,filterBy:{dataSiloId:i}}),_=r[g.dataSilo.type];_||(this.logger.error(a.red(`This plugin "${g.dataSilo.type}" is not supported for offline silo discovery.`)),this.process.exit(1));let v=await u({scanPath:t,fileGlobs:f,ignoreDirs:p,config:_});await c(h,{pluginId:g.id,results:v,logger:this.logger});let y=new URL(e);y.pathname=`/data-map/data-inventory/silo-discovery/triage`,y.search=l({filters:JSON.stringify({pluginIds:[g.id]})}),this.logger.info(a.green(`Scan found ${v.length} potential data silos at ${t}! View at '${y.href}'
2
2
 
3
3
  NOTE: it may take 2-3 minutes for scan results to appear in the UI.`))}export{d as discoverSilos};
4
- //# sourceMappingURL=impl-CIncREux.mjs.map
4
+ //# sourceMappingURL=impl-BwRcpAno.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BwRcpAno.mjs","names":[],"sources":["../src/lib/code-scanning/findFilesToScan.ts","../src/commands/inventory/discover-silos/impl.ts"],"sourcesContent":["import fastGlob from 'fast-glob';\n\nimport { logger } from '../../logger.js';\nimport { CodeScanningConfig } from './types.js';\n\nexport interface SiloDiscoveryRawResults {\n /** The name of the potential data silo entry */\n name: string;\n /** A unique UUID (represents the same resource across different silo discovery runs) */\n resourceId: string;\n /** Any hosts associated with the entry */\n host?: string;\n /** Type of data silo */\n type?: string | undefined;\n}\n\n/**\n * Helper to scan for data silos in all package.json files that it can find in a directory\n *\n * @deprecated TODO: https://transcend.height.app/T-32325 - use code scanning instead\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n}: {\n /** Where to look for package.json files */\n scanPath: string;\n /** Globs to look for */\n fileGlobs: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs: string;\n /** Silo Discovery configuration */\n config: CodeScanningConfig;\n}): Promise<SiloDiscoveryRawResults[]> {\n const { ignoreDirs: IGNORE_DIRS, supportedFiles, scanFunction } = config;\n const globsToSupport =\n fileGlobs === '' ? supportedFiles : supportedFiles.concat(fileGlobs.split(','));\n const dirsToIgnore = [...ignoreDirs.split(','), ...IGNORE_DIRS].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${globsToSupport.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(`Scanning: ${filesToScan.length} files`);\n const allPackages = filesToScan.map((filePath: string) => scanFunction(filePath)).flat();\n const allSdks = allPackages\n .map((appPackage) => appPackage.softwareDevelopmentKits || [])\n .flat();\n const uniqueDeps = new Set(allSdks.map((sdk) => sdk.name));\n const deps = [...uniqueDeps];\n logger.info(`Found: ${deps.length} unique dependencies`);\n return deps.map((dep) => ({\n name: dep,\n resourceId: `${scanPath}/**/${dep}`,\n useStrictClassifier: true,\n }));\n } catch (error) {\n throw new Error(`Error scanning globs ${findFilesToScan} with error: ${error}`);\n }\n}\n","import {\n buildTranscendGraphQLClient,\n fetchActiveSiloDiscoPlugin,\n uploadSiloDiscoveryResults,\n} from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { stringify } from 'query-string';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findFilesToScan } from '../../../lib/code-scanning/findFilesToScan.js';\nimport { SILO_DISCOVERY_CONFIGS } from '../../../lib/code-scanning/index.js';\n\nexport interface DiscoverSilosCommandFlags {\n scanPath: string;\n dataSiloId: string;\n auth: string;\n fileGlobs: string;\n ignoreDirs: string;\n transcendUrl: string;\n}\n\nexport async function discoverSilos(\n this: LocalContext,\n { scanPath, dataSiloId, auth, fileGlobs, ignoreDirs, transcendUrl }: DiscoverSilosCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const plugin = await fetchActiveSiloDiscoPlugin(client, {\n logger: this.logger,\n filterBy: { dataSiloId },\n });\n\n const config = SILO_DISCOVERY_CONFIGS[plugin.dataSilo.type];\n if (!config) {\n this.logger.error(\n colors.red(\n `This plugin \"${plugin.dataSilo.type}\" is not supported for offline silo discovery.`,\n ),\n );\n this.process.exit(1);\n }\n\n const results = await findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n });\n\n await uploadSiloDiscoveryResults(client, {\n pluginId: plugin.id,\n results,\n logger: this.logger,\n });\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/data-map/data-inventory/silo-discovery/triage';\n newUrl.search = stringify({\n filters: JSON.stringify({ pluginIds: [plugin.id] }),\n });\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Scan found ${results.length} potential data silos at ${scanPath}! ` +\n `View at '${newUrl.href}' ` +\n '\\n\\n NOTE: it may take 2-3 minutes for scan results to appear in the UI.',\n ),\n );\n}\n"],"mappings":"gZAuBA,eAAsB,EAAgB,CACpC,WACA,YACA,aACA,UAUqC,CACrC,GAAM,CAAE,WAAY,EAAa,iBAAgB,gBAAiB,EAC5D,EACJ,IAAc,GAAK,EAAiB,EAAe,OAAO,EAAU,MAAM,IAAI,CAAC,CAC3E,EAAe,CAAC,GAAG,EAAW,MAAM,IAAI,CAAE,GAAG,EAAY,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC/F,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KAAK,aAAa,EAAY,OAAO,QAAQ,CAEpD,IAAM,EADc,EAAY,IAAK,GAAqB,EAAa,EAAS,CAAC,CAAC,MACvD,CACxB,IAAK,GAAe,EAAW,yBAA2B,EAAE,CAAC,CAC7D,MAAM,CAEH,EAAO,CAAC,GAAG,IADM,IAAI,EAAQ,IAAK,GAAQ,EAAI,KAAK,CAC9B,CAAC,CAE5B,OADA,EAAO,KAAK,UAAU,EAAK,OAAO,sBAAsB,CACjD,EAAK,IAAK,IAAS,CACxB,KAAM,EACN,WAAY,GAAG,EAAS,MAAM,IAC9B,oBAAqB,GACtB,EAAE,OACI,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAgB,eAAe,IAAQ,ECvCnF,eAAsB,EAEpB,CAAE,WAAU,aAAY,OAAM,YAAW,aAAY,gBACtC,CACf,EAAoB,KAAK,QAAQ,CAGjC,IAAM,EAAS,EAA4B,EAAc,EAAK,CAExD,EAAS,MAAM,EAA2B,EAAQ,CACtD,OAAQ,KAAK,OACb,SAAU,CAAE,aAAY,CACzB,CAAC,CAEI,EAAS,EAAuB,EAAO,SAAS,MACjD,IACH,KAAK,OAAO,MACV,EAAO,IACL,gBAAgB,EAAO,SAAS,KAAK,gDACtC,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,IAAM,EAAU,MAAM,EAAgB,CACpC,WACA,YACA,aACA,SACD,CAAC,CAEF,MAAM,EAA2B,EAAQ,CACvC,SAAU,EAAO,GACjB,UACA,OAAQ,KAAK,OACd,CAAC,CAEF,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,iDAClB,EAAO,OAAS,EAAU,CACxB,QAAS,KAAK,UAAU,CAAE,UAAW,CAAC,EAAO,GAAG,CAAE,CAAC,CACpD,CAAC,CAGF,KAAK,OAAO,KACV,EAAO,MACL,cAAc,EAAQ,OAAO,2BAA2B,EAAS,aACnD,EAAO,KAAK;;sEAE3B,CACF"}
@@ -0,0 +1,3 @@
1
+ import{r as e,t}from"./policyEngineCliError-DY8V-qkK.mjs";import{i as n,n as r,t as i}from"./printResult-esxW3HhT.mjs";import{t as a}from"./formatPolicyBundleVersionSummary-CrFtcPwS.mjs";import{n as o}from"./resolveBundleIdByName-DuxWYrDF.mjs";import{t as s}from"./resolvePolicyBundleVersion-DhXZKwb4.mjs";import{t as c}from"./done-input-validation-Cjk7a3jX.mjs";import l from"colors";async function u({"bundle-name":u,version:d,auth:f,"transcend-url":p,"dry-run":m,json:h,debug:g=!1}){c(this.process),e(g);let _=n(p,f),v=await o(_,u);if(!v)throw Error(`Policy bundle "${u}" was not found for this organization.`);let y=await s(_,v,{version:d});this.logger.info(l.green(m?`Validating activation for version "${y.version}"...`:`Activating version "${y.version}"...`));let b;try{b=await r(_.post(`v1/policy-engine/policy-bundles/${v}/versions/${y.id}/activate`,{json:m?{dryRun:!0}:{}}).json())}catch(e){throw(e instanceof t?e.cause:void 0)?.response?.statusCode===409?new t(`Version "${y.version}" of policy bundle "${u}" is already the active version.`,{cause:e}):e}i(this.process.stdout,{json:h,data:b,renderTable:()=>[`bundleId ${b.bundle.id}`,`bundleName ${b.bundle.bundleName}`,a(b.version)].join(`
2
+ `)}),this.logger.info(l.green(m?`Activation validation succeeded.`:`Policy bundle version activated.`))}export{u as activate};
3
+ //# sourceMappingURL=impl-BySmbxEt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-BySmbxEt.mjs","names":[],"sources":["../src/commands/policy/activate/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport {\n buildPolicyEngineClient,\n formatPolicyBundleVersionSummary,\n policyEngineRequest,\n PolicyEngineCliError,\n printResult,\n resolveBundleIdByName,\n resolvePolicyBundleVersion,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { ActivatePolicyBundleVersionResponse } from '../types.js';\n\n/** CLI flags for `transcend policy activate`. */\nexport interface ActivateCommandFlags {\n /** Logical bundle name to activate */\n 'bundle-name': string;\n /** Caller-supplied version label to activate */\n version?: string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Validate activation without flipping */\n 'dry-run': boolean;\n /** Print raw JSON response */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Activate an uploaded policy bundle version.\n *\n * Resolves `--bundle-name` to the parent bundle UUID internally, then calls the\n * Policy Engine activate endpoint. The bundle is addressed by name only -- the\n * UUID is never exposed to the operator.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function activate(\n this: LocalContext,\n {\n 'bundle-name': bundleName,\n version,\n auth,\n 'transcend-url': transcendUrl,\n 'dry-run': dryRun,\n json,\n debug = false,\n }: ActivateCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const resolvedBundleId = await resolveBundleIdByName(client, bundleName);\n if (!resolvedBundleId) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n const resolvedVersion = await resolvePolicyBundleVersion(client, resolvedBundleId, { version });\n\n this.logger.info(\n colors.green(\n dryRun\n ? `Validating activation for version \"${resolvedVersion.version}\"...`\n : `Activating version \"${resolvedVersion.version}\"...`,\n ),\n );\n\n let body: ActivatePolicyBundleVersionResponse;\n try {\n body = await policyEngineRequest(\n client\n .post(\n `v1/policy-engine/policy-bundles/${resolvedBundleId}/versions/${resolvedVersion.id}/activate`,\n {\n json: dryRun ? { dryRun: true } : {},\n },\n )\n .json<ActivatePolicyBundleVersionResponse>(),\n );\n } catch (err) {\n // A 409 here means the requested version is already the active version --\n // surface that specifically (referencing the operator-facing bundle name\n // and version label) rather than the generic conflict fallback.\n const statusCode = (\n err instanceof PolicyEngineCliError\n ? (err.cause as { response?: { statusCode?: number } } | undefined)\n : undefined\n )?.response?.statusCode;\n if (statusCode === 409) {\n throw new PolicyEngineCliError(\n `Version \"${resolvedVersion.version}\" of policy bundle \"${bundleName}\" is already the active version.`,\n { cause: err },\n );\n }\n throw err;\n }\n\n printResult(this.process.stdout, {\n json,\n data: body,\n renderTable: () =>\n [\n `bundleId ${body.bundle.id}`,\n `bundleName ${body.bundle.bundleName}`,\n formatPolicyBundleVersionSummary(body.version),\n ].join('\\n'),\n });\n\n this.logger.info(\n colors.green(dryRun ? 'Activation validation succeeded.' : 'Policy bundle version activated.'),\n );\n}\n"],"mappings":"iYA4CA,eAAsB,EAEpB,CACE,cAAe,EACf,UACA,OACA,gBAAiB,EACjB,UAAW,EACX,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CACpD,EAAmB,MAAM,EAAsB,EAAQ,EAAW,CACxE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAEvF,IAAM,EAAkB,MAAM,EAA2B,EAAQ,EAAkB,CAAE,UAAS,CAAC,CAE/F,KAAK,OAAO,KACV,EAAO,MACL,EACI,sCAAsC,EAAgB,QAAQ,MAC9D,uBAAuB,EAAgB,QAAQ,MACpD,CACF,CAED,IAAI,EACJ,GAAI,CACF,EAAO,MAAM,EACX,EACG,KACC,mCAAmC,EAAiB,YAAY,EAAgB,GAAG,WACnF,CACE,KAAM,EAAS,CAAE,OAAQ,GAAM,CAAG,EAAE,CACrC,CACF,CACA,MAA2C,CAC/C,OACM,EAAK,CAeZ,MAVE,aAAe,EACV,EAAI,MACL,IAAA,KACH,UAAU,aACM,IACX,IAAI,EACR,YAAY,EAAgB,QAAQ,sBAAsB,EAAW,kCACrE,CAAE,MAAO,EAAK,CACf,CAEG,EAGR,EAAY,KAAK,QAAQ,OAAQ,CAC/B,OACA,KAAM,EACN,gBACE,CACE,eAAe,EAAK,OAAO,KAC3B,eAAe,EAAK,OAAO,aAC3B,EAAiC,EAAK,QAAQ,CAC/C,CAAC,KAAK;EAAK,CACf,CAAC,CAEF,KAAK,OAAO,KACV,EAAO,MAAM,EAAS,mCAAqC,mCAAmC,CAC/F"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./pushCronIdentifiersFromCsv-DjeY7TtK.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o}){t(this.process),await e({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o})}export{n as markIdentifiersCompleted};
2
+ //# sourceMappingURL=impl-C50tdWlL2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-q66XVeBW2.mjs","names":[],"sources":["../src/commands/request/cron/mark-identifiers-completed/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushCronIdentifiersFromCsv } from '../../../../lib/cron/index.js';\n\nexport interface MarkIdentifiersCompletedCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n}\n\nexport async function markIdentifiersCompleted(\n this: LocalContext,\n { file, transcendUrl, auth, sombraAuth, dataSiloId }: MarkIdentifiersCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pushCronIdentifiersFromCsv({\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n });\n}\n"],"mappings":"kHAYA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,aAAY,cACzB,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAA2B,CAC/B,OACA,eACA,OACA,aACA,aACD,CAAC"}
1
+ {"version":3,"file":"impl-C50tdWlL2.mjs","names":[],"sources":["../src/commands/request/cron/mark-identifiers-completed/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushCronIdentifiersFromCsv } from '../../../../lib/cron/index.js';\n\nexport interface MarkIdentifiersCompletedCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n}\n\nexport async function markIdentifiersCompleted(\n this: LocalContext,\n { file, transcendUrl, auth, sombraAuth, dataSiloId }: MarkIdentifiersCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await pushCronIdentifiersFromCsv({\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n });\n}\n"],"mappings":"kHAYA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,aAAY,cACzB,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAA2B,CAC/B,OACA,eACA,OACA,aACA,aACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./pullManualEnrichmentIdentifiersToCsv-qjdNA75O.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,transcendUrl:r,file:i,concurrency:a,actions:o,sombraAuth:s}){t(this.process),await e({file:i,transcendUrl:r,concurrency:a,requestActions:o,auth:n,sombraAuth:s})}export{n as pullIdentifiers};
2
+ //# sourceMappingURL=impl-C5dzaDga2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-jVkU5ZQe2.mjs","names":[],"sources":["../src/commands/request/preflight/pull-identifiers/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pullManualEnrichmentIdentifiersToCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n auth: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n actions?: RequestAction[];\n concurrency: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n { auth, transcendUrl, file, concurrency, actions, sombraAuth }: PullIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pullManualEnrichmentIdentifiersToCsv({\n file,\n transcendUrl,\n concurrency,\n requestActions: actions,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"4HAeA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,cAAa,UAAS,cACnC,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAqC,CACzC,OACA,eACA,cACA,eAAgB,EAChB,OACA,aACD,CAAC"}
1
+ {"version":3,"file":"impl-C5dzaDga2.mjs","names":[],"sources":["../src/commands/request/preflight/pull-identifiers/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pullManualEnrichmentIdentifiersToCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n auth: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n actions?: RequestAction[];\n concurrency: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n { auth, transcendUrl, file, concurrency, actions, sombraAuth }: PullIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await pullManualEnrichmentIdentifiersToCsv({\n file,\n transcendUrl,\n concurrency,\n requestActions: actions,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"4HAeA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,cAAa,UAAS,cACnC,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAqC,CACzC,OACA,eACA,cACA,eAAgB,EAChB,OACA,aACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./retryRequestDataSilos-D9dBtbdl.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,dataSiloId:r,actions:i,transcendUrl:a}){t(this.process),await e({requestActions:i,transcendUrl:a,auth:n,dataSiloId:r})}export{n as retryRequestDataSilos};
2
+ //# sourceMappingURL=impl-C8BmxFQ2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-C8BmxFQ2.mjs","names":["retryRequestDataSilosHelper"],"sources":["../src/commands/request/system/retry-request-data-silos/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { retryRequestDataSilos as retryRequestDataSilosHelper } from '../../../../lib/requests/index.js';\n\nexport interface RetryRequestDataSilosCommandFlags {\n auth: string;\n dataSiloId: string;\n actions: RequestAction[];\n transcendUrl: string;\n}\n\nexport async function retryRequestDataSilos(\n this: LocalContext,\n { auth, dataSiloId, actions, transcendUrl }: RetryRequestDataSilosCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await retryRequestDataSilosHelper({\n requestActions: actions,\n transcendUrl,\n auth,\n dataSiloId,\n });\n}\n"],"mappings":"6GAaA,eAAsB,EAEpB,CAAE,OAAM,aAAY,UAAS,gBACd,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAMA,EAA4B,CAChC,eAAgB,EAChB,eACA,OACA,aACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./updateConsentManagerVersionToLatest-CaEkTnlL.mjs";import{t}from"./validateTranscendAuth-CnHMn77m.mjs";import{t as n}from"./done-input-validation-Cjk7a3jX.mjs";import{ConsentBundleType as r}from"@transcend-io/privacy-types";import i from"colors";import{mapSeries as a}from"@transcend-io/utils";async function o({auth:o,bundleTypes:s=[r.Production,r.Test],deploy:c,transcendUrl:l}){n(this.process);let u=await t(o,this);typeof u==`string`?(await e({deploy:c,transcendUrl:l,auth:u,bundleTypes:s}),this.logger.info(i.green(`Successfully updated Consent Manager!`))):(await a(u,async t=>{this.logger.info(i.magenta(`Updating Consent Manager for organization "${t.organizationName}"...`)),await e({deploy:c,transcendUrl:l,auth:t.apiKey,bundleTypes:s}),this.logger.info(i.green(`Successfully updated Consent Manager for organization "${t.organizationName}"!`))}),this.logger.info(i.green(`Successfully updated Consent Managers!`)))}export{o as updateConsentManager};
2
+ //# sourceMappingURL=impl-CDtUusmg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-CDtUusmg.mjs","names":[],"sources":["../src/commands/consent/update-consent-manager/impl.ts"],"sourcesContent":["import { ConsentBundleType } from '@transcend-io/privacy-types';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { updateConsentManagerVersionToLatest } from '../../../lib/consent-manager/index.js';\n\nexport interface UpdateConsentManagerCommandFlags {\n auth: string;\n bundleTypes: ConsentBundleType[];\n deploy: boolean;\n transcendUrl: string;\n}\n\nexport async function updateConsentManager(\n this: LocalContext,\n {\n auth,\n bundleTypes = [ConsentBundleType.Production, ConsentBundleType.Test],\n deploy,\n transcendUrl,\n }: UpdateConsentManagerCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth, this);\n\n // Handle single update\n if (typeof apiKeyOrList === 'string') {\n // Update consent manager\n await updateConsentManagerVersionToLatest({\n deploy,\n transcendUrl,\n auth: apiKeyOrList,\n bundleTypes,\n });\n this.logger.info(colors.green('Successfully updated Consent Manager!'));\n } else {\n await mapSeries(apiKeyOrList, async (apiKey) => {\n this.logger.info(\n colors.magenta(`Updating Consent Manager for organization \"${apiKey.organizationName}\"...`),\n );\n\n await updateConsentManagerVersionToLatest({\n deploy,\n transcendUrl,\n auth: apiKey.apiKey,\n bundleTypes,\n });\n\n this.logger.info(\n colors.green(\n `Successfully updated Consent Manager for organization \"${apiKey.organizationName}\"!`,\n ),\n );\n });\n this.logger.info(colors.green('Successfully updated Consent Managers!'));\n }\n}\n"],"mappings":"0TAgBA,eAAsB,EAEpB,CACE,OACA,cAAc,CAAC,EAAkB,WAAY,EAAkB,KAAK,CACpE,SACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAGjC,IAAM,EAAe,MAAM,EAAsB,EAAM,KAAK,CAGxD,OAAO,GAAiB,UAE1B,MAAM,EAAoC,CACxC,SACA,eACA,KAAM,EACN,cACD,CAAC,CACF,KAAK,OAAO,KAAK,EAAO,MAAM,wCAAwC,CAAC,GAEvE,MAAM,EAAU,EAAc,KAAO,IAAW,CAC9C,KAAK,OAAO,KACV,EAAO,QAAQ,8CAA8C,EAAO,iBAAiB,MAAM,CAC5F,CAED,MAAM,EAAoC,CACxC,SACA,eACA,KAAM,EAAO,OACb,cACD,CAAC,CAEF,KAAK,OAAO,KACV,EAAO,MACL,0DAA0D,EAAO,iBAAiB,IACnF,CACF,EACD,CACF,KAAK,OAAO,KAAK,EAAO,MAAM,yCAAyC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./bulkRetryEnrichers-BA9cboSe.mjs";import{t}from"./done-input-validation-Cjk7a3jX.mjs";async function n({auth:n,enricherId:r,actions:i,requestEnricherStatuses:a,requestIds:o,createdAtBefore:s,createdAtAfter:c,updatedAtBefore:l,updatedAtAfter:u,concurrency:d,transcendUrl:f}){t(this.process),await e({auth:n,enricherId:r,requestActions:i,requestEnricherStatuses:a,requestIds:o,createdAtBefore:s?new Date(s):void 0,createdAtAfter:c?new Date(c):void 0,updatedAtBefore:l?new Date(l):void 0,updatedAtAfter:u?new Date(u):void 0,concurrency:d,transcendUrl:f})}export{n as enricherRestart};
2
+ //# sourceMappingURL=impl-CE56-wQh.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-CFB9lqIN.mjs","names":[],"sources":["../src/commands/request/enricher-restart/impl.ts"],"sourcesContent":["import type { RequestAction, RequestEnricherStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { bulkRetryEnrichers } from '../../../lib/requests/index.js';\n\nexport interface EnricherRestartCommandFlags {\n auth: string;\n enricherId: string;\n actions?: RequestAction[];\n requestEnricherStatuses?: RequestEnricherStatus[];\n transcendUrl: string;\n concurrency: number;\n requestIds?: string[];\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n}\n\nexport async function enricherRestart(\n this: LocalContext,\n {\n auth,\n enricherId,\n actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n }: EnricherRestartCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await bulkRetryEnrichers({\n auth,\n enricherId,\n requestActions: actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n updatedAtBefore: updatedAtBefore ? new Date(updatedAtBefore) : undefined,\n updatedAtAfter: updatedAtAfter ? new Date(updatedAtAfter) : undefined,\n concurrency,\n transcendUrl,\n });\n}\n"],"mappings":"0GAoBA,eAAsB,EAEpB,CACE,OACA,aACA,UACA,0BACA,aACA,kBACA,iBACA,kBACA,iBACA,cACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAmB,CACvB,OACA,aACA,eAAgB,EAChB,0BACA,aACA,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,cACA,eACD,CAAC"}
1
+ {"version":3,"file":"impl-CE56-wQh.mjs","names":[],"sources":["../src/commands/request/enricher-restart/impl.ts"],"sourcesContent":["import type { RequestAction, RequestEnricherStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { bulkRetryEnrichers } from '../../../lib/requests/index.js';\n\nexport interface EnricherRestartCommandFlags {\n auth: string;\n enricherId: string;\n actions?: RequestAction[];\n requestEnricherStatuses?: RequestEnricherStatus[];\n transcendUrl: string;\n concurrency: number;\n requestIds?: string[];\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n}\n\nexport async function enricherRestart(\n this: LocalContext,\n {\n auth,\n enricherId,\n actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n }: EnricherRestartCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await bulkRetryEnrichers({\n auth,\n enricherId,\n requestActions: actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n updatedAtBefore: updatedAtBefore ? new Date(updatedAtBefore) : undefined,\n updatedAtAfter: updatedAtAfter ? new Date(updatedAtAfter) : undefined,\n concurrency,\n transcendUrl,\n });\n}\n"],"mappings":"0GAoBA,eAAsB,EAEpB,CACE,OACA,aACA,UACA,0BACA,aACA,kBACA,iBACA,kBACA,iBACA,cACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAmB,CACvB,OACA,aACA,eAAgB,EAChB,0BACA,aACA,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,cACA,eACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{n as e}from"./constants-BG53Mbi9.mjs";import{s as t}from"./writeCsv-D46aDkGf.mjs";import{t as n}from"./pullAllDatapoints-H92qjLSx.mjs";import{t as r}from"./done-input-validation-Cjk7a3jX.mjs";import{groupBy as i,uniq as a}from"lodash-es";import o from"colors";import{buildTranscendGraphQLClient as s}from"@transcend-io/sdk";async function c({auth:c,file:l,transcendUrl:u,dataSiloIds:d,includeAttributes:f,includeGuessedCategories:p,parentCategories:m,subCategories:h=[]}){r(this.process);try{let e=await n(s(u,c),{dataSiloIds:d,includeGuessedCategories:p,parentCategories:m,includeAttributes:f,subCategories:h});this.logger.info(o.magenta(`Writing datapoints to file "${l}"...`));let r=[];await t(l,e.map(e=>{let t={"Property ID":e.id,"Data Silo":e.dataSilo.title,Object:e.dataPoint.name,"Object Path":e.dataPoint.path.join(`.`),Property:e.name,"Property Description":e.description,"Data Categories":e.categories.map(e=>`${e.category}:${e.name}`).join(`, `),"Guessed Category":e.pendingCategoryGuesses?.[0]?`${e.pendingCategoryGuesses[0].category.category}:${e.pendingCategoryGuesses[0].category.name}`:``,"Processing Purposes":e.purposes.map(e=>`${e.purpose}:${e.name}`).join(`, `),...Object.entries(i(e.attributeValues||[],({attributeKey:e})=>e.name)).reduce((e,[t,n])=>(e[t]=n.map(e=>e.name).join(`,`),e),{})};return r=a([...r,...Object.keys(t)]),t}),r)}catch(e){this.logger.error(o.red(`An error occurred syncing the datapoints: ${e.message}`)),this.process.exit(1)}this.logger.info(o.green(`Successfully synced datapoints to disk at ${l}! View at ${e}`))}export{c as pullDatapoints};
2
+ //# sourceMappingURL=impl-CEmXPEq22.mjs.map