@transcend-io/cli 13.0.4 → 13.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/{app-DuniUvGi.mjs → app-DQ5b5mys.mjs} +16 -16
  2. package/dist/{app-DuniUvGi.mjs.map → app-DQ5b5mys.mjs.map} +1 -1
  3. package/dist/{approvePrivacyRequests-57LFIxUv.mjs → approvePrivacyRequests-O70eyhdH.mjs} +2 -2
  4. package/dist/{approvePrivacyRequests-57LFIxUv.mjs.map → approvePrivacyRequests-O70eyhdH.mjs.map} +1 -1
  5. package/dist/bin/bash-complete.mjs +1 -1
  6. package/dist/bin/cli.mjs +1 -1
  7. package/dist/bin/deprecated-command.mjs +1 -1
  8. package/dist/{buildExamples-bIkCTZtO.mjs → buildExamples-BsMXuFwm.mjs} +2 -2
  9. package/dist/{buildExamples-bIkCTZtO.mjs.map → buildExamples-BsMXuFwm.mjs.map} +1 -1
  10. package/dist/{buildXdiSyncEndpoint-BUKWuQE6.mjs → buildXdiSyncEndpoint-CRJSuwdq.mjs} +2 -2
  11. package/dist/{buildXdiSyncEndpoint-BUKWuQE6.mjs.map → buildXdiSyncEndpoint-CRJSuwdq.mjs.map} +1 -1
  12. package/dist/{bulkRestartRequests-V4cDUp29.mjs → bulkRestartRequests-C9cHasoq.mjs} +2 -2
  13. package/dist/{bulkRestartRequests-V4cDUp29.mjs.map → bulkRestartRequests-C9cHasoq.mjs.map} +1 -1
  14. package/dist/{bulkRetryEnrichers-DYxHf2th.mjs → bulkRetryEnrichers-BLDtr5Ws.mjs} +2 -2
  15. package/dist/{bulkRetryEnrichers-DYxHf2th.mjs.map → bulkRetryEnrichers-BLDtr5Ws.mjs.map} +1 -1
  16. package/dist/{cancelPrivacyRequests-4MzlSkHA.mjs → cancelPrivacyRequests-DSjAUS5b.mjs} +2 -2
  17. package/dist/{cancelPrivacyRequests-4MzlSkHA.mjs.map → cancelPrivacyRequests-DSjAUS5b.mjs.map} +1 -1
  18. package/dist/{command-BYXHxOsD.mjs → command-DB0ydG0y.mjs} +2 -2
  19. package/dist/{command-BYXHxOsD.mjs.map → command-DB0ydG0y.mjs.map} +1 -1
  20. package/dist/{constants-6F0ha8ue.mjs → constants-ZX8RSZos.mjs} +2 -2
  21. package/dist/{constants-6F0ha8ue.mjs.map → constants-ZX8RSZos.mjs.map} +1 -1
  22. package/dist/{createPoolingCommandUi-BUBLRVVY.mjs → createPoolingCommandUi-Bj6pO1t7.mjs} +2 -2
  23. package/dist/{createPoolingCommandUi-BUBLRVVY.mjs.map → createPoolingCommandUi-Bj6pO1t7.mjs.map} +1 -1
  24. package/dist/{downloadPrivacyRequestFiles-BckoJe0z.mjs → downloadPrivacyRequestFiles-DKRfQoAo.mjs} +2 -2
  25. package/dist/{downloadPrivacyRequestFiles-BckoJe0z.mjs.map → downloadPrivacyRequestFiles-DKRfQoAo.mjs.map} +1 -1
  26. package/dist/{generateCrossAccountApiKeys-B7961x_Z.mjs → generateCrossAccountApiKeys-BnUQ_wCI.mjs} +2 -2
  27. package/dist/{generateCrossAccountApiKeys-B7961x_Z.mjs.map → generateCrossAccountApiKeys-BnUQ_wCI.mjs.map} +1 -1
  28. package/dist/{impl-BSxV7vYK.mjs → impl-5s_Ya3XD.mjs} +2 -2
  29. package/dist/{impl-BSxV7vYK.mjs.map → impl-5s_Ya3XD.mjs.map} +1 -1
  30. package/dist/{impl-DrTKXQwb.mjs → impl-77sXwCIh.mjs} +2 -2
  31. package/dist/{impl-DrTKXQwb.mjs.map → impl-77sXwCIh.mjs.map} +1 -1
  32. package/dist/{impl-CHDAZLJt2.mjs → impl-B1TF4tzM2.mjs} +2 -2
  33. package/dist/{impl-CHDAZLJt2.mjs.map → impl-B1TF4tzM2.mjs.map} +1 -1
  34. package/dist/{impl-BQDX9769.mjs → impl-B7PA6_OB.mjs} +2 -2
  35. package/dist/{impl-BQDX9769.mjs.map → impl-B7PA6_OB.mjs.map} +1 -1
  36. package/dist/{impl-DVaook8H2.mjs → impl-B8sKYzjF2.mjs} +2 -2
  37. package/dist/{impl-DVaook8H2.mjs.map → impl-B8sKYzjF2.mjs.map} +1 -1
  38. package/dist/{impl-BMhPV4td.mjs → impl-BAd2ga54.mjs} +2 -2
  39. package/dist/{impl-BMhPV4td.mjs.map → impl-BAd2ga54.mjs.map} +1 -1
  40. package/dist/{impl-D0pWt40T.mjs → impl-BLX_G5bC.mjs} +2 -2
  41. package/dist/{impl-D0pWt40T.mjs.map → impl-BLX_G5bC.mjs.map} +1 -1
  42. package/dist/{impl-yVOrJekX.mjs → impl-BOVkmW_l.mjs} +2 -2
  43. package/dist/{impl-yVOrJekX.mjs.map → impl-BOVkmW_l.mjs.map} +1 -1
  44. package/dist/{impl-ByTDMJFP.mjs → impl-BUMhJG9i.mjs} +2 -2
  45. package/dist/{impl-ByTDMJFP.mjs.map → impl-BUMhJG9i.mjs.map} +1 -1
  46. package/dist/{impl-Bq596FSL.mjs → impl-BUziAyU5.mjs} +2 -2
  47. package/dist/{impl-Bq596FSL.mjs.map → impl-BUziAyU5.mjs.map} +1 -1
  48. package/dist/{impl-Canhp2iV.mjs → impl-B_5zE1r4.mjs} +2 -2
  49. package/dist/{impl-Canhp2iV.mjs.map → impl-B_5zE1r4.mjs.map} +1 -1
  50. package/dist/{impl-BK_CU73F.mjs → impl-Bizz-Eku.mjs} +2 -2
  51. package/dist/{impl-BK_CU73F.mjs.map → impl-Bizz-Eku.mjs.map} +1 -1
  52. package/dist/{impl-D9z1ovJu.mjs → impl-C7oKqTBj.mjs} +2 -2
  53. package/dist/{impl-D9z1ovJu.mjs.map → impl-C7oKqTBj.mjs.map} +1 -1
  54. package/dist/{impl-BCABQS_h.mjs → impl-CDB2WA0G.mjs} +2 -2
  55. package/dist/{impl-BCABQS_h.mjs.map → impl-CDB2WA0G.mjs.map} +1 -1
  56. package/dist/{impl-BpF_4RGh.mjs → impl-CFza6vNy.mjs} +2 -2
  57. package/dist/{impl-BpF_4RGh.mjs.map → impl-CFza6vNy.mjs.map} +1 -1
  58. package/dist/{impl-BjMQ2W772.mjs → impl-CHq5HbuZ2.mjs} +2 -2
  59. package/dist/{impl-BjMQ2W772.mjs.map → impl-CHq5HbuZ2.mjs.map} +1 -1
  60. package/dist/{impl-DC-YqHJx.mjs → impl-CIEPBjFF.mjs} +2 -2
  61. package/dist/{impl-DC-YqHJx.mjs.map → impl-CIEPBjFF.mjs.map} +1 -1
  62. package/dist/{impl-zrqmQLuL.mjs → impl-COz--q8S.mjs} +2 -2
  63. package/dist/{impl-zrqmQLuL.mjs.map → impl-COz--q8S.mjs.map} +1 -1
  64. package/dist/{impl-Dj-u3wBR2.mjs → impl-CPW2Q51W2.mjs} +2 -2
  65. package/dist/{impl-Dj-u3wBR2.mjs.map → impl-CPW2Q51W2.mjs.map} +1 -1
  66. package/dist/{impl-DEChTmJW.mjs → impl-CWykfeDx.mjs} +2 -2
  67. package/dist/{impl-DEChTmJW.mjs.map → impl-CWykfeDx.mjs.map} +1 -1
  68. package/dist/{impl-DMli5cx_.mjs → impl-CXOLmyC1.mjs} +2 -2
  69. package/dist/{impl-DMli5cx_.mjs.map → impl-CXOLmyC1.mjs.map} +1 -1
  70. package/dist/{impl-Chsw1pPO.mjs → impl-CaPpiEL2.mjs} +2 -2
  71. package/dist/{impl-Chsw1pPO.mjs.map → impl-CaPpiEL2.mjs.map} +1 -1
  72. package/dist/{impl-Bm_dPfqr.mjs → impl-CcVNbgw3.mjs} +2 -2
  73. package/dist/{impl-Bm_dPfqr.mjs.map → impl-CcVNbgw3.mjs.map} +1 -1
  74. package/dist/{impl-B5z48Qiw.mjs → impl-CeR4wR2T.mjs} +2 -2
  75. package/dist/{impl-B5z48Qiw.mjs.map → impl-CeR4wR2T.mjs.map} +1 -1
  76. package/dist/{impl-DsOUCV22.mjs → impl-CihGggtZ.mjs} +2 -2
  77. package/dist/{impl-DsOUCV22.mjs.map → impl-CihGggtZ.mjs.map} +1 -1
  78. package/dist/{impl-ChE-8VKk.mjs → impl-DEK7xark.mjs} +2 -2
  79. package/dist/{impl-ChE-8VKk.mjs.map → impl-DEK7xark.mjs.map} +1 -1
  80. package/dist/{impl-L1xM2Wb2.mjs → impl-DHq2UBl4.mjs} +2 -2
  81. package/dist/{impl-L1xM2Wb2.mjs.map → impl-DHq2UBl4.mjs.map} +1 -1
  82. package/dist/{impl-Bl42P-wI.mjs → impl-DJ5kJ80R.mjs} +2 -2
  83. package/dist/{impl-Bl42P-wI.mjs.map → impl-DJ5kJ80R.mjs.map} +1 -1
  84. package/dist/{impl-BnTWnayD.mjs → impl-DQftQKzh.mjs} +2 -2
  85. package/dist/{impl-BnTWnayD.mjs.map → impl-DQftQKzh.mjs.map} +1 -1
  86. package/dist/{impl-Ba1p4QRD.mjs → impl-DRmy2-be.mjs} +2 -2
  87. package/dist/{impl-Ba1p4QRD.mjs.map → impl-DRmy2-be.mjs.map} +1 -1
  88. package/dist/{impl-BVlc0BRG.mjs → impl-DgMukyER.mjs} +2 -2
  89. package/dist/{impl-BVlc0BRG.mjs.map → impl-DgMukyER.mjs.map} +1 -1
  90. package/dist/{impl-p77uCDi3.mjs → impl-Do_3rQWz.mjs} +2 -2
  91. package/dist/{impl-p77uCDi3.mjs.map → impl-Do_3rQWz.mjs.map} +1 -1
  92. package/dist/{impl-8VWWJO22.mjs → impl-DpLBWRCJ.mjs} +2 -2
  93. package/dist/{impl-8VWWJO22.mjs.map → impl-DpLBWRCJ.mjs.map} +1 -1
  94. package/dist/{impl-CFJR1dQP.mjs → impl-IQy1_4me.mjs} +2 -2
  95. package/dist/{impl-CFJR1dQP.mjs.map → impl-IQy1_4me.mjs.map} +1 -1
  96. package/dist/{impl-CjgdTR8k2.mjs → impl-XbrQy_Ti2.mjs} +2 -2
  97. package/dist/{impl-CjgdTR8k2.mjs.map → impl-XbrQy_Ti2.mjs.map} +1 -1
  98. package/dist/{impl-CCKFPk1i.mjs → impl-bWws4YDq.mjs} +2 -2
  99. package/dist/{impl-CCKFPk1i.mjs.map → impl-bWws4YDq.mjs.map} +1 -1
  100. package/dist/{impl-BeDNGUVg.mjs → impl-fmS5PIlk.mjs} +2 -2
  101. package/dist/{impl-BeDNGUVg.mjs.map → impl-fmS5PIlk.mjs.map} +1 -1
  102. package/dist/{impl-ouUdsmXK.mjs → impl-t0qVrVte.mjs} +2 -2
  103. package/dist/{impl-ouUdsmXK.mjs.map → impl-t0qVrVte.mjs.map} +1 -1
  104. package/dist/{impl-DL1d2zHJ.mjs → impl-tQda5dQ2.mjs} +2 -2
  105. package/dist/{impl-DL1d2zHJ.mjs.map → impl-tQda5dQ2.mjs.map} +1 -1
  106. package/dist/index.mjs +1 -1
  107. package/dist/{markRequestDataSiloIdsCompleted-CQl97k0h.mjs → markRequestDataSiloIdsCompleted-ZZvKQhtT.mjs} +2 -2
  108. package/dist/{markRequestDataSiloIdsCompleted-CQl97k0h.mjs.map → markRequestDataSiloIdsCompleted-ZZvKQhtT.mjs.map} +1 -1
  109. package/dist/{markSilentPrivacyRequests-D78iaCVp.mjs → markSilentPrivacyRequests-DZ13Jy20.mjs} +2 -2
  110. package/dist/{markSilentPrivacyRequests-D78iaCVp.mjs.map → markSilentPrivacyRequests-DZ13Jy20.mjs.map} +1 -1
  111. package/dist/{notifyPrivacyRequestsAdditionalTime-DCjnQmPj.mjs → notifyPrivacyRequestsAdditionalTime-BspmtrPe.mjs} +2 -2
  112. package/dist/{notifyPrivacyRequestsAdditionalTime-DCjnQmPj.mjs.map → notifyPrivacyRequestsAdditionalTime-BspmtrPe.mjs.map} +1 -1
  113. package/dist/{policy-bundle-manifest-CJnaA9Ub.mjs → policy-bundle-manifest-BKRoT17e.mjs} +2 -2
  114. package/dist/{policy-bundle-manifest-CJnaA9Ub.mjs.map → policy-bundle-manifest-BKRoT17e.mjs.map} +1 -1
  115. package/dist/{policy-project-discovery-BXmG3T6V.mjs → policy-project-discovery-BXcvhfK7.mjs} +2 -2
  116. package/dist/{policy-project-discovery-BXmG3T6V.mjs.map → policy-project-discovery-BXcvhfK7.mjs.map} +1 -1
  117. package/dist/{policy-scaffold-config-CCCySUqW.mjs → policy-scaffold-config-DvyJctQz.mjs} +2 -2
  118. package/dist/{policy-scaffold-config-CCCySUqW.mjs.map → policy-scaffold-config-DvyJctQz.mjs.map} +1 -1
  119. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-D5lFuhaD.mjs → pullChunkedCustomSiloOutstandingIdentifiers-CDHCpiXU.mjs} +2 -2
  120. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-D5lFuhaD.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-CDHCpiXU.mjs.map} +1 -1
  121. package/dist/{pullManualEnrichmentIdentifiersToCsv-BJ60h_P2.mjs → pullManualEnrichmentIdentifiersToCsv-BSM4bSjf.mjs} +2 -2
  122. package/dist/{pullManualEnrichmentIdentifiersToCsv-BJ60h_P2.mjs.map → pullManualEnrichmentIdentifiersToCsv-BSM4bSjf.mjs.map} +1 -1
  123. package/dist/{pushCronIdentifiersFromCsv-ageZIHg8.mjs → pushCronIdentifiersFromCsv-CnMWjt94.mjs} +2 -2
  124. package/dist/{pushCronIdentifiersFromCsv-ageZIHg8.mjs.map → pushCronIdentifiersFromCsv-CnMWjt94.mjs.map} +1 -1
  125. package/dist/{pushManualEnrichmentIdentifiersFromCsv-CXkMb7CB.mjs → pushManualEnrichmentIdentifiersFromCsv-iv9Ts42q.mjs} +2 -2
  126. package/dist/{pushManualEnrichmentIdentifiersFromCsv-CXkMb7CB.mjs.map → pushManualEnrichmentIdentifiersFromCsv-iv9Ts42q.mjs.map} +1 -1
  127. package/dist/{removeUnverifiedRequestIdentifiers-CUI1CqAm.mjs → removeUnverifiedRequestIdentifiers-Bo5U01oM.mjs} +2 -2
  128. package/dist/{removeUnverifiedRequestIdentifiers-CUI1CqAm.mjs.map → removeUnverifiedRequestIdentifiers-Bo5U01oM.mjs.map} +1 -1
  129. package/dist/{retryRequestDataSilos-ClvwV9pP.mjs → retryRequestDataSilos-BWGlpn1o.mjs} +2 -2
  130. package/dist/{retryRequestDataSilos-ClvwV9pP.mjs.map → retryRequestDataSilos-BWGlpn1o.mjs.map} +1 -1
  131. package/dist/{skipPreflightJobs-CUUEekOc.mjs → skipPreflightJobs-B0LSm9IU.mjs} +2 -2
  132. package/dist/{skipPreflightJobs-CUUEekOc.mjs.map → skipPreflightJobs-B0LSm9IU.mjs.map} +1 -1
  133. package/dist/{skipRequestDataSilos-C_ZYQo4_.mjs → skipRequestDataSilos-EEaly2ls.mjs} +2 -2
  134. package/dist/{skipRequestDataSilos-C_ZYQo4_.mjs.map → skipRequestDataSilos-EEaly2ls.mjs.map} +1 -1
  135. package/dist/{streamPrivacyRequestsToCsv-ITzRIbT8.mjs → streamPrivacyRequestsToCsv-DUFu0-AB.mjs} +2 -2
  136. package/dist/{streamPrivacyRequestsToCsv-ITzRIbT8.mjs.map → streamPrivacyRequestsToCsv-DUFu0-AB.mjs.map} +1 -1
  137. package/dist/{updateConsentManagerVersionToLatest-CQ1tEPPa.mjs → updateConsentManagerVersionToLatest-C4D6cqMh.mjs} +2 -2
  138. package/dist/{updateConsentManagerVersionToLatest-CQ1tEPPa.mjs.map → updateConsentManagerVersionToLatest-C4D6cqMh.mjs.map} +1 -1
  139. package/dist/{uploadConsents-Crcidppk.mjs → uploadConsents-CMTmdRLm.mjs} +2 -2
  140. package/dist/{uploadConsents-Crcidppk.mjs.map → uploadConsents-CMTmdRLm.mjs.map} +1 -1
  141. package/dist/{uploadPrivacyRequestsFromCsv-CWJ1atMX.mjs → uploadPrivacyRequestsFromCsv-BIe_wJ4A.mjs} +2 -2
  142. package/dist/{uploadPrivacyRequestsFromCsv-CWJ1atMX.mjs.map → uploadPrivacyRequestsFromCsv-BIe_wJ4A.mjs.map} +1 -1
  143. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Chsw1pPO.mjs","names":[],"sources":["../src/commands/request/cron/pull-profiles/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, fetchRequestFilesForRequest } from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport { uniq, chunk } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n pullChunkedCustomSiloOutstandingIdentifiers,\n type CsvFormattedIdentifier,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\n\nexport interface PullProfilesCommandFlags {\n file: string;\n fileTarget: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n cronDataSiloId: string;\n targetDataSiloId: string;\n actions: RequestAction[];\n skipRequestCount: boolean;\n pageLimit: number;\n chunkSize: number;\n}\n\nexport async function pullProfiles(\n this: LocalContext,\n {\n file,\n fileTarget,\n transcendUrl,\n auth,\n sombraAuth,\n cronDataSiloId,\n targetDataSiloId,\n actions,\n skipRequestCount,\n pageLimit,\n chunkSize,\n }: PullProfilesCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n this.logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n this.logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process);\n\n // Create GraphQL client to connect to Transcend backend\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n const { baseName, extension } = parseFilePath(file);\n const { baseName: baseNameTarget, extension: extensionTarget } = parseFilePath(fileTarget);\n\n let allIdentifiersCount = 0;\n let allTargetIdentifiersCount = 0;\n let fileCount = 0;\n // Create onSave callback to handle chunked processing\n const onSave = async (chunkToSave: CsvFormattedIdentifier[]): Promise<void> => {\n // Add to all identifiers\n allIdentifiersCount += chunkToSave.length;\n\n // Get unique request IDs from this chunk\n const requestIds = chunkToSave.map((d) => d.requestId as string);\n const uniqueRequestIds = uniq(requestIds);\n\n // Pull down target identifiers for this chunk\n const chunkedRequestIds = chunk(uniqueRequestIds, pageLimit);\n const results = await map(\n chunkedRequestIds,\n async (requestIds) => {\n this.logger.info(\n colors.magenta(`Fetching target identifiers for ${requestIds.length} requests`),\n );\n const results = await fetchRequestFilesForRequest(client, {\n logger: this.logger,\n pageSize: pageLimit * 2,\n filterBy: {\n requestIds,\n dataSiloIds: [targetDataSiloId],\n },\n });\n return results.map(({ fileName, remoteId }) => {\n if (!remoteId) {\n throw new Error(`Failed to find remoteId for ${fileName}`);\n }\n return {\n RecordId: remoteId,\n Object: fileName.replace('.json', '').split('/').pop()?.replace(' Information', ''),\n Comment: 'Customer data deletion request submitted via transcend.io',\n };\n });\n },\n // We are grabbing all the request files for the 'pageLimit' # of requests at a time\n {\n concurrency: 1,\n },\n );\n\n allTargetIdentifiersCount += results.flat().length;\n\n // Write the identifiers and target identifiers to CSV\n const headers = uniq(chunkToSave.map((d) => Object.keys(d)).flat());\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n const numberedFileNameTarget = `${baseNameTarget}-${fileCount}${extensionTarget}`;\n await writeLargeCsv(numberedFileName, chunkToSave, headers);\n this.logger.info(\n colors.green(`Successfully wrote ${chunkToSave.length} identifiers to file \"${file}\"`),\n );\n\n const targetIdentifiers = results.flat();\n const headers2 = uniq(targetIdentifiers.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileNameTarget, targetIdentifiers, headers2);\n this.logger.info(\n colors.green(\n `Successfully wrote ${targetIdentifiers.length} identifiers to file \"${fileTarget}\"`,\n ),\n );\n\n this.logger.info(\n colors.blue(\n `Processed chunk of ${chunk.length} identifiers, found ${targetIdentifiers.length} target identifiers`,\n ),\n );\n fileCount += 1;\n };\n\n // Pull down outstanding identifiers using the new chunked function\n await pullChunkedCustomSiloOutstandingIdentifiers({\n dataSiloId: cronDataSiloId,\n auth,\n sombraAuth,\n actions,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n transcendUrl,\n skipRequestCount,\n });\n\n this.logger.info(\n colors.green(`Successfully wrote ${allIdentifiersCount} identifiers to file \"${file}\"`),\n );\n this.logger.info(\n colors.green(\n `Successfully wrote ${allTargetIdentifiersCount} identifiers to file \"${fileTarget}\"`,\n ),\n );\n}\n"],"mappings":"wYA4BA,eAAsB,EAEpB,CACE,OACA,aACA,eACA,OACA,aACA,iBACA,mBACA,UACA,mBACA,YACA,aAEa,CACX,GACF,KAAK,OAAO,KACV,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,KAAK,OAAO,MACV,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,CAGjC,IAAM,EAAS,EAA4B,EAAc,EAAK,CACxD,CAAE,WAAU,aAAc,EAAc,EAAK,CAC7C,CAAE,SAAU,EAAgB,UAAW,GAAoB,EAAc,EAAW,CAEtF,EAAsB,EACtB,EAA4B,EAC5B,EAAY,EAwEhB,MAAM,EAA4C,CAChD,WAAY,EACZ,OACA,aACA,UACA,YAAa,EACb,aAAc,EACd,YA7EoB,IAAyD,CAE7E,GAAuB,EAAY,OAQnC,IAAM,EAAU,MAAM,EADI,EAHD,EADN,EAAY,IAAK,GAAM,EAAE,UACJ,CAGQ,CAAE,EAE/B,CACjB,KAAO,KACL,KAAK,OAAO,KACV,EAAO,QAAQ,mCAAmC,EAAW,OAAO,WAAW,CAChF,EASM,MARe,EAA4B,EAAQ,CACxD,OAAQ,KAAK,OACb,SAAU,EAAY,EACtB,SAAU,CACR,aACA,YAAa,CAAC,EAAiB,CAChC,CACF,CAAC,EACa,KAAK,CAAE,WAAU,cAAe,CAC7C,GAAI,CAAC,EACH,MAAU,MAAM,+BAA+B,IAAW,CAE5D,MAAO,CACL,SAAU,EACV,OAAQ,EAAS,QAAQ,QAAS,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,QAAQ,eAAgB,GAAG,CACnF,QAAS,4DACV,EACD,EAGJ,CACE,YAAa,EACd,CACF,CAED,GAA6B,EAAQ,MAAM,CAAC,OAG5C,IAAM,EAAU,EAAK,EAAY,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAC7D,EAAmB,GAAG,EAAS,GAAG,IAAY,IAC9C,EAAyB,GAAG,EAAe,GAAG,IAAY,IAChE,MAAM,EAAc,EAAkB,EAAa,EAAQ,CAC3D,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAY,OAAO,wBAAwB,EAAK,GAAG,CACvF,CAED,IAAM,EAAoB,EAAQ,MAAM,CAExC,MAAM,EAAc,EAAwB,EAD3B,EAAK,EAAkB,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACF,CAAC,CACxE,KAAK,OAAO,KACV,EAAO,MACL,sBAAsB,EAAkB,OAAO,wBAAwB,EAAW,GACnF,CACF,CAED,KAAK,OAAO,KACV,EAAO,KACL,sBAAsB,EAAM,OAAO,sBAAsB,EAAkB,OAAO,qBACnF,CACF,CACD,GAAa,GAYb,eACA,mBACD,CAAC,CAEF,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAoB,wBAAwB,EAAK,GAAG,CACxF,CACD,KAAK,OAAO,KACV,EAAO,MACL,sBAAsB,EAA0B,wBAAwB,EAAW,GACpF,CACF"}
1
+ {"version":3,"file":"impl-CaPpiEL2.mjs","names":[],"sources":["../src/commands/request/cron/pull-profiles/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, fetchRequestFilesForRequest } from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport { uniq, chunk } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n pullChunkedCustomSiloOutstandingIdentifiers,\n type CsvFormattedIdentifier,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\n\nexport interface PullProfilesCommandFlags {\n file: string;\n fileTarget: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n cronDataSiloId: string;\n targetDataSiloId: string;\n actions: RequestAction[];\n skipRequestCount: boolean;\n pageLimit: number;\n chunkSize: number;\n}\n\nexport async function pullProfiles(\n this: LocalContext,\n {\n file,\n fileTarget,\n transcendUrl,\n auth,\n sombraAuth,\n cronDataSiloId,\n targetDataSiloId,\n actions,\n skipRequestCount,\n pageLimit,\n chunkSize,\n }: PullProfilesCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n this.logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n this.logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process);\n\n // Create GraphQL client to connect to Transcend backend\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n const { baseName, extension } = parseFilePath(file);\n const { baseName: baseNameTarget, extension: extensionTarget } = parseFilePath(fileTarget);\n\n let allIdentifiersCount = 0;\n let allTargetIdentifiersCount = 0;\n let fileCount = 0;\n // Create onSave callback to handle chunked processing\n const onSave = async (chunkToSave: CsvFormattedIdentifier[]): Promise<void> => {\n // Add to all identifiers\n allIdentifiersCount += chunkToSave.length;\n\n // Get unique request IDs from this chunk\n const requestIds = chunkToSave.map((d) => d.requestId as string);\n const uniqueRequestIds = uniq(requestIds);\n\n // Pull down target identifiers for this chunk\n const chunkedRequestIds = chunk(uniqueRequestIds, pageLimit);\n const results = await map(\n chunkedRequestIds,\n async (requestIds) => {\n this.logger.info(\n colors.magenta(`Fetching target identifiers for ${requestIds.length} requests`),\n );\n const results = await fetchRequestFilesForRequest(client, {\n logger: this.logger,\n pageSize: pageLimit * 2,\n filterBy: {\n requestIds,\n dataSiloIds: [targetDataSiloId],\n },\n });\n return results.map(({ fileName, remoteId }) => {\n if (!remoteId) {\n throw new Error(`Failed to find remoteId for ${fileName}`);\n }\n return {\n RecordId: remoteId,\n Object: fileName.replace('.json', '').split('/').pop()?.replace(' Information', ''),\n Comment: 'Customer data deletion request submitted via transcend.io',\n };\n });\n },\n // We are grabbing all the request files for the 'pageLimit' # of requests at a time\n {\n concurrency: 1,\n },\n );\n\n allTargetIdentifiersCount += results.flat().length;\n\n // Write the identifiers and target identifiers to CSV\n const headers = uniq(chunkToSave.map((d) => Object.keys(d)).flat());\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n const numberedFileNameTarget = `${baseNameTarget}-${fileCount}${extensionTarget}`;\n await writeLargeCsv(numberedFileName, chunkToSave, headers);\n this.logger.info(\n colors.green(`Successfully wrote ${chunkToSave.length} identifiers to file \"${file}\"`),\n );\n\n const targetIdentifiers = results.flat();\n const headers2 = uniq(targetIdentifiers.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileNameTarget, targetIdentifiers, headers2);\n this.logger.info(\n colors.green(\n `Successfully wrote ${targetIdentifiers.length} identifiers to file \"${fileTarget}\"`,\n ),\n );\n\n this.logger.info(\n colors.blue(\n `Processed chunk of ${chunk.length} identifiers, found ${targetIdentifiers.length} target identifiers`,\n ),\n );\n fileCount += 1;\n };\n\n // Pull down outstanding identifiers using the new chunked function\n await pullChunkedCustomSiloOutstandingIdentifiers({\n dataSiloId: cronDataSiloId,\n auth,\n sombraAuth,\n actions,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n transcendUrl,\n skipRequestCount,\n });\n\n this.logger.info(\n colors.green(`Successfully wrote ${allIdentifiersCount} identifiers to file \"${file}\"`),\n );\n this.logger.info(\n colors.green(\n `Successfully wrote ${allTargetIdentifiersCount} identifiers to file \"${fileTarget}\"`,\n ),\n );\n}\n"],"mappings":"wYA4BA,eAAsB,EAEpB,CACE,OACA,aACA,eACA,OACA,aACA,iBACA,mBACA,UACA,mBACA,YACA,aAEa,CACX,GACF,KAAK,OAAO,KACV,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,KAAK,OAAO,MACV,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,CAGjC,IAAM,EAAS,EAA4B,EAAc,EAAK,CACxD,CAAE,WAAU,aAAc,EAAc,EAAK,CAC7C,CAAE,SAAU,EAAgB,UAAW,GAAoB,EAAc,EAAW,CAEtF,EAAsB,EACtB,EAA4B,EAC5B,EAAY,EAwEhB,MAAM,EAA4C,CAChD,WAAY,EACZ,OACA,aACA,UACA,YAAa,EACb,aAAc,EACd,YA7EoB,IAAyD,CAE7E,GAAuB,EAAY,OAQnC,IAAM,EAAU,MAAM,EADI,EAHD,EADN,EAAY,IAAK,GAAM,EAAE,UACJ,CAGQ,CAAE,EAE/B,CACjB,KAAO,KACL,KAAK,OAAO,KACV,EAAO,QAAQ,mCAAmC,EAAW,OAAO,WAAW,CAChF,EASM,MARe,EAA4B,EAAQ,CACxD,OAAQ,KAAK,OACb,SAAU,EAAY,EACtB,SAAU,CACR,aACA,YAAa,CAAC,EAAiB,CAChC,CACF,CAAC,EACa,KAAK,CAAE,WAAU,cAAe,CAC7C,GAAI,CAAC,EACH,MAAU,MAAM,+BAA+B,IAAW,CAE5D,MAAO,CACL,SAAU,EACV,OAAQ,EAAS,QAAQ,QAAS,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,QAAQ,eAAgB,GAAG,CACnF,QAAS,4DACV,EACD,EAGJ,CACE,YAAa,EACd,CACF,CAED,GAA6B,EAAQ,MAAM,CAAC,OAG5C,IAAM,EAAU,EAAK,EAAY,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAC7D,EAAmB,GAAG,EAAS,GAAG,IAAY,IAC9C,EAAyB,GAAG,EAAe,GAAG,IAAY,IAChE,MAAM,EAAc,EAAkB,EAAa,EAAQ,CAC3D,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAY,OAAO,wBAAwB,EAAK,GAAG,CACvF,CAED,IAAM,EAAoB,EAAQ,MAAM,CAExC,MAAM,EAAc,EAAwB,EAD3B,EAAK,EAAkB,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACF,CAAC,CACxE,KAAK,OAAO,KACV,EAAO,MACL,sBAAsB,EAAkB,OAAO,wBAAwB,EAAW,GACnF,CACF,CAED,KAAK,OAAO,KACV,EAAO,KACL,sBAAsB,EAAM,OAAO,sBAAsB,EAAkB,OAAO,qBACnF,CACF,CACD,GAAa,GAYb,eACA,mBACD,CAAC,CAEF,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAoB,wBAAwB,EAAK,GAAG,CACxF,CACD,KAAK,OAAO,KACV,EAAO,MACL,sBAAsB,EAA0B,wBAAwB,EAAW,GACpF,CACF"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./downloadPrivacyRequestFiles-BckoJe0z.mjs";import{t}from"./done-input-validation-LiTaCEzF.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-Bm_dPfqr.mjs.map
1
+ import{t as e}from"./downloadPrivacyRequestFiles-DKRfQoAo.mjs";import{t}from"./done-input-validation-LiTaCEzF.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-CcVNbgw3.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Bm_dPfqr.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
+ {"version":3,"file":"impl-CcVNbgw3.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{n as e}from"./buildXdiSyncEndpoint-BUKWuQE6.mjs";import{t}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.mjs";import r from"colors";async function i({auth:i,xdiLocation:a,file:o,removeIpAddresses:s,domainBlockList:c,xdiAllowedCommands:l,transcendUrl:u}){n(this.process);let{syncGroups:d,html:f}=await e(await t(i,this),{xdiLocation:a,transcendUrl:u,removeIpAddresses:s,domainBlockList:c.length>0?c:void 0,xdiAllowedCommands:l});this.logger.info(r.green(`Successfully constructed sync endpoint for sync groups: ${JSON.stringify(d,null,2)}`)),this.fs.writeFileSync(o,f),this.logger.info(r.green(`Wrote configuration to file "${o}"!`))}export{i as buildXdiSyncEndpoint};
2
- //# sourceMappingURL=impl-B5z48Qiw.mjs.map
1
+ import{n as e}from"./buildXdiSyncEndpoint-CRJSuwdq.mjs";import{t}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.mjs";import r from"colors";async function i({auth:i,xdiLocation:a,file:o,removeIpAddresses:s,domainBlockList:c,xdiAllowedCommands:l,transcendUrl:u}){n(this.process);let{syncGroups:d,html:f}=await e(await t(i,this),{xdiLocation:a,transcendUrl:u,removeIpAddresses:s,domainBlockList:c.length>0?c:void 0,xdiAllowedCommands:l});this.logger.info(r.green(`Successfully constructed sync endpoint for sync groups: ${JSON.stringify(d,null,2)}`)),this.fs.writeFileSync(o,f),this.logger.info(r.green(`Wrote configuration to file "${o}"!`))}export{i as buildXdiSyncEndpoint};
2
+ //# sourceMappingURL=impl-CeR4wR2T.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-B5z48Qiw.mjs","names":["buildXdiSyncEndpointHelper"],"sources":["../src/commands/consent/build-xdi-sync-endpoint/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildXdiSyncEndpoint as buildXdiSyncEndpointHelper } from '../../../lib/consent-manager/index.js';\n\nexport interface BuildXdiSyncEndpointCommandFlags {\n auth: string;\n xdiLocation: string;\n file: string;\n removeIpAddresses: boolean;\n domainBlockList: string[];\n xdiAllowedCommands: string;\n transcendUrl: string;\n}\n\nexport async function buildXdiSyncEndpoint(\n this: LocalContext,\n {\n auth,\n xdiLocation,\n file,\n removeIpAddresses,\n domainBlockList,\n xdiAllowedCommands,\n transcendUrl,\n }: BuildXdiSyncEndpointCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth, this);\n\n // Build the sync endpoint\n const { syncGroups, html } = await buildXdiSyncEndpointHelper(apiKeyOrList, {\n xdiLocation,\n transcendUrl,\n removeIpAddresses,\n domainBlockList: domainBlockList.length > 0 ? domainBlockList : undefined,\n xdiAllowedCommands,\n });\n\n // Log success\n this.logger.info(\n colors.green(\n `Successfully constructed sync endpoint for sync groups: ${JSON.stringify(\n syncGroups,\n null,\n 2,\n )}`,\n ),\n );\n\n // Write to disk\n this.fs.writeFileSync(file, html);\n this.logger.info(colors.green(`Wrote configuration to file \"${file}\"!`));\n}\n"],"mappings":"2LAiBA,eAAsB,EAEpB,CACE,OACA,cACA,OACA,oBACA,kBACA,qBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAMjC,GAAM,CAAE,aAAY,QAAS,MAAMA,EAA2B,MAHnC,EAAsB,EAAM,KAAK,CAGgB,CAC1E,cACA,eACA,oBACA,gBAAiB,EAAgB,OAAS,EAAI,EAAkB,IAAA,GAChE,qBACD,CAAC,CAGF,KAAK,OAAO,KACV,EAAO,MACL,2DAA2D,KAAK,UAC9D,EACA,KACA,EACD,GACF,CACF,CAGD,KAAK,GAAG,cAAc,EAAM,EAAK,CACjC,KAAK,OAAO,KAAK,EAAO,MAAM,gCAAgC,EAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"impl-CeR4wR2T.mjs","names":["buildXdiSyncEndpointHelper"],"sources":["../src/commands/consent/build-xdi-sync-endpoint/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildXdiSyncEndpoint as buildXdiSyncEndpointHelper } from '../../../lib/consent-manager/index.js';\n\nexport interface BuildXdiSyncEndpointCommandFlags {\n auth: string;\n xdiLocation: string;\n file: string;\n removeIpAddresses: boolean;\n domainBlockList: string[];\n xdiAllowedCommands: string;\n transcendUrl: string;\n}\n\nexport async function buildXdiSyncEndpoint(\n this: LocalContext,\n {\n auth,\n xdiLocation,\n file,\n removeIpAddresses,\n domainBlockList,\n xdiAllowedCommands,\n transcendUrl,\n }: BuildXdiSyncEndpointCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth, this);\n\n // Build the sync endpoint\n const { syncGroups, html } = await buildXdiSyncEndpointHelper(apiKeyOrList, {\n xdiLocation,\n transcendUrl,\n removeIpAddresses,\n domainBlockList: domainBlockList.length > 0 ? domainBlockList : undefined,\n xdiAllowedCommands,\n });\n\n // Log success\n this.logger.info(\n colors.green(\n `Successfully constructed sync endpoint for sync groups: ${JSON.stringify(\n syncGroups,\n null,\n 2,\n )}`,\n ),\n );\n\n // Write to disk\n this.fs.writeFileSync(file, html);\n this.logger.info(colors.green(`Wrote configuration to file \"${file}\"!`));\n}\n"],"mappings":"2LAiBA,eAAsB,EAEpB,CACE,OACA,cACA,OACA,oBACA,kBACA,qBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAMjC,GAAM,CAAE,aAAY,QAAS,MAAMA,EAA2B,MAHnC,EAAsB,EAAM,KAAK,CAGgB,CAC1E,cACA,eACA,oBACA,gBAAiB,EAAgB,OAAS,EAAI,EAAkB,IAAA,GAChE,qBACD,CAAC,CAGF,KAAK,OAAO,KACV,EAAO,MACL,2DAA2D,KAAK,UAC9D,EACA,KACA,EACD,GACF,CACF,CAGD,KAAK,GAAG,cAAc,EAAM,EAAK,CACjC,KAAK,OAAO,KAAK,EAAO,MAAM,gCAAgC,EAAK,IAAI,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./retryRequestDataSilos-ClvwV9pP.mjs";import{t}from"./done-input-validation-LiTaCEzF.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-DsOUCV22.mjs.map
1
+ import{t as e}from"./retryRequestDataSilos-BWGlpn1o.mjs";import{t}from"./done-input-validation-LiTaCEzF.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-CihGggtZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DsOUCV22.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"}
1
+ {"version":3,"file":"impl-CihGggtZ.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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./pullChunkedCustomSiloOutstandingIdentifiers-D5lFuhaD.mjs";import{i as t,s as n}from"./writeCsv-CNZrq3zU.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{uniq as i}from"lodash-es";import a from"colors";async function o({file:o,transcendUrl:s,auth:c,sombraAuth:l,dataSiloId:u,actions:d,pageLimit:f,skipRequestCount:p,chunkSize:m}){p&&this.logger.info(a.yellow(`Skipping request count as requested. This may help speed up the call.`)),(Number.isNaN(m)||m<=0||m%f!==0)&&(this.logger.error(a.red(`Invalid chunk size: "${m}". Must be a positive integer that is a multiple of ${f}.`)),this.process.exit(1)),r(this.process);let{baseName:h,extension:g}=t(o),_=0;await e({transcendUrl:s,apiPageSize:f,savePageSize:m,onSave:async e=>{let t=`${h}-${_}${g}`;return this.logger.info(a.blue(`Saving ${e.length} identifiers to file "${t}"`)),await n(t,e,i(e.map(e=>Object.keys(e)).flat())),this.logger.info(a.green(`Successfully wrote ${e.length} identifiers to file "${t}"`)),_+=1,Promise.resolve()},actions:d,auth:c,sombraAuth:l,dataSiloId:u,skipRequestCount:p})}export{o as pullIdentifiers};
2
- //# sourceMappingURL=impl-ChE-8VKk.mjs.map
1
+ import{t as e}from"./pullChunkedCustomSiloOutstandingIdentifiers-CDHCpiXU.mjs";import{i as t,s as n}from"./writeCsv-CNZrq3zU.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{uniq as i}from"lodash-es";import a from"colors";async function o({file:o,transcendUrl:s,auth:c,sombraAuth:l,dataSiloId:u,actions:d,pageLimit:f,skipRequestCount:p,chunkSize:m}){p&&this.logger.info(a.yellow(`Skipping request count as requested. This may help speed up the call.`)),(Number.isNaN(m)||m<=0||m%f!==0)&&(this.logger.error(a.red(`Invalid chunk size: "${m}". Must be a positive integer that is a multiple of ${f}.`)),this.process.exit(1)),r(this.process);let{baseName:h,extension:g}=t(o),_=0;await e({transcendUrl:s,apiPageSize:f,savePageSize:m,onSave:async e=>{let t=`${h}-${_}${g}`;return this.logger.info(a.blue(`Saving ${e.length} identifiers to file "${t}"`)),await n(t,e,i(e.map(e=>Object.keys(e)).flat())),this.logger.info(a.green(`Successfully wrote ${e.length} identifiers to file "${t}"`)),_+=1,Promise.resolve()},actions:d,auth:c,sombraAuth:l,dataSiloId:u,skipRequestCount:p})}export{o as pullIdentifiers};
2
+ //# sourceMappingURL=impl-DEK7xark.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-ChE-8VKk.mjs","names":[],"sources":["../src/commands/request/cron/pull-identifiers/impl.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport colors from 'colors';\nimport { uniq } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n CsvFormattedIdentifier,\n pullChunkedCustomSiloOutstandingIdentifiers,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n actions: RequestAction[];\n pageLimit: number;\n skipRequestCount: boolean;\n chunkSize: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n {\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n actions,\n pageLimit,\n skipRequestCount,\n chunkSize,\n }: PullIdentifiersCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n this.logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n this.logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process);\n\n const { baseName, extension } = parseFilePath(file);\n let fileCount = 0;\n\n const onSave = async (chunk: CsvFormattedIdentifier[]): Promise<void> => {\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n this.logger.info(\n colors.blue(`Saving ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n\n const headers = uniq(chunk.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileName, chunk, headers);\n this.logger.info(\n colors.green(`Successfully wrote ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n fileCount += 1;\n return Promise.resolve();\n };\n\n // Pull down outstanding identifiers\n await pullChunkedCustomSiloOutstandingIdentifiers({\n transcendUrl,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n actions,\n auth,\n sombraAuth,\n dataSiloId,\n skipRequestCount,\n });\n}\n"],"mappings":"kPAwBA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,aACA,aACA,UACA,YACA,mBACA,aAEa,CACX,GACF,KAAK,OAAO,KACV,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,KAAK,OAAO,MACV,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,CAEjC,GAAM,CAAE,WAAU,aAAc,EAAc,EAAK,CAC/C,EAAY,EAkBhB,MAAM,EAA4C,CAChD,eACA,YAAa,EACb,aAAc,EACd,YApBoB,IAAmD,CACvE,IAAM,EAAmB,GAAG,EAAS,GAAG,IAAY,IAWpD,OAVA,KAAK,OAAO,KACV,EAAO,KAAK,UAAU,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAChF,CAGD,MAAM,EAAc,EAAkB,EADtB,EAAK,EAAM,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACR,CAAC,CACrD,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAC7F,CACD,GAAa,EACN,QAAQ,SAAS,EASxB,UACA,OACA,aACA,aACA,mBACD,CAAC"}
1
+ {"version":3,"file":"impl-DEK7xark.mjs","names":[],"sources":["../src/commands/request/cron/pull-identifiers/impl.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport colors from 'colors';\nimport { uniq } from 'lodash-es';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport {\n CsvFormattedIdentifier,\n pullChunkedCustomSiloOutstandingIdentifiers,\n} from '../../../../lib/cron/index.js';\nimport { parseFilePath, writeLargeCsv } from '../../../../lib/helpers/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n actions: RequestAction[];\n pageLimit: number;\n skipRequestCount: boolean;\n chunkSize: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n {\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n actions,\n pageLimit,\n skipRequestCount,\n chunkSize,\n }: PullIdentifiersCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n this.logger.info(\n colors.yellow('Skipping request count as requested. This may help speed up the call.'),\n );\n }\n\n if (Number.isNaN(chunkSize) || chunkSize <= 0 || chunkSize % pageLimit !== 0) {\n this.logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process);\n\n const { baseName, extension } = parseFilePath(file);\n let fileCount = 0;\n\n const onSave = async (chunk: CsvFormattedIdentifier[]): Promise<void> => {\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n this.logger.info(\n colors.blue(`Saving ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n\n const headers = uniq(chunk.map((d) => Object.keys(d)).flat());\n await writeLargeCsv(numberedFileName, chunk, headers);\n this.logger.info(\n colors.green(`Successfully wrote ${chunk.length} identifiers to file \"${numberedFileName}\"`),\n );\n fileCount += 1;\n return Promise.resolve();\n };\n\n // Pull down outstanding identifiers\n await pullChunkedCustomSiloOutstandingIdentifiers({\n transcendUrl,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n actions,\n auth,\n sombraAuth,\n dataSiloId,\n skipRequestCount,\n });\n}\n"],"mappings":"kPAwBA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,aACA,aACA,UACA,YACA,mBACA,aAEa,CACX,GACF,KAAK,OAAO,KACV,EAAO,OAAO,wEAAwE,CACvF,EAGC,OAAO,MAAM,EAAU,EAAI,GAAa,GAAK,EAAY,IAAc,KACzE,KAAK,OAAO,MACV,EAAO,IACL,wBAAwB,EAAU,sDAAsD,EAAU,GACnG,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,EAAoB,KAAK,QAAQ,CAEjC,GAAM,CAAE,WAAU,aAAc,EAAc,EAAK,CAC/C,EAAY,EAkBhB,MAAM,EAA4C,CAChD,eACA,YAAa,EACb,aAAc,EACd,YApBoB,IAAmD,CACvE,IAAM,EAAmB,GAAG,EAAS,GAAG,IAAY,IAWpD,OAVA,KAAK,OAAO,KACV,EAAO,KAAK,UAAU,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAChF,CAGD,MAAM,EAAc,EAAkB,EADtB,EAAK,EAAM,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CACR,CAAC,CACrD,KAAK,OAAO,KACV,EAAO,MAAM,sBAAsB,EAAM,OAAO,wBAAwB,EAAiB,GAAG,CAC7F,CACD,GAAa,EACN,QAAQ,SAAS,EASxB,UACA,OACA,aACA,aACA,mBACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{i as e}from"./enums-OiLcZ26O.mjs";import{r as t}from"./constants-6F0ha8ue.mjs";import{n,t as r}from"./command-BYXHxOsD.mjs";import{o as i}from"./readTranscendYaml-D576bvzR.mjs";import{n as a}from"./pullTranscendConfiguration-CDUDqxpm.mjs";import{t as o}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as s}from"./done-input-validation-LiTaCEzF.mjs";import c from"node:path";import l from"colors";import{mapSeries as u}from"@transcend-io/utils";import{buildTranscendGraphQLClient as d}from"@transcend-io/sdk";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(d(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 u(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=d(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-L1xM2Wb2.mjs.map
1
+ import{i as e}from"./enums-OiLcZ26O.mjs";import{r as t}from"./constants-ZX8RSZos.mjs";import{n,t as r}from"./command-DB0ydG0y.mjs";import{o as i}from"./readTranscendYaml-D576bvzR.mjs";import{n as a}from"./pullTranscendConfiguration-CDUDqxpm.mjs";import{t as o}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as s}from"./done-input-validation-LiTaCEzF.mjs";import c from"node:path";import l from"colors";import{mapSeries as u}from"@transcend-io/utils";import{buildTranscendGraphQLClient as d}from"@transcend-io/sdk";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(d(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 u(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=d(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-DHq2UBl4.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-L1xM2Wb2.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"}
1
+ {"version":3,"file":"impl-DHq2UBl4.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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./bulkRestartRequests-V4cDUp29.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,requestReceiptFolder:r,sombraAuth:i,actions:a,statuses:o,requestIds:s,createdAt:c,emailIsVerified:l,silentModeBefore:u,sendEmailReceipt:d,copyIdentifiers:f,restartIdentifierStrategy:p,skipWaitingPeriod:m,createdAtBefore:h,createdAtAfter:g,updatedAtBefore:_,updatedAtAfter:v,concurrency:y,transcendUrl:b}){t(this.process),await e({requestReceiptFolder:r,auth:n,sombraAuth:i,requestActions:a,requestStatuses:o,requestIds:s,createdAt:c,emailIsVerified:l,silentModeBefore:u,sendEmailReceipt:d,copyIdentifiers:f,restartIdentifierStrategy:p,skipWaitingPeriod:m,createdAtBefore:h,createdAtAfter:g,updatedAtBefore:_,updatedAtAfter:v,concurrency:y,transcendUrl:b})}export{n as restart};
2
- //# sourceMappingURL=impl-Bl42P-wI.mjs.map
1
+ import{t as e}from"./bulkRestartRequests-C9cHasoq.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,requestReceiptFolder:r,sombraAuth:i,actions:a,statuses:o,requestIds:s,createdAt:c,emailIsVerified:l,silentModeBefore:u,sendEmailReceipt:d,copyIdentifiers:f,restartIdentifierStrategy:p,skipWaitingPeriod:m,createdAtBefore:h,createdAtAfter:g,updatedAtBefore:_,updatedAtAfter:v,concurrency:y,transcendUrl:b}){t(this.process),await e({requestReceiptFolder:r,auth:n,sombraAuth:i,requestActions:a,requestStatuses:o,requestIds:s,createdAt:c,emailIsVerified:l,silentModeBefore:u,sendEmailReceipt:d,copyIdentifiers:f,restartIdentifierStrategy:p,skipWaitingPeriod:m,createdAtBefore:h,createdAtAfter:g,updatedAtBefore:_,updatedAtAfter:v,concurrency:y,transcendUrl:b})}export{n as restart};
2
+ //# sourceMappingURL=impl-DJ5kJ80R.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Bl42P-wI.mjs","names":[],"sources":["../src/commands/request/restart/impl.ts"],"sourcesContent":["import type {\n RequestAction,\n RequestStatus,\n RestartIdentifierStrategy,\n} from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { bulkRestartRequests } from '../../../lib/requests/index.js';\n\nexport interface RestartCommandFlags {\n auth: string;\n actions: RequestAction[];\n statuses: RequestStatus[];\n transcendUrl: string;\n requestReceiptFolder: string;\n sombraAuth?: string;\n concurrency: number;\n requestIds?: string[];\n emailIsVerified: boolean;\n createdAt?: Date;\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n sendEmailReceipt: boolean;\n copyIdentifiers: boolean;\n restartIdentifierStrategy?: RestartIdentifierStrategy;\n skipWaitingPeriod: boolean;\n}\n\nexport async function restart(\n this: LocalContext,\n {\n auth,\n requestReceiptFolder,\n sombraAuth,\n actions,\n statuses,\n requestIds,\n createdAt,\n emailIsVerified,\n silentModeBefore,\n sendEmailReceipt,\n copyIdentifiers,\n restartIdentifierStrategy,\n skipWaitingPeriod,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n }: RestartCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await bulkRestartRequests({\n requestReceiptFolder,\n auth,\n sombraAuth,\n requestActions: actions,\n requestStatuses: statuses,\n requestIds,\n createdAt,\n emailIsVerified,\n silentModeBefore,\n sendEmailReceipt,\n copyIdentifiers,\n restartIdentifierStrategy,\n skipWaitingPeriod,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n });\n}\n"],"mappings":"2GAgCA,eAAsB,EAEpB,CACE,OACA,uBACA,aACA,UACA,WACA,aACA,YACA,kBACA,mBACA,mBACA,kBACA,4BACA,oBACA,kBACA,iBACA,kBACA,iBACA,cACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAoB,CACxB,uBACA,OACA,aACA,eAAgB,EAChB,gBAAiB,EACjB,aACA,YACA,kBACA,mBACA,mBACA,kBACA,4BACA,oBACA,kBACA,iBACA,kBACA,iBACA,cACA,eACD,CAAC"}
1
+ {"version":3,"file":"impl-DJ5kJ80R.mjs","names":[],"sources":["../src/commands/request/restart/impl.ts"],"sourcesContent":["import type {\n RequestAction,\n RequestStatus,\n RestartIdentifierStrategy,\n} from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { bulkRestartRequests } from '../../../lib/requests/index.js';\n\nexport interface RestartCommandFlags {\n auth: string;\n actions: RequestAction[];\n statuses: RequestStatus[];\n transcendUrl: string;\n requestReceiptFolder: string;\n sombraAuth?: string;\n concurrency: number;\n requestIds?: string[];\n emailIsVerified: boolean;\n createdAt?: Date;\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n sendEmailReceipt: boolean;\n copyIdentifiers: boolean;\n restartIdentifierStrategy?: RestartIdentifierStrategy;\n skipWaitingPeriod: boolean;\n}\n\nexport async function restart(\n this: LocalContext,\n {\n auth,\n requestReceiptFolder,\n sombraAuth,\n actions,\n statuses,\n requestIds,\n createdAt,\n emailIsVerified,\n silentModeBefore,\n sendEmailReceipt,\n copyIdentifiers,\n restartIdentifierStrategy,\n skipWaitingPeriod,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n }: RestartCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await bulkRestartRequests({\n requestReceiptFolder,\n auth,\n sombraAuth,\n requestActions: actions,\n requestStatuses: statuses,\n requestIds,\n createdAt,\n emailIsVerified,\n silentModeBefore,\n sendEmailReceipt,\n copyIdentifiers,\n restartIdentifierStrategy,\n skipWaitingPeriod,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n concurrency,\n transcendUrl,\n });\n}\n"],"mappings":"2GAgCA,eAAsB,EAEpB,CACE,OACA,uBACA,aACA,UACA,WACA,aACA,YACA,kBACA,mBACA,mBACA,kBACA,4BACA,oBACA,kBACA,iBACA,kBACA,iBACA,cACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAoB,CACxB,uBACA,OACA,aACA,eAAgB,EAChB,gBAAiB,EACjB,aACA,YACA,kBACA,mBACA,mBACA,kBACA,4BACA,oBACA,kBACA,iBACA,kBACA,iBACA,cACA,eACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{g as e}from"./constants-6F0ha8ue.mjs";import{r as t,t as n}from"./project-plan-output-BHHlkLxe.mjs";import{t as r}from"./project-discovery-CWRjlFnC.mjs";import{t as i}from"./done-input-validation-LiTaCEzF.mjs";import{n as a}from"./project-discovery-g29vd44a.mjs";import{i as o,n as s,r as c,t as l}from"./prompts-BhXfYD6g.mjs";import{t as u}from"./run-captured-process-BjaSDWXG.mjs";import{r as d,t as f}from"./deno-runtime-CB2HBach.mjs";import{t as p}from"./scaffold-model-CUZER0BC.mjs";import{t as m}from"./project-plan-apply-Bg_1eMX9.mjs";import{c as h,i as g,n as _,s as v}from"./scaffold-planning-Bp_yqZWx.mjs";import y from"colors";import{CUSTOM_FUNCTION_TYPES_VERSION as b}from"@transcend-io/custom-function-types";const x={[p.Deno]:`Deno configuration`,[p.Editor]:`VS Code settings`,[p.Skill]:`Agent skill`,[p.Ci]:`GitHub Actions`},S=Object.values(p);async function C(C,w){i(this.process);try{let i=a(this,{...w?{directory:w}:{},...C.manifest?{manifest:C.manifest}:{}}),l=new s(this),T=c(C,this.process.stdin.isTTY,this.process.stderr.isTTY),E=await o(l,{features:S,labels:x,enabled:{[p.Deno]:C.deno,[p.Editor]:C.editor,[p.Skill]:C.skill,[p.Ci]:C.ci},interactive:T}),D=_({state:i,snapshots:r(this,i.projectRoot,g(i,{features:E})),contractVersion:b,cliVersion:e},{features:E});if(E.includes(p.Deno)){let e=await u(`deno`,[`--version`],{cwd:this.process.cwd()},this);if(e.error?.code===`ENOENT`)D.warnings.push(`Deno 2.x is not installed. Install it from ${f}`);else if(e.code!==0)D.warnings.push(`Deno was found, but its version could not be determined. Deno 2.x is required. See ${f}`);else{let t=d(e.stdout);t.level!==`compatible`&&D.warnings.push(t.message)}}C.json||this.logger.info(t(D,{cwd:this.process.cwd(),title:`Custom Function plan`,details:[{label:`Target`,path:D.targetDirectory},{label:`Manifest`,path:D.manifestPath}]}));let O=D.changes.length===0||C.dryRun;if(D.changes.length>0&&!C.dryRun)if(C.yes)O=!0;else if(T)O=await l.confirm(`Apply this complete plan?`,!0);else throw Error(`The plan requires approval in a non-interactive invocation. Review with --dryRun, then pass --yes.`);O&&!C.dryRun&&D.changes.length>0&&await m(this,D);let k=O&&!C.dryRun&&D.changes.length>0,A=O&&!C.dryRun,j=h({targetDirectory:n(this.process.cwd(),i.targetDirectory),manifestPath:n(this.process.cwd(),i.manifestPath),cliVersion:e,hasSkill:A&&E.includes(p.Skill),hasGithubWorkflow:A&&E.includes(p.Ci)&&!!(i.repositoryRoot&&i.usesGithub)}),M=v(D,{applied:k,dryRun:C.dryRun,cwd:this.process.cwd(),aiHandoff:j});if(C.json){this.process.stdout.write(`${JSON.stringify(M)}\n`);return}if(C.dryRun){this.logger.info(y.yellow(`Dry run complete. No changes were written.`));return}if(!O){this.logger.info(y.yellow(`No changes applied.`));return}if(D.changes.length===0){this.logger.info(y.green(`Custom Function project is already initialized.`));return}this.logger.info(y.green(`Custom Function project initialized.`)),D.nextSteps.length>0&&(this.logger.info(`\n${y.bold(`Next steps`)}`),D.nextSteps.forEach(e=>this.logger.info(e))),this.logger.info(`\n${y.bold(`AI handoff — paste into your coding agent`)}`),this.logger.info(j)}catch(e){throw e instanceof l&&this.process.exit(130),e}}export{C as init};
2
- //# sourceMappingURL=impl-BnTWnayD.mjs.map
1
+ import{g as e}from"./constants-ZX8RSZos.mjs";import{r as t,t as n}from"./project-plan-output-BHHlkLxe.mjs";import{t as r}from"./project-discovery-CWRjlFnC.mjs";import{t as i}from"./done-input-validation-LiTaCEzF.mjs";import{n as a}from"./project-discovery-g29vd44a.mjs";import{i as o,n as s,r as c,t as l}from"./prompts-BhXfYD6g.mjs";import{t as u}from"./run-captured-process-BjaSDWXG.mjs";import{r as d,t as f}from"./deno-runtime-CB2HBach.mjs";import{t as p}from"./scaffold-model-CUZER0BC.mjs";import{t as m}from"./project-plan-apply-Bg_1eMX9.mjs";import{c as h,i as g,n as _,s as v}from"./scaffold-planning-Bp_yqZWx.mjs";import y from"colors";import{CUSTOM_FUNCTION_TYPES_VERSION as b}from"@transcend-io/custom-function-types";const x={[p.Deno]:`Deno configuration`,[p.Editor]:`VS Code settings`,[p.Skill]:`Agent skill`,[p.Ci]:`GitHub Actions`},S=Object.values(p);async function C(C,w){i(this.process);try{let i=a(this,{...w?{directory:w}:{},...C.manifest?{manifest:C.manifest}:{}}),l=new s(this),T=c(C,this.process.stdin.isTTY,this.process.stderr.isTTY),E=await o(l,{features:S,labels:x,enabled:{[p.Deno]:C.deno,[p.Editor]:C.editor,[p.Skill]:C.skill,[p.Ci]:C.ci},interactive:T}),D=_({state:i,snapshots:r(this,i.projectRoot,g(i,{features:E})),contractVersion:b,cliVersion:e},{features:E});if(E.includes(p.Deno)){let e=await u(`deno`,[`--version`],{cwd:this.process.cwd()},this);if(e.error?.code===`ENOENT`)D.warnings.push(`Deno 2.x is not installed. Install it from ${f}`);else if(e.code!==0)D.warnings.push(`Deno was found, but its version could not be determined. Deno 2.x is required. See ${f}`);else{let t=d(e.stdout);t.level!==`compatible`&&D.warnings.push(t.message)}}C.json||this.logger.info(t(D,{cwd:this.process.cwd(),title:`Custom Function plan`,details:[{label:`Target`,path:D.targetDirectory},{label:`Manifest`,path:D.manifestPath}]}));let O=D.changes.length===0||C.dryRun;if(D.changes.length>0&&!C.dryRun)if(C.yes)O=!0;else if(T)O=await l.confirm(`Apply this complete plan?`,!0);else throw Error(`The plan requires approval in a non-interactive invocation. Review with --dryRun, then pass --yes.`);O&&!C.dryRun&&D.changes.length>0&&await m(this,D);let k=O&&!C.dryRun&&D.changes.length>0,A=O&&!C.dryRun,j=h({targetDirectory:n(this.process.cwd(),i.targetDirectory),manifestPath:n(this.process.cwd(),i.manifestPath),cliVersion:e,hasSkill:A&&E.includes(p.Skill),hasGithubWorkflow:A&&E.includes(p.Ci)&&!!(i.repositoryRoot&&i.usesGithub)}),M=v(D,{applied:k,dryRun:C.dryRun,cwd:this.process.cwd(),aiHandoff:j});if(C.json){this.process.stdout.write(`${JSON.stringify(M)}\n`);return}if(C.dryRun){this.logger.info(y.yellow(`Dry run complete. No changes were written.`));return}if(!O){this.logger.info(y.yellow(`No changes applied.`));return}if(D.changes.length===0){this.logger.info(y.green(`Custom Function project is already initialized.`));return}this.logger.info(y.green(`Custom Function project initialized.`)),D.nextSteps.length>0&&(this.logger.info(`\n${y.bold(`Next steps`)}`),D.nextSteps.forEach(e=>this.logger.info(e))),this.logger.info(`\n${y.bold(`AI handoff — paste into your coding agent`)}`),this.logger.info(j)}catch(e){throw e instanceof l&&this.process.exit(130),e}}export{C as init};
2
+ //# sourceMappingURL=impl-DQftQKzh.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-BnTWnayD.mjs","names":["CLI_VERSION"],"sources":["../src/commands/custom-functions/init/impl.ts"],"sourcesContent":["import { CUSTOM_FUNCTION_TYPES_VERSION } from '@transcend-io/custom-function-types';\nimport colors from 'colors';\n\nimport { version as CLI_VERSION } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { runCapturedProcess } from '../../../lib/cli/run-captured-process.js';\nimport { buildInitAiHandoff } from '../../../lib/custom-functions/ai-handoff.js';\nimport {\n DENO_INSTALL_URL,\n getDenoRuntimeCompatibility,\n SUPPORTED_DENO_MAJOR_VERSION,\n} from '../../../lib/custom-functions/deno-runtime.js';\nimport { discoverCustomFunctionProject } from '../../../lib/custom-functions/project-discovery.js';\nimport {\n CustomFunctionSetupFeature,\n type CustomFunctionSetupFeature as CustomFunctionSetupFeatureType,\n} from '../../../lib/custom-functions/scaffold-model.js';\nimport { buildPlanResult } from '../../../lib/custom-functions/scaffold-output.js';\nimport {\n buildInitPlan,\n getInitPlanningCandidatePaths,\n} from '../../../lib/custom-functions/scaffold-planning.js';\nimport { collectPlanningSnapshots } from '../../../lib/scaffolding/project-discovery.js';\nimport { applyProjectPlan } from '../../../lib/scaffolding/project-plan-apply.js';\nimport {\n displayProjectPath,\n renderProjectPlan,\n} from '../../../lib/scaffolding/project-plan-output.js';\nimport {\n isInteractivePromptInvocation,\n PromptCancelledError,\n resolveSetupFeatures,\n ScaffoldPrompts,\n} from '../../../lib/scaffolding/prompts.js';\n\n/** Flags for `custom-functions init`. */\nexport interface CustomFunctionInitFlags {\n /** Explicit manifest path. */\n manifest?: string;\n /** Install Deno configuration. */\n deno?: boolean;\n /** Install editor recommendations. */\n editor?: boolean;\n /** Install the coding-agent skill. */\n skill?: boolean;\n /** Install GitHub Actions validation. */\n ci?: boolean;\n /** Disable prompts. */\n noInteractive: boolean;\n /** Render but do not apply. */\n dryRun: boolean;\n /** Approve the final displayed plan. */\n yes: boolean;\n /** Emit one stable JSON result on stdout. */\n json: boolean;\n}\n\n/** User-facing setup labels. */\nconst SETUP_LABELS: Readonly<Record<CustomFunctionSetupFeatureType, string>> = {\n [CustomFunctionSetupFeature.Deno]: 'Deno configuration',\n [CustomFunctionSetupFeature.Editor]: 'VS Code settings',\n [CustomFunctionSetupFeature.Skill]: 'Agent skill',\n [CustomFunctionSetupFeature.Ci]: 'GitHub Actions',\n};\n\n/** All optional setup features in stable prompt order. */\nconst ALL_SETUP_FEATURES = Object.values(CustomFunctionSetupFeature);\n\n/**\n * Initialize a credential-free local Custom Function project.\n *\n * @param this - CLI context\n * @param flags - Scaffold and interaction flags\n * @param directory - Optional target directory\n */\nexport async function init(\n this: LocalContext,\n flags: CustomFunctionInitFlags,\n directory?: string,\n): Promise<void> {\n doneInputValidation(this.process);\n try {\n const state = discoverCustomFunctionProject(this, {\n ...(directory ? { directory } : {}),\n ...(flags.manifest ? { manifest: flags.manifest } : {}),\n });\n const prompts = new ScaffoldPrompts(this);\n const interactive = isInteractivePromptInvocation(\n flags,\n this.process.stdin.isTTY,\n this.process.stderr.isTTY,\n );\n const features = await resolveSetupFeatures(prompts, {\n features: ALL_SETUP_FEATURES,\n labels: SETUP_LABELS,\n enabled: {\n [CustomFunctionSetupFeature.Deno]: flags.deno,\n [CustomFunctionSetupFeature.Editor]: flags.editor,\n [CustomFunctionSetupFeature.Skill]: flags.skill,\n [CustomFunctionSetupFeature.Ci]: flags.ci,\n },\n interactive,\n });\n const snapshots = collectPlanningSnapshots(\n this,\n state.projectRoot,\n getInitPlanningCandidatePaths(state, { features }),\n );\n const plan = buildInitPlan(\n {\n state,\n snapshots,\n contractVersion: CUSTOM_FUNCTION_TYPES_VERSION,\n cliVersion: CLI_VERSION,\n },\n { features },\n );\n if (features.includes(CustomFunctionSetupFeature.Deno)) {\n const denoVersion = await runCapturedProcess(\n 'deno',\n ['--version'],\n { cwd: this.process.cwd() },\n this,\n );\n if (denoVersion.error?.code === 'ENOENT') {\n plan.warnings.push(\n `Deno ${SUPPORTED_DENO_MAJOR_VERSION}.x is not installed. Install it from ${DENO_INSTALL_URL}`,\n );\n } else if (denoVersion.code !== 0) {\n plan.warnings.push(\n `Deno was found, but its version could not be determined. Deno ${SUPPORTED_DENO_MAJOR_VERSION}.x is required. See ${DENO_INSTALL_URL}`,\n );\n } else {\n const compatibility = getDenoRuntimeCompatibility(denoVersion.stdout);\n if (compatibility.level !== 'compatible') {\n plan.warnings.push(compatibility.message);\n }\n }\n }\n if (!flags.json) {\n this.logger.info(\n renderProjectPlan(plan, {\n cwd: this.process.cwd(),\n title: 'Custom Function plan',\n details: [\n { label: 'Target', path: plan.targetDirectory },\n { label: 'Manifest', path: plan.manifestPath },\n ],\n }),\n );\n }\n\n let approved = plan.changes.length === 0 || flags.dryRun;\n if (plan.changes.length > 0 && !flags.dryRun) {\n if (flags.yes) {\n approved = true;\n } else if (interactive) {\n approved = await prompts.confirm('Apply this complete plan?', true);\n } else {\n throw new Error(\n 'The plan requires approval in a non-interactive invocation. Review with --dryRun, then pass --yes.',\n );\n }\n }\n\n if (approved && !flags.dryRun && plan.changes.length > 0) {\n await applyProjectPlan(this, plan);\n }\n const applied = approved && !flags.dryRun && plan.changes.length > 0;\n const setupAvailable = approved && !flags.dryRun;\n const aiHandoff = buildInitAiHandoff({\n targetDirectory: displayProjectPath(this.process.cwd(), state.targetDirectory),\n manifestPath: displayProjectPath(this.process.cwd(), state.manifestPath),\n cliVersion: CLI_VERSION,\n hasSkill: setupAvailable && features.includes(CustomFunctionSetupFeature.Skill),\n hasGithubWorkflow:\n setupAvailable &&\n features.includes(CustomFunctionSetupFeature.Ci) &&\n Boolean(state.repositoryRoot && state.usesGithub),\n });\n const result = buildPlanResult(plan, {\n applied,\n dryRun: flags.dryRun,\n cwd: this.process.cwd(),\n aiHandoff,\n });\n if (flags.json) {\n this.process.stdout.write(`${JSON.stringify(result)}\\n`);\n return;\n }\n if (flags.dryRun) {\n this.logger.info(colors.yellow('Dry run complete. No changes were written.'));\n return;\n }\n if (!approved) {\n this.logger.info(colors.yellow('No changes applied.'));\n return;\n }\n if (plan.changes.length === 0) {\n this.logger.info(colors.green('Custom Function project is already initialized.'));\n return;\n }\n this.logger.info(colors.green('Custom Function project initialized.'));\n if (plan.nextSteps.length > 0) {\n this.logger.info(`\\n${colors.bold('Next steps')}`);\n plan.nextSteps.forEach((step) => this.logger.info(step));\n }\n this.logger.info(`\\n${colors.bold('AI handoff — paste into your coding agent')}`);\n this.logger.info(aiHandoff);\n } catch (error) {\n if (error instanceof PromptCancelledError) {\n this.process.exit(130);\n }\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"impl-DQftQKzh.mjs","names":["CLI_VERSION"],"sources":["../src/commands/custom-functions/init/impl.ts"],"sourcesContent":["import { CUSTOM_FUNCTION_TYPES_VERSION } from '@transcend-io/custom-function-types';\nimport colors from 'colors';\n\nimport { version as CLI_VERSION } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { runCapturedProcess } from '../../../lib/cli/run-captured-process.js';\nimport { buildInitAiHandoff } from '../../../lib/custom-functions/ai-handoff.js';\nimport {\n DENO_INSTALL_URL,\n getDenoRuntimeCompatibility,\n SUPPORTED_DENO_MAJOR_VERSION,\n} from '../../../lib/custom-functions/deno-runtime.js';\nimport { discoverCustomFunctionProject } from '../../../lib/custom-functions/project-discovery.js';\nimport {\n CustomFunctionSetupFeature,\n type CustomFunctionSetupFeature as CustomFunctionSetupFeatureType,\n} from '../../../lib/custom-functions/scaffold-model.js';\nimport { buildPlanResult } from '../../../lib/custom-functions/scaffold-output.js';\nimport {\n buildInitPlan,\n getInitPlanningCandidatePaths,\n} from '../../../lib/custom-functions/scaffold-planning.js';\nimport { collectPlanningSnapshots } from '../../../lib/scaffolding/project-discovery.js';\nimport { applyProjectPlan } from '../../../lib/scaffolding/project-plan-apply.js';\nimport {\n displayProjectPath,\n renderProjectPlan,\n} from '../../../lib/scaffolding/project-plan-output.js';\nimport {\n isInteractivePromptInvocation,\n PromptCancelledError,\n resolveSetupFeatures,\n ScaffoldPrompts,\n} from '../../../lib/scaffolding/prompts.js';\n\n/** Flags for `custom-functions init`. */\nexport interface CustomFunctionInitFlags {\n /** Explicit manifest path. */\n manifest?: string;\n /** Install Deno configuration. */\n deno?: boolean;\n /** Install editor recommendations. */\n editor?: boolean;\n /** Install the coding-agent skill. */\n skill?: boolean;\n /** Install GitHub Actions validation. */\n ci?: boolean;\n /** Disable prompts. */\n noInteractive: boolean;\n /** Render but do not apply. */\n dryRun: boolean;\n /** Approve the final displayed plan. */\n yes: boolean;\n /** Emit one stable JSON result on stdout. */\n json: boolean;\n}\n\n/** User-facing setup labels. */\nconst SETUP_LABELS: Readonly<Record<CustomFunctionSetupFeatureType, string>> = {\n [CustomFunctionSetupFeature.Deno]: 'Deno configuration',\n [CustomFunctionSetupFeature.Editor]: 'VS Code settings',\n [CustomFunctionSetupFeature.Skill]: 'Agent skill',\n [CustomFunctionSetupFeature.Ci]: 'GitHub Actions',\n};\n\n/** All optional setup features in stable prompt order. */\nconst ALL_SETUP_FEATURES = Object.values(CustomFunctionSetupFeature);\n\n/**\n * Initialize a credential-free local Custom Function project.\n *\n * @param this - CLI context\n * @param flags - Scaffold and interaction flags\n * @param directory - Optional target directory\n */\nexport async function init(\n this: LocalContext,\n flags: CustomFunctionInitFlags,\n directory?: string,\n): Promise<void> {\n doneInputValidation(this.process);\n try {\n const state = discoverCustomFunctionProject(this, {\n ...(directory ? { directory } : {}),\n ...(flags.manifest ? { manifest: flags.manifest } : {}),\n });\n const prompts = new ScaffoldPrompts(this);\n const interactive = isInteractivePromptInvocation(\n flags,\n this.process.stdin.isTTY,\n this.process.stderr.isTTY,\n );\n const features = await resolveSetupFeatures(prompts, {\n features: ALL_SETUP_FEATURES,\n labels: SETUP_LABELS,\n enabled: {\n [CustomFunctionSetupFeature.Deno]: flags.deno,\n [CustomFunctionSetupFeature.Editor]: flags.editor,\n [CustomFunctionSetupFeature.Skill]: flags.skill,\n [CustomFunctionSetupFeature.Ci]: flags.ci,\n },\n interactive,\n });\n const snapshots = collectPlanningSnapshots(\n this,\n state.projectRoot,\n getInitPlanningCandidatePaths(state, { features }),\n );\n const plan = buildInitPlan(\n {\n state,\n snapshots,\n contractVersion: CUSTOM_FUNCTION_TYPES_VERSION,\n cliVersion: CLI_VERSION,\n },\n { features },\n );\n if (features.includes(CustomFunctionSetupFeature.Deno)) {\n const denoVersion = await runCapturedProcess(\n 'deno',\n ['--version'],\n { cwd: this.process.cwd() },\n this,\n );\n if (denoVersion.error?.code === 'ENOENT') {\n plan.warnings.push(\n `Deno ${SUPPORTED_DENO_MAJOR_VERSION}.x is not installed. Install it from ${DENO_INSTALL_URL}`,\n );\n } else if (denoVersion.code !== 0) {\n plan.warnings.push(\n `Deno was found, but its version could not be determined. Deno ${SUPPORTED_DENO_MAJOR_VERSION}.x is required. See ${DENO_INSTALL_URL}`,\n );\n } else {\n const compatibility = getDenoRuntimeCompatibility(denoVersion.stdout);\n if (compatibility.level !== 'compatible') {\n plan.warnings.push(compatibility.message);\n }\n }\n }\n if (!flags.json) {\n this.logger.info(\n renderProjectPlan(plan, {\n cwd: this.process.cwd(),\n title: 'Custom Function plan',\n details: [\n { label: 'Target', path: plan.targetDirectory },\n { label: 'Manifest', path: plan.manifestPath },\n ],\n }),\n );\n }\n\n let approved = plan.changes.length === 0 || flags.dryRun;\n if (plan.changes.length > 0 && !flags.dryRun) {\n if (flags.yes) {\n approved = true;\n } else if (interactive) {\n approved = await prompts.confirm('Apply this complete plan?', true);\n } else {\n throw new Error(\n 'The plan requires approval in a non-interactive invocation. Review with --dryRun, then pass --yes.',\n );\n }\n }\n\n if (approved && !flags.dryRun && plan.changes.length > 0) {\n await applyProjectPlan(this, plan);\n }\n const applied = approved && !flags.dryRun && plan.changes.length > 0;\n const setupAvailable = approved && !flags.dryRun;\n const aiHandoff = buildInitAiHandoff({\n targetDirectory: displayProjectPath(this.process.cwd(), state.targetDirectory),\n manifestPath: displayProjectPath(this.process.cwd(), state.manifestPath),\n cliVersion: CLI_VERSION,\n hasSkill: setupAvailable && features.includes(CustomFunctionSetupFeature.Skill),\n hasGithubWorkflow:\n setupAvailable &&\n features.includes(CustomFunctionSetupFeature.Ci) &&\n Boolean(state.repositoryRoot && state.usesGithub),\n });\n const result = buildPlanResult(plan, {\n applied,\n dryRun: flags.dryRun,\n cwd: this.process.cwd(),\n aiHandoff,\n });\n if (flags.json) {\n this.process.stdout.write(`${JSON.stringify(result)}\\n`);\n return;\n }\n if (flags.dryRun) {\n this.logger.info(colors.yellow('Dry run complete. No changes were written.'));\n return;\n }\n if (!approved) {\n this.logger.info(colors.yellow('No changes applied.'));\n return;\n }\n if (plan.changes.length === 0) {\n this.logger.info(colors.green('Custom Function project is already initialized.'));\n return;\n }\n this.logger.info(colors.green('Custom Function project initialized.'));\n if (plan.nextSteps.length > 0) {\n this.logger.info(`\\n${colors.bold('Next steps')}`);\n plan.nextSteps.forEach((step) => this.logger.info(step));\n }\n this.logger.info(`\\n${colors.bold('AI handoff — paste into your coding agent')}`);\n this.logger.info(aiHandoff);\n } catch (error) {\n if (error instanceof PromptCancelledError) {\n this.process.exit(130);\n }\n throw error;\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./notifyPrivacyRequestsAdditionalTime-DCjnQmPj.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,transcendUrl:r,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s,actions:c,daysLeft:l,days:u,requestIds:d,emailTemplate:f,concurrency:p}){t(this.process),await e({transcendUrl:r,requestActions:c,auth:n,emailTemplate:f,days:u,daysLeft:l,requestIds:d,concurrency:p,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s})}export{n as notifyAdditionalTime};
2
- //# sourceMappingURL=impl-Ba1p4QRD.mjs.map
1
+ import{t as e}from"./notifyPrivacyRequestsAdditionalTime-BspmtrPe.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,transcendUrl:r,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s,actions:c,daysLeft:l,days:u,requestIds:d,emailTemplate:f,concurrency:p}){t(this.process),await e({transcendUrl:r,requestActions:c,auth:n,emailTemplate:f,days:u,daysLeft:l,requestIds:d,concurrency:p,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s})}export{n as notifyAdditionalTime};
2
+ //# sourceMappingURL=impl-DRmy2-be.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Ba1p4QRD.mjs","names":[],"sources":["../src/commands/request/notify-additional-time/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 { notifyPrivacyRequestsAdditionalTime } from '../../../lib/requests/index.js';\n\nexport interface NotifyAdditionalTimeCommandFlags {\n auth: string;\n createdAtBefore: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n actions?: RequestAction[];\n daysLeft: number;\n days: number;\n requestIds?: string[];\n emailTemplate: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function notifyAdditionalTime(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n actions,\n daysLeft,\n days,\n requestIds,\n emailTemplate,\n concurrency,\n }: NotifyAdditionalTimeCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await notifyPrivacyRequestsAdditionalTime({\n transcendUrl,\n requestActions: actions,\n auth,\n emailTemplate,\n days,\n daysLeft,\n requestIds,\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"2HAqBA,eAAsB,EAEpB,CACE,OACA,eACA,kBACA,iBACA,kBACA,iBACA,UACA,WACA,OACA,aACA,gBACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAoC,CACxC,eACA,eAAgB,EAChB,OACA,gBACA,OACA,WACA,aACA,cACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
1
+ {"version":3,"file":"impl-DRmy2-be.mjs","names":[],"sources":["../src/commands/request/notify-additional-time/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 { notifyPrivacyRequestsAdditionalTime } from '../../../lib/requests/index.js';\n\nexport interface NotifyAdditionalTimeCommandFlags {\n auth: string;\n createdAtBefore: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n actions?: RequestAction[];\n daysLeft: number;\n days: number;\n requestIds?: string[];\n emailTemplate: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function notifyAdditionalTime(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n actions,\n daysLeft,\n days,\n requestIds,\n emailTemplate,\n concurrency,\n }: NotifyAdditionalTimeCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await notifyPrivacyRequestsAdditionalTime({\n transcendUrl,\n requestActions: actions,\n auth,\n emailTemplate,\n days,\n daysLeft,\n requestIds,\n concurrency,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"2HAqBA,eAAsB,EAEpB,CACE,OACA,eACA,kBACA,iBACA,kBACA,iBACA,UACA,WACA,OACA,aACA,gBACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAoC,CACxC,eACA,eAAgB,EAChB,OACA,gBACA,OACA,WACA,aACA,cACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{i as e,n as t,t as n}from"./policy-project-discovery-BXmG3T6V.mjs";import{n as r,r as i}from"./runOpa-ojIqU1tO.mjs";import{t as a}from"./done-input-validation-LiTaCEzF.mjs";import o from"node:path";import s from"colors";async function c({format:c,verbose:l,run:u,coverage:d,threshold:f,timeout:p,"var-values":m,explain:h,schema:g,"exit-zero-on-skipped":_},v=n){a(this.process),i();let y=e(this.process.cwd(),v);if(!this.fs.existsSync(y)||!this.fs.statSync(y).isDirectory())throw Error(`Policy directory does not exist or is not a directory: ${y}`);if(f!==void 0&&!d)throw Error(`--threshold requires --coverage.`);if(f!==void 0){let e=Number(f);if(!Number.isFinite(e)||e<0||e>100)throw Error(`--threshold must be a number between 0 and 100, got: ${f}`)}let b=g?o.resolve(this.process.cwd(),g):void 0;if(b&&!this.fs.existsSync(b))throw Error(`Schema path not found: ${b}`);let x=t(this,y);if(x.length===0)throw Error("No publishable policy bundles found. Add one with `transcend policy new`, or pass a directory that contains a `.manifest`.");for(let e of x){this.logger.info(s.green(`Running policy tests in ${e}...`));let t=await r([`test`,`--fail-on-empty`,`-b`,e,`--format`,c,...l?[`--verbose`]:[],...u?[`--run`,u]:[],...d?[`--coverage`]:[],...f===void 0?[]:[`--threshold`,f],...p?[`--timeout`,p]:[],...m?[`--var-values`]:[],...h?[`--explain`,h]:[],...b?[`--schema`,b]:[],..._?[`--exit-zero-on-skipped`]:[]]);t!==0&&this.process.exit(t)}this.logger.info(s.green(`Policy tests passed.`))}export{c as test};
2
- //# sourceMappingURL=impl-BVlc0BRG.mjs.map
1
+ import{i as e,n as t,t as n}from"./policy-project-discovery-BXcvhfK7.mjs";import{n as r,r as i}from"./runOpa-ojIqU1tO.mjs";import{t as a}from"./done-input-validation-LiTaCEzF.mjs";import o from"node:path";import s from"colors";async function c({format:c,verbose:l,run:u,coverage:d,threshold:f,timeout:p,"var-values":m,explain:h,schema:g,"exit-zero-on-skipped":_},v=n){a(this.process),i();let y=e(this.process.cwd(),v);if(!this.fs.existsSync(y)||!this.fs.statSync(y).isDirectory())throw Error(`Policy directory does not exist or is not a directory: ${y}`);if(f!==void 0&&!d)throw Error(`--threshold requires --coverage.`);if(f!==void 0){let e=Number(f);if(!Number.isFinite(e)||e<0||e>100)throw Error(`--threshold must be a number between 0 and 100, got: ${f}`)}let b=g?o.resolve(this.process.cwd(),g):void 0;if(b&&!this.fs.existsSync(b))throw Error(`Schema path not found: ${b}`);let x=t(this,y);if(x.length===0)throw Error("No publishable policy bundles found. Add one with `transcend policy new`, or pass a directory that contains a `.manifest`.");for(let e of x){this.logger.info(s.green(`Running policy tests in ${e}...`));let t=await r([`test`,`--fail-on-empty`,`-b`,e,`--format`,c,...l?[`--verbose`]:[],...u?[`--run`,u]:[],...d?[`--coverage`]:[],...f===void 0?[]:[`--threshold`,f],...p?[`--timeout`,p]:[],...m?[`--var-values`]:[],...h?[`--explain`,h]:[],...b?[`--schema`,b]:[],..._?[`--exit-zero-on-skipped`]:[]]);t!==0&&this.process.exit(t)}this.logger.info(s.green(`Policy tests passed.`))}export{c as test};
2
+ //# sourceMappingURL=impl-DgMukyER.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-BVlc0BRG.mjs","names":[],"sources":["../src/commands/policy/test/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 {\n DEFAULT_POLICY_PROJECT_DIRECTORY,\n discoverPolicyBundleDirectories,\n resolvePolicyProjectDirectory,\n} from '../../../lib/policy/policy-project-discovery.js';\nimport { assertOpaInstalled, runOpa } from '../helpers/index.js';\nimport type { PolicyTestExplainMode, PolicyTestFormat } from './command.js';\n\n/** CLI flags for `transcend policy test`. */\nexport interface TestCommandFlags {\n /** `opa test --format` value. */\n format: PolicyTestFormat;\n /** `opa test --verbose`. */\n verbose: boolean;\n /** Optional `opa test --run` regex. */\n run?: string;\n /** `opa test --coverage`. */\n coverage: boolean;\n /** Optional `opa test --threshold` coverage percent. */\n threshold?: string;\n /** Optional `opa test --timeout` duration. */\n timeout?: string;\n /** `opa test --var-values`. */\n 'var-values': boolean;\n /** Optional `opa test --explain` mode. */\n explain?: PolicyTestExplainMode;\n /** Optional `opa test --schema` path. */\n schema?: string;\n /** `opa test --exit-zero-on-skipped`. */\n 'exit-zero-on-skipped': boolean;\n}\n\n/**\n * Run OPA tests against local policy bundles.\n *\n * With no directory (or the default workspace path), discovers every immediate\n * child that contains a `.manifest` and tests each. Pass one bundle path to\n * test a single publishable unit.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy workspace or bundle directory\n */\nexport async function test(\n this: LocalContext,\n {\n format,\n verbose,\n run,\n coverage,\n threshold,\n timeout,\n 'var-values': varValues,\n explain,\n schema,\n 'exit-zero-on-skipped': exitZeroOnSkipped,\n }: TestCommandFlags,\n directory: string = DEFAULT_POLICY_PROJECT_DIRECTORY,\n): Promise<void> {\n doneInputValidation(this.process);\n\n assertOpaInstalled();\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n throw new Error(`Policy directory does not exist or is not a directory: ${resolvedDir}`);\n }\n\n if (threshold !== undefined && !coverage) {\n throw new Error('--threshold requires --coverage.');\n }\n if (threshold !== undefined) {\n const parsed = Number(threshold);\n if (!Number.isFinite(parsed) || parsed < 0 || parsed > 100) {\n throw new Error(`--threshold must be a number between 0 and 100, got: ${threshold}`);\n }\n }\n\n const schemaPath = schema ? path.resolve(this.process.cwd(), schema) : undefined;\n if (schemaPath && !this.fs.existsSync(schemaPath)) {\n throw new Error(`Schema path not found: ${schemaPath}`);\n }\n\n const bundleDirectories = discoverPolicyBundleDirectories(this, resolvedDir);\n if (bundleDirectories.length === 0) {\n throw new Error(\n 'No publishable policy bundles found. Add one with `transcend policy new`, ' +\n 'or pass a directory that contains a `.manifest`.',\n );\n }\n\n for (const bundleDirectory of bundleDirectories) {\n this.logger.info(colors.green(`Running policy tests in ${bundleDirectory}...`));\n const exitCode = await runOpa([\n 'test',\n '--fail-on-empty',\n '-b',\n bundleDirectory,\n '--format',\n format,\n ...(verbose ? ['--verbose'] : []),\n ...(run ? ['--run', run] : []),\n ...(coverage ? ['--coverage'] : []),\n ...(threshold !== undefined ? ['--threshold', threshold] : []),\n ...(timeout ? ['--timeout', timeout] : []),\n ...(varValues ? ['--var-values'] : []),\n ...(explain ? ['--explain', explain] : []),\n ...(schemaPath ? ['--schema', schemaPath] : []),\n ...(exitZeroOnSkipped ? ['--exit-zero-on-skipped'] : []),\n ]);\n if (exitCode !== 0) {\n this.process.exit(exitCode);\n }\n }\n\n this.logger.info(colors.green('Policy tests passed.'));\n}\n"],"mappings":"mOAiDA,eAAsB,EAEpB,CACE,SACA,UACA,MACA,WACA,YACA,UACA,aAAc,EACd,UACA,SACA,uBAAwB,GAE1B,EAAoB,EACL,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAoB,CACpB,IAAM,EAAc,EAA8B,KAAK,QAAQ,KAAK,CAAE,EAAU,CAChF,GAAI,CAAC,KAAK,GAAG,WAAW,EAAY,EAAI,CAAC,KAAK,GAAG,SAAS,EAAY,CAAC,aAAa,CAClF,MAAU,MAAM,0DAA0D,IAAc,CAG1F,GAAI,IAAc,IAAA,IAAa,CAAC,EAC9B,MAAU,MAAM,mCAAmC,CAErD,GAAI,IAAc,IAAA,GAAW,CAC3B,IAAM,EAAS,OAAO,EAAU,CAChC,GAAI,CAAC,OAAO,SAAS,EAAO,EAAI,EAAS,GAAK,EAAS,IACrD,MAAU,MAAM,wDAAwD,IAAY,CAIxF,IAAM,EAAa,EAAS,EAAK,QAAQ,KAAK,QAAQ,KAAK,CAAE,EAAO,CAAG,IAAA,GACvE,GAAI,GAAc,CAAC,KAAK,GAAG,WAAW,EAAW,CAC/C,MAAU,MAAM,0BAA0B,IAAa,CAGzD,IAAM,EAAoB,EAAgC,KAAM,EAAY,CAC5E,GAAI,EAAkB,SAAW,EAC/B,MAAU,MACR,6HAED,CAGH,IAAK,IAAM,KAAmB,EAAmB,CAC/C,KAAK,OAAO,KAAK,EAAO,MAAM,2BAA2B,EAAgB,KAAK,CAAC,CAC/E,IAAM,EAAW,MAAM,EAAO,CAC5B,OACA,kBACA,KACA,EACA,WACA,EACA,GAAI,EAAU,CAAC,YAAY,CAAG,EAAE,CAChC,GAAI,EAAM,CAAC,QAAS,EAAI,CAAG,EAAE,CAC7B,GAAI,EAAW,CAAC,aAAa,CAAG,EAAE,CAClC,GAAI,IAAc,IAAA,GAAyC,EAAE,CAA/B,CAAC,cAAe,EAAU,CACxD,GAAI,EAAU,CAAC,YAAa,EAAQ,CAAG,EAAE,CACzC,GAAI,EAAY,CAAC,eAAe,CAAG,EAAE,CACrC,GAAI,EAAU,CAAC,YAAa,EAAQ,CAAG,EAAE,CACzC,GAAI,EAAa,CAAC,WAAY,EAAW,CAAG,EAAE,CAC9C,GAAI,EAAoB,CAAC,yBAAyB,CAAG,EAAE,CACxD,CAAC,CACE,IAAa,GACf,KAAK,QAAQ,KAAK,EAAS,CAI/B,KAAK,OAAO,KAAK,EAAO,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"impl-DgMukyER.mjs","names":[],"sources":["../src/commands/policy/test/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 {\n DEFAULT_POLICY_PROJECT_DIRECTORY,\n discoverPolicyBundleDirectories,\n resolvePolicyProjectDirectory,\n} from '../../../lib/policy/policy-project-discovery.js';\nimport { assertOpaInstalled, runOpa } from '../helpers/index.js';\nimport type { PolicyTestExplainMode, PolicyTestFormat } from './command.js';\n\n/** CLI flags for `transcend policy test`. */\nexport interface TestCommandFlags {\n /** `opa test --format` value. */\n format: PolicyTestFormat;\n /** `opa test --verbose`. */\n verbose: boolean;\n /** Optional `opa test --run` regex. */\n run?: string;\n /** `opa test --coverage`. */\n coverage: boolean;\n /** Optional `opa test --threshold` coverage percent. */\n threshold?: string;\n /** Optional `opa test --timeout` duration. */\n timeout?: string;\n /** `opa test --var-values`. */\n 'var-values': boolean;\n /** Optional `opa test --explain` mode. */\n explain?: PolicyTestExplainMode;\n /** Optional `opa test --schema` path. */\n schema?: string;\n /** `opa test --exit-zero-on-skipped`. */\n 'exit-zero-on-skipped': boolean;\n}\n\n/**\n * Run OPA tests against local policy bundles.\n *\n * With no directory (or the default workspace path), discovers every immediate\n * child that contains a `.manifest` and tests each. Pass one bundle path to\n * test a single publishable unit.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy workspace or bundle directory\n */\nexport async function test(\n this: LocalContext,\n {\n format,\n verbose,\n run,\n coverage,\n threshold,\n timeout,\n 'var-values': varValues,\n explain,\n schema,\n 'exit-zero-on-skipped': exitZeroOnSkipped,\n }: TestCommandFlags,\n directory: string = DEFAULT_POLICY_PROJECT_DIRECTORY,\n): Promise<void> {\n doneInputValidation(this.process);\n\n assertOpaInstalled();\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n throw new Error(`Policy directory does not exist or is not a directory: ${resolvedDir}`);\n }\n\n if (threshold !== undefined && !coverage) {\n throw new Error('--threshold requires --coverage.');\n }\n if (threshold !== undefined) {\n const parsed = Number(threshold);\n if (!Number.isFinite(parsed) || parsed < 0 || parsed > 100) {\n throw new Error(`--threshold must be a number between 0 and 100, got: ${threshold}`);\n }\n }\n\n const schemaPath = schema ? path.resolve(this.process.cwd(), schema) : undefined;\n if (schemaPath && !this.fs.existsSync(schemaPath)) {\n throw new Error(`Schema path not found: ${schemaPath}`);\n }\n\n const bundleDirectories = discoverPolicyBundleDirectories(this, resolvedDir);\n if (bundleDirectories.length === 0) {\n throw new Error(\n 'No publishable policy bundles found. Add one with `transcend policy new`, ' +\n 'or pass a directory that contains a `.manifest`.',\n );\n }\n\n for (const bundleDirectory of bundleDirectories) {\n this.logger.info(colors.green(`Running policy tests in ${bundleDirectory}...`));\n const exitCode = await runOpa([\n 'test',\n '--fail-on-empty',\n '-b',\n bundleDirectory,\n '--format',\n format,\n ...(verbose ? ['--verbose'] : []),\n ...(run ? ['--run', run] : []),\n ...(coverage ? ['--coverage'] : []),\n ...(threshold !== undefined ? ['--threshold', threshold] : []),\n ...(timeout ? ['--timeout', timeout] : []),\n ...(varValues ? ['--var-values'] : []),\n ...(explain ? ['--explain', explain] : []),\n ...(schemaPath ? ['--schema', schemaPath] : []),\n ...(exitZeroOnSkipped ? ['--exit-zero-on-skipped'] : []),\n ]);\n if (exitCode !== 0) {\n this.process.exit(exitCode);\n }\n }\n\n this.logger.info(colors.green('Policy tests passed.'));\n}\n"],"mappings":"mOAiDA,eAAsB,EAEpB,CACE,SACA,UACA,MACA,WACA,YACA,UACA,aAAc,EACd,UACA,SACA,uBAAwB,GAE1B,EAAoB,EACL,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAoB,CACpB,IAAM,EAAc,EAA8B,KAAK,QAAQ,KAAK,CAAE,EAAU,CAChF,GAAI,CAAC,KAAK,GAAG,WAAW,EAAY,EAAI,CAAC,KAAK,GAAG,SAAS,EAAY,CAAC,aAAa,CAClF,MAAU,MAAM,0DAA0D,IAAc,CAG1F,GAAI,IAAc,IAAA,IAAa,CAAC,EAC9B,MAAU,MAAM,mCAAmC,CAErD,GAAI,IAAc,IAAA,GAAW,CAC3B,IAAM,EAAS,OAAO,EAAU,CAChC,GAAI,CAAC,OAAO,SAAS,EAAO,EAAI,EAAS,GAAK,EAAS,IACrD,MAAU,MAAM,wDAAwD,IAAY,CAIxF,IAAM,EAAa,EAAS,EAAK,QAAQ,KAAK,QAAQ,KAAK,CAAE,EAAO,CAAG,IAAA,GACvE,GAAI,GAAc,CAAC,KAAK,GAAG,WAAW,EAAW,CAC/C,MAAU,MAAM,0BAA0B,IAAa,CAGzD,IAAM,EAAoB,EAAgC,KAAM,EAAY,CAC5E,GAAI,EAAkB,SAAW,EAC/B,MAAU,MACR,6HAED,CAGH,IAAK,IAAM,KAAmB,EAAmB,CAC/C,KAAK,OAAO,KAAK,EAAO,MAAM,2BAA2B,EAAgB,KAAK,CAAC,CAC/E,IAAM,EAAW,MAAM,EAAO,CAC5B,OACA,kBACA,KACA,EACA,WACA,EACA,GAAI,EAAU,CAAC,YAAY,CAAG,EAAE,CAChC,GAAI,EAAM,CAAC,QAAS,EAAI,CAAG,EAAE,CAC7B,GAAI,EAAW,CAAC,aAAa,CAAG,EAAE,CAClC,GAAI,IAAc,IAAA,GAAyC,EAAE,CAA/B,CAAC,cAAe,EAAU,CACxD,GAAI,EAAU,CAAC,YAAa,EAAQ,CAAG,EAAE,CACzC,GAAI,EAAY,CAAC,eAAe,CAAG,EAAE,CACrC,GAAI,EAAU,CAAC,YAAa,EAAQ,CAAG,EAAE,CACzC,GAAI,EAAa,CAAC,WAAY,EAAW,CAAG,EAAE,CAC9C,GAAI,EAAoB,CAAC,yBAAyB,CAAG,EAAE,CACxD,CAAC,CACE,IAAa,GACf,KAAK,QAAQ,KAAK,EAAS,CAI/B,KAAK,OAAO,KAAK,EAAO,MAAM,uBAAuB,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./updateConsentManagerVersionToLatest-CQ1tEPPa.mjs";import{t}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.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-p77uCDi3.mjs.map
1
+ import{t as e}from"./updateConsentManagerVersionToLatest-C4D6cqMh.mjs";import{t}from"./validateTranscendAuth-BrVGfq6X.mjs";import{t as n}from"./done-input-validation-LiTaCEzF.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-Do_3rQWz.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-p77uCDi3.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"}
1
+ {"version":3,"file":"impl-Do_3rQWz.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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./collectParquetFilesOrExit-CbNQ9CJc.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";import{n,r,t as i}from"./createPoolingCommandUi-BUBLRVVY.mjs";import a from"colors";import{CHILD_FLAG as o,PoolCancelledError as s,computePoolSize as c,resolveWorkerPath as l,runPool as u}from"@transcend-io/utils";function d(e){return n(e)}function f(e){return r(e)}const p={renderHeader:d,renderWorkers:f};async function m(n){t(this.process);let{directory:r,outputDir:d,clearOutputDir:f,concurrency:m,viewerMode:h}=n,g=i(this,p,h),_=e(r,this),{poolSize:v,cpuCount:y}=c(m,_.length);this.logger.info(a.green(`Converting ${_.length} Parquet file(s) → CSV with pool size ${v} (CPU=${y})`));let b=_.map(e=>({filePath:e,options:{outputDir:d,clearOutputDir:f}}));await u({title:`Parquet → CSV - ${r}`,baseDir:r||d||this.process.cwd(),childFlag:o,childModulePath:l(import.meta.url,`commands/admin/parquet-to-csv/worker.mjs`),poolSize:v,cpuCount:y,filesTotal:_.length,hooks:{nextTask:()=>b.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:h,...g}).catch(e=>{throw e instanceof s&&this.process.exit(130),e})}export{m as parquetToCsv};
2
- //# sourceMappingURL=impl-8VWWJO22.mjs.map
1
+ import{t as e}from"./collectParquetFilesOrExit-CbNQ9CJc.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";import{n,r,t as i}from"./createPoolingCommandUi-Bj6pO1t7.mjs";import a from"colors";import{CHILD_FLAG as o,PoolCancelledError as s,computePoolSize as c,resolveWorkerPath as l,runPool as u}from"@transcend-io/utils";function d(e){return n(e)}function f(e){return r(e)}const p={renderHeader:d,renderWorkers:f};async function m(n){t(this.process);let{directory:r,outputDir:d,clearOutputDir:f,concurrency:m,viewerMode:h}=n,g=i(this,p,h),_=e(r,this),{poolSize:v,cpuCount:y}=c(m,_.length);this.logger.info(a.green(`Converting ${_.length} Parquet file(s) → CSV with pool size ${v} (CPU=${y})`));let b=_.map(e=>({filePath:e,options:{outputDir:d,clearOutputDir:f}}));await u({title:`Parquet → CSV - ${r}`,baseDir:r||d||this.process.cwd(),childFlag:o,childModulePath:l(import.meta.url,`commands/admin/parquet-to-csv/worker.mjs`),poolSize:v,cpuCount:y,filesTotal:_.length,hooks:{nextTask:()=>b.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:h,...g}).catch(e=>{throw e instanceof s&&this.process.exit(130),e})}export{m as parquetToCsv};
2
+ //# sourceMappingURL=impl-DpLBWRCJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-8VWWJO22.mjs","names":[],"sources":["../src/commands/admin/parquet-to-csv/ui/plugin.ts","../src/commands/admin/parquet-to-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for parquet-to-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for parquet-to-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const parquetToCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectParquetFilesOrExit } from '../../../lib/helpers/index.js';\nimport { createPoolingCommandUi } from '../../../lib/pooling/index.js';\nimport { parquetToCsvPlugin } from './ui/index.js';\nimport type { ParquetProgress, ParquetResult, ParquetTask } from './worker.js';\n\n/** No custom totals for the header; the runner’s built-ins suffice. */\ntype Totals = Record<string, never>;\n\nexport type ParquetToCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Convert all Parquet files in a directory to CSV, in parallel.\n *\n * @param flags - The command flags.\n */\nexport async function parquetToCsv(\n this: LocalContext,\n flags: ParquetToCsvCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const { directory, outputDir, clearOutputDir, concurrency, viewerMode } = flags;\n const poolingUi = createPoolingCommandUi(this, parquetToCsvPlugin, viewerMode);\n\n /* 1) Discover .parquet inputs */\n const files = collectParquetFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n this.logger.info(\n colors.green(\n `Converting ${files.length} Parquet file(s) → CSV with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Build FIFO queue of tasks (one per file) */\n const queue = files.map<ParquetTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir },\n }));\n\n /* 4) Pool hooks */\n const hooks: PoolHooks<ParquetTask, ParquetProgress, ParquetResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n postProcess: async () => {\n // nothing special post-run\n },\n };\n\n /* 5) Launch the pool runner with custom dashboard plugin */\n await runPool({\n title: `Parquet → CSV - ${directory}`,\n baseDir: directory || outputDir || this.process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/parquet-to-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n ...poolingUi,\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n this.process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"uUAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAAkE,CAC7E,eACA,gBAED,CCAD,eAAsB,EAEpB,EACe,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAe,EACpE,EAAY,EAAuB,KAAM,EAAoB,EAAW,CAGxE,EAAQ,EAA0B,EAAW,KAAK,CAGlD,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,KAAK,OAAO,KACV,EAAO,MACL,cAAc,EAAM,OAAO,wCAAwC,EAAS,QAAQ,EAAS,GAC9F,CACF,CAGD,IAAM,EAAQ,EAAM,IAAkB,IAAc,CAClD,WACA,QAAS,CAAE,YAAW,iBAAgB,CACvC,EAAE,CAgBH,MAAM,EAAQ,CACZ,MAAO,mBAAmB,IAC1B,QAAS,GAAa,GAAa,KAAK,QAAQ,KAAK,CACrD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,2CAA2C,CAC/F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CApBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EACpD,YAAa,SAAY,GAcpB,CACL,aACA,GAAG,EACJ,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,KAAK,QAAQ,KAAK,IAAI,CAElB,GACN"}
1
+ {"version":3,"file":"impl-DpLBWRCJ.mjs","names":[],"sources":["../src/commands/admin/parquet-to-csv/ui/plugin.ts","../src/commands/admin/parquet-to-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for parquet-to-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for parquet-to-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const parquetToCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectParquetFilesOrExit } from '../../../lib/helpers/index.js';\nimport { createPoolingCommandUi } from '../../../lib/pooling/index.js';\nimport { parquetToCsvPlugin } from './ui/index.js';\nimport type { ParquetProgress, ParquetResult, ParquetTask } from './worker.js';\n\n/** No custom totals for the header; the runner’s built-ins suffice. */\ntype Totals = Record<string, never>;\n\nexport type ParquetToCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Convert all Parquet files in a directory to CSV, in parallel.\n *\n * @param flags - The command flags.\n */\nexport async function parquetToCsv(\n this: LocalContext,\n flags: ParquetToCsvCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const { directory, outputDir, clearOutputDir, concurrency, viewerMode } = flags;\n const poolingUi = createPoolingCommandUi(this, parquetToCsvPlugin, viewerMode);\n\n /* 1) Discover .parquet inputs */\n const files = collectParquetFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n this.logger.info(\n colors.green(\n `Converting ${files.length} Parquet file(s) → CSV with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Build FIFO queue of tasks (one per file) */\n const queue = files.map<ParquetTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir },\n }));\n\n /* 4) Pool hooks */\n const hooks: PoolHooks<ParquetTask, ParquetProgress, ParquetResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n postProcess: async () => {\n // nothing special post-run\n },\n };\n\n /* 5) Launch the pool runner with custom dashboard plugin */\n await runPool({\n title: `Parquet → CSV - ${directory}`,\n baseDir: directory || outputDir || this.process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/parquet-to-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n ...poolingUi,\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n this.process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"uUAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAAkE,CAC7E,eACA,gBAED,CCAD,eAAsB,EAEpB,EACe,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAe,EACpE,EAAY,EAAuB,KAAM,EAAoB,EAAW,CAGxE,EAAQ,EAA0B,EAAW,KAAK,CAGlD,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,KAAK,OAAO,KACV,EAAO,MACL,cAAc,EAAM,OAAO,wCAAwC,EAAS,QAAQ,EAAS,GAC9F,CACF,CAGD,IAAM,EAAQ,EAAM,IAAkB,IAAc,CAClD,WACA,QAAS,CAAE,YAAW,iBAAgB,CACvC,EAAE,CAgBH,MAAM,EAAQ,CACZ,MAAO,mBAAmB,IAC1B,QAAS,GAAa,GAAa,KAAK,QAAQ,KAAK,CACrD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,2CAA2C,CAC/F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CApBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EACpD,YAAa,SAAY,GAcpB,CACL,aACA,GAAG,EACJ,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,KAAK,QAAQ,KAAK,IAAI,CAElB,GACN"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./buildExamples-bIkCTZtO.mjs";import{r as t}from"./policyEngineCliError-CZrOHhLv.mjs";import{a as n,c as r,g as i,i as a}from"./policy-project-discovery-BXmG3T6V.mjs";import{r as o,t as s}from"./runOpa-ojIqU1tO.mjs";import{n as c,t as l}from"./policy-bundle-manifest-CJnaA9Ub.mjs";import{i as u,n as d,t as f}from"./printResult-Dmwv78e7.mjs";import{t as p}from"./formatPolicyBundleVersionSummary-DCHl1Vhy.mjs";import{n as m}from"./resolveBundleIdByName-D7NUOpLc.mjs";import{n as h}from"./inquirer-DK1JbPA0.mjs";import{t as g}from"./done-input-validation-LiTaCEzF.mjs";import{r as _}from"./prompts-BhXfYD6g.mjs";import{t as v}from"./command-output-BJcDRXNr.mjs";import y,{join as b}from"node:path";import x from"colors";import{spawnSync as S}from"node:child_process";import C from"node:fs";import w from"node:os";import{gunzipSync as T}from"node:zlib";import{MAX_BUNDLE_COMPRESSED_BYTES as E,MAX_BUNDLE_DECOMPRESSED_BYTES as D}from"@transcend-io/utils";import O from"fast-glob";function k(e){let t=O.sync(`**/*.rego`,{cwd:e,onlyFiles:!0,dot:!1}).sort(),n=y.join(e,r),{publishableRegoPaths:i}=c(C.existsSync(n)?C.readFileSync(n,`utf8`):void 0,t.map(t=>({path:t,contents:C.readFileSync(y.join(e,t),`utf8`)})));return{entries:[r,...i]}}async function A(e){let t=y.join(w.tmpdir(),`transcend-policy-bundle-build-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`);try{let{code:n,stderr:r}=await s([`build`,`--ignore`,`*_test.rego`,`-b`,`-o`,t,`.`],{cwd:e});if(n!==0)throw Error(r.trim()||`opa build failed with exit code ${n}`)}finally{C.existsSync(t)&&C.unlinkSync(t)}}function j(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t%1==0?t.toFixed(0):t.toFixed(1)} KiB`;let n=t/1024;return`${n%1==0?n.toFixed(0):n.toFixed(1)} MiB`}async function M(e){o();let t=y.resolve(e);if(!C.existsSync(t)||!C.statSync(t).isDirectory())throw Error(`Policy directory does not exist or is not a directory: ${t}`);let{entries:n}=k(t),{code:r,stderr:i}=await s([`check`,`--strict`,t]);if(r!==0)throw Error(i.trim()||`opa check failed with exit code ${r}`);await A(t);let a=y.join(w.tmpdir(),`transcend-policy-bundle-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`),c=S(`tar`,[`-czf`,a,`-C`,t,...n],{env:{...process.env,COPYFILE_DISABLE:`1`},encoding:`utf8`});if(c.status!==0)throw Error(`Failed to create policy bundle archive: ${c.stderr.trim()||`tar failed`}`);let l=C.readFileSync(a);if(l.byteLength>E)throw C.unlinkSync(a),Error(`Policy bundle exceeds the ${j(E)} compressed upload limit (bundle is ${j(l.byteLength)}). The server also rejects decompressed bundles larger than ${j(D)}.`);let u=T(l);if(u.byteLength>D)throw C.unlinkSync(a),Error(`Policy bundle exceeds the ${j(D)} decompressed upload limit (bundle is ${j(u.byteLength)} decompressed).`);return a}function N(e){let t=C.readFileSync(e.bundlePath),n=new FormData;return n.append(`bundle`,new Blob([t],{type:`application/gzip`}),y.basename(e.bundlePath)),n.append(`version`,e.version),e.description&&n.append(`description`,e.description),e.bundleName&&n.append(`bundleName`,e.bundleName),n}function P(e){return e.toISOString().slice(0,19).replace(/[T:]/g,`-`)}function F(e,t=new Date){return`${e}-${P(t)}`}function I(e){return e.template===i.Permissions?!0:e.template===i.Generic?!1:e.roots.some(e=>e===`permissions`||e.startsWith(`permissions/`))}function L(e,t){let r=I(t),i=e===n;if(r&&!i)return`This directory looks like a Permissions API policy, but --remote-bundle-name is "${e}". Permissions API only loads the remote bundle named "${n}". Upload still succeeds; pass --remote-bundle-name=${n} if that is the intended path.`;if(!r&&i)return`--remote-bundle-name=${n} reserves the Permissions API path. Upload treats all bundles the same; only that fixed name is queried by the Permissions API. Continue only if you intend this bundle for the Permissions API.`}async function R({"remote-bundle-name":n,auth:i,"transcend-url":o,version:s,description:c,json:y,yes:S,debug:C=!1},w){g(this.process),t(C);let T=v(this.logger,y),E=a(this.process.cwd(),w),D=s??F(n),O=u(o,i),k=_({json:y,noInteractive:!1},this.process.stdin.isTTY,this.process.stderr.isTTY),A;try{T.info(x.green(`Building policy bundle from ${E}...`)),A=await M(E);try{let e=b(E,r),t=L(n,l(this.fs.readFileSync(e,`utf8`)));t&&T.warn(x.yellow(t))}catch{}let t=await m(O,n),i;if(t){T.info(x.green(`Uploading new version for bundle "${n}"...`));let e=N({bundlePath:A,version:D,description:c});i=await d(O.post(`v1/policy-engine/policy-bundles/${t}/versions`,{body:e}).json())}else{if(!k&&!S){this.logger.error(x.red(`Cannot create a new bundle in non-interactive or JSON mode; pass --yes to confirm.`)),this.process.exit(1);return}if(!S&&(T.warn(x.yellow(`No policy bundle named "${n}" exists for this organization.`)),!await h({message:`No policy bundle named "${n}" exists. Create a new bundle and upload its first version?`}))){T.info(x.yellow(`Publish cancelled.`));return}T.info(x.green(`Creating bundle "${n}" and uploading first version...`));let e=N({bundlePath:A,version:D,description:c,bundleName:n});i=await d(O.post(`v1/policy-engine/policy-bundles`,{body:e}).json())}f(this.process.stdout,{json:y,data:i,renderTable:()=>p(i.version)}),T.info(x.green(`Policy bundle version uploaded successfully.`));let a=e([`policy`,`activate`],{version:i.version.version,"remote-bundle-name":n});T.info(x.yellow(`Publishing a policy does not activate it. To activate this version, run:\n ${a}`))}finally{A&&this.fs.existsSync(A)&&this.fs.unlinkSync(A)}}export{R as publish};
2
- //# sourceMappingURL=impl-CFJR1dQP.mjs.map
1
+ import{t as e}from"./buildExamples-BsMXuFwm.mjs";import{r as t}from"./policyEngineCliError-CZrOHhLv.mjs";import{a as n,c as r,g as i,i as a}from"./policy-project-discovery-BXcvhfK7.mjs";import{r as o,t as s}from"./runOpa-ojIqU1tO.mjs";import{n as c,t as l}from"./policy-bundle-manifest-BKRoT17e.mjs";import{i as u,n as d,t as f}from"./printResult-Dmwv78e7.mjs";import{t as p}from"./formatPolicyBundleVersionSummary-DCHl1Vhy.mjs";import{n as m}from"./resolveBundleIdByName-D7NUOpLc.mjs";import{n as h}from"./inquirer-DK1JbPA0.mjs";import{t as g}from"./done-input-validation-LiTaCEzF.mjs";import{r as _}from"./prompts-BhXfYD6g.mjs";import{t as v}from"./command-output-BJcDRXNr.mjs";import y,{join as b}from"node:path";import x from"colors";import{spawnSync as S}from"node:child_process";import C from"node:fs";import w from"node:os";import{gunzipSync as T}from"node:zlib";import{MAX_BUNDLE_COMPRESSED_BYTES as E,MAX_BUNDLE_DECOMPRESSED_BYTES as D}from"@transcend-io/utils";import O from"fast-glob";function k(e){let t=O.sync(`**/*.rego`,{cwd:e,onlyFiles:!0,dot:!1}).sort(),n=y.join(e,r),{publishableRegoPaths:i}=c(C.existsSync(n)?C.readFileSync(n,`utf8`):void 0,t.map(t=>({path:t,contents:C.readFileSync(y.join(e,t),`utf8`)})));return{entries:[r,...i]}}async function A(e){let t=y.join(w.tmpdir(),`transcend-policy-bundle-build-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`);try{let{code:n,stderr:r}=await s([`build`,`--ignore`,`*_test.rego`,`-b`,`-o`,t,`.`],{cwd:e});if(n!==0)throw Error(r.trim()||`opa build failed with exit code ${n}`)}finally{C.existsSync(t)&&C.unlinkSync(t)}}function j(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t%1==0?t.toFixed(0):t.toFixed(1)} KiB`;let n=t/1024;return`${n%1==0?n.toFixed(0):n.toFixed(1)} MiB`}async function M(e){o();let t=y.resolve(e);if(!C.existsSync(t)||!C.statSync(t).isDirectory())throw Error(`Policy directory does not exist or is not a directory: ${t}`);let{entries:n}=k(t),{code:r,stderr:i}=await s([`check`,`--strict`,t]);if(r!==0)throw Error(i.trim()||`opa check failed with exit code ${r}`);await A(t);let a=y.join(w.tmpdir(),`transcend-policy-bundle-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`),c=S(`tar`,[`-czf`,a,`-C`,t,...n],{env:{...process.env,COPYFILE_DISABLE:`1`},encoding:`utf8`});if(c.status!==0)throw Error(`Failed to create policy bundle archive: ${c.stderr.trim()||`tar failed`}`);let l=C.readFileSync(a);if(l.byteLength>E)throw C.unlinkSync(a),Error(`Policy bundle exceeds the ${j(E)} compressed upload limit (bundle is ${j(l.byteLength)}). The server also rejects decompressed bundles larger than ${j(D)}.`);let u=T(l);if(u.byteLength>D)throw C.unlinkSync(a),Error(`Policy bundle exceeds the ${j(D)} decompressed upload limit (bundle is ${j(u.byteLength)} decompressed).`);return a}function N(e){let t=C.readFileSync(e.bundlePath),n=new FormData;return n.append(`bundle`,new Blob([t],{type:`application/gzip`}),y.basename(e.bundlePath)),n.append(`version`,e.version),e.description&&n.append(`description`,e.description),e.bundleName&&n.append(`bundleName`,e.bundleName),n}function P(e){return e.toISOString().slice(0,19).replace(/[T:]/g,`-`)}function F(e,t=new Date){return`${e}-${P(t)}`}function I(e){return e.template===i.Permissions?!0:e.template===i.Generic?!1:e.roots.some(e=>e===`permissions`||e.startsWith(`permissions/`))}function L(e,t){let r=I(t),i=e===n;if(r&&!i)return`This directory looks like a Permissions API policy, but --remote-bundle-name is "${e}". Permissions API only loads the remote bundle named "${n}". Upload still succeeds; pass --remote-bundle-name=${n} if that is the intended path.`;if(!r&&i)return`--remote-bundle-name=${n} reserves the Permissions API path. Upload treats all bundles the same; only that fixed name is queried by the Permissions API. Continue only if you intend this bundle for the Permissions API.`}async function R({"remote-bundle-name":n,auth:i,"transcend-url":o,version:s,description:c,json:y,yes:S,debug:C=!1},w){g(this.process),t(C);let T=v(this.logger,y),E=a(this.process.cwd(),w),D=s??F(n),O=u(o,i),k=_({json:y,noInteractive:!1},this.process.stdin.isTTY,this.process.stderr.isTTY),A;try{T.info(x.green(`Building policy bundle from ${E}...`)),A=await M(E);try{let e=b(E,r),t=L(n,l(this.fs.readFileSync(e,`utf8`)));t&&T.warn(x.yellow(t))}catch{}let t=await m(O,n),i;if(t){T.info(x.green(`Uploading new version for bundle "${n}"...`));let e=N({bundlePath:A,version:D,description:c});i=await d(O.post(`v1/policy-engine/policy-bundles/${t}/versions`,{body:e}).json())}else{if(!k&&!S){this.logger.error(x.red(`Cannot create a new bundle in non-interactive or JSON mode; pass --yes to confirm.`)),this.process.exit(1);return}if(!S&&(T.warn(x.yellow(`No policy bundle named "${n}" exists for this organization.`)),!await h({message:`No policy bundle named "${n}" exists. Create a new bundle and upload its first version?`}))){T.info(x.yellow(`Publish cancelled.`));return}T.info(x.green(`Creating bundle "${n}" and uploading first version...`));let e=N({bundlePath:A,version:D,description:c,bundleName:n});i=await d(O.post(`v1/policy-engine/policy-bundles`,{body:e}).json())}f(this.process.stdout,{json:y,data:i,renderTable:()=>p(i.version)}),T.info(x.green(`Policy bundle version uploaded successfully.`));let a=e([`policy`,`activate`],{version:i.version.version,"remote-bundle-name":n});T.info(x.yellow(`Publishing a policy does not activate it. To activate this version, run:\n ${a}`))}finally{A&&this.fs.existsSync(A)&&this.fs.unlinkSync(A)}}export{R as publish};
2
+ //# sourceMappingURL=impl-IQy1_4me.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-CFJR1dQP.mjs","names":["fg"],"sources":["../src/commands/policy/helpers/buildOpaBundleTarball.ts","../src/commands/policy/helpers/buildPolicyBundleFormData.ts","../src/commands/policy/helpers/defaultPolicyVersionLabel.ts","../src/lib/policy/policy-publish-hints.ts","../src/commands/policy/publish/impl.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { gunzipSync } from 'node:zlib';\n\nimport { MAX_BUNDLE_COMPRESSED_BYTES, MAX_BUNDLE_DECOMPRESSED_BYTES } from '@transcend-io/utils';\nimport fg from 'fast-glob';\n\nimport { validatePolicyBundleContents } from '../../../lib/policy/policy-bundle-manifest.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { assertOpaInstalled } from './assertOpaInstalled.js';\nimport { runOPACapture } from './runOpa.js';\n\n/** Result of collecting publishable entries from a policy bundle directory. */\ninterface PolicyBundleArchiveContents {\n /** Relative paths to include in the upload tarball (manifest first, then rego) */\n entries: string[];\n}\n\n/**\n * Collects `.manifest` and publishable `.rego` files from a policy directory.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @returns Validated archive entries\n */\nfunction collectPolicyBundleArchiveEntries(dir: string): PolicyBundleArchiveContents {\n const regoFiles = fg\n .sync('**/*.rego', {\n cwd: dir,\n onlyFiles: true,\n dot: false,\n })\n .sort();\n const onDiskManifestPath = path.join(dir, POLICY_MANIFEST_FILENAME);\n const { publishableRegoPaths } = validatePolicyBundleContents(\n fs.existsSync(onDiskManifestPath) ? fs.readFileSync(onDiskManifestPath, 'utf8') : undefined,\n regoFiles.map((relativePath) => ({\n path: relativePath,\n contents: fs.readFileSync(path.join(dir, relativePath), 'utf8'),\n })),\n );\n\n return {\n entries: [POLICY_MANIFEST_FILENAME, ...publishableRegoPaths],\n };\n}\n\n/**\n * Verifies that a policy directory compiles end-to-end with `opa build`.\n *\n * The compiled output is discarded — the server receives the `.manifest` +\n * `.rego` archive produced by {@link buildOpaBundleTarball}, not the OPA bundle\n * — but a successful build guarantees the policies compile and link, surfacing\n * errors (syntax, missing imports, undefined references, etc.) before upload.\n *\n * @param dir - Absolute path to the policy bundle directory\n */\nasync function assertBundleCompiles(dir: string): Promise<void> {\n const buildOutputPath = path.join(\n os.tmpdir(),\n `transcend-policy-bundle-build-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`,\n );\n try {\n // Run with `cwd` set to the bundle directory and pass `.` so `opa build`\n // resolves the bundle root correctly. Bundle mode (`-b`) keeps local\n // `input.json` / `input.example.json` fixtures from merging as data.\n // `*_test.rego` files are local-only.\n const { code, stderr } = await runOPACapture(\n ['build', '--ignore', '*_test.rego', '-b', '-o', buildOutputPath, '.'],\n { cwd: dir },\n );\n if (code !== 0) {\n throw new Error(stderr.trim() || `opa build failed with exit code ${code}`);\n }\n } finally {\n if (fs.existsSync(buildOutputPath)) {\n fs.unlinkSync(buildOutputPath);\n }\n }\n}\n\n/**\n * Formats a byte count as a human-readable size with binary units.\n *\n * @param bytes - Number of bytes\n * @returns Human-readable size, e.g. `14 MiB` or `4 KiB`\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const kib = bytes / 1024;\n if (kib < 1024) {\n return `${kib % 1 === 0 ? kib.toFixed(0) : kib.toFixed(1)} KiB`;\n }\n const mib = kib / 1024;\n return `${mib % 1 === 0 ? mib.toFixed(0) : mib.toFixed(1)} MiB`;\n}\n\n/**\n * Builds a gzip-compressed policy bundle tarball for upload to Transcend.\n *\n * The Policy Engine API expects a plain archive containing `.manifest` and\n * one or more `.rego` files. Local projects author an OPA `.manifest` and it\n * is uploaded directly — no rename at pack time. Before packaging, the\n * manifest is validated (shape + root coverage) and the bundle is validated\n * with `opa check` (strict Rego linting) and `opa build` (full compilation) so\n * failures surface client-side rather than after upload.\n *\n * @param dir - Directory containing `.manifest` and `.rego` policy files\n * @returns Absolute path to the generated `.tar.gz` bundle\n */\nexport async function buildOpaBundleTarball(dir: string): Promise<string> {\n assertOpaInstalled();\n\n const resolvedDir = path.resolve(dir);\n if (!fs.existsSync(resolvedDir) || !fs.statSync(resolvedDir).isDirectory()) {\n throw new Error(`Policy directory does not exist or is not a directory: ${resolvedDir}`);\n }\n\n // Validate the manifest shape and that roots cover every Rego package before\n // invoking OPA, so invalid manifests surface a clear error instead of an\n // opaque `opa build failed with exit code 1`.\n const { entries: archiveEntries } = collectPolicyBundleArchiveEntries(resolvedDir);\n\n // Match the Rego v1 validation the Policy Engine API runs on upload.\n const { code: checkCode, stderr: checkStderr } = await runOPACapture([\n 'check',\n '--strict',\n resolvedDir,\n ]);\n if (checkCode !== 0) {\n throw new Error(checkStderr.trim() || `opa check failed with exit code ${checkCode}`);\n }\n\n // Ensure the bundle compiles end-to-end before packaging for upload.\n await assertBundleCompiles(resolvedDir);\n\n const outputPath = path.join(\n os.tmpdir(),\n `transcend-policy-bundle-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`,\n );\n const tarResult = spawnSync('tar', ['-czf', outputPath, '-C', resolvedDir, ...archiveEntries], {\n env: { ...process.env, COPYFILE_DISABLE: '1' },\n encoding: 'utf8',\n });\n if (tarResult.status !== 0) {\n throw new Error(\n `Failed to create policy bundle archive: ${tarResult.stderr.trim() || 'tar failed'}`,\n );\n }\n\n const compressedBytes = fs.readFileSync(outputPath);\n if (compressedBytes.byteLength > MAX_BUNDLE_COMPRESSED_BYTES) {\n fs.unlinkSync(outputPath);\n throw new Error(\n `Policy bundle exceeds the ${formatBytes(MAX_BUNDLE_COMPRESSED_BYTES)} compressed upload limit ` +\n `(bundle is ${formatBytes(compressedBytes.byteLength)}). ` +\n `The server also rejects decompressed bundles larger than ${formatBytes(MAX_BUNDLE_DECOMPRESSED_BYTES)}.`,\n );\n }\n\n const decompressedBytes = gunzipSync(compressedBytes);\n if (decompressedBytes.byteLength > MAX_BUNDLE_DECOMPRESSED_BYTES) {\n fs.unlinkSync(outputPath);\n throw new Error(\n `Policy bundle exceeds the ${formatBytes(MAX_BUNDLE_DECOMPRESSED_BYTES)} decompressed upload limit ` +\n `(bundle is ${formatBytes(decompressedBytes.byteLength)} decompressed).`,\n );\n }\n\n return outputPath;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n/** Fields for building a policy bundle upload form. */\nexport interface BuildPolicyBundleFormDataOptions {\n /** Absolute path to the bundle tarball */\n bundlePath: string;\n /** Version label */\n version: string;\n /** Optional description */\n description?: string;\n /** Bundle name (only for create) */\n bundleName?: string;\n}\n\n/**\n * Builds multipart form data for a policy bundle upload.\n *\n * @param options - Upload fields\n * @returns FormData ready for POST\n */\nexport function buildPolicyBundleFormData(options: BuildPolicyBundleFormDataOptions): FormData {\n const bundleBytes = fs.readFileSync(options.bundlePath);\n const form = new FormData();\n form.append(\n 'bundle',\n new Blob([bundleBytes], { type: 'application/gzip' }),\n path.basename(options.bundlePath),\n );\n form.append('version', options.version);\n if (options.description) {\n form.append('description', options.description);\n }\n if (options.bundleName) {\n form.append('bundleName', options.bundleName);\n }\n return form;\n}\n","/**\n * Formats a date as `yyyy-mm-dd-hh-mm-ss` in UTC.\n *\n * @param date - Date to format\n * @returns Timestamp label\n */\nfunction formatPolicyVersionTimestamp(date: Date): string {\n return date.toISOString().slice(0, 19).replace(/[T:]/g, '-');\n}\n\n/**\n * Returns a default version label from the bundle name and current UTC timestamp.\n *\n * @param bundleName - Tenant-unique policy bundle name\n * @param now - Current time (for testing)\n * @returns Version label in `{bundleName}-yyyy-mm-dd-hh-mm-ss` form\n */\nexport function defaultPolicyVersionLabel(bundleName: string, now: Date = new Date()): string {\n return `${bundleName}-${formatPolicyVersionTimestamp(now)}`;\n}\n","import {\n PERMISSIONS_POLICY_BUNDLE_NAME,\n PolicyTemplate,\n type PolicyTemplateName,\n} from './policy-scaffold-templates.js';\n\n/** Inputs used to soft-warn about Permissions vs generic publish naming. */\nexport interface PolicyPublishBundleNameHintInput {\n /** Optional scaffold template from `.manifest` metadata. */\n template?: PolicyTemplateName;\n /** Declared OPA package roots. */\n roots: string[];\n}\n\n/**\n * Whether local authoring signals suggest a Permissions API bundle.\n *\n * Prefers explicit `metadata.transcend.io.template`. Without metadata, falls\n * back to a root that is exactly `permissions` or nested under it.\n *\n * @param input - Manifest template hint and roots\n * @returns Whether the local tree looks Permissions-oriented\n */\nfunction looksLikePermissionsBundle(input: PolicyPublishBundleNameHintInput): boolean {\n if (input.template === PolicyTemplate.Permissions) {\n return true;\n }\n if (input.template === PolicyTemplate.Generic) {\n return false;\n }\n return input.roots.some(\n (root) =>\n root === PERMISSIONS_POLICY_BUNDLE_NAME ||\n root.startsWith(`${PERMISSIONS_POLICY_BUNDLE_NAME}/`),\n );\n}\n\n/**\n * Soft-warning when `--remote-bundle-name` disagrees with Permissions conventions.\n *\n * Upload does not enforce bundle kinds. Permissions API only loads the\n * remote bundle named {@link PERMISSIONS_POLICY_BUNDLE_NAME}.\n *\n * @param bundleName - Value of `--remote-bundle-name`\n * @param input - Local manifest template/roots\n * @returns Warning text, or undefined when names align\n */\nexport function formatPolicyPublishBundleNameHint(\n bundleName: string,\n input: PolicyPublishBundleNameHintInput,\n): string | undefined {\n const permissionsLocal = looksLikePermissionsBundle(input);\n const permissionsRemote = bundleName === PERMISSIONS_POLICY_BUNDLE_NAME;\n\n if (permissionsLocal && !permissionsRemote) {\n return (\n `This directory looks like a Permissions API policy, but --remote-bundle-name is ` +\n `\"${bundleName}\". Permissions API only loads the remote bundle named ` +\n `\"${PERMISSIONS_POLICY_BUNDLE_NAME}\". Upload still succeeds; pass ` +\n `--remote-bundle-name=${PERMISSIONS_POLICY_BUNDLE_NAME} if that is the intended path.`\n );\n }\n\n if (!permissionsLocal && permissionsRemote) {\n return (\n `--remote-bundle-name=${PERMISSIONS_POLICY_BUNDLE_NAME} reserves the Permissions API ` +\n `path. Upload treats all bundles the same; only that fixed name is queried by ` +\n `the Permissions API. Continue only if you intend this bundle for the Permissions API.`\n );\n }\n\n return undefined;\n}\n","import { join } from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { selectCommandLogger } from '../../../lib/cli/command-output.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildExampleCommand } from '../../../lib/docgen/buildExamples.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport { parsePolicyBundleManifest } from '../../../lib/policy/policy-bundle-manifest.js';\nimport { resolvePolicyProjectDirectory } from '../../../lib/policy/policy-project-discovery.js';\nimport { formatPolicyPublishBundleNameHint } from '../../../lib/policy/policy-publish-hints.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { isInteractivePromptInvocation } from '../../../lib/scaffolding/prompts.js';\nimport type { ActivateCommandFlags } from '../activate/impl.js';\nimport {\n buildPolicyBundleFormData,\n buildPolicyEngineClient,\n buildOpaBundleTarball,\n defaultPolicyVersionLabel,\n formatPolicyBundleVersionSummary,\n policyEngineRequest,\n printResult,\n resolveBundleIdByName,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { CreatePolicyBundleResponse, CreatePolicyBundleVersionResponse } from '../types.js';\n\n/** CLI flags for `transcend policy publish`. */\nexport interface PublishCommandFlags {\n /** Tenant-unique bundle name */\n 'remote-bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Version label (defaults to `{bundleName}-yyyy-mm-dd-hh-mm-ss`) */\n version?: string;\n /** Optional version description */\n description?: string;\n /** Print raw JSON response */\n json: boolean;\n /** Skip the \"create new bundle\" confirmation */\n yes: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Build and upload a new immutable policy bundle version.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy bundle directory containing a `.manifest`\n */\nexport async function publish(\n this: LocalContext,\n {\n 'remote-bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n version,\n description,\n json,\n yes,\n debug = false,\n }: PublishCommandFlags,\n directory: string,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const commandLogger = selectCommandLogger(this.logger, json);\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n const versionLabel = version ?? defaultPolicyVersionLabel(bundleName);\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const interactive = isInteractivePromptInvocation(\n { json, noInteractive: false },\n this.process.stdin.isTTY,\n this.process.stderr.isTTY,\n );\n\n let bundlePath: string | undefined;\n try {\n commandLogger.info(colors.green(`Building policy bundle from ${resolvedDir}...`));\n bundlePath = await buildOpaBundleTarball(resolvedDir);\n\n try {\n const manifestPath = join(resolvedDir, POLICY_MANIFEST_FILENAME);\n const manifest = parsePolicyBundleManifest(this.fs.readFileSync(manifestPath, 'utf8'));\n const bundleNameHint = formatPolicyPublishBundleNameHint(bundleName, manifest);\n if (bundleNameHint) {\n commandLogger.warn(colors.yellow(bundleNameHint));\n }\n } catch {\n // Best-effort authoring hint; tarball build already validated the manifest.\n }\n\n const existingBundleId = await resolveBundleIdByName(client, bundleName);\n\n let responseBody: CreatePolicyBundleResponse | CreatePolicyBundleVersionResponse;\n\n if (existingBundleId) {\n commandLogger.info(colors.green(`Uploading new version for bundle \"${bundleName}\"...`));\n const form = buildPolicyBundleFormData({\n bundlePath,\n version: versionLabel,\n description,\n });\n responseBody = await policyEngineRequest(\n client\n .post(`v1/policy-engine/policy-bundles/${existingBundleId}/versions`, { body: form })\n .json<CreatePolicyBundleVersionResponse>(),\n );\n } else {\n if (!interactive && !yes) {\n this.logger.error(\n colors.red(\n 'Cannot create a new bundle in non-interactive or JSON mode; pass --yes to confirm.',\n ),\n );\n this.process.exit(1);\n return;\n }\n\n if (!yes) {\n commandLogger.warn(\n colors.yellow(`No policy bundle named \"${bundleName}\" exists for this organization.`),\n );\n const shouldCreate = await inquirerConfirmBoolean({\n message: `No policy bundle named \"${bundleName}\" exists. Create a new bundle and upload its first version?`,\n });\n if (!shouldCreate) {\n commandLogger.info(colors.yellow('Publish cancelled.'));\n return;\n }\n }\n\n commandLogger.info(\n colors.green(`Creating bundle \"${bundleName}\" and uploading first version...`),\n );\n const createForm = buildPolicyBundleFormData({\n bundlePath,\n version: versionLabel,\n description,\n bundleName,\n });\n responseBody = await policyEngineRequest(\n client\n .post('v1/policy-engine/policy-bundles', {\n body: createForm,\n })\n .json<CreatePolicyBundleResponse>(),\n );\n }\n\n printResult(this.process.stdout, {\n json,\n data: responseBody,\n renderTable: () => formatPolicyBundleVersionSummary(responseBody.version),\n });\n\n commandLogger.info(colors.green('Policy bundle version uploaded successfully.'));\n\n const activateCommand = buildExampleCommand<ActivateCommandFlags>(['policy', 'activate'], {\n version: responseBody.version.version,\n 'remote-bundle-name': bundleName,\n });\n commandLogger.info(\n colors.yellow(\n `Publishing a policy does not activate it. To activate this version, run:\\n ${activateCommand}`,\n ),\n );\n } finally {\n if (bundlePath && this.fs.existsSync(bundlePath)) {\n this.fs.unlinkSync(bundlePath);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"impl-IQy1_4me.mjs","names":["fg"],"sources":["../src/commands/policy/helpers/buildOpaBundleTarball.ts","../src/commands/policy/helpers/buildPolicyBundleFormData.ts","../src/commands/policy/helpers/defaultPolicyVersionLabel.ts","../src/lib/policy/policy-publish-hints.ts","../src/commands/policy/publish/impl.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { gunzipSync } from 'node:zlib';\n\nimport { MAX_BUNDLE_COMPRESSED_BYTES, MAX_BUNDLE_DECOMPRESSED_BYTES } from '@transcend-io/utils';\nimport fg from 'fast-glob';\n\nimport { validatePolicyBundleContents } from '../../../lib/policy/policy-bundle-manifest.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { assertOpaInstalled } from './assertOpaInstalled.js';\nimport { runOPACapture } from './runOpa.js';\n\n/** Result of collecting publishable entries from a policy bundle directory. */\ninterface PolicyBundleArchiveContents {\n /** Relative paths to include in the upload tarball (manifest first, then rego) */\n entries: string[];\n}\n\n/**\n * Collects `.manifest` and publishable `.rego` files from a policy directory.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @returns Validated archive entries\n */\nfunction collectPolicyBundleArchiveEntries(dir: string): PolicyBundleArchiveContents {\n const regoFiles = fg\n .sync('**/*.rego', {\n cwd: dir,\n onlyFiles: true,\n dot: false,\n })\n .sort();\n const onDiskManifestPath = path.join(dir, POLICY_MANIFEST_FILENAME);\n const { publishableRegoPaths } = validatePolicyBundleContents(\n fs.existsSync(onDiskManifestPath) ? fs.readFileSync(onDiskManifestPath, 'utf8') : undefined,\n regoFiles.map((relativePath) => ({\n path: relativePath,\n contents: fs.readFileSync(path.join(dir, relativePath), 'utf8'),\n })),\n );\n\n return {\n entries: [POLICY_MANIFEST_FILENAME, ...publishableRegoPaths],\n };\n}\n\n/**\n * Verifies that a policy directory compiles end-to-end with `opa build`.\n *\n * The compiled output is discarded — the server receives the `.manifest` +\n * `.rego` archive produced by {@link buildOpaBundleTarball}, not the OPA bundle\n * — but a successful build guarantees the policies compile and link, surfacing\n * errors (syntax, missing imports, undefined references, etc.) before upload.\n *\n * @param dir - Absolute path to the policy bundle directory\n */\nasync function assertBundleCompiles(dir: string): Promise<void> {\n const buildOutputPath = path.join(\n os.tmpdir(),\n `transcend-policy-bundle-build-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`,\n );\n try {\n // Run with `cwd` set to the bundle directory and pass `.` so `opa build`\n // resolves the bundle root correctly. Bundle mode (`-b`) keeps local\n // `input.json` / `input.example.json` fixtures from merging as data.\n // `*_test.rego` files are local-only.\n const { code, stderr } = await runOPACapture(\n ['build', '--ignore', '*_test.rego', '-b', '-o', buildOutputPath, '.'],\n { cwd: dir },\n );\n if (code !== 0) {\n throw new Error(stderr.trim() || `opa build failed with exit code ${code}`);\n }\n } finally {\n if (fs.existsSync(buildOutputPath)) {\n fs.unlinkSync(buildOutputPath);\n }\n }\n}\n\n/**\n * Formats a byte count as a human-readable size with binary units.\n *\n * @param bytes - Number of bytes\n * @returns Human-readable size, e.g. `14 MiB` or `4 KiB`\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const kib = bytes / 1024;\n if (kib < 1024) {\n return `${kib % 1 === 0 ? kib.toFixed(0) : kib.toFixed(1)} KiB`;\n }\n const mib = kib / 1024;\n return `${mib % 1 === 0 ? mib.toFixed(0) : mib.toFixed(1)} MiB`;\n}\n\n/**\n * Builds a gzip-compressed policy bundle tarball for upload to Transcend.\n *\n * The Policy Engine API expects a plain archive containing `.manifest` and\n * one or more `.rego` files. Local projects author an OPA `.manifest` and it\n * is uploaded directly — no rename at pack time. Before packaging, the\n * manifest is validated (shape + root coverage) and the bundle is validated\n * with `opa check` (strict Rego linting) and `opa build` (full compilation) so\n * failures surface client-side rather than after upload.\n *\n * @param dir - Directory containing `.manifest` and `.rego` policy files\n * @returns Absolute path to the generated `.tar.gz` bundle\n */\nexport async function buildOpaBundleTarball(dir: string): Promise<string> {\n assertOpaInstalled();\n\n const resolvedDir = path.resolve(dir);\n if (!fs.existsSync(resolvedDir) || !fs.statSync(resolvedDir).isDirectory()) {\n throw new Error(`Policy directory does not exist or is not a directory: ${resolvedDir}`);\n }\n\n // Validate the manifest shape and that roots cover every Rego package before\n // invoking OPA, so invalid manifests surface a clear error instead of an\n // opaque `opa build failed with exit code 1`.\n const { entries: archiveEntries } = collectPolicyBundleArchiveEntries(resolvedDir);\n\n // Match the Rego v1 validation the Policy Engine API runs on upload.\n const { code: checkCode, stderr: checkStderr } = await runOPACapture([\n 'check',\n '--strict',\n resolvedDir,\n ]);\n if (checkCode !== 0) {\n throw new Error(checkStderr.trim() || `opa check failed with exit code ${checkCode}`);\n }\n\n // Ensure the bundle compiles end-to-end before packaging for upload.\n await assertBundleCompiles(resolvedDir);\n\n const outputPath = path.join(\n os.tmpdir(),\n `transcend-policy-bundle-${Date.now()}-${Math.random().toString(36).slice(2)}.tar.gz`,\n );\n const tarResult = spawnSync('tar', ['-czf', outputPath, '-C', resolvedDir, ...archiveEntries], {\n env: { ...process.env, COPYFILE_DISABLE: '1' },\n encoding: 'utf8',\n });\n if (tarResult.status !== 0) {\n throw new Error(\n `Failed to create policy bundle archive: ${tarResult.stderr.trim() || 'tar failed'}`,\n );\n }\n\n const compressedBytes = fs.readFileSync(outputPath);\n if (compressedBytes.byteLength > MAX_BUNDLE_COMPRESSED_BYTES) {\n fs.unlinkSync(outputPath);\n throw new Error(\n `Policy bundle exceeds the ${formatBytes(MAX_BUNDLE_COMPRESSED_BYTES)} compressed upload limit ` +\n `(bundle is ${formatBytes(compressedBytes.byteLength)}). ` +\n `The server also rejects decompressed bundles larger than ${formatBytes(MAX_BUNDLE_DECOMPRESSED_BYTES)}.`,\n );\n }\n\n const decompressedBytes = gunzipSync(compressedBytes);\n if (decompressedBytes.byteLength > MAX_BUNDLE_DECOMPRESSED_BYTES) {\n fs.unlinkSync(outputPath);\n throw new Error(\n `Policy bundle exceeds the ${formatBytes(MAX_BUNDLE_DECOMPRESSED_BYTES)} decompressed upload limit ` +\n `(bundle is ${formatBytes(decompressedBytes.byteLength)} decompressed).`,\n );\n }\n\n return outputPath;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n/** Fields for building a policy bundle upload form. */\nexport interface BuildPolicyBundleFormDataOptions {\n /** Absolute path to the bundle tarball */\n bundlePath: string;\n /** Version label */\n version: string;\n /** Optional description */\n description?: string;\n /** Bundle name (only for create) */\n bundleName?: string;\n}\n\n/**\n * Builds multipart form data for a policy bundle upload.\n *\n * @param options - Upload fields\n * @returns FormData ready for POST\n */\nexport function buildPolicyBundleFormData(options: BuildPolicyBundleFormDataOptions): FormData {\n const bundleBytes = fs.readFileSync(options.bundlePath);\n const form = new FormData();\n form.append(\n 'bundle',\n new Blob([bundleBytes], { type: 'application/gzip' }),\n path.basename(options.bundlePath),\n );\n form.append('version', options.version);\n if (options.description) {\n form.append('description', options.description);\n }\n if (options.bundleName) {\n form.append('bundleName', options.bundleName);\n }\n return form;\n}\n","/**\n * Formats a date as `yyyy-mm-dd-hh-mm-ss` in UTC.\n *\n * @param date - Date to format\n * @returns Timestamp label\n */\nfunction formatPolicyVersionTimestamp(date: Date): string {\n return date.toISOString().slice(0, 19).replace(/[T:]/g, '-');\n}\n\n/**\n * Returns a default version label from the bundle name and current UTC timestamp.\n *\n * @param bundleName - Tenant-unique policy bundle name\n * @param now - Current time (for testing)\n * @returns Version label in `{bundleName}-yyyy-mm-dd-hh-mm-ss` form\n */\nexport function defaultPolicyVersionLabel(bundleName: string, now: Date = new Date()): string {\n return `${bundleName}-${formatPolicyVersionTimestamp(now)}`;\n}\n","import {\n PERMISSIONS_POLICY_BUNDLE_NAME,\n PolicyTemplate,\n type PolicyTemplateName,\n} from './policy-scaffold-templates.js';\n\n/** Inputs used to soft-warn about Permissions vs generic publish naming. */\nexport interface PolicyPublishBundleNameHintInput {\n /** Optional scaffold template from `.manifest` metadata. */\n template?: PolicyTemplateName;\n /** Declared OPA package roots. */\n roots: string[];\n}\n\n/**\n * Whether local authoring signals suggest a Permissions API bundle.\n *\n * Prefers explicit `metadata.transcend.io.template`. Without metadata, falls\n * back to a root that is exactly `permissions` or nested under it.\n *\n * @param input - Manifest template hint and roots\n * @returns Whether the local tree looks Permissions-oriented\n */\nfunction looksLikePermissionsBundle(input: PolicyPublishBundleNameHintInput): boolean {\n if (input.template === PolicyTemplate.Permissions) {\n return true;\n }\n if (input.template === PolicyTemplate.Generic) {\n return false;\n }\n return input.roots.some(\n (root) =>\n root === PERMISSIONS_POLICY_BUNDLE_NAME ||\n root.startsWith(`${PERMISSIONS_POLICY_BUNDLE_NAME}/`),\n );\n}\n\n/**\n * Soft-warning when `--remote-bundle-name` disagrees with Permissions conventions.\n *\n * Upload does not enforce bundle kinds. Permissions API only loads the\n * remote bundle named {@link PERMISSIONS_POLICY_BUNDLE_NAME}.\n *\n * @param bundleName - Value of `--remote-bundle-name`\n * @param input - Local manifest template/roots\n * @returns Warning text, or undefined when names align\n */\nexport function formatPolicyPublishBundleNameHint(\n bundleName: string,\n input: PolicyPublishBundleNameHintInput,\n): string | undefined {\n const permissionsLocal = looksLikePermissionsBundle(input);\n const permissionsRemote = bundleName === PERMISSIONS_POLICY_BUNDLE_NAME;\n\n if (permissionsLocal && !permissionsRemote) {\n return (\n `This directory looks like a Permissions API policy, but --remote-bundle-name is ` +\n `\"${bundleName}\". Permissions API only loads the remote bundle named ` +\n `\"${PERMISSIONS_POLICY_BUNDLE_NAME}\". Upload still succeeds; pass ` +\n `--remote-bundle-name=${PERMISSIONS_POLICY_BUNDLE_NAME} if that is the intended path.`\n );\n }\n\n if (!permissionsLocal && permissionsRemote) {\n return (\n `--remote-bundle-name=${PERMISSIONS_POLICY_BUNDLE_NAME} reserves the Permissions API ` +\n `path. Upload treats all bundles the same; only that fixed name is queried by ` +\n `the Permissions API. Continue only if you intend this bundle for the Permissions API.`\n );\n }\n\n return undefined;\n}\n","import { join } from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { selectCommandLogger } from '../../../lib/cli/command-output.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildExampleCommand } from '../../../lib/docgen/buildExamples.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport { parsePolicyBundleManifest } from '../../../lib/policy/policy-bundle-manifest.js';\nimport { resolvePolicyProjectDirectory } from '../../../lib/policy/policy-project-discovery.js';\nimport { formatPolicyPublishBundleNameHint } from '../../../lib/policy/policy-publish-hints.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { isInteractivePromptInvocation } from '../../../lib/scaffolding/prompts.js';\nimport type { ActivateCommandFlags } from '../activate/impl.js';\nimport {\n buildPolicyBundleFormData,\n buildPolicyEngineClient,\n buildOpaBundleTarball,\n defaultPolicyVersionLabel,\n formatPolicyBundleVersionSummary,\n policyEngineRequest,\n printResult,\n resolveBundleIdByName,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { CreatePolicyBundleResponse, CreatePolicyBundleVersionResponse } from '../types.js';\n\n/** CLI flags for `transcend policy publish`. */\nexport interface PublishCommandFlags {\n /** Tenant-unique bundle name */\n 'remote-bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Version label (defaults to `{bundleName}-yyyy-mm-dd-hh-mm-ss`) */\n version?: string;\n /** Optional version description */\n description?: string;\n /** Print raw JSON response */\n json: boolean;\n /** Skip the \"create new bundle\" confirmation */\n yes: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * Build and upload a new immutable policy bundle version.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy bundle directory containing a `.manifest`\n */\nexport async function publish(\n this: LocalContext,\n {\n 'remote-bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n version,\n description,\n json,\n yes,\n debug = false,\n }: PublishCommandFlags,\n directory: string,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const commandLogger = selectCommandLogger(this.logger, json);\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n const versionLabel = version ?? defaultPolicyVersionLabel(bundleName);\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const interactive = isInteractivePromptInvocation(\n { json, noInteractive: false },\n this.process.stdin.isTTY,\n this.process.stderr.isTTY,\n );\n\n let bundlePath: string | undefined;\n try {\n commandLogger.info(colors.green(`Building policy bundle from ${resolvedDir}...`));\n bundlePath = await buildOpaBundleTarball(resolvedDir);\n\n try {\n const manifestPath = join(resolvedDir, POLICY_MANIFEST_FILENAME);\n const manifest = parsePolicyBundleManifest(this.fs.readFileSync(manifestPath, 'utf8'));\n const bundleNameHint = formatPolicyPublishBundleNameHint(bundleName, manifest);\n if (bundleNameHint) {\n commandLogger.warn(colors.yellow(bundleNameHint));\n }\n } catch {\n // Best-effort authoring hint; tarball build already validated the manifest.\n }\n\n const existingBundleId = await resolveBundleIdByName(client, bundleName);\n\n let responseBody: CreatePolicyBundleResponse | CreatePolicyBundleVersionResponse;\n\n if (existingBundleId) {\n commandLogger.info(colors.green(`Uploading new version for bundle \"${bundleName}\"...`));\n const form = buildPolicyBundleFormData({\n bundlePath,\n version: versionLabel,\n description,\n });\n responseBody = await policyEngineRequest(\n client\n .post(`v1/policy-engine/policy-bundles/${existingBundleId}/versions`, { body: form })\n .json<CreatePolicyBundleVersionResponse>(),\n );\n } else {\n if (!interactive && !yes) {\n this.logger.error(\n colors.red(\n 'Cannot create a new bundle in non-interactive or JSON mode; pass --yes to confirm.',\n ),\n );\n this.process.exit(1);\n return;\n }\n\n if (!yes) {\n commandLogger.warn(\n colors.yellow(`No policy bundle named \"${bundleName}\" exists for this organization.`),\n );\n const shouldCreate = await inquirerConfirmBoolean({\n message: `No policy bundle named \"${bundleName}\" exists. Create a new bundle and upload its first version?`,\n });\n if (!shouldCreate) {\n commandLogger.info(colors.yellow('Publish cancelled.'));\n return;\n }\n }\n\n commandLogger.info(\n colors.green(`Creating bundle \"${bundleName}\" and uploading first version...`),\n );\n const createForm = buildPolicyBundleFormData({\n bundlePath,\n version: versionLabel,\n description,\n bundleName,\n });\n responseBody = await policyEngineRequest(\n client\n .post('v1/policy-engine/policy-bundles', {\n body: createForm,\n })\n .json<CreatePolicyBundleResponse>(),\n );\n }\n\n printResult(this.process.stdout, {\n json,\n data: responseBody,\n renderTable: () => formatPolicyBundleVersionSummary(responseBody.version),\n });\n\n commandLogger.info(colors.green('Policy bundle version uploaded successfully.'));\n\n const activateCommand = buildExampleCommand<ActivateCommandFlags>(['policy', 'activate'], {\n version: responseBody.version.version,\n 'remote-bundle-name': bundleName,\n });\n commandLogger.info(\n colors.yellow(\n `Publishing a policy does not activate it. To activate this version, run:\\n ${activateCommand}`,\n ),\n );\n } finally {\n if (bundlePath && this.fs.existsSync(bundlePath)) {\n this.fs.unlinkSync(bundlePath);\n }\n }\n}\n"],"mappings":"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"}