@transcend-io/cli 10.23.2 → 10.23.3

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 (131) hide show
  1. package/dist/{app-CJQU1quO.mjs → app-C_Rupn-o.mjs} +16 -16
  2. package/dist/{app-CJQU1quO.mjs.map → app-C_Rupn-o.mjs.map} +1 -1
  3. package/dist/{approvePrivacyRequests-Bat_tgMc.mjs → approvePrivacyRequests-OiTdKaRa.mjs} +2 -2
  4. package/dist/{approvePrivacyRequests-Bat_tgMc.mjs.map → approvePrivacyRequests-OiTdKaRa.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-BwdJZSoR.mjs → buildExamples-BlYDwF-S.mjs} +2 -2
  9. package/dist/{buildExamples-BwdJZSoR.mjs.map → buildExamples-BlYDwF-S.mjs.map} +1 -1
  10. package/dist/{buildXdiSyncEndpoint-CnuJDaXk.mjs → buildXdiSyncEndpoint-5L1O_yrs.mjs} +2 -2
  11. package/dist/{buildXdiSyncEndpoint-CnuJDaXk.mjs.map → buildXdiSyncEndpoint-5L1O_yrs.mjs.map} +1 -1
  12. package/dist/{bulkRestartRequests-DMYL5KtN.mjs → bulkRestartRequests-BKLpHkmr.mjs} +2 -2
  13. package/dist/{bulkRestartRequests-DMYL5KtN.mjs.map → bulkRestartRequests-BKLpHkmr.mjs.map} +1 -1
  14. package/dist/{bulkRetryEnrichers-BcfRtvv9.mjs → bulkRetryEnrichers-M7DfLUtG.mjs} +2 -2
  15. package/dist/{bulkRetryEnrichers-BcfRtvv9.mjs.map → bulkRetryEnrichers-M7DfLUtG.mjs.map} +1 -1
  16. package/dist/{cancelPrivacyRequests-DCYH-YB0.mjs → cancelPrivacyRequests-DTCvyDRw.mjs} +2 -2
  17. package/dist/{cancelPrivacyRequests-DCYH-YB0.mjs.map → cancelPrivacyRequests-DTCvyDRw.mjs.map} +1 -1
  18. package/dist/{command-BO85FTk1.mjs → command-Byianxsi.mjs} +2 -2
  19. package/dist/{command-BO85FTk1.mjs.map → command-Byianxsi.mjs.map} +1 -1
  20. package/dist/{constants-DLmuwAxY.mjs → constants-FvNUybuo.mjs} +2 -2
  21. package/dist/{constants-DLmuwAxY.mjs.map → constants-FvNUybuo.mjs.map} +1 -1
  22. package/dist/{createExtraKeyHandler-MX1ZNR9c.mjs → createExtraKeyHandler-DmBY_oth.mjs} +2 -2
  23. package/dist/{createExtraKeyHandler-MX1ZNR9c.mjs.map → createExtraKeyHandler-DmBY_oth.mjs.map} +1 -1
  24. package/dist/{downloadPrivacyRequestFiles-ChRO8xkU.mjs → downloadPrivacyRequestFiles-CPvZpAuB.mjs} +2 -2
  25. package/dist/{downloadPrivacyRequestFiles-ChRO8xkU.mjs.map → downloadPrivacyRequestFiles-CPvZpAuB.mjs.map} +1 -1
  26. package/dist/{generateCrossAccountApiKeys-CN17E6qO.mjs → generateCrossAccountApiKeys-CXyKrcUX.mjs} +2 -2
  27. package/dist/{generateCrossAccountApiKeys-CN17E6qO.mjs.map → generateCrossAccountApiKeys-CXyKrcUX.mjs.map} +1 -1
  28. package/dist/{impl-MAAGqA0d2.mjs → impl-2_uumAeu2.mjs} +2 -2
  29. package/dist/{impl-MAAGqA0d2.mjs.map → impl-2_uumAeu2.mjs.map} +1 -1
  30. package/dist/{impl-CHwKiYPF.mjs → impl-4n_0Mp6M.mjs} +2 -2
  31. package/dist/{impl-CHwKiYPF.mjs.map → impl-4n_0Mp6M.mjs.map} +1 -1
  32. package/dist/{impl-B1Lux2OG2.mjs → impl-8x-_ymRL2.mjs} +2 -2
  33. package/dist/{impl-B1Lux2OG2.mjs.map → impl-8x-_ymRL2.mjs.map} +1 -1
  34. package/dist/{impl-DkCsefy1.mjs → impl-BAgai3CJ.mjs} +2 -2
  35. package/dist/{impl-DkCsefy1.mjs.map → impl-BAgai3CJ.mjs.map} +1 -1
  36. package/dist/{impl-nKBSsApu2.mjs → impl-BFisQPcN2.mjs} +2 -2
  37. package/dist/{impl-nKBSsApu2.mjs.map → impl-BFisQPcN2.mjs.map} +1 -1
  38. package/dist/{impl-c9aM2mJw2.mjs → impl-BUitvEpH2.mjs} +2 -2
  39. package/dist/{impl-c9aM2mJw2.mjs.map → impl-BUitvEpH2.mjs.map} +1 -1
  40. package/dist/{impl-BeNVz2wB.mjs → impl-BrsgkAas.mjs} +2 -2
  41. package/dist/{impl-BeNVz2wB.mjs.map → impl-BrsgkAas.mjs.map} +1 -1
  42. package/dist/{impl-BXYhSvBQ2.mjs → impl-BtDPKaci2.mjs} +2 -2
  43. package/dist/{impl-BXYhSvBQ2.mjs.map → impl-BtDPKaci2.mjs.map} +1 -1
  44. package/dist/{impl-McLWRGru.mjs → impl-C2H6aCBJ.mjs} +2 -2
  45. package/dist/{impl-McLWRGru.mjs.map → impl-C2H6aCBJ.mjs.map} +1 -1
  46. package/dist/{impl-DlGUg4Nr2.mjs → impl-C6rkmAmP2.mjs} +2 -2
  47. package/dist/{impl-DlGUg4Nr2.mjs.map → impl-C6rkmAmP2.mjs.map} +1 -1
  48. package/dist/{impl-D101FbzY.mjs → impl-CE4PMco7.mjs} +2 -2
  49. package/dist/{impl-D101FbzY.mjs.map → impl-CE4PMco7.mjs.map} +1 -1
  50. package/dist/{impl-ciYh2pmH2.mjs → impl-CG_H2ynt2.mjs} +2 -2
  51. package/dist/{impl-ciYh2pmH2.mjs.map → impl-CG_H2ynt2.mjs.map} +1 -1
  52. package/dist/{impl-Nm3spVmW.mjs → impl-COQ3iQNF.mjs} +2 -2
  53. package/dist/{impl-Nm3spVmW.mjs.map → impl-COQ3iQNF.mjs.map} +1 -1
  54. package/dist/{impl-Wrx1yiEs2.mjs → impl-CbVqfl-Q2.mjs} +2 -2
  55. package/dist/{impl-Wrx1yiEs2.mjs.map → impl-CbVqfl-Q2.mjs.map} +1 -1
  56. package/dist/{impl-DNaa8Vn0.mjs → impl-CcrCW-aY.mjs} +2 -2
  57. package/dist/{impl-DNaa8Vn0.mjs.map → impl-CcrCW-aY.mjs.map} +1 -1
  58. package/dist/{impl-BE4fgip62.mjs → impl-CdYy80RW2.mjs} +2 -2
  59. package/dist/{impl-BE4fgip62.mjs.map → impl-CdYy80RW2.mjs.map} +1 -1
  60. package/dist/{impl-D_wG-7a4.mjs → impl-D-e909Cm.mjs} +2 -2
  61. package/dist/{impl-D_wG-7a4.mjs.map → impl-D-e909Cm.mjs.map} +1 -1
  62. package/dist/{impl-hfNny0zo2.mjs → impl-D1WFPOUv2.mjs} +2 -2
  63. package/dist/{impl-hfNny0zo2.mjs.map → impl-D1WFPOUv2.mjs.map} +1 -1
  64. package/dist/{impl-BHs3eVhp2.mjs → impl-D2GVNiVe2.mjs} +2 -2
  65. package/dist/{impl-BHs3eVhp2.mjs.map → impl-D2GVNiVe2.mjs.map} +1 -1
  66. package/dist/{impl-Bc50xvlc.mjs → impl-D58C8lma.mjs} +2 -2
  67. package/dist/{impl-Bc50xvlc.mjs.map → impl-D58C8lma.mjs.map} +1 -1
  68. package/dist/{impl-uM6iI4022.mjs → impl-D5iPfceZ2.mjs} +2 -2
  69. package/dist/{impl-uM6iI4022.mjs.map → impl-D5iPfceZ2.mjs.map} +1 -1
  70. package/dist/{impl-B0DHOG6N.mjs → impl-D5k-ODY_.mjs} +2 -2
  71. package/dist/{impl-B0DHOG6N.mjs.map → impl-D5k-ODY_.mjs.map} +1 -1
  72. package/dist/{impl-DgDP0us6.mjs → impl-D8na2-uT.mjs} +2 -2
  73. package/dist/{impl-DgDP0us6.mjs.map → impl-D8na2-uT.mjs.map} +1 -1
  74. package/dist/{impl-FG8rHJOo.mjs → impl-DIOz8HbL.mjs} +2 -2
  75. package/dist/{impl-FG8rHJOo.mjs.map → impl-DIOz8HbL.mjs.map} +1 -1
  76. package/dist/{impl-D80SbYOi.mjs → impl-DYlGPJgH.mjs} +2 -2
  77. package/dist/{impl-D80SbYOi.mjs.map → impl-DYlGPJgH.mjs.map} +1 -1
  78. package/dist/{impl-Dp5ViMnH.mjs → impl-DdeK8SB2.mjs} +2 -2
  79. package/dist/{impl-Dp5ViMnH.mjs.map → impl-DdeK8SB2.mjs.map} +1 -1
  80. package/dist/{impl-nriMQPFY2.mjs → impl-DiPfQtsi2.mjs} +2 -2
  81. package/dist/{impl-nriMQPFY2.mjs.map → impl-DiPfQtsi2.mjs.map} +1 -1
  82. package/dist/{impl-CuJ_Yc182.mjs → impl-DoODnmDh2.mjs} +2 -2
  83. package/dist/{impl-CuJ_Yc182.mjs.map → impl-DoODnmDh2.mjs.map} +1 -1
  84. package/dist/{impl-5lRGODmy2.mjs → impl-VpPmlaGq2.mjs} +2 -2
  85. package/dist/{impl-5lRGODmy2.mjs.map → impl-VpPmlaGq2.mjs.map} +1 -1
  86. package/dist/{impl-DEuyVB3Z.mjs → impl-icQ7BxhJ.mjs} +2 -2
  87. package/dist/{impl-DEuyVB3Z.mjs.map → impl-icQ7BxhJ.mjs.map} +1 -1
  88. package/dist/{impl-DYRaB9NY2.mjs → impl-jSWXoXO82.mjs} +2 -2
  89. package/dist/{impl-DYRaB9NY2.mjs.map → impl-jSWXoXO82.mjs.map} +1 -1
  90. package/dist/{impl-DKuS3x3o.mjs → impl-lNZ6B44X.mjs} +2 -2
  91. package/dist/{impl-DKuS3x3o.mjs.map → impl-lNZ6B44X.mjs.map} +1 -1
  92. package/dist/{impl-ICUaojZB.mjs → impl-srSvjFPi.mjs} +2 -2
  93. package/dist/{impl-ICUaojZB.mjs.map → impl-srSvjFPi.mjs.map} +1 -1
  94. package/dist/{impl-CWRNtU5r2.mjs → impl-urIzkY5O2.mjs} +2 -2
  95. package/dist/{impl-CWRNtU5r2.mjs.map → impl-urIzkY5O2.mjs.map} +1 -1
  96. package/dist/index.mjs +1 -1
  97. package/dist/{markRequestDataSiloIdsCompleted-BqV_17sv.mjs → markRequestDataSiloIdsCompleted-z_-xldRm.mjs} +2 -2
  98. package/dist/{markRequestDataSiloIdsCompleted-BqV_17sv.mjs.map → markRequestDataSiloIdsCompleted-z_-xldRm.mjs.map} +1 -1
  99. package/dist/{markSilentPrivacyRequests-m_dXMMcD.mjs → markSilentPrivacyRequests-Ci_bOJ6f.mjs} +2 -2
  100. package/dist/{markSilentPrivacyRequests-m_dXMMcD.mjs.map → markSilentPrivacyRequests-Ci_bOJ6f.mjs.map} +1 -1
  101. package/dist/{notifyPrivacyRequestsAdditionalTime-g9HqfNPC.mjs → notifyPrivacyRequestsAdditionalTime-Rs4HemLL.mjs} +2 -2
  102. package/dist/{notifyPrivacyRequestsAdditionalTime-g9HqfNPC.mjs.map → notifyPrivacyRequestsAdditionalTime-Rs4HemLL.mjs.map} +1 -1
  103. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-CgTe6SAm.mjs → pullChunkedCustomSiloOutstandingIdentifiers-RrREZ-_t.mjs} +2 -2
  104. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-CgTe6SAm.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-RrREZ-_t.mjs.map} +1 -1
  105. package/dist/{pullManualEnrichmentIdentifiersToCsv-DF9RJNPy.mjs → pullManualEnrichmentIdentifiersToCsv-xU8OC8OY.mjs} +2 -2
  106. package/dist/{pullManualEnrichmentIdentifiersToCsv-DF9RJNPy.mjs.map → pullManualEnrichmentIdentifiersToCsv-xU8OC8OY.mjs.map} +1 -1
  107. package/dist/{pushCronIdentifiersFromCsv-DFa0br1k.mjs → pushCronIdentifiersFromCsv-tfTDerAd.mjs} +2 -2
  108. package/dist/{pushCronIdentifiersFromCsv-DFa0br1k.mjs.map → pushCronIdentifiersFromCsv-tfTDerAd.mjs.map} +1 -1
  109. package/dist/{pushManualEnrichmentIdentifiersFromCsv-CHbEMJjC.mjs → pushManualEnrichmentIdentifiersFromCsv-iB0_3emX.mjs} +2 -2
  110. package/dist/{pushManualEnrichmentIdentifiersFromCsv-CHbEMJjC.mjs.map → pushManualEnrichmentIdentifiersFromCsv-iB0_3emX.mjs.map} +1 -1
  111. package/dist/{removeUnverifiedRequestIdentifiers-Dc3YVC_s.mjs → removeUnverifiedRequestIdentifiers-BQd7FW8R.mjs} +2 -2
  112. package/dist/{removeUnverifiedRequestIdentifiers-Dc3YVC_s.mjs.map → removeUnverifiedRequestIdentifiers-BQd7FW8R.mjs.map} +1 -1
  113. package/dist/{retryRequestDataSilos-DVvFRQMg.mjs → retryRequestDataSilos-yXYBxFz3.mjs} +2 -2
  114. package/dist/{retryRequestDataSilos-DVvFRQMg.mjs.map → retryRequestDataSilos-yXYBxFz3.mjs.map} +1 -1
  115. package/dist/{skipPreflightJobs-BnsBW32R.mjs → skipPreflightJobs-BVlPUC_C.mjs} +2 -2
  116. package/dist/{skipPreflightJobs-BnsBW32R.mjs.map → skipPreflightJobs-BVlPUC_C.mjs.map} +1 -1
  117. package/dist/{skipRequestDataSilos-D1q7X3UG.mjs → skipRequestDataSilos-DcRsUIie.mjs} +2 -2
  118. package/dist/{skipRequestDataSilos-D1q7X3UG.mjs.map → skipRequestDataSilos-DcRsUIie.mjs.map} +1 -1
  119. package/dist/{streamPrivacyRequestsToCsv-S6KkzRmu.mjs → streamPrivacyRequestsToCsv-Qf83JD4N.mjs} +2 -2
  120. package/dist/{streamPrivacyRequestsToCsv-S6KkzRmu.mjs.map → streamPrivacyRequestsToCsv-Qf83JD4N.mjs.map} +1 -1
  121. package/dist/{updateConsentManagerVersionToLatest-F-VtxsbZ.mjs → updateConsentManagerVersionToLatest-CNFpVfHH.mjs} +2 -2
  122. package/dist/{updateConsentManagerVersionToLatest-F-VtxsbZ.mjs.map → updateConsentManagerVersionToLatest-CNFpVfHH.mjs.map} +1 -1
  123. package/dist/{uploadConsents-BRdWNrha.mjs → uploadConsents-DZJNyu16.mjs} +2 -2
  124. package/dist/{uploadConsents-BRdWNrha.mjs.map → uploadConsents-DZJNyu16.mjs.map} +1 -1
  125. package/dist/{uploadCookiesFromCsv-C5FCvPyJ.mjs → uploadCookiesFromCsv-vlpWQ6a7.mjs} +2 -2
  126. package/dist/{uploadCookiesFromCsv-C5FCvPyJ.mjs.map → uploadCookiesFromCsv-vlpWQ6a7.mjs.map} +1 -1
  127. package/dist/{uploadDataFlowsFromCsv-DkdTbXrx.mjs → uploadDataFlowsFromCsv-BMs7dUzd.mjs} +2 -2
  128. package/dist/{uploadDataFlowsFromCsv-DkdTbXrx.mjs.map → uploadDataFlowsFromCsv-BMs7dUzd.mjs.map} +1 -1
  129. package/dist/{uploadPrivacyRequestsFromCsv-CsZ1_cGX.mjs → uploadPrivacyRequestsFromCsv-Ds3Qghge.mjs} +2 -2
  130. package/dist/{uploadPrivacyRequestsFromCsv-CsZ1_cGX.mjs.map → uploadPrivacyRequestsFromCsv-Ds3Qghge.mjs.map} +1 -1
  131. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"impl-CHwKiYPF.mjs","names":["fg"],"sources":["../src/commands/policy/helpers/buildOpaBundleTarball.ts","../src/commands/policy/helpers/buildPolicyBundleFormData.ts","../src/commands/policy/helpers/defaultPolicyVersionLabel.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 fg from 'fast-glob';\n\nimport { MAX_BUNDLE_COMPRESSED_BYTES, MAX_BUNDLE_DECOMPRESSED_BYTES } from '../constants.js';\nimport { assertOpaInstalled } from './assertOpaInstalled.js';\nimport { runOPACapture } from './runOpa.js';\n\n/**\n * Returns whether a relative path is a publishable Rego policy file.\n *\n * OPA test files (`*_test.rego`) are excluded because they are for local\n * validation only and are not part of the upload contract.\n *\n * @param relativePath - Path relative to the bundle directory\n * @returns Whether the file should be included in the upload archive\n */\nfunction isPublishableRegoFile(relativePath: string): boolean {\n return relativePath.endsWith('.rego') && !relativePath.endsWith('_test.rego');\n}\n\n/** Shape of the OPA bundle `manifest.json` as accepted by the Policy Engine. */\ninterface PolicyBundleManifest {\n /** Roots of the bundle, e.g. `[\"policy_engine\"]` or `[\"policy_engine/transcend\"]` */\n roots: string[];\n}\n\n/**\n * Reads and validates `manifest.json` from a policy bundle directory.\n *\n * The Policy Engine requires `manifest.json` to declare `roots` as an array of\n * strings. OPA's own tooling does not always enforce this against the Rego\n * packages on upload, so we validate the shape client-side to surface a clear,\n * actionable error instead of an opaque server `400` or a decide-time\n * fail-closed footgun.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @returns The parsed manifest\n */\nfunction readPolicyBundleManifest(dir: string): PolicyBundleManifest {\n const manifestPath = path.join(dir, 'manifest.json');\n if (!fs.existsSync(manifestPath)) {\n throw new Error('Policy bundle directory must contain a manifest.json file.');\n }\n\n const raw = fs.readFileSync(manifestPath, 'utf8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `manifest.json is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('manifest.json must contain a JSON object.');\n }\n\n const roots = (parsed as { roots?: unknown }).roots;\n if (!Array.isArray(roots) || roots.length === 0) {\n throw new Error(\n 'manifest.json must declare \"roots\" as a non-empty array of strings (e.g. {\"roots\":[\"policy_engine\"]}).',\n );\n }\n\n if (!roots.every((root) => typeof root === 'string' && root.length > 0)) {\n throw new Error('manifest.json \"roots\" must be an array of non-empty strings.');\n }\n\n return { roots };\n}\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 /** Parsed manifest */\n manifest: PolicyBundleManifest;\n}\n\n/**\n * Collects `manifest.json` and publishable `.rego` files from a policy directory.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @returns Archive entries and the parsed manifest\n */\nfunction collectPolicyBundleArchiveEntries(dir: string): PolicyBundleArchiveContents {\n const manifest = readPolicyBundleManifest(dir);\n\n const regoFiles = fg\n .sync('**/*.rego', {\n cwd: dir,\n onlyFiles: true,\n dot: false,\n })\n .filter(isPublishableRegoFile);\n\n if (regoFiles.length === 0) {\n throw new Error('Policy bundle directory must contain at least one .rego policy file.');\n }\n\n return { entries: ['manifest.json', ...regoFiles.sort()], manifest };\n}\n\n/** Matches a Rego `package <path>` declaration. */\nconst PACKAGE_DECLARATION_PATTERN = /^\\s*package\\s+([A-Za-z_][\\w.]*)/m;\n\n/**\n * Normalizes an OPA manifest root to a dotted package prefix.\n *\n * Roots use `/` as the path separator (e.g. `policy_engine/transcend`); Rego\n * package paths use `.` (e.g. `policy_engine.transcend`).\n *\n * @param root - A manifest root string\n * @returns The root in dotted form\n */\nfunction normalizeRootToPackagePrefix(root: string): string {\n return root.replace(/\\//g, '.');\n}\n\n/**\n * Reads the Rego package path declared in a `.rego` file.\n *\n * @param filePath - Absolute path to the `.rego` file\n * @returns The dotted package path, or `undefined` if no `package` declaration\n */\nfunction readRegoPackagePath(filePath: string): string | undefined {\n const contents = fs.readFileSync(filePath, 'utf8');\n const match = PACKAGE_DECLARATION_PATTERN.exec(contents);\n return match?.[1];\n}\n\n/**\n * Verifies that every publishable `.rego` package is covered by a manifest root.\n *\n * A bundle whose `roots` do not cover its Rego packages will upload cleanly but\n * fail-closed at decide time — the customer only discovers the mismatch via\n * denied decisions. This surfaces the mismatch at upload with a clear message.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @param regoFiles - Relative paths to publishable `.rego` files\n * @param roots - Manifest roots\n */\nfunction assertRootsCoverPackages(dir: string, regoFiles: string[], roots: string[]): void {\n const rootPrefixes = roots.map(normalizeRootToPackagePrefix);\n\n const uncovered: string[] = [];\n for (const relativeRego of regoFiles) {\n const pkg = readRegoPackagePath(path.join(dir, relativeRego));\n if (!pkg) {\n continue;\n }\n const covered = rootPrefixes.some((prefix) => pkg === prefix || pkg.startsWith(`${prefix}.`));\n if (!covered) {\n uncovered.push(\n ` - ${relativeRego} (package ${pkg}) is not covered by roots [${roots.join(', ')}]`,\n );\n }\n }\n\n if (uncovered.length > 0) {\n throw new Error(\n [\n 'manifest.json \"roots\" do not cover all Rego packages in the bundle; ' +\n 'uncovered packages will fail-closed at decide time. Either broaden \"roots\" or move the policy under a covered package:',\n ...uncovered,\n ].join('\\n'),\n );\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.json` +\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. `*_test.rego` files are local-only.\n const { code, stderr } = await runOPACapture(\n ['build', '--v0-compatible', '--ignore', '*_test.rego', '-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.json` and\n * one or more `.rego` files. This differs from `opa build` output, which embeds\n * `.manifest`, `data.json`, and other OPA bundle metadata that the server\n * rejects. Before packaging, the manifest is validated (shape + root coverage)\n * and the bundle is validated with `opa check` (strict Rego linting) and\n * `opa build` (full compilation) so failures surface client-side rather than\n * after upload.\n *\n * @param dir - Directory containing `manifest.json` 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, manifest } = collectPolicyBundleArchiveEntries(resolvedDir);\n const regoFiles = archiveEntries.filter((entry) => entry !== 'manifest.json');\n assertRootsCoverPackages(resolvedDir, regoFiles, manifest.roots);\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 '--v0-compatible',\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\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 fs from 'node:fs';\nimport 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 { buildExampleCommand } from '../../../lib/docgen/buildExamples.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport { logger } from '../../../logger.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 /** Directory containing Rego policy files */\n dir: string;\n /** Tenant-unique bundle name */\n 'bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** 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 */\nexport async function publish(\n this: LocalContext,\n {\n dir,\n 'bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n version,\n description,\n json,\n yes,\n debug = false,\n }: PublishCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n setPolicyEngineCliDebug(debug);\n\n const resolvedDir = path.resolve(dir);\n const versionLabel = version ?? defaultPolicyVersionLabel(bundleName);\n const client = buildPolicyEngineClient(transcendUrl, auth);\n\n let bundlePath: string | undefined;\n try {\n logger.info(colors.green(`Building policy bundle from ${resolvedDir}...`));\n bundlePath = await buildOpaBundleTarball(resolvedDir);\n\n const existingBundleId = await resolveBundleIdByName(client, bundleName);\n\n let responseBody: CreatePolicyBundleResponse | CreatePolicyBundleVersionResponse;\n\n if (existingBundleId) {\n logger.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 (!this.process.stdin.isTTY && !yes) {\n logger.error(\n colors.red(\n 'Cannot create a new bundle in a non-interactive environment; pass --yes to confirm.',\n ),\n );\n this.process.exit(1);\n return;\n }\n\n if (!yes) {\n logger.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 logger.info(colors.yellow('Publish cancelled.'));\n return;\n }\n }\n\n logger.info(colors.green(`Creating bundle \"${bundleName}\" and uploading first version...`));\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 logger.info(colors.green('Policy bundle version uploaded successfully.'));\n\n const activateCommand = buildExampleCommand<ActivateCommandFlags>(['policy', 'activate'], {\n version: responseBody.version.version,\n 'bundle-name': bundleName,\n });\n logger.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 && fs.existsSync(bundlePath)) {\n fs.unlinkSync(bundlePath);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"impl-4n_0Mp6M.mjs","names":["fg"],"sources":["../src/commands/policy/helpers/buildOpaBundleTarball.ts","../src/commands/policy/helpers/buildPolicyBundleFormData.ts","../src/commands/policy/helpers/defaultPolicyVersionLabel.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 fg from 'fast-glob';\n\nimport { MAX_BUNDLE_COMPRESSED_BYTES, MAX_BUNDLE_DECOMPRESSED_BYTES } from '../constants.js';\nimport { assertOpaInstalled } from './assertOpaInstalled.js';\nimport { runOPACapture } from './runOpa.js';\n\n/**\n * Returns whether a relative path is a publishable Rego policy file.\n *\n * OPA test files (`*_test.rego`) are excluded because they are for local\n * validation only and are not part of the upload contract.\n *\n * @param relativePath - Path relative to the bundle directory\n * @returns Whether the file should be included in the upload archive\n */\nfunction isPublishableRegoFile(relativePath: string): boolean {\n return relativePath.endsWith('.rego') && !relativePath.endsWith('_test.rego');\n}\n\n/** Shape of the OPA bundle `manifest.json` as accepted by the Policy Engine. */\ninterface PolicyBundleManifest {\n /** Roots of the bundle, e.g. `[\"policy_engine\"]` or `[\"policy_engine/transcend\"]` */\n roots: string[];\n}\n\n/**\n * Reads and validates `manifest.json` from a policy bundle directory.\n *\n * The Policy Engine requires `manifest.json` to declare `roots` as an array of\n * strings. OPA's own tooling does not always enforce this against the Rego\n * packages on upload, so we validate the shape client-side to surface a clear,\n * actionable error instead of an opaque server `400` or a decide-time\n * fail-closed footgun.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @returns The parsed manifest\n */\nfunction readPolicyBundleManifest(dir: string): PolicyBundleManifest {\n const manifestPath = path.join(dir, 'manifest.json');\n if (!fs.existsSync(manifestPath)) {\n throw new Error('Policy bundle directory must contain a manifest.json file.');\n }\n\n const raw = fs.readFileSync(manifestPath, 'utf8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `manifest.json is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('manifest.json must contain a JSON object.');\n }\n\n const roots = (parsed as { roots?: unknown }).roots;\n if (!Array.isArray(roots) || roots.length === 0) {\n throw new Error(\n 'manifest.json must declare \"roots\" as a non-empty array of strings (e.g. {\"roots\":[\"policy_engine\"]}).',\n );\n }\n\n if (!roots.every((root) => typeof root === 'string' && root.length > 0)) {\n throw new Error('manifest.json \"roots\" must be an array of non-empty strings.');\n }\n\n return { roots };\n}\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 /** Parsed manifest */\n manifest: PolicyBundleManifest;\n}\n\n/**\n * Collects `manifest.json` and publishable `.rego` files from a policy directory.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @returns Archive entries and the parsed manifest\n */\nfunction collectPolicyBundleArchiveEntries(dir: string): PolicyBundleArchiveContents {\n const manifest = readPolicyBundleManifest(dir);\n\n const regoFiles = fg\n .sync('**/*.rego', {\n cwd: dir,\n onlyFiles: true,\n dot: false,\n })\n .filter(isPublishableRegoFile);\n\n if (regoFiles.length === 0) {\n throw new Error('Policy bundle directory must contain at least one .rego policy file.');\n }\n\n return { entries: ['manifest.json', ...regoFiles.sort()], manifest };\n}\n\n/** Matches a Rego `package <path>` declaration. */\nconst PACKAGE_DECLARATION_PATTERN = /^\\s*package\\s+([A-Za-z_][\\w.]*)/m;\n\n/**\n * Normalizes an OPA manifest root to a dotted package prefix.\n *\n * Roots use `/` as the path separator (e.g. `policy_engine/transcend`); Rego\n * package paths use `.` (e.g. `policy_engine.transcend`).\n *\n * @param root - A manifest root string\n * @returns The root in dotted form\n */\nfunction normalizeRootToPackagePrefix(root: string): string {\n return root.replace(/\\//g, '.');\n}\n\n/**\n * Reads the Rego package path declared in a `.rego` file.\n *\n * @param filePath - Absolute path to the `.rego` file\n * @returns The dotted package path, or `undefined` if no `package` declaration\n */\nfunction readRegoPackagePath(filePath: string): string | undefined {\n const contents = fs.readFileSync(filePath, 'utf8');\n const match = PACKAGE_DECLARATION_PATTERN.exec(contents);\n return match?.[1];\n}\n\n/**\n * Verifies that every publishable `.rego` package is covered by a manifest root.\n *\n * A bundle whose `roots` do not cover its Rego packages will upload cleanly but\n * fail-closed at decide time — the customer only discovers the mismatch via\n * denied decisions. This surfaces the mismatch at upload with a clear message.\n *\n * @param dir - Absolute path to the policy bundle directory\n * @param regoFiles - Relative paths to publishable `.rego` files\n * @param roots - Manifest roots\n */\nfunction assertRootsCoverPackages(dir: string, regoFiles: string[], roots: string[]): void {\n const rootPrefixes = roots.map(normalizeRootToPackagePrefix);\n\n const uncovered: string[] = [];\n for (const relativeRego of regoFiles) {\n const pkg = readRegoPackagePath(path.join(dir, relativeRego));\n if (!pkg) {\n continue;\n }\n const covered = rootPrefixes.some((prefix) => pkg === prefix || pkg.startsWith(`${prefix}.`));\n if (!covered) {\n uncovered.push(\n ` - ${relativeRego} (package ${pkg}) is not covered by roots [${roots.join(', ')}]`,\n );\n }\n }\n\n if (uncovered.length > 0) {\n throw new Error(\n [\n 'manifest.json \"roots\" do not cover all Rego packages in the bundle; ' +\n 'uncovered packages will fail-closed at decide time. Either broaden \"roots\" or move the policy under a covered package:',\n ...uncovered,\n ].join('\\n'),\n );\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.json` +\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. `*_test.rego` files are local-only.\n const { code, stderr } = await runOPACapture(\n ['build', '--v0-compatible', '--ignore', '*_test.rego', '-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.json` and\n * one or more `.rego` files. This differs from `opa build` output, which embeds\n * `.manifest`, `data.json`, and other OPA bundle metadata that the server\n * rejects. Before packaging, the manifest is validated (shape + root coverage)\n * and the bundle is validated with `opa check` (strict Rego linting) and\n * `opa build` (full compilation) so failures surface client-side rather than\n * after upload.\n *\n * @param dir - Directory containing `manifest.json` 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, manifest } = collectPolicyBundleArchiveEntries(resolvedDir);\n const regoFiles = archiveEntries.filter((entry) => entry !== 'manifest.json');\n assertRootsCoverPackages(resolvedDir, regoFiles, manifest.roots);\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 '--v0-compatible',\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\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 fs from 'node:fs';\nimport 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 { buildExampleCommand } from '../../../lib/docgen/buildExamples.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport { logger } from '../../../logger.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 /** Directory containing Rego policy files */\n dir: string;\n /** Tenant-unique bundle name */\n 'bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** 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 */\nexport async function publish(\n this: LocalContext,\n {\n dir,\n 'bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n version,\n description,\n json,\n yes,\n debug = false,\n }: PublishCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n setPolicyEngineCliDebug(debug);\n\n const resolvedDir = path.resolve(dir);\n const versionLabel = version ?? defaultPolicyVersionLabel(bundleName);\n const client = buildPolicyEngineClient(transcendUrl, auth);\n\n let bundlePath: string | undefined;\n try {\n logger.info(colors.green(`Building policy bundle from ${resolvedDir}...`));\n bundlePath = await buildOpaBundleTarball(resolvedDir);\n\n const existingBundleId = await resolveBundleIdByName(client, bundleName);\n\n let responseBody: CreatePolicyBundleResponse | CreatePolicyBundleVersionResponse;\n\n if (existingBundleId) {\n logger.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 (!this.process.stdin.isTTY && !yes) {\n logger.error(\n colors.red(\n 'Cannot create a new bundle in a non-interactive environment; pass --yes to confirm.',\n ),\n );\n this.process.exit(1);\n return;\n }\n\n if (!yes) {\n logger.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 logger.info(colors.yellow('Publish cancelled.'));\n return;\n }\n }\n\n logger.info(colors.green(`Creating bundle \"${bundleName}\" and uploading first version...`));\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 logger.info(colors.green('Policy bundle version uploaded successfully.'));\n\n const activateCommand = buildExampleCommand<ActivateCommandFlags>(['policy', 'activate'], {\n version: responseBody.version.version,\n 'bundle-name': bundleName,\n });\n logger.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 && fs.existsSync(bundlePath)) {\n fs.unlinkSync(bundlePath);\n }\n }\n}\n"],"mappings":"8tBAqBA,SAAS,EAAsB,EAA+B,CAC5D,OAAO,EAAa,SAAS,QAAQ,EAAI,CAAC,EAAa,SAAS,aAAa,CAqB/E,SAAS,EAAyB,EAAmC,CACnE,IAAM,EAAe,EAAK,KAAK,EAAK,gBAAgB,CACpD,GAAI,CAAC,EAAG,WAAW,EAAa,CAC9B,MAAU,MAAM,6DAA6D,CAG/E,IAAM,EAAM,EAAG,aAAa,EAAc,OAAO,CAC7C,EACJ,GAAI,CACF,EAAS,KAAK,MAAM,EAAI,OACjB,EAAK,CACZ,MAAU,MACR,oCAAoC,aAAe,MAAQ,EAAI,QAAU,OAAO,EAAI,GACpF,CAAE,MAAO,EAAK,CACf,CAGH,GAAI,CAAC,GAAU,OAAO,GAAW,UAAY,MAAM,QAAQ,EAAO,CAChE,MAAU,MAAM,4CAA4C,CAG9D,IAAM,EAAS,EAA+B,MAC9C,GAAI,CAAC,MAAM,QAAQ,EAAM,EAAI,EAAM,SAAW,EAC5C,MAAU,MACR,yGACD,CAGH,GAAI,CAAC,EAAM,MAAO,GAAS,OAAO,GAAS,UAAY,EAAK,OAAS,EAAE,CACrE,MAAU,MAAM,+DAA+D,CAGjF,MAAO,CAAE,QAAO,CAiBlB,SAAS,EAAkC,EAA0C,CACnF,IAAM,EAAW,EAAyB,EAAI,CAExC,EAAYA,EACf,KAAK,YAAa,CACjB,IAAK,EACL,UAAW,GACX,IAAK,GACN,CAAC,CACD,OAAO,EAAsB,CAEhC,GAAI,EAAU,SAAW,EACvB,MAAU,MAAM,uEAAuE,CAGzF,MAAO,CAAE,QAAS,CAAC,gBAAiB,GAAG,EAAU,MAAM,CAAC,CAAE,WAAU,CAItE,MAAM,EAA8B,mCAWpC,SAAS,EAA6B,EAAsB,CAC1D,OAAO,EAAK,QAAQ,MAAO,IAAI,CASjC,SAAS,EAAoB,EAAsC,CACjE,IAAM,EAAW,EAAG,aAAa,EAAU,OAAO,CAElD,OADc,EAA4B,KAAK,EACnC,GAAG,GAcjB,SAAS,EAAyB,EAAa,EAAqB,EAAuB,CACzF,IAAM,EAAe,EAAM,IAAI,EAA6B,CAEtD,EAAsB,EAAE,CAC9B,IAAK,IAAM,KAAgB,EAAW,CACpC,IAAM,EAAM,EAAoB,EAAK,KAAK,EAAK,EAAa,CAAC,CACxD,IAGW,EAAa,KAAM,GAAW,IAAQ,GAAU,EAAI,WAAW,GAAG,EAAO,GAAG,CAChF,EACV,EAAU,KACR,OAAO,EAAa,YAAY,EAAI,6BAA6B,EAAM,KAAK,KAAK,CAAC,GACnF,EAIL,GAAI,EAAU,OAAS,EACrB,MAAU,MACR,CACE,6LAEA,GAAG,EACJ,CAAC,KAAK;EAAK,CACb,CAcL,eAAe,EAAqB,EAA4B,CAC9D,IAAM,EAAkB,EAAK,KAC3B,EAAG,QAAQ,CACX,iCAAiC,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,SACpF,CACD,GAAI,CAGF,GAAM,CAAE,OAAM,UAAW,MAAM,EAC7B,CAAC,QAAS,kBAAmB,WAAY,cAAe,KAAM,EAAiB,IAAI,CACnF,CAAE,IAAK,EAAK,CACb,CACD,GAAI,IAAS,EACX,MAAU,MAAM,EAAO,MAAM,EAAI,mCAAmC,IAAO,QAErE,CACJ,EAAG,WAAW,EAAgB,EAChC,EAAG,WAAW,EAAgB,EAWpC,SAAS,EAAY,EAAuB,CAC1C,GAAI,EAAQ,KACV,MAAO,GAAG,EAAM,IAElB,IAAM,EAAM,EAAQ,KACpB,GAAI,EAAM,KACR,MAAO,GAAG,EAAM,GAAM,EAAI,EAAI,QAAQ,EAAE,CAAG,EAAI,QAAQ,EAAE,CAAC,MAE5D,IAAM,EAAM,EAAM,KAClB,MAAO,GAAG,EAAM,GAAM,EAAI,EAAI,QAAQ,EAAE,CAAG,EAAI,QAAQ,EAAE,CAAC,MAiB5D,eAAsB,EAAsB,EAA8B,CACxE,GAAoB,CAEpB,IAAM,EAAc,EAAK,QAAQ,EAAI,CACrC,GAAI,CAAC,EAAG,WAAW,EAAY,EAAI,CAAC,EAAG,SAAS,EAAY,CAAC,aAAa,CACxE,MAAU,MAAM,0DAA0D,IAAc,CAM1F,GAAM,CAAE,QAAS,EAAgB,YAAa,EAAkC,EAAY,CAE5F,EAAyB,EADP,EAAe,OAAQ,GAAU,IAAU,gBACd,CAAE,EAAS,MAAM,CAGhE,GAAM,CAAE,KAAM,EAAW,OAAQ,GAAgB,MAAM,EAAc,CACnE,QACA,WACA,kBACA,EACD,CAAC,CACF,GAAI,IAAc,EAChB,MAAU,MAAM,EAAY,MAAM,EAAI,mCAAmC,IAAY,CAIvF,MAAM,EAAqB,EAAY,CAEvC,IAAM,EAAa,EAAK,KACtB,EAAG,QAAQ,CACX,2BAA2B,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,SAC9E,CAEK,EAAY,EAAU,MAAO,CAAC,OAAQ,EAAY,KAAM,EAAa,GAAG,EAAe,CAAE,CAC7F,IAAK,CAAE,GAAG,QAAQ,IAAK,iBAAkB,IAAK,CAC9C,SAAU,OACX,CAAC,CACF,GAAI,EAAU,SAAW,EACvB,MAAU,MACR,2CAA2C,EAAU,OAAO,MAAM,EAAI,eACvE,CAGH,IAAM,EAAkB,EAAG,aAAa,EAAW,CACnD,GAAI,EAAgB,WAAA,KAElB,MADA,EAAG,WAAW,EAAW,CACf,MACR,6BAA6B,EAAY,EAA4B,CAAC,sCACtD,EAAY,EAAgB,WAAW,CAAC,8DACM,EAAY,EAA8B,CAAC,GAC1G,CAGH,IAAM,EAAoB,EAAW,EAAgB,CACrD,GAAI,EAAkB,WAAA,MAEpB,MADA,EAAG,WAAW,EAAW,CACf,MACR,6BAA6B,EAAY,EAA8B,CAAC,wCACxD,EAAY,EAAkB,WAAW,CAAC,iBAC3D,CAGH,OAAO,EC3RT,SAAgB,EAA0B,EAAqD,CAC7F,IAAM,EAAc,EAAG,aAAa,EAAQ,WAAW,CACjD,EAAO,IAAI,SAajB,OAZA,EAAK,OACH,SACA,IAAI,KAAK,CAAC,EAAY,CAAE,CAAE,KAAM,mBAAoB,CAAC,CACrD,EAAK,SAAS,EAAQ,WAAW,CAClC,CACD,EAAK,OAAO,UAAW,EAAQ,QAAQ,CACnC,EAAQ,aACV,EAAK,OAAO,cAAe,EAAQ,YAAY,CAE7C,EAAQ,YACV,EAAK,OAAO,aAAc,EAAQ,WAAW,CAExC,EC9BT,SAAS,EAA6B,EAAoB,CACxD,OAAO,EAAK,aAAa,CAAC,MAAM,EAAG,GAAG,CAAC,QAAQ,QAAS,IAAI,CAU9D,SAAgB,EAA0B,EAAoB,EAAY,IAAI,KAAgB,CAC5F,MAAO,GAAG,EAAW,GAAG,EAA6B,EAAI,GCkC3D,eAAsB,EAEpB,CACE,MACA,cAAe,EACf,OACA,gBAAiB,EACjB,UACA,cACA,OACA,MACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,KAAK,CACtC,EAAwB,EAAM,CAE9B,IAAM,EAAc,EAAK,QAAQ,EAAI,CAC/B,EAAe,GAAW,EAA0B,EAAW,CAC/D,EAAS,EAAwB,EAAc,EAAK,CAEtD,EACJ,GAAI,CACF,EAAO,KAAK,EAAO,MAAM,+BAA+B,EAAY,KAAK,CAAC,CAC1E,EAAa,MAAM,EAAsB,EAAY,CAErD,IAAM,EAAmB,MAAM,EAAsB,EAAQ,EAAW,CAEpE,EAEJ,GAAI,EAAkB,CACpB,EAAO,KAAK,EAAO,MAAM,qCAAqC,EAAW,MAAM,CAAC,CAChF,IAAM,EAAO,EAA0B,CACrC,aACA,QAAS,EACT,cACD,CAAC,CACF,EAAe,MAAM,EACnB,EACG,KAAK,mCAAmC,EAAiB,WAAY,CAAE,KAAM,EAAM,CAAC,CACpF,MAAyC,CAC7C,KACI,CACL,GAAI,CAAC,KAAK,QAAQ,MAAM,OAAS,CAAC,EAAK,CACrC,EAAO,MACL,EAAO,IACL,sFACD,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,CACpB,OAGF,GAAI,CAAC,IACH,EAAO,KACL,EAAO,OAAO,2BAA2B,EAAW,iCAAiC,CACtF,CAIG,CAAC,MAHsB,EAAuB,CAChD,QAAS,2BAA2B,EAAW,6DAChD,CAAC,EACiB,CACjB,EAAO,KAAK,EAAO,OAAO,qBAAqB,CAAC,CAChD,OAIJ,EAAO,KAAK,EAAO,MAAM,oBAAoB,EAAW,kCAAkC,CAAC,CAC3F,IAAM,EAAa,EAA0B,CAC3C,aACA,QAAS,EACT,cACA,aACD,CAAC,CACF,EAAe,MAAM,EACnB,EACG,KAAK,kCAAmC,CACvC,KAAM,EACP,CAAC,CACD,MAAkC,CACtC,CAGH,EAAY,KAAK,QAAQ,OAAQ,CAC/B,OACA,KAAM,EACN,gBAAmB,EAAiC,EAAa,QAAQ,CAC1E,CAAC,CAEF,EAAO,KAAK,EAAO,MAAM,+CAA+C,CAAC,CAEzE,IAAM,EAAkB,EAA0C,CAAC,SAAU,WAAW,CAAE,CACxF,QAAS,EAAa,QAAQ,QAC9B,cAAe,EAChB,CAAC,CACF,EAAO,KACL,EAAO,OACL,+EAA+E,IAChF,CACF,QACO,CACJ,GAAc,EAAG,WAAW,EAAW,EACzC,EAAG,WAAW,EAAW"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./uploadPrivacyRequestsFromCsv-CsZ1_cGX.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";import{splitCsvToList as n}from"@transcend-io/utils";async function r({auth:r,file:i,transcendUrl:a,cacheFilepath:o,requestReceiptFolder:s,sombraAuth:c,concurrency:l,attributes:u,isTest:d,isSilent:f,skipSendingReceipt:p,emailIsVerified:m,skipFilterStep:h,dryRun:g,debug:_,defaultPhoneCountryCode:v}){t(this.process.exit),await e({cacheFilepath:o,requestReceiptFolder:s,file:i,auth:r,sombraAuth:c,concurrency:l,transcendUrl:a,defaultPhoneCountryCode:v,attributes:n(u),debug:_,skipFilterStep:h,isSilent:f,skipSendingReceipt:p,emailIsVerified:m,isTest:d,dryRun:g})}export{r as upload};
2
- //# sourceMappingURL=impl-B1Lux2OG2.mjs.map
1
+ import{t as e}from"./uploadPrivacyRequestsFromCsv-Ds3Qghge.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";import{splitCsvToList as n}from"@transcend-io/utils";async function r({auth:r,file:i,transcendUrl:a,cacheFilepath:o,requestReceiptFolder:s,sombraAuth:c,concurrency:l,attributes:u,isTest:d,isSilent:f,skipSendingReceipt:p,emailIsVerified:m,skipFilterStep:h,dryRun:g,debug:_,defaultPhoneCountryCode:v}){t(this.process.exit),await e({cacheFilepath:o,requestReceiptFolder:s,file:i,auth:r,sombraAuth:c,concurrency:l,transcendUrl:a,defaultPhoneCountryCode:v,attributes:n(u),debug:_,skipFilterStep:h,isSilent:f,skipSendingReceipt:p,emailIsVerified:m,isTest:d,dryRun:g})}export{r as upload};
2
+ //# sourceMappingURL=impl-8x-_ymRL2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-B1Lux2OG2.mjs","names":[],"sources":["../src/commands/request/upload/impl.ts"],"sourcesContent":["import { splitCsvToList } from '@transcend-io/utils';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { uploadPrivacyRequestsFromCsv } from '../../../lib/requests/index.js';\n\nexport interface UploadCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n cacheFilepath: string;\n requestReceiptFolder: string;\n sombraAuth?: string;\n concurrency: number;\n attributes: string;\n isTest: boolean;\n isSilent: boolean;\n skipSendingReceipt: boolean;\n emailIsVerified: boolean;\n skipFilterStep: boolean;\n dryRun: boolean;\n debug: boolean;\n defaultPhoneCountryCode: string;\n}\n\nexport async function upload(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n cacheFilepath,\n requestReceiptFolder,\n sombraAuth,\n concurrency,\n attributes,\n isTest,\n isSilent,\n skipSendingReceipt,\n emailIsVerified,\n skipFilterStep,\n dryRun,\n debug,\n defaultPhoneCountryCode,\n }: UploadCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await uploadPrivacyRequestsFromCsv({\n cacheFilepath,\n requestReceiptFolder,\n file,\n auth,\n sombraAuth,\n concurrency,\n transcendUrl,\n defaultPhoneCountryCode,\n attributes: splitCsvToList(attributes),\n debug,\n skipFilterStep,\n isSilent,\n skipSendingReceipt,\n emailIsVerified,\n isTest,\n dryRun,\n });\n}\n"],"mappings":"yKAyBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,gBACA,uBACA,aACA,cACA,aACA,SACA,WACA,qBACA,kBACA,iBACA,SACA,QACA,2BAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAA6B,CACjC,gBACA,uBACA,OACA,OACA,aACA,cACA,eACA,0BACA,WAAY,EAAe,EAAW,CACtC,QACA,iBACA,WACA,qBACA,kBACA,SACA,SACD,CAAC"}
1
+ {"version":3,"file":"impl-8x-_ymRL2.mjs","names":[],"sources":["../src/commands/request/upload/impl.ts"],"sourcesContent":["import { splitCsvToList } from '@transcend-io/utils';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { uploadPrivacyRequestsFromCsv } from '../../../lib/requests/index.js';\n\nexport interface UploadCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n cacheFilepath: string;\n requestReceiptFolder: string;\n sombraAuth?: string;\n concurrency: number;\n attributes: string;\n isTest: boolean;\n isSilent: boolean;\n skipSendingReceipt: boolean;\n emailIsVerified: boolean;\n skipFilterStep: boolean;\n dryRun: boolean;\n debug: boolean;\n defaultPhoneCountryCode: string;\n}\n\nexport async function upload(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n cacheFilepath,\n requestReceiptFolder,\n sombraAuth,\n concurrency,\n attributes,\n isTest,\n isSilent,\n skipSendingReceipt,\n emailIsVerified,\n skipFilterStep,\n dryRun,\n debug,\n defaultPhoneCountryCode,\n }: UploadCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await uploadPrivacyRequestsFromCsv({\n cacheFilepath,\n requestReceiptFolder,\n file,\n auth,\n sombraAuth,\n concurrency,\n transcendUrl,\n defaultPhoneCountryCode,\n attributes: splitCsvToList(attributes),\n debug,\n skipFilterStep,\n isSilent,\n skipSendingReceipt,\n emailIsVerified,\n isTest,\n dryRun,\n });\n}\n"],"mappings":"yKAyBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,gBACA,uBACA,aACA,cACA,aACA,SACA,WACA,qBACA,kBACA,iBACA,SACA,QACA,2BAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAA6B,CACjC,gBACA,uBACA,OACA,OACA,aACA,cACA,eACA,0BACA,WAAY,EAAe,EAAW,CACtC,QACA,iBACA,WACA,qBACA,kBACA,SACA,SACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./logger-Ckep4QXn.mjs";import{n as t}from"./buildXdiSyncEndpoint-CnuJDaXk.mjs";import{t as n}from"./validateTranscendAuth-DhzCBA3F.mjs";import{t as r}from"./done-input-validation-uqIgnJcw.mjs";import{writeFileSync as i}from"node:fs";import a from"colors";async function o({auth:o,xdiLocation:s,file:c,removeIpAddresses:l,domainBlockList:u,xdiAllowedCommands:d,transcendUrl:f}){r(this.process.exit);let{syncGroups:p,html:m}=await t(await n(o),{xdiLocation:s,transcendUrl:f,removeIpAddresses:l,domainBlockList:u.length>0?u:void 0,xdiAllowedCommands:d});e.info(a.green(`Successfully constructed sync endpoint for sync groups: ${JSON.stringify(p,null,2)}`)),i(c,m),e.info(a.green(`Wrote configuration to file "${c}"!`))}export{o as buildXdiSyncEndpoint};
2
- //# sourceMappingURL=impl-DkCsefy1.mjs.map
1
+ import{t as e}from"./logger-Ckep4QXn.mjs";import{n as t}from"./buildXdiSyncEndpoint-5L1O_yrs.mjs";import{t as n}from"./validateTranscendAuth-DhzCBA3F.mjs";import{t as r}from"./done-input-validation-uqIgnJcw.mjs";import{writeFileSync as i}from"node:fs";import a from"colors";async function o({auth:o,xdiLocation:s,file:c,removeIpAddresses:l,domainBlockList:u,xdiAllowedCommands:d,transcendUrl:f}){r(this.process.exit);let{syncGroups:p,html:m}=await t(await n(o),{xdiLocation:s,transcendUrl:f,removeIpAddresses:l,domainBlockList:u.length>0?u:void 0,xdiAllowedCommands:d});e.info(a.green(`Successfully constructed sync endpoint for sync groups: ${JSON.stringify(p,null,2)}`)),i(c,m),e.info(a.green(`Wrote configuration to file "${c}"!`))}export{o as buildXdiSyncEndpoint};
2
+ //# sourceMappingURL=impl-BAgai3CJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DkCsefy1.mjs","names":["buildXdiSyncEndpointHelper"],"sources":["../src/commands/consent/build-xdi-sync-endpoint/impl.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildXdiSyncEndpoint as buildXdiSyncEndpointHelper } from '../../../lib/consent-manager/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface BuildXdiSyncEndpointCommandFlags {\n auth: string;\n xdiLocation: string;\n file: string;\n removeIpAddresses: boolean;\n domainBlockList: string[];\n xdiAllowedCommands: string;\n transcendUrl: string;\n}\n\nexport async function buildXdiSyncEndpoint(\n this: LocalContext,\n {\n auth,\n xdiLocation,\n file,\n removeIpAddresses,\n domainBlockList,\n xdiAllowedCommands,\n transcendUrl,\n }: BuildXdiSyncEndpointCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Build the sync endpoint\n const { syncGroups, html } = await buildXdiSyncEndpointHelper(apiKeyOrList, {\n xdiLocation,\n transcendUrl,\n removeIpAddresses,\n domainBlockList: domainBlockList.length > 0 ? domainBlockList : undefined,\n xdiAllowedCommands,\n });\n\n // Log success\n logger.info(\n colors.green(\n `Successfully constructed sync endpoint for sync groups: ${JSON.stringify(\n syncGroups,\n null,\n 2,\n )}`,\n ),\n );\n\n // Write to disk\n writeFileSync(file, html);\n logger.info(colors.green(`Wrote configuration to file \"${file}\"!`));\n}\n"],"mappings":"kRAoBA,eAAsB,EAEpB,CACE,OACA,cACA,OACA,oBACA,kBACA,qBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAMtC,GAAM,CAAE,aAAY,QAAS,MAAMA,EAA2B,MAHnC,EAAsB,EAAK,CAGsB,CAC1E,cACA,eACA,oBACA,gBAAiB,EAAgB,OAAS,EAAI,EAAkB,IAAA,GAChE,qBACD,CAAC,CAGF,EAAO,KACL,EAAO,MACL,2DAA2D,KAAK,UAC9D,EACA,KACA,EACD,GACF,CACF,CAGD,EAAc,EAAM,EAAK,CACzB,EAAO,KAAK,EAAO,MAAM,gCAAgC,EAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"impl-BAgai3CJ.mjs","names":["buildXdiSyncEndpointHelper"],"sources":["../src/commands/consent/build-xdi-sync-endpoint/impl.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { buildXdiSyncEndpoint as buildXdiSyncEndpointHelper } from '../../../lib/consent-manager/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface BuildXdiSyncEndpointCommandFlags {\n auth: string;\n xdiLocation: string;\n file: string;\n removeIpAddresses: boolean;\n domainBlockList: string[];\n xdiAllowedCommands: string;\n transcendUrl: string;\n}\n\nexport async function buildXdiSyncEndpoint(\n this: LocalContext,\n {\n auth,\n xdiLocation,\n file,\n removeIpAddresses,\n domainBlockList,\n xdiAllowedCommands,\n transcendUrl,\n }: BuildXdiSyncEndpointCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Build the sync endpoint\n const { syncGroups, html } = await buildXdiSyncEndpointHelper(apiKeyOrList, {\n xdiLocation,\n transcendUrl,\n removeIpAddresses,\n domainBlockList: domainBlockList.length > 0 ? domainBlockList : undefined,\n xdiAllowedCommands,\n });\n\n // Log success\n logger.info(\n colors.green(\n `Successfully constructed sync endpoint for sync groups: ${JSON.stringify(\n syncGroups,\n null,\n 2,\n )}`,\n ),\n );\n\n // Write to disk\n writeFileSync(file, html);\n logger.info(colors.green(`Wrote configuration to file \"${file}\"!`));\n}\n"],"mappings":"kRAoBA,eAAsB,EAEpB,CACE,OACA,cACA,OACA,oBACA,kBACA,qBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAMtC,GAAM,CAAE,aAAY,QAAS,MAAMA,EAA2B,MAHnC,EAAsB,EAAK,CAGsB,CAC1E,cACA,eACA,oBACA,gBAAiB,EAAgB,OAAS,EAAI,EAAkB,IAAA,GAChE,qBACD,CAAC,CAGF,EAAO,KACL,EAAO,MACL,2DAA2D,KAAK,UAC9D,EACA,KACA,EACD,GACF,CACF,CAGD,EAAc,EAAM,EAAK,CACzB,EAAO,KAAK,EAAO,MAAM,gCAAgC,EAAK,IAAI,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./retryRequestDataSilos-DVvFRQMg.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,dataSiloId:r,actions:i,transcendUrl:a}){t(this.process.exit),await e({requestActions:i,transcendUrl:a,auth:n,dataSiloId:r})}export{n as retryRequestDataSilos};
2
- //# sourceMappingURL=impl-nKBSsApu2.mjs.map
1
+ import{t as e}from"./retryRequestDataSilos-yXYBxFz3.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,dataSiloId:r,actions:i,transcendUrl:a}){t(this.process.exit),await e({requestActions:i,transcendUrl:a,auth:n,dataSiloId:r})}export{n as retryRequestDataSilos};
2
+ //# sourceMappingURL=impl-BFisQPcN2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-nKBSsApu2.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.exit);\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,KAAK,CAEtC,MAAMA,EAA4B,CAChC,eAAgB,EAChB,eACA,OACA,aACD,CAAC"}
1
+ {"version":3,"file":"impl-BFisQPcN2.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.exit);\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,KAAK,CAEtC,MAAMA,EAA4B,CAChC,eAAgB,EAChB,eACA,OACA,aACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./readCsv-C84Jhrzx.mjs";import{t as n}from"./markRequestDataSiloIdsCompleted-BqV_17sv.mjs";import{t as r}from"./done-input-validation-uqIgnJcw.mjs";import i from"colors";import*as a from"io-ts";const o=a.type({"Request Id":a.string});async function s({auth:a,dataSiloId:s,file:c,transcendUrl:l}){r(this.process.exit),e.info(i.magenta(`Reading "${c}" from disk`)),await n({requestIds:t(c,o).map(e=>e[`Request Id`]),transcendUrl:l,auth:a,dataSiloId:s})}export{s as markRequestDataSilosCompleted};
2
- //# sourceMappingURL=impl-c9aM2mJw2.mjs.map
1
+ import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./readCsv-C84Jhrzx.mjs";import{t as n}from"./markRequestDataSiloIdsCompleted-z_-xldRm.mjs";import{t as r}from"./done-input-validation-uqIgnJcw.mjs";import i from"colors";import*as a from"io-ts";const o=a.type({"Request Id":a.string});async function s({auth:a,dataSiloId:s,file:c,transcendUrl:l}){r(this.process.exit),e.info(i.magenta(`Reading "${c}" from disk`)),await n({requestIds:t(c,o).map(e=>e[`Request Id`]),transcendUrl:l,auth:a,dataSiloId:s})}export{s as markRequestDataSilosCompleted};
2
+ //# sourceMappingURL=impl-BUitvEpH2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-c9aM2mJw2.mjs","names":[],"sources":["../src/commands/request/system/mark-request-data-silos-completed/impl.ts"],"sourcesContent":["import colors from 'colors';\nimport * as t from 'io-ts';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { markRequestDataSiloIdsCompleted } from '../../../../lib/cron/index.js';\nimport { readCsv } from '../../../../lib/requests/index.js';\nimport { logger } from '../../../../logger.js';\n\nconst RequestIdRow = t.type({\n 'Request Id': t.string,\n});\n\nexport interface MarkRequestDataSilosCompletedCommandFlags {\n auth: string;\n dataSiloId: string;\n file: string;\n transcendUrl: string;\n}\n\nexport async function markRequestDataSilosCompleted(\n this: LocalContext,\n { auth, dataSiloId, file, transcendUrl }: MarkRequestDataSilosCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, RequestIdRow);\n\n await markRequestDataSiloIdsCompleted({\n requestIds: activeResults.map((request) => request['Request Id']),\n transcendUrl,\n auth,\n dataSiloId,\n });\n}\n"],"mappings":"0PASA,MAAM,EAAe,EAAE,KAAK,CAC1B,aAAc,EAAE,OACjB,CAAC,CASF,eAAsB,EAEpB,CAAE,OAAM,aAAY,OAAM,gBACX,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAG1D,MAAM,EAAgC,CACpC,WAHoB,EAAQ,EAAM,EAGT,CAAC,IAAK,GAAY,EAAQ,cAAc,CACjE,eACA,OACA,aACD,CAAC"}
1
+ {"version":3,"file":"impl-BUitvEpH2.mjs","names":[],"sources":["../src/commands/request/system/mark-request-data-silos-completed/impl.ts"],"sourcesContent":["import colors from 'colors';\nimport * as t from 'io-ts';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { markRequestDataSiloIdsCompleted } from '../../../../lib/cron/index.js';\nimport { readCsv } from '../../../../lib/requests/index.js';\nimport { logger } from '../../../../logger.js';\n\nconst RequestIdRow = t.type({\n 'Request Id': t.string,\n});\n\nexport interface MarkRequestDataSilosCompletedCommandFlags {\n auth: string;\n dataSiloId: string;\n file: string;\n transcendUrl: string;\n}\n\nexport async function markRequestDataSilosCompleted(\n this: LocalContext,\n { auth, dataSiloId, file, transcendUrl }: MarkRequestDataSilosCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, RequestIdRow);\n\n await markRequestDataSiloIdsCompleted({\n requestIds: activeResults.map((request) => request['Request Id']),\n transcendUrl,\n auth,\n dataSiloId,\n });\n}\n"],"mappings":"0PASA,MAAM,EAAe,EAAE,KAAK,CAC1B,aAAc,EAAE,OACjB,CAAC,CASF,eAAsB,EAEpB,CAAE,OAAM,aAAY,OAAM,gBACX,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAG1D,MAAM,EAAgC,CACpC,WAHoB,EAAQ,EAAM,EAGT,CAAC,IAAK,GAAY,EAAQ,cAAc,CACjE,eACA,OACA,aACD,CAAC"}
@@ -1,4 +1,4 @@
1
- import{t as e}from"./constants-DLmuwAxY.mjs";import{t}from"./logger-Ckep4QXn.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{n as r}from"./constants-B44yUGaB.mjs";import i from"fast-glob";import a from"colors";import{buildTranscendGraphQLClient as o,fetchActiveSiloDiscoPlugin as s,uploadSiloDiscoveryResults as c}from"@transcend-io/sdk";import{stringify as l}from"query-string";async function u({scanPath:e,fileGlobs:n,ignoreDirs:r,config:a}){let{ignoreDirs:o,supportedFiles:s,scanFunction:c}=a,l=n===``?s:s.concat(n.split(`,`)),d=[...r.split(`,`),...o].filter(e=>e.length>0);try{let n=await i(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(`Scanning: ${n.length} files`);let r=n.map(e=>c(e)).flat().map(e=>e.softwareDevelopmentKits||[]).flat(),a=[...new Set(r.map(e=>e.name))];return t.info(`Found: ${a.length} unique dependencies`),a.map(t=>({name:t,resourceId:`${e}/**/${t}`,useStrictClassifier:!0}))}catch(e){throw Error(`Error scanning globs ${u} with error: ${e}`)}}async function d({scanPath:i,dataSiloId:d,auth:f,fileGlobs:p,ignoreDirs:m,transcendUrl:h}){n(this.process.exit);let g=o(h,f),_=await s(g,{logger:t,filterBy:{dataSiloId:d}}),v=r[_.dataSilo.type];v||(t.error(a.red(`This plugin "${_.dataSilo.type}" is not supported for offline silo discovery.`)),this.process.exit(1));let y=await u({scanPath:i,fileGlobs:p,ignoreDirs:m,config:v});await c(g,{pluginId:_.id,results:y,logger:t});let b=new URL(e);b.pathname=`/data-map/data-inventory/silo-discovery/triage`,b.search=l({filters:JSON.stringify({pluginIds:[_.id]})}),t.info(a.green(`Scan found ${y.length} potential data silos at ${i}! View at '${b.href}'
1
+ import{t as e}from"./constants-FvNUybuo.mjs";import{t}from"./logger-Ckep4QXn.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{n as r}from"./constants-B44yUGaB.mjs";import i from"fast-glob";import a from"colors";import{buildTranscendGraphQLClient as o,fetchActiveSiloDiscoPlugin as s,uploadSiloDiscoveryResults as c}from"@transcend-io/sdk";import{stringify as l}from"query-string";async function u({scanPath:e,fileGlobs:n,ignoreDirs:r,config:a}){let{ignoreDirs:o,supportedFiles:s,scanFunction:c}=a,l=n===``?s:s.concat(n.split(`,`)),d=[...r.split(`,`),...o].filter(e=>e.length>0);try{let n=await i(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(`Scanning: ${n.length} files`);let r=n.map(e=>c(e)).flat().map(e=>e.softwareDevelopmentKits||[]).flat(),a=[...new Set(r.map(e=>e.name))];return t.info(`Found: ${a.length} unique dependencies`),a.map(t=>({name:t,resourceId:`${e}/**/${t}`,useStrictClassifier:!0}))}catch(e){throw Error(`Error scanning globs ${u} with error: ${e}`)}}async function d({scanPath:i,dataSiloId:d,auth:f,fileGlobs:p,ignoreDirs:m,transcendUrl:h}){n(this.process.exit);let g=o(h,f),_=await s(g,{logger:t,filterBy:{dataSiloId:d}}),v=r[_.dataSilo.type];v||(t.error(a.red(`This plugin "${_.dataSilo.type}" is not supported for offline silo discovery.`)),this.process.exit(1));let y=await u({scanPath:i,fileGlobs:p,ignoreDirs:m,config:v});await c(g,{pluginId:_.id,results:y,logger:t});let b=new URL(e);b.pathname=`/data-map/data-inventory/silo-discovery/triage`,b.search=l({filters:JSON.stringify({pluginIds:[_.id]})}),t.info(a.green(`Scan found ${y.length} potential data silos at ${i}! View at '${b.href}'
2
2
 
3
3
  NOTE: it may take 2-3 minutes for scan results to appear in the UI.`))}export{d as discoverSilos};
4
- //# sourceMappingURL=impl-BeNVz2wB.mjs.map
4
+ //# sourceMappingURL=impl-BrsgkAas.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-BeNVz2wB.mjs","names":[],"sources":["../src/lib/code-scanning/findFilesToScan.ts","../src/commands/inventory/discover-silos/impl.ts"],"sourcesContent":["import fastGlob from 'fast-glob';\n\nimport { logger } from '../../logger.js';\nimport { CodeScanningConfig } from './types.js';\n\nexport interface SiloDiscoveryRawResults {\n /** The name of the potential data silo entry */\n name: string;\n /** A unique UUID (represents the same resource across different silo discovery runs) */\n resourceId: string;\n /** Any hosts associated with the entry */\n host?: string;\n /** Type of data silo */\n type?: string | undefined;\n}\n\n/**\n * Helper to scan for data silos in all package.json files that it can find in a directory\n *\n * @deprecated TODO: https://transcend.height.app/T-32325 - use code scanning instead\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n}: {\n /** Where to look for package.json files */\n scanPath: string;\n /** Globs to look for */\n fileGlobs: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs: string;\n /** Silo Discovery configuration */\n config: CodeScanningConfig;\n}): Promise<SiloDiscoveryRawResults[]> {\n const { ignoreDirs: IGNORE_DIRS, supportedFiles, scanFunction } = config;\n const globsToSupport =\n fileGlobs === '' ? supportedFiles : supportedFiles.concat(fileGlobs.split(','));\n const dirsToIgnore = [...ignoreDirs.split(','), ...IGNORE_DIRS].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${globsToSupport.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(`Scanning: ${filesToScan.length} files`);\n const allPackages = filesToScan.map((filePath: string) => scanFunction(filePath)).flat();\n const allSdks = allPackages\n .map((appPackage) => appPackage.softwareDevelopmentKits || [])\n .flat();\n const uniqueDeps = new Set(allSdks.map((sdk) => sdk.name));\n const deps = [...uniqueDeps];\n logger.info(`Found: ${deps.length} unique dependencies`);\n return deps.map((dep) => ({\n name: dep,\n resourceId: `${scanPath}/**/${dep}`,\n useStrictClassifier: true,\n }));\n } catch (error) {\n throw new Error(`Error scanning globs ${findFilesToScan} with error: ${error}`);\n }\n}\n","import {\n buildTranscendGraphQLClient,\n fetchActiveSiloDiscoPlugin,\n uploadSiloDiscoveryResults,\n} from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { stringify } from 'query-string';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findFilesToScan } from '../../../lib/code-scanning/findFilesToScan.js';\nimport { SILO_DISCOVERY_CONFIGS } from '../../../lib/code-scanning/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface DiscoverSilosCommandFlags {\n scanPath: string;\n dataSiloId: string;\n auth: string;\n fileGlobs: string;\n ignoreDirs: string;\n transcendUrl: string;\n}\n\nexport async function discoverSilos(\n this: LocalContext,\n { scanPath, dataSiloId, auth, fileGlobs, ignoreDirs, transcendUrl }: DiscoverSilosCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const plugin = await fetchActiveSiloDiscoPlugin(client, {\n logger,\n filterBy: { dataSiloId },\n });\n\n const config = SILO_DISCOVERY_CONFIGS[plugin.dataSilo.type];\n if (!config) {\n logger.error(\n colors.red(\n `This plugin \"${plugin.dataSilo.type}\" is not supported for offline silo discovery.`,\n ),\n );\n this.process.exit(1);\n }\n\n const results = await findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n });\n\n await uploadSiloDiscoveryResults(client, {\n pluginId: plugin.id,\n results,\n logger,\n });\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/data-map/data-inventory/silo-discovery/triage';\n newUrl.search = stringify({\n filters: JSON.stringify({ pluginIds: [plugin.id] }),\n });\n\n // Indicate success\n logger.info(\n colors.green(\n `Scan found ${results.length} potential data silos at ${scanPath}! ` +\n `View at '${newUrl.href}' ` +\n '\\n\\n NOTE: it may take 2-3 minutes for scan results to appear in the UI.',\n ),\n );\n}\n"],"mappings":"gZAuBA,eAAsB,EAAgB,CACpC,WACA,YACA,aACA,UAUqC,CACrC,GAAM,CAAE,WAAY,EAAa,iBAAgB,gBAAiB,EAC5D,EACJ,IAAc,GAAK,EAAiB,EAAe,OAAO,EAAU,MAAM,IAAI,CAAC,CAC3E,EAAe,CAAC,GAAG,EAAW,MAAM,IAAI,CAAE,GAAG,EAAY,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC/F,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KAAK,aAAa,EAAY,OAAO,QAAQ,CAEpD,IAAM,EADc,EAAY,IAAK,GAAqB,EAAa,EAAS,CAAC,CAAC,MACvD,CACxB,IAAK,GAAe,EAAW,yBAA2B,EAAE,CAAC,CAC7D,MAAM,CAEH,EAAO,CAAC,GAAG,IADM,IAAI,EAAQ,IAAK,GAAQ,EAAI,KAAK,CAC9B,CAAC,CAE5B,OADA,EAAO,KAAK,UAAU,EAAK,OAAO,sBAAsB,CACjD,EAAK,IAAK,IAAS,CACxB,KAAM,EACN,WAAY,GAAG,EAAS,MAAM,IAC9B,oBAAqB,GACtB,EAAE,OACI,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAgB,eAAe,IAAQ,ECtCnF,eAAsB,EAEpB,CAAE,WAAU,aAAY,OAAM,YAAW,aAAY,gBACtC,CACf,EAAoB,KAAK,QAAQ,KAAK,CAGtC,IAAM,EAAS,EAA4B,EAAc,EAAK,CAExD,EAAS,MAAM,EAA2B,EAAQ,CACtD,SACA,SAAU,CAAE,aAAY,CACzB,CAAC,CAEI,EAAS,EAAuB,EAAO,SAAS,MACjD,IACH,EAAO,MACL,EAAO,IACL,gBAAgB,EAAO,SAAS,KAAK,gDACtC,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,IAAM,EAAU,MAAM,EAAgB,CACpC,WACA,YACA,aACA,SACD,CAAC,CAEF,MAAM,EAA2B,EAAQ,CACvC,SAAU,EAAO,GACjB,UACA,SACD,CAAC,CAEF,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,iDAClB,EAAO,OAAS,EAAU,CACxB,QAAS,KAAK,UAAU,CAAE,UAAW,CAAC,EAAO,GAAG,CAAE,CAAC,CACpD,CAAC,CAGF,EAAO,KACL,EAAO,MACL,cAAc,EAAQ,OAAO,2BAA2B,EAAS,aACnD,EAAO,KAAK;;sEAE3B,CACF"}
1
+ {"version":3,"file":"impl-BrsgkAas.mjs","names":[],"sources":["../src/lib/code-scanning/findFilesToScan.ts","../src/commands/inventory/discover-silos/impl.ts"],"sourcesContent":["import fastGlob from 'fast-glob';\n\nimport { logger } from '../../logger.js';\nimport { CodeScanningConfig } from './types.js';\n\nexport interface SiloDiscoveryRawResults {\n /** The name of the potential data silo entry */\n name: string;\n /** A unique UUID (represents the same resource across different silo discovery runs) */\n resourceId: string;\n /** Any hosts associated with the entry */\n host?: string;\n /** Type of data silo */\n type?: string | undefined;\n}\n\n/**\n * Helper to scan for data silos in all package.json files that it can find in a directory\n *\n * @deprecated TODO: https://transcend.height.app/T-32325 - use code scanning instead\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n}: {\n /** Where to look for package.json files */\n scanPath: string;\n /** Globs to look for */\n fileGlobs: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs: string;\n /** Silo Discovery configuration */\n config: CodeScanningConfig;\n}): Promise<SiloDiscoveryRawResults[]> {\n const { ignoreDirs: IGNORE_DIRS, supportedFiles, scanFunction } = config;\n const globsToSupport =\n fileGlobs === '' ? supportedFiles : supportedFiles.concat(fileGlobs.split(','));\n const dirsToIgnore = [...ignoreDirs.split(','), ...IGNORE_DIRS].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${globsToSupport.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(`Scanning: ${filesToScan.length} files`);\n const allPackages = filesToScan.map((filePath: string) => scanFunction(filePath)).flat();\n const allSdks = allPackages\n .map((appPackage) => appPackage.softwareDevelopmentKits || [])\n .flat();\n const uniqueDeps = new Set(allSdks.map((sdk) => sdk.name));\n const deps = [...uniqueDeps];\n logger.info(`Found: ${deps.length} unique dependencies`);\n return deps.map((dep) => ({\n name: dep,\n resourceId: `${scanPath}/**/${dep}`,\n useStrictClassifier: true,\n }));\n } catch (error) {\n throw new Error(`Error scanning globs ${findFilesToScan} with error: ${error}`);\n }\n}\n","import {\n buildTranscendGraphQLClient,\n fetchActiveSiloDiscoPlugin,\n uploadSiloDiscoveryResults,\n} from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { stringify } from 'query-string';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findFilesToScan } from '../../../lib/code-scanning/findFilesToScan.js';\nimport { SILO_DISCOVERY_CONFIGS } from '../../../lib/code-scanning/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface DiscoverSilosCommandFlags {\n scanPath: string;\n dataSiloId: string;\n auth: string;\n fileGlobs: string;\n ignoreDirs: string;\n transcendUrl: string;\n}\n\nexport async function discoverSilos(\n this: LocalContext,\n { scanPath, dataSiloId, auth, fileGlobs, ignoreDirs, transcendUrl }: DiscoverSilosCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const plugin = await fetchActiveSiloDiscoPlugin(client, {\n logger,\n filterBy: { dataSiloId },\n });\n\n const config = SILO_DISCOVERY_CONFIGS[plugin.dataSilo.type];\n if (!config) {\n logger.error(\n colors.red(\n `This plugin \"${plugin.dataSilo.type}\" is not supported for offline silo discovery.`,\n ),\n );\n this.process.exit(1);\n }\n\n const results = await findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n });\n\n await uploadSiloDiscoveryResults(client, {\n pluginId: plugin.id,\n results,\n logger,\n });\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/data-map/data-inventory/silo-discovery/triage';\n newUrl.search = stringify({\n filters: JSON.stringify({ pluginIds: [plugin.id] }),\n });\n\n // Indicate success\n logger.info(\n colors.green(\n `Scan found ${results.length} potential data silos at ${scanPath}! ` +\n `View at '${newUrl.href}' ` +\n '\\n\\n NOTE: it may take 2-3 minutes for scan results to appear in the UI.',\n ),\n );\n}\n"],"mappings":"gZAuBA,eAAsB,EAAgB,CACpC,WACA,YACA,aACA,UAUqC,CACrC,GAAM,CAAE,WAAY,EAAa,iBAAgB,gBAAiB,EAC5D,EACJ,IAAc,GAAK,EAAiB,EAAe,OAAO,EAAU,MAAM,IAAI,CAAC,CAC3E,EAAe,CAAC,GAAG,EAAW,MAAM,IAAI,CAAE,GAAG,EAAY,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC/F,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KAAK,aAAa,EAAY,OAAO,QAAQ,CAEpD,IAAM,EADc,EAAY,IAAK,GAAqB,EAAa,EAAS,CAAC,CAAC,MACvD,CACxB,IAAK,GAAe,EAAW,yBAA2B,EAAE,CAAC,CAC7D,MAAM,CAEH,EAAO,CAAC,GAAG,IADM,IAAI,EAAQ,IAAK,GAAQ,EAAI,KAAK,CAC9B,CAAC,CAE5B,OADA,EAAO,KAAK,UAAU,EAAK,OAAO,sBAAsB,CACjD,EAAK,IAAK,IAAS,CACxB,KAAM,EACN,WAAY,GAAG,EAAS,MAAM,IAC9B,oBAAqB,GACtB,EAAE,OACI,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAgB,eAAe,IAAQ,ECtCnF,eAAsB,EAEpB,CAAE,WAAU,aAAY,OAAM,YAAW,aAAY,gBACtC,CACf,EAAoB,KAAK,QAAQ,KAAK,CAGtC,IAAM,EAAS,EAA4B,EAAc,EAAK,CAExD,EAAS,MAAM,EAA2B,EAAQ,CACtD,SACA,SAAU,CAAE,aAAY,CACzB,CAAC,CAEI,EAAS,EAAuB,EAAO,SAAS,MACjD,IACH,EAAO,MACL,EAAO,IACL,gBAAgB,EAAO,SAAS,KAAK,gDACtC,CACF,CACD,KAAK,QAAQ,KAAK,EAAE,EAGtB,IAAM,EAAU,MAAM,EAAgB,CACpC,WACA,YACA,aACA,SACD,CAAC,CAEF,MAAM,EAA2B,EAAQ,CACvC,SAAU,EAAO,GACjB,UACA,SACD,CAAC,CAEF,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,iDAClB,EAAO,OAAS,EAAU,CACxB,QAAS,KAAK,UAAU,CAAE,UAAW,CAAC,EAAO,GAAG,CAAE,CAAC,CACpD,CAAC,CAGF,EAAO,KACL,EAAO,MACL,cAAc,EAAQ,OAAO,2BAA2B,EAAS,aACnD,EAAO,KAAK;;sEAE3B,CACF"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./approvePrivacyRequests-Bat_tgMc.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,actions:r,origins:i,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l,transcendUrl:u,concurrency:d}){t(this.process.exit),await e({transcendUrl:u,requestActions:r,auth:n,requestOrigins:i,concurrency:d,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l})}export{n as approve};
2
- //# sourceMappingURL=impl-BXYhSvBQ2.mjs.map
1
+ import{t as e}from"./approvePrivacyRequests-OiTdKaRa.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,actions:r,origins:i,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l,transcendUrl:u,concurrency:d}){t(this.process.exit),await e({transcendUrl:u,requestActions:r,auth:n,requestOrigins:i,concurrency:d,silentModeBefore:a,createdAtBefore:o,createdAtAfter:s,updatedAtBefore:c,updatedAtAfter:l})}export{n as approve};
2
+ //# sourceMappingURL=impl-BtDPKaci2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-BXYhSvBQ2.mjs","names":[],"sources":["../src/commands/request/approve/impl.ts"],"sourcesContent":["import { RequestAction, RequestOrigin } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { approvePrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface ApproveCommandFlags {\n auth: string;\n actions: RequestAction[];\n origins?: RequestOrigin[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function approve(\n this: LocalContext,\n {\n auth,\n actions,\n origins,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n transcendUrl,\n concurrency,\n }: ApproveCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await approvePrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n requestOrigins: origins,\n concurrency,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"8GAmBA,eAAsB,EAEpB,CACE,OACA,UACA,UACA,mBACA,kBACA,iBACA,kBACA,iBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAuB,CAC3B,eACA,eAAgB,EAChB,OACA,eAAgB,EAChB,cACA,mBACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
1
+ {"version":3,"file":"impl-BtDPKaci2.mjs","names":[],"sources":["../src/commands/request/approve/impl.ts"],"sourcesContent":["import { RequestAction, RequestOrigin } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { approvePrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface ApproveCommandFlags {\n auth: string;\n actions: RequestAction[];\n origins?: RequestOrigin[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function approve(\n this: LocalContext,\n {\n auth,\n actions,\n origins,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n transcendUrl,\n concurrency,\n }: ApproveCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await approvePrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n requestOrigins: origins,\n concurrency,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n });\n}\n"],"mappings":"8GAmBA,eAAsB,EAEpB,CACE,OACA,UACA,UACA,mBACA,kBACA,iBACA,kBACA,iBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAuB,CAC3B,eACA,eAAgB,EAChB,OACA,eAAgB,EAChB,cACA,mBACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{r as e}from"./constants-DLmuwAxY.mjs";import{t}from"./logger-Ckep4QXn.mjs";import{r as n}from"./readTranscendYaml-dI3G3Og9.mjs";import{n as r,r as i,t as a}from"./parseVariablesFromString-RM3zV9Av.mjs";import{t as o}from"./validateTranscendAuth-DhzCBA3F.mjs";import{t as s}from"./listFiles-BPx3iDV6.mjs";import{t as c}from"./done-input-validation-uqIgnJcw.mjs";import{existsSync as l,lstatSync as u}from"node:fs";import{join as d}from"node:path";import f from"colors";import{buildTranscendGraphQLClient as p}from"@transcend-io/sdk";import{mapSeries as m}from"@transcend-io/utils";async function h({transcendUrl:e,auth:n,pageSize:r,publishToPrivacyCenter:a,contents:o,deleteExtraAttributeValues:s=!1,classifyService:c=!1}){let l=p(e,n);try{let e=await i(o,l,{pageSize:r,publishToPrivacyCenter:a,classifyService:c,deleteExtraAttributeValues:s,logger:t});return e.success||e.errors.forEach(({resource:e,item:n,message:r})=>{t.error(f.red(`Failed to sync ${e}${n?` "${n}"`:``}: ${r}`))}),e.success}catch(e){return t.error(f.red(`An unexpected error occurred syncing the schema: ${e.message}`)),!1}}async function g({file:i=`./transcend.yml`,transcendUrl:p,auth:g,variables:_,pageSize:v,publishToPrivacyCenter:y,classifyService:b,deleteExtraAttributeValues:x}){c(this.process.exit);let S=await o(g),C=a(_),w;if(w=Array.isArray(S)&&u(i).isDirectory()?s(i).map(e=>d(i,e)):i.split(`,`),w.length<1)throw Error(`No file specified!`);let T=w.map(e=>{l(e)?t.info(f.magenta(`Reading file "${e}"...`)):(t.error(f.red(`The file path does not exist on disk: ${e}. You can specify the filepath using --file=./examples/transcend.yml`)),this.process.exit(1));try{let r=n(e,C);return t.info(f.green(`Successfully read in "${e}"`)),{content:r,name:e.split(`/`).pop().replace(`.yml`,``)}}catch(e){t.error(f.red(`The shape of your yaml file is invalid with the following errors: ${e.message}`)),this.process.exit(1)}});if(typeof S==`string`){let[n,...i]=T.map(({content:e})=>e);await h({transcendUrl:p,auth:S,contents:r(n,...i),publishToPrivacyCenter:y,deleteExtraAttributeValues:x,pageSize:v,classifyService:!!b})||(t.info(f.red(`Sync encountered errors. View output above for more information, or check out ${e}`)),this.process.exit(1))}else{if(T.length!==1&&T.length!==S.length)throw Error(`Expected list of yml files to be equal to the list of API keys.Got ${T.length} YML file${T.length===1?``:`s`} and ${S.length} API key${S.length===1?``:`s`}`);let n=[];await m(S,async(e,r)=>{let i=`[${r+1}/${S.length}][${e.organizationName}] `;t.info(f.magenta(`~~~\n\n${i}Attempting to push configuration...\n\n~~~`));let a=T.length===1?T[0].content:T.find(t=>t.name===e.organizationName)?.content;if(!a){t.error(f.red(`${i}Failed to find transcend.yml file for organization: "${e.organizationName}".`)),n.push(e.organizationName);return}await h({transcendUrl:p,auth:e.apiKey,contents:a,pageSize:v,publishToPrivacyCenter:y,deleteExtraAttributeValues:x,classifyService:b})?t.info(f.green(`${i}Successfully pushed configuration!`)):(t.error(f.red(`${i}Failed to sync configuration.`)),n.push(e.organizationName))}),n.length>0&&(t.info(f.red(`Sync encountered errors for "${n.join(`,`)}". View output above for more information, or check out ${e}`)),this.process.exit(1))}t.info(f.green(`Successfully synced yaml file to Transcend! View at ${e}`))}export{g as push};
2
- //# sourceMappingURL=impl-McLWRGru.mjs.map
1
+ import{r as e}from"./constants-FvNUybuo.mjs";import{t}from"./logger-Ckep4QXn.mjs";import{r as n}from"./readTranscendYaml-dI3G3Og9.mjs";import{n as r,r as i,t as a}from"./parseVariablesFromString-RM3zV9Av.mjs";import{t as o}from"./validateTranscendAuth-DhzCBA3F.mjs";import{t as s}from"./listFiles-BPx3iDV6.mjs";import{t as c}from"./done-input-validation-uqIgnJcw.mjs";import{existsSync as l,lstatSync as u}from"node:fs";import{join as d}from"node:path";import f from"colors";import{buildTranscendGraphQLClient as p}from"@transcend-io/sdk";import{mapSeries as m}from"@transcend-io/utils";async function h({transcendUrl:e,auth:n,pageSize:r,publishToPrivacyCenter:a,contents:o,deleteExtraAttributeValues:s=!1,classifyService:c=!1}){let l=p(e,n);try{let e=await i(o,l,{pageSize:r,publishToPrivacyCenter:a,classifyService:c,deleteExtraAttributeValues:s,logger:t});return e.success||e.errors.forEach(({resource:e,item:n,message:r})=>{t.error(f.red(`Failed to sync ${e}${n?` "${n}"`:``}: ${r}`))}),e.success}catch(e){return t.error(f.red(`An unexpected error occurred syncing the schema: ${e.message}`)),!1}}async function g({file:i=`./transcend.yml`,transcendUrl:p,auth:g,variables:_,pageSize:v,publishToPrivacyCenter:y,classifyService:b,deleteExtraAttributeValues:x}){c(this.process.exit);let S=await o(g),C=a(_),w;if(w=Array.isArray(S)&&u(i).isDirectory()?s(i).map(e=>d(i,e)):i.split(`,`),w.length<1)throw Error(`No file specified!`);let T=w.map(e=>{l(e)?t.info(f.magenta(`Reading file "${e}"...`)):(t.error(f.red(`The file path does not exist on disk: ${e}. You can specify the filepath using --file=./examples/transcend.yml`)),this.process.exit(1));try{let r=n(e,C);return t.info(f.green(`Successfully read in "${e}"`)),{content:r,name:e.split(`/`).pop().replace(`.yml`,``)}}catch(e){t.error(f.red(`The shape of your yaml file is invalid with the following errors: ${e.message}`)),this.process.exit(1)}});if(typeof S==`string`){let[n,...i]=T.map(({content:e})=>e);await h({transcendUrl:p,auth:S,contents:r(n,...i),publishToPrivacyCenter:y,deleteExtraAttributeValues:x,pageSize:v,classifyService:!!b})||(t.info(f.red(`Sync encountered errors. View output above for more information, or check out ${e}`)),this.process.exit(1))}else{if(T.length!==1&&T.length!==S.length)throw Error(`Expected list of yml files to be equal to the list of API keys.Got ${T.length} YML file${T.length===1?``:`s`} and ${S.length} API key${S.length===1?``:`s`}`);let n=[];await m(S,async(e,r)=>{let i=`[${r+1}/${S.length}][${e.organizationName}] `;t.info(f.magenta(`~~~\n\n${i}Attempting to push configuration...\n\n~~~`));let a=T.length===1?T[0].content:T.find(t=>t.name===e.organizationName)?.content;if(!a){t.error(f.red(`${i}Failed to find transcend.yml file for organization: "${e.organizationName}".`)),n.push(e.organizationName);return}await h({transcendUrl:p,auth:e.apiKey,contents:a,pageSize:v,publishToPrivacyCenter:y,deleteExtraAttributeValues:x,classifyService:b})?t.info(f.green(`${i}Successfully pushed configuration!`)):(t.error(f.red(`${i}Failed to sync configuration.`)),n.push(e.organizationName))}),n.length>0&&(t.info(f.red(`Sync encountered errors for "${n.join(`,`)}". View output above for more information, or check out ${e}`)),this.process.exit(1))}t.info(f.green(`Successfully synced yaml file to Transcend! View at ${e}`))}export{g as push};
2
+ //# sourceMappingURL=impl-C2H6aCBJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-McLWRGru.mjs","names":[],"sources":["../src/commands/inventory/push/impl.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { TranscendInput } from '../../../codecs.js';\nimport { ADMIN_DASH_INTEGRATIONS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth, listFiles } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { syncConfigurationToTranscend } from '../../../lib/graphql/index.js';\nimport { parseVariablesFromString } from '../../../lib/helpers/parseVariablesFromString.js';\nimport { mergeTranscendInputs } from '../../../lib/mergeTranscendInputs.js';\nimport { readTranscendYaml } from '../../../lib/readTranscendYaml.js';\nimport { logger } from '../../../logger.js';\n\n/**\n * Sync configuration to Transcend\n *\n * @param options - Options\n * @returns True if synced successfully, false if error occurs\n */\nasync function syncConfiguration({\n transcendUrl,\n auth,\n pageSize,\n publishToPrivacyCenter,\n contents,\n deleteExtraAttributeValues = false,\n classifyService = false,\n}: {\n /** Transcend YAML */\n contents: TranscendInput;\n /** Transcend URL */\n transcendUrl: string;\n /** API key */\n auth: string;\n /** Page size */\n pageSize: number;\n /** Skip privacy center publish step */\n publishToPrivacyCenter: boolean;\n /** classify data flow service if missing */\n classifyService?: boolean;\n /** Delete attributes when syncing */\n deleteExtraAttributeValues?: boolean;\n}): Promise<boolean> {\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Sync to Transcend\n try {\n const result = await syncConfigurationToTranscend(contents, client, {\n pageSize,\n publishToPrivacyCenter,\n classifyService,\n deleteExtraAttributeValues,\n logger,\n });\n if (!result.success) {\n result.errors.forEach(({ resource, item, message }) => {\n logger.error(\n colors.red(`Failed to sync ${resource}${item ? ` \"${item}\"` : ''}: ${message}`),\n );\n });\n }\n return result.success;\n } catch (err) {\n logger.error(colors.red(`An unexpected error occurred syncing the schema: ${err.message}`));\n return false;\n }\n}\n\nexport interface PushCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n pageSize: number;\n variables: string;\n publishToPrivacyCenter: boolean;\n classifyService: boolean;\n deleteExtraAttributeValues: boolean;\n}\n\nexport async function push(\n this: LocalContext,\n {\n file = './transcend.yml',\n transcendUrl,\n auth,\n variables,\n pageSize,\n publishToPrivacyCenter,\n classifyService,\n deleteExtraAttributeValues,\n }: PushCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Parse out the variables\n const vars = parseVariablesFromString(variables);\n\n // check if we are being passed a list of API keys and a list of files\n let fileList: string[];\n if (Array.isArray(apiKeyOrList) && lstatSync(file).isDirectory()) {\n fileList = listFiles(file).map((filePath) => join(file, filePath));\n } else {\n fileList = file.split(',');\n }\n\n // Ensure at least one file is parsed\n if (fileList.length < 1) {\n throw new Error('No file specified!');\n }\n\n // eslint-disable-next-line array-callback-return,consistent-return\n const transcendInputs = fileList.map((filePath) => {\n // Ensure yaml file exists on disk\n if (!existsSync(filePath)) {\n logger.error(\n colors.red(\n `The file path does not exist on disk: ${filePath}. You can specify the filepath using --file=./examples/transcend.yml`,\n ),\n );\n this.process.exit(1);\n } else {\n logger.info(colors.magenta(`Reading file \"${filePath}\"...`));\n }\n\n try {\n // Read in the yaml file and validate it's shape\n const newContents = readTranscendYaml(filePath, vars);\n logger.info(colors.green(`Successfully read in \"${filePath}\"`));\n return {\n content: newContents,\n name: filePath.split('/').pop()!.replace('.yml', ''),\n };\n } catch (err) {\n logger.error(\n colors.red(\n `The shape of your yaml file is invalid with the following errors: ${err.message}`,\n ),\n );\n this.process.exit(1);\n }\n });\n\n // process a single API key\n if (typeof apiKeyOrList === 'string') {\n // if passed multiple inputs, merge them together\n const [base, ...rest] = transcendInputs.map(({ content }) => content);\n const contents = mergeTranscendInputs(base, ...rest);\n\n // sync the configuration\n const success = await syncConfiguration({\n transcendUrl,\n auth: apiKeyOrList,\n contents,\n publishToPrivacyCenter,\n deleteExtraAttributeValues,\n pageSize,\n classifyService: !!classifyService,\n });\n\n // exist with error code\n if (!success) {\n logger.info(\n colors.red(\n `Sync encountered errors. View output above for more information, or check out ${ADMIN_DASH_INTEGRATIONS}`,\n ),\n );\n\n this.process.exit(1);\n }\n } else {\n // if passed multiple inputs, expect them to be one per instance\n if (transcendInputs.length !== 1 && transcendInputs.length !== apiKeyOrList.length) {\n throw new Error(\n 'Expected list of yml files to be equal to the list of API keys.' +\n `Got ${transcendInputs.length} YML file${\n transcendInputs.length === 1 ? '' : 's'\n } and ${apiKeyOrList.length} API key${apiKeyOrList.length === 1 ? '' : 's'}`,\n );\n }\n\n const encounteredErrors: string[] = [];\n await mapSeries(apiKeyOrList, async (apiKey, ind) => {\n const prefix = `[${ind + 1}/${apiKeyOrList.length}][${apiKey.organizationName}] `;\n logger.info(colors.magenta(`~~~\\n\\n${prefix}Attempting to push configuration...\\n\\n~~~`));\n\n // use the merged contents if 1 yml passed, else use the contents that map to that organization\n const useContents =\n transcendInputs.length === 1\n ? transcendInputs[0].content\n : transcendInputs.find((input) => input.name === apiKey.organizationName)?.content;\n\n // Throw error if cannot find a yml file matching that organization name\n if (!useContents) {\n logger.error(\n colors.red(\n `${prefix}Failed to find transcend.yml file for organization: \"${apiKey.organizationName}\".`,\n ),\n );\n encounteredErrors.push(apiKey.organizationName);\n return;\n }\n\n const success = await syncConfiguration({\n transcendUrl,\n auth: apiKey.apiKey,\n contents: useContents,\n pageSize,\n publishToPrivacyCenter,\n deleteExtraAttributeValues,\n classifyService,\n });\n\n if (success) {\n logger.info(colors.green(`${prefix}Successfully pushed configuration!`));\n } else {\n logger.error(colors.red(`${prefix}Failed to sync configuration.`));\n encounteredErrors.push(apiKey.organizationName);\n }\n });\n\n if (encounteredErrors.length > 0) {\n 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 // Indicate success\n logger.info(\n colors.green(`Successfully synced yaml file to Transcend! View at ${ADMIN_DASH_INTEGRATIONS}`),\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"impl-C2H6aCBJ.mjs","names":[],"sources":["../src/commands/inventory/push/impl.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { TranscendInput } from '../../../codecs.js';\nimport { ADMIN_DASH_INTEGRATIONS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { validateTranscendAuth, listFiles } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { syncConfigurationToTranscend } from '../../../lib/graphql/index.js';\nimport { parseVariablesFromString } from '../../../lib/helpers/parseVariablesFromString.js';\nimport { mergeTranscendInputs } from '../../../lib/mergeTranscendInputs.js';\nimport { readTranscendYaml } from '../../../lib/readTranscendYaml.js';\nimport { logger } from '../../../logger.js';\n\n/**\n * Sync configuration to Transcend\n *\n * @param options - Options\n * @returns True if synced successfully, false if error occurs\n */\nasync function syncConfiguration({\n transcendUrl,\n auth,\n pageSize,\n publishToPrivacyCenter,\n contents,\n deleteExtraAttributeValues = false,\n classifyService = false,\n}: {\n /** Transcend YAML */\n contents: TranscendInput;\n /** Transcend URL */\n transcendUrl: string;\n /** API key */\n auth: string;\n /** Page size */\n pageSize: number;\n /** Skip privacy center publish step */\n publishToPrivacyCenter: boolean;\n /** classify data flow service if missing */\n classifyService?: boolean;\n /** Delete attributes when syncing */\n deleteExtraAttributeValues?: boolean;\n}): Promise<boolean> {\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Sync to Transcend\n try {\n const result = await syncConfigurationToTranscend(contents, client, {\n pageSize,\n publishToPrivacyCenter,\n classifyService,\n deleteExtraAttributeValues,\n logger,\n });\n if (!result.success) {\n result.errors.forEach(({ resource, item, message }) => {\n logger.error(\n colors.red(`Failed to sync ${resource}${item ? ` \"${item}\"` : ''}: ${message}`),\n );\n });\n }\n return result.success;\n } catch (err) {\n logger.error(colors.red(`An unexpected error occurred syncing the schema: ${err.message}`));\n return false;\n }\n}\n\nexport interface PushCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n pageSize: number;\n variables: string;\n publishToPrivacyCenter: boolean;\n classifyService: boolean;\n deleteExtraAttributeValues: boolean;\n}\n\nexport async function push(\n this: LocalContext,\n {\n file = './transcend.yml',\n transcendUrl,\n auth,\n variables,\n pageSize,\n publishToPrivacyCenter,\n classifyService,\n deleteExtraAttributeValues,\n }: PushCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Parse out the variables\n const vars = parseVariablesFromString(variables);\n\n // check if we are being passed a list of API keys and a list of files\n let fileList: string[];\n if (Array.isArray(apiKeyOrList) && lstatSync(file).isDirectory()) {\n fileList = listFiles(file).map((filePath) => join(file, filePath));\n } else {\n fileList = file.split(',');\n }\n\n // Ensure at least one file is parsed\n if (fileList.length < 1) {\n throw new Error('No file specified!');\n }\n\n // eslint-disable-next-line array-callback-return,consistent-return\n const transcendInputs = fileList.map((filePath) => {\n // Ensure yaml file exists on disk\n if (!existsSync(filePath)) {\n logger.error(\n colors.red(\n `The file path does not exist on disk: ${filePath}. You can specify the filepath using --file=./examples/transcend.yml`,\n ),\n );\n this.process.exit(1);\n } else {\n logger.info(colors.magenta(`Reading file \"${filePath}\"...`));\n }\n\n try {\n // Read in the yaml file and validate it's shape\n const newContents = readTranscendYaml(filePath, vars);\n logger.info(colors.green(`Successfully read in \"${filePath}\"`));\n return {\n content: newContents,\n name: filePath.split('/').pop()!.replace('.yml', ''),\n };\n } catch (err) {\n logger.error(\n colors.red(\n `The shape of your yaml file is invalid with the following errors: ${err.message}`,\n ),\n );\n this.process.exit(1);\n }\n });\n\n // process a single API key\n if (typeof apiKeyOrList === 'string') {\n // if passed multiple inputs, merge them together\n const [base, ...rest] = transcendInputs.map(({ content }) => content);\n const contents = mergeTranscendInputs(base, ...rest);\n\n // sync the configuration\n const success = await syncConfiguration({\n transcendUrl,\n auth: apiKeyOrList,\n contents,\n publishToPrivacyCenter,\n deleteExtraAttributeValues,\n pageSize,\n classifyService: !!classifyService,\n });\n\n // exist with error code\n if (!success) {\n logger.info(\n colors.red(\n `Sync encountered errors. View output above for more information, or check out ${ADMIN_DASH_INTEGRATIONS}`,\n ),\n );\n\n this.process.exit(1);\n }\n } else {\n // if passed multiple inputs, expect them to be one per instance\n if (transcendInputs.length !== 1 && transcendInputs.length !== apiKeyOrList.length) {\n throw new Error(\n 'Expected list of yml files to be equal to the list of API keys.' +\n `Got ${transcendInputs.length} YML file${\n transcendInputs.length === 1 ? '' : 's'\n } and ${apiKeyOrList.length} API key${apiKeyOrList.length === 1 ? '' : 's'}`,\n );\n }\n\n const encounteredErrors: string[] = [];\n await mapSeries(apiKeyOrList, async (apiKey, ind) => {\n const prefix = `[${ind + 1}/${apiKeyOrList.length}][${apiKey.organizationName}] `;\n logger.info(colors.magenta(`~~~\\n\\n${prefix}Attempting to push configuration...\\n\\n~~~`));\n\n // use the merged contents if 1 yml passed, else use the contents that map to that organization\n const useContents =\n transcendInputs.length === 1\n ? transcendInputs[0].content\n : transcendInputs.find((input) => input.name === apiKey.organizationName)?.content;\n\n // Throw error if cannot find a yml file matching that organization name\n if (!useContents) {\n logger.error(\n colors.red(\n `${prefix}Failed to find transcend.yml file for organization: \"${apiKey.organizationName}\".`,\n ),\n );\n encounteredErrors.push(apiKey.organizationName);\n return;\n }\n\n const success = await syncConfiguration({\n transcendUrl,\n auth: apiKey.apiKey,\n contents: useContents,\n pageSize,\n publishToPrivacyCenter,\n deleteExtraAttributeValues,\n classifyService,\n });\n\n if (success) {\n logger.info(colors.green(`${prefix}Successfully pushed configuration!`));\n } else {\n logger.error(colors.red(`${prefix}Failed to sync configuration.`));\n encounteredErrors.push(apiKey.organizationName);\n }\n });\n\n if (encounteredErrors.length > 0) {\n 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 // Indicate success\n logger.info(\n colors.green(`Successfully synced yaml file to Transcend! View at ${ADMIN_DASH_INTEGRATIONS}`),\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./pullManualEnrichmentIdentifiersToCsv-DF9RJNPy.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,transcendUrl:r,file:i,concurrency:a,actions:o,sombraAuth:s}){t(this.process.exit),await e({file:i,transcendUrl:r,concurrency:a,requestActions:o,auth:n,sombraAuth:s})}export{n as pullIdentifiers};
2
- //# sourceMappingURL=impl-DlGUg4Nr2.mjs.map
1
+ import{t as e}from"./pullManualEnrichmentIdentifiersToCsv-xU8OC8OY.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,transcendUrl:r,file:i,concurrency:a,actions:o,sombraAuth:s}){t(this.process.exit),await e({file:i,transcendUrl:r,concurrency:a,requestActions:o,auth:n,sombraAuth:s})}export{n as pullIdentifiers};
2
+ //# sourceMappingURL=impl-C6rkmAmP2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DlGUg4Nr2.mjs","names":[],"sources":["../src/commands/request/preflight/pull-identifiers/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pullManualEnrichmentIdentifiersToCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n auth: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n actions?: RequestAction[];\n concurrency: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n { auth, transcendUrl, file, concurrency, actions, sombraAuth }: PullIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pullManualEnrichmentIdentifiersToCsv({\n file,\n transcendUrl,\n concurrency,\n requestActions: actions,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"4HAeA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,cAAa,UAAS,cACnC,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAqC,CACzC,OACA,eACA,cACA,eAAgB,EAChB,OACA,aACD,CAAC"}
1
+ {"version":3,"file":"impl-C6rkmAmP2.mjs","names":[],"sources":["../src/commands/request/preflight/pull-identifiers/impl.ts"],"sourcesContent":["import type { RequestAction } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pullManualEnrichmentIdentifiersToCsv } from '../../../../lib/manual-enrichment/index.js';\n\nexport interface PullIdentifiersCommandFlags {\n auth: string;\n sombraAuth?: string;\n transcendUrl: string;\n file: string;\n actions?: RequestAction[];\n concurrency: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n { auth, transcendUrl, file, concurrency, actions, sombraAuth }: PullIdentifiersCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await pullManualEnrichmentIdentifiersToCsv({\n file,\n transcendUrl,\n concurrency,\n requestActions: actions,\n auth,\n sombraAuth,\n });\n}\n"],"mappings":"4HAeA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,cAAa,UAAS,cACnC,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAM,EAAqC,CACzC,OACA,eACA,cACA,eAAgB,EAChB,OACA,aACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./notifyPrivacyRequestsAdditionalTime-g9HqfNPC.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,transcendUrl:r,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s,actions:c,daysLeft:l,days:u,requestIds:d,emailTemplate:f,concurrency:p}){t(this.process.exit),await e({transcendUrl:r,requestActions:c,auth:n,emailTemplate:f,days:u,daysLeft:l,requestIds:d,concurrency:p,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s})}export{n as notifyAdditionalTime};
2
- //# sourceMappingURL=impl-D101FbzY.mjs.map
1
+ import{t as e}from"./notifyPrivacyRequestsAdditionalTime-Rs4HemLL.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,transcendUrl:r,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s,actions:c,daysLeft:l,days:u,requestIds:d,emailTemplate:f,concurrency:p}){t(this.process.exit),await e({transcendUrl:r,requestActions:c,auth:n,emailTemplate:f,days:u,daysLeft:l,requestIds:d,concurrency:p,createdAtBefore:i,createdAtAfter:a,updatedAtBefore:o,updatedAtAfter:s})}export{n as notifyAdditionalTime};
2
+ //# sourceMappingURL=impl-CE4PMco7.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-D101FbzY.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.exit);\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,KAAK,CAEtC,MAAM,EAAoC,CACxC,eACA,eAAgB,EAChB,OACA,gBACA,OACA,WACA,aACA,cACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
1
+ {"version":3,"file":"impl-CE4PMco7.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.exit);\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,KAAK,CAEtC,MAAM,EAAoC,CACxC,eACA,eAAgB,EAChB,OACA,gBACA,OACA,WACA,aACA,cACA,kBACA,iBACA,kBACA,iBACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./skipPreflightJobs-BnsBW32R.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,transcendUrl:r,enricherIds:i}){t(this.process.exit),await e({transcendUrl:r,auth:n,enricherIds:i})}export{n as skipPreflightJobs};
2
- //# sourceMappingURL=impl-ciYh2pmH2.mjs.map
1
+ import{t as e}from"./skipPreflightJobs-BVlPUC_C.mjs";import{t}from"./done-input-validation-uqIgnJcw.mjs";async function n({auth:n,transcendUrl:r,enricherIds:i}){t(this.process.exit),await e({transcendUrl:r,auth:n,enricherIds:i})}export{n as skipPreflightJobs};
2
+ //# sourceMappingURL=impl-CG_H2ynt2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-ciYh2pmH2.mjs","names":["skipPreflightJobsHelper"],"sources":["../src/commands/request/skip-preflight-jobs/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { skipPreflightJobs as skipPreflightJobsHelper } from '../../../lib/requests/index.js';\n\nexport interface SkipPreflightJobsCommandFlags {\n auth: string;\n enricherIds: string[];\n transcendUrl: string;\n}\n\nexport async function skipPreflightJobs(\n this: LocalContext,\n { auth, transcendUrl, enricherIds }: SkipPreflightJobsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await skipPreflightJobsHelper({\n transcendUrl,\n auth,\n enricherIds,\n });\n}\n"],"mappings":"yGAUA,eAAsB,EAEpB,CAAE,OAAM,eAAc,eACP,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAMA,EAAwB,CAC5B,eACA,OACA,cACD,CAAC"}
1
+ {"version":3,"file":"impl-CG_H2ynt2.mjs","names":["skipPreflightJobsHelper"],"sources":["../src/commands/request/skip-preflight-jobs/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { skipPreflightJobs as skipPreflightJobsHelper } from '../../../lib/requests/index.js';\n\nexport interface SkipPreflightJobsCommandFlags {\n auth: string;\n enricherIds: string[];\n transcendUrl: string;\n}\n\nexport async function skipPreflightJobs(\n this: LocalContext,\n { auth, transcendUrl, enricherIds }: SkipPreflightJobsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n await skipPreflightJobsHelper({\n transcendUrl,\n auth,\n enricherIds,\n });\n}\n"],"mappings":"yGAUA,eAAsB,EAEpB,CAAE,OAAM,eAAc,eACP,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,MAAMA,EAAwB,CAC5B,eACA,OACA,cACD,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./collectParquetFilesOrExit-DyZISY9X.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{a as r,i,n as a,r as o,t as s}from"./createExtraKeyHandler-MX1ZNR9c.mjs";import c from"colors";import{CHILD_FLAG as l,PoolCancelledError as u,computePoolSize as d,resolveWorkerPath as f,runPool as p}from"@transcend-io/utils";function m(e){return a(e)}function h(e){return o(e)}const g={renderHeader:m,renderWorkers:h};async function _(a){n(this.process.exit);let{directory:o,outputDir:m,clearOutputDir:h,concurrency:_,viewerMode:v}=a,y=t(o,this),{poolSize:b,cpuCount:x}=d(_,y.length);e.info(c.green(`Converting ${y.length} Parquet file(s) → CSV with pool size ${b} (CPU=${x})`));let S=y.map(e=>({filePath:e,options:{outputDir:m,clearOutputDir:h}}));await p({title:`Parquet → CSV - ${o}`,baseDir:o||m||process.cwd(),childFlag:l,childModulePath:f(import.meta.url,`commands/admin/parquet-to-csv/worker.mjs`),poolSize:b,cpuCount:x,filesTotal:y.length,hooks:{nextTask:()=>S.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:v,render:e=>i(e,g,v),installInteractiveSwitcher:v?void 0:({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,setPaused:o,repaint:s})=>r({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,onAttach:()=>o(!0),onDetach:()=>{o(!1),s()},onEnterAttachScreen:e=>{o(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Attached to worker ${e}. (Esc/Ctrl+] detach \u2022 Ctrl+D EOF \u2022 Ctrl+C SIGINT)\n`)}}),extraKeyHandler:({logsBySlot:e,repaint:t,setPaused:n})=>s({logsBySlot:e,repaint:t,setPaused:n})}).catch(e=>{throw e instanceof u&&process.exit(130),e})}export{_ as parquetToCsv};
2
- //# sourceMappingURL=impl-Nm3spVmW.mjs.map
1
+ import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./collectParquetFilesOrExit-DyZISY9X.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{a as r,i,n as a,r as o,t as s}from"./createExtraKeyHandler-DmBY_oth.mjs";import c from"colors";import{CHILD_FLAG as l,PoolCancelledError as u,computePoolSize as d,resolveWorkerPath as f,runPool as p}from"@transcend-io/utils";function m(e){return a(e)}function h(e){return o(e)}const g={renderHeader:m,renderWorkers:h};async function _(a){n(this.process.exit);let{directory:o,outputDir:m,clearOutputDir:h,concurrency:_,viewerMode:v}=a,y=t(o,this),{poolSize:b,cpuCount:x}=d(_,y.length);e.info(c.green(`Converting ${y.length} Parquet file(s) → CSV with pool size ${b} (CPU=${x})`));let S=y.map(e=>({filePath:e,options:{outputDir:m,clearOutputDir:h}}));await p({title:`Parquet → CSV - ${o}`,baseDir:o||m||process.cwd(),childFlag:l,childModulePath:f(import.meta.url,`commands/admin/parquet-to-csv/worker.mjs`),poolSize:b,cpuCount:x,filesTotal:y.length,hooks:{nextTask:()=>S.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:v,render:e=>i(e,g,v),installInteractiveSwitcher:v?void 0:({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,setPaused:o,repaint:s})=>r({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,onAttach:()=>o(!0),onDetach:()=>{o(!1),s()},onEnterAttachScreen:e=>{o(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Attached to worker ${e}. (Esc/Ctrl+] detach \u2022 Ctrl+D EOF \u2022 Ctrl+C SIGINT)\n`)}}),extraKeyHandler:({logsBySlot:e,repaint:t,setPaused:n})=>s({logsBySlot:e,repaint:t,setPaused:n})}).catch(e=>{throw e instanceof u&&process.exit(130),e})}export{_ as parquetToCsv};
2
+ //# sourceMappingURL=impl-COQ3iQNF.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Nm3spVmW.mjs","names":[],"sources":["../src/commands/admin/parquet-to-csv/ui/plugin.ts","../src/commands/admin/parquet-to-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for parquet-to-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for parquet-to-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const parquetToCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectParquetFilesOrExit } from '../../../lib/helpers/index.js';\nimport {\n createExtraKeyHandler,\n dashboardPlugin,\n installInteractiveSwitcher,\n} from '../../../lib/pooling/index.js';\nimport { logger } from '../../../logger.js';\nimport { parquetToCsvPlugin } from './ui/index.js';\nimport type { ParquetProgress, ParquetResult, ParquetTask } from './worker.js';\n\n/** No custom totals for the header; the runner’s built-ins suffice. */\ntype Totals = Record<string, never>;\n\nexport type ParquetToCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Convert all Parquet files in a directory to CSV, in parallel.\n *\n * @param flags - The command flags.\n */\nexport async function parquetToCsv(\n this: LocalContext,\n flags: ParquetToCsvCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { directory, outputDir, clearOutputDir, concurrency, viewerMode } = flags;\n\n /* 1) Discover .parquet inputs */\n const files = collectParquetFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n logger.info(\n colors.green(\n `Converting ${files.length} Parquet file(s) → CSV with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Build FIFO queue of tasks (one per file) */\n const queue = files.map<ParquetTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir },\n }));\n\n /* 4) Pool hooks */\n const hooks: PoolHooks<ParquetTask, ParquetProgress, ParquetResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n postProcess: async () => {\n // nothing special post-run\n },\n };\n\n /* 5) Launch the pool runner with custom dashboard plugin */\n await runPool({\n title: `Parquet → CSV - ${directory}`,\n baseDir: directory || outputDir || process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/parquet-to-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n render: (input) => dashboardPlugin(input, parquetToCsvPlugin, viewerMode),\n installInteractiveSwitcher: viewerMode\n ? undefined\n : ({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n setPaused,\n repaint: rp,\n }) =>\n installInteractiveSwitcher({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n onAttach: () => setPaused(true),\n onDetach: () => {\n setPaused(false);\n rp();\n },\n onEnterAttachScreen: (id) => {\n setPaused(true);\n process.stdout.write('\\x1b[2J\\x1b[H');\n process.stdout.write(\n `Attached to worker ${id}. (Esc/Ctrl+] detach \\u2022 Ctrl+D EOF \\u2022 Ctrl+C SIGINT)\\n`,\n );\n },\n }),\n extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n createExtraKeyHandler({ logsBySlot, repaint, setPaused }),\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"mYAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAAkE,CAC7E,eACA,gBAED,CCKD,eAAsB,EAEpB,EACe,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAe,EAGpE,EAAQ,EAA0B,EAAW,KAAK,CAGlD,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,EAAO,KACL,EAAO,MACL,cAAc,EAAM,OAAO,wCAAwC,EAAS,QAAQ,EAAS,GAC9F,CACF,CAGD,IAAM,EAAQ,EAAM,IAAkB,IAAc,CAClD,WACA,QAAS,CAAE,YAAW,iBAAgB,CACvC,EAAE,CAgBH,MAAM,EAAQ,CACZ,MAAO,mBAAmB,IAC1B,QAAS,GAAa,GAAa,QAAQ,KAAK,CAChD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,2CAA2C,CAC/F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CApBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EACpD,YAAa,SAAY,GAcpB,CACL,aACA,OAAS,GAAU,EAAgB,EAAO,EAAoB,EAAW,CACzE,2BAA4B,EACxB,IAAA,IACC,CACC,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,YACA,QAAS,KAET,EAA2B,CACzB,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,aAAgB,EAAU,GAAK,CAC/B,aAAgB,CACd,EAAU,GAAM,CAChB,GAAI,EAEN,oBAAsB,GAAO,CAC3B,EAAU,GAAK,CACf,QAAQ,OAAO,MAAM,gBAAgB,CACrC,QAAQ,OAAO,MACb,sBAAsB,EAAG,gEAC1B,EAEJ,CAAC,CACR,iBAAkB,CAAE,aAAY,UAAS,eACvC,EAAsB,CAAE,aAAY,UAAS,YAAW,CAAC,CAC5D,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,QAAQ,KAAK,IAAI,CAEb,GACN"}
1
+ {"version":3,"file":"impl-COQ3iQNF.mjs","names":[],"sources":["../src/commands/admin/parquet-to-csv/ui/plugin.ts","../src/commands/admin/parquet-to-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for parquet-to-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for parquet-to-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const parquetToCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectParquetFilesOrExit } from '../../../lib/helpers/index.js';\nimport {\n createExtraKeyHandler,\n dashboardPlugin,\n installInteractiveSwitcher,\n} from '../../../lib/pooling/index.js';\nimport { logger } from '../../../logger.js';\nimport { parquetToCsvPlugin } from './ui/index.js';\nimport type { ParquetProgress, ParquetResult, ParquetTask } from './worker.js';\n\n/** No custom totals for the header; the runner’s built-ins suffice. */\ntype Totals = Record<string, never>;\n\nexport type ParquetToCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Convert all Parquet files in a directory to CSV, in parallel.\n *\n * @param flags - The command flags.\n */\nexport async function parquetToCsv(\n this: LocalContext,\n flags: ParquetToCsvCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { directory, outputDir, clearOutputDir, concurrency, viewerMode } = flags;\n\n /* 1) Discover .parquet inputs */\n const files = collectParquetFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n logger.info(\n colors.green(\n `Converting ${files.length} Parquet file(s) → CSV with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Build FIFO queue of tasks (one per file) */\n const queue = files.map<ParquetTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir },\n }));\n\n /* 4) Pool hooks */\n const hooks: PoolHooks<ParquetTask, ParquetProgress, ParquetResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n postProcess: async () => {\n // nothing special post-run\n },\n };\n\n /* 5) Launch the pool runner with custom dashboard plugin */\n await runPool({\n title: `Parquet → CSV - ${directory}`,\n baseDir: directory || outputDir || process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/parquet-to-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n render: (input) => dashboardPlugin(input, parquetToCsvPlugin, viewerMode),\n installInteractiveSwitcher: viewerMode\n ? undefined\n : ({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n setPaused,\n repaint: rp,\n }) =>\n installInteractiveSwitcher({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n onAttach: () => setPaused(true),\n onDetach: () => {\n setPaused(false);\n rp();\n },\n onEnterAttachScreen: (id) => {\n setPaused(true);\n process.stdout.write('\\x1b[2J\\x1b[H');\n process.stdout.write(\n `Attached to worker ${id}. (Esc/Ctrl+] detach \\u2022 Ctrl+D EOF \\u2022 Ctrl+C SIGINT)\\n`,\n );\n },\n }),\n extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n createExtraKeyHandler({ logsBySlot, repaint, setPaused }),\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"mYAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAAkE,CAC7E,eACA,gBAED,CCKD,eAAsB,EAEpB,EACe,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAe,EAGpE,EAAQ,EAA0B,EAAW,KAAK,CAGlD,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,EAAO,KACL,EAAO,MACL,cAAc,EAAM,OAAO,wCAAwC,EAAS,QAAQ,EAAS,GAC9F,CACF,CAGD,IAAM,EAAQ,EAAM,IAAkB,IAAc,CAClD,WACA,QAAS,CAAE,YAAW,iBAAgB,CACvC,EAAE,CAgBH,MAAM,EAAQ,CACZ,MAAO,mBAAmB,IAC1B,QAAS,GAAa,GAAa,QAAQ,KAAK,CAChD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,2CAA2C,CAC/F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CApBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EACpD,YAAa,SAAY,GAcpB,CACL,aACA,OAAS,GAAU,EAAgB,EAAO,EAAoB,EAAW,CACzE,2BAA4B,EACxB,IAAA,IACC,CACC,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,YACA,QAAS,KAET,EAA2B,CACzB,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,aAAgB,EAAU,GAAK,CAC/B,aAAgB,CACd,EAAU,GAAM,CAChB,GAAI,EAEN,oBAAsB,GAAO,CAC3B,EAAU,GAAK,CACf,QAAQ,OAAO,MAAM,gBAAgB,CACrC,QAAQ,OAAO,MACb,sBAAsB,EAAG,gEAC1B,EAEJ,CAAC,CACR,iBAAkB,CAAE,aAAY,UAAS,eACvC,EAAsB,CAAE,aAAY,UAAS,YAAW,CAAC,CAC5D,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,QAAQ,KAAK,IAAI,CAEb,GACN"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./bulkRestartRequests-DMYL5KtN.mjs";import{t}from"./done-input-validation-uqIgnJcw.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.exit),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-Wrx1yiEs2.mjs.map
1
+ import{t as e}from"./bulkRestartRequests-BKLpHkmr.mjs";import{t}from"./done-input-validation-uqIgnJcw.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.exit),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-CbVqfl-Q2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Wrx1yiEs2.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.exit);\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,KAAK,CAEtC,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-CbVqfl-Q2.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.exit);\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,KAAK,CAEtC,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{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./collectCsvFilesOrExit-C8-Pr9Hr.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{a as r,i,n as a,r as o,t as s}from"./createExtraKeyHandler-MX1ZNR9c.mjs";import c from"colors";import{CHILD_FLAG as l,PoolCancelledError as u,computePoolSize as d,resolveWorkerPath as f,runPool as p}from"@transcend-io/utils";function m(e){return a(e)}function h(e){return o(e)}const g={renderHeader:m,renderWorkers:h};async function _(a){n(this.process.exit);let{directory:o,outputDir:m,clearOutputDir:h,chunkSizeMB:_,concurrency:v,viewerMode:y}=a,b=t(o,this),{poolSize:x,cpuCount:S}=d(v,b.length);e.info(c.green(`Chunking ${b.length} CSV file(s) with pool size ${x} (CPU=${S})`));let C=b.map(e=>({filePath:e,options:{outputDir:m,clearOutputDir:h,chunkSizeMB:_}}));await p({title:`Chunk CSV - ${o}`,baseDir:o||m||process.cwd(),childFlag:l,childModulePath:f(import.meta.url,`commands/admin/chunk-csv/worker.mjs`),poolSize:x,cpuCount:S,filesTotal:b.length,hooks:{nextTask:()=>C.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:y,render:e=>i(e,g,y),installInteractiveSwitcher:y?void 0:({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,setPaused:o,repaint:s})=>r({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,onAttach:()=>o(!0),onDetach:()=>{o(!1),s()},onEnterAttachScreen:e=>{o(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Attached to worker ${e}. (Esc/Ctrl+] detach \u2022 Ctrl+D EOF \u2022 Ctrl+C SIGINT)\n`)}}),extraKeyHandler:({logsBySlot:e,repaint:t,setPaused:n})=>s({logsBySlot:e,repaint:t,setPaused:n})}).catch(e=>{throw e instanceof u&&process.exit(130),e})}export{_ as chunkCsv};
2
- //# sourceMappingURL=impl-DNaa8Vn0.mjs.map
1
+ import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./collectCsvFilesOrExit-C8-Pr9Hr.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{a as r,i,n as a,r as o,t as s}from"./createExtraKeyHandler-DmBY_oth.mjs";import c from"colors";import{CHILD_FLAG as l,PoolCancelledError as u,computePoolSize as d,resolveWorkerPath as f,runPool as p}from"@transcend-io/utils";function m(e){return a(e)}function h(e){return o(e)}const g={renderHeader:m,renderWorkers:h};async function _(a){n(this.process.exit);let{directory:o,outputDir:m,clearOutputDir:h,chunkSizeMB:_,concurrency:v,viewerMode:y}=a,b=t(o,this),{poolSize:x,cpuCount:S}=d(v,b.length);e.info(c.green(`Chunking ${b.length} CSV file(s) with pool size ${x} (CPU=${S})`));let C=b.map(e=>({filePath:e,options:{outputDir:m,clearOutputDir:h,chunkSizeMB:_}}));await p({title:`Chunk CSV - ${o}`,baseDir:o||m||process.cwd(),childFlag:l,childModulePath:f(import.meta.url,`commands/admin/chunk-csv/worker.mjs`),poolSize:x,cpuCount:S,filesTotal:b.length,hooks:{nextTask:()=>C.shift(),taskLabel:e=>e.filePath,initTotals:()=>({}),initSlotProgress:()=>void 0,onProgress:e=>e,onResult:(e,t)=>({totals:e,ok:!!t.ok}),postProcess:async()=>{}},viewerMode:y,render:e=>i(e,g,y),installInteractiveSwitcher:y?void 0:({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,setPaused:o,repaint:s})=>r({workers:e,onCtrlC:t,getLogPaths:n,replayBytes:i,replayWhich:a,onAttach:()=>o(!0),onDetach:()=>{o(!1),s()},onEnterAttachScreen:e=>{o(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Attached to worker ${e}. (Esc/Ctrl+] detach \u2022 Ctrl+D EOF \u2022 Ctrl+C SIGINT)\n`)}}),extraKeyHandler:({logsBySlot:e,repaint:t,setPaused:n})=>s({logsBySlot:e,repaint:t,setPaused:n})}).catch(e=>{throw e instanceof u&&process.exit(130),e})}export{_ as chunkCsv};
2
+ //# sourceMappingURL=impl-CcrCW-aY.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DNaa8Vn0.mjs","names":[],"sources":["../src/commands/admin/chunk-csv/ui/plugin.ts","../src/commands/admin/chunk-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for chunk-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for chunk-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const chunkCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectCsvFilesOrExit } from '../../../lib/helpers/collectCsvFilesOrExit.js';\nimport {\n createExtraKeyHandler,\n dashboardPlugin,\n installInteractiveSwitcher,\n} from '../../../lib/pooling/index.js';\nimport { logger } from '../../../logger.js';\nimport { chunkCsvPlugin } from './ui/index.js';\nimport type { ChunkProgress, ChunkResult, ChunkTask } from './worker.js';\n\n/**\n * Totals aggregate for this command.\n * We don’t need custom counters since the runner already tracks\n * completed/failed counts in its header — so we just use an empty record.\n */\ntype Totals = Record<string, never>;\n\n/**\n * CLI flags accepted by the `chunk-csv` command.\n *\n * These are passed down from the CLI parser into the parent process.\n */\nexport type ChunkCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n chunkSizeMB: number;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Parent entrypoint for chunking many CSVs in parallel using the worker pool runner.\n *\n * Lifecycle:\n * 1) Discover CSV inputs (exit if none).\n * 2) Compute pool size (CPU-count heuristic or --concurrency).\n * 3) Build a FIFO queue of `ChunkTask`s.\n * 4) Define pool hooks to drive task assignment, progress, and result handling.\n * 5) Launch the pool with `runPool`, rendering via the `chunkCsvPlugin`.\n *\n * @param this - Bound CLI context (provides process exit + logging).\n * @param flags - CLI options for the run.\n */\nexport async function chunkCsv(this: LocalContext, flags: ChunkCsvCommandFlags): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { directory, outputDir, clearOutputDir, chunkSizeMB, concurrency, viewerMode } = flags;\n\n /* 1) Discover CSV inputs */\n const files = collectCsvFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n logger.info(\n colors.green(\n `Chunking ${files.length} CSV file(s) with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Prepare a simple FIFO queue of tasks (one per file). */\n const queue = files.map<ChunkTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir, chunkSizeMB },\n }));\n\n /* 4) Define pool hooks to adapt runner to this command. */\n const hooks: PoolHooks<ChunkTask, ChunkProgress, ChunkResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n // postProcess receives log context when viewerMode=true — we don’t need it here.\n postProcess: async () => {\n // nothing extra for chunk-csv\n },\n };\n\n /* 5) Launch the pool runner with our hooks and custom dashboard plugin. */\n await runPool({\n title: `Chunk CSV - ${directory}`,\n baseDir: directory || outputDir || process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/chunk-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n render: (input) => dashboardPlugin(input, chunkCsvPlugin, viewerMode),\n installInteractiveSwitcher: viewerMode\n ? undefined\n : ({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n setPaused,\n repaint: rp,\n }) =>\n installInteractiveSwitcher({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n onAttach: () => setPaused(true),\n onDetach: () => {\n setPaused(false);\n rp();\n },\n onEnterAttachScreen: (id) => {\n setPaused(true);\n process.stdout.write('\\x1b[2J\\x1b[H');\n process.stdout.write(\n `Attached to worker ${id}. (Esc/Ctrl+] detach \\u2022 Ctrl+D EOF \\u2022 Ctrl+C SIGINT)\\n`,\n );\n },\n }),\n extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n createExtraKeyHandler({\n logsBySlot,\n repaint,\n setPaused,\n }),\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"+XAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAA8D,CACzE,eACA,gBAED,CCuBD,eAAsB,EAA6B,EAA4C,CAC7F,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAa,cAAe,EAGjF,EAAQ,EAAsB,EAAW,KAAK,CAG9C,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,EAAO,KACL,EAAO,MACL,YAAY,EAAM,OAAO,8BAA8B,EAAS,QAAQ,EAAS,GAClF,CACF,CAGD,IAAM,EAAQ,EAAM,IAAgB,IAAc,CAChD,WACA,QAAS,CAAE,YAAW,iBAAgB,cAAa,CACpD,EAAE,CAiBH,MAAM,EAAQ,CACZ,MAAO,eAAe,IACtB,QAAS,GAAa,GAAa,QAAQ,KAAK,CAChD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,sCAAsC,CAC1F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CArBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EAEpD,YAAa,SAAY,GAcpB,CACL,aACA,OAAS,GAAU,EAAgB,EAAO,EAAgB,EAAW,CACrE,2BAA4B,EACxB,IAAA,IACC,CACC,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,YACA,QAAS,KAET,EAA2B,CACzB,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,aAAgB,EAAU,GAAK,CAC/B,aAAgB,CACd,EAAU,GAAM,CAChB,GAAI,EAEN,oBAAsB,GAAO,CAC3B,EAAU,GAAK,CACf,QAAQ,OAAO,MAAM,gBAAgB,CACrC,QAAQ,OAAO,MACb,sBAAsB,EAAG,gEAC1B,EAEJ,CAAC,CACR,iBAAkB,CAAE,aAAY,UAAS,eACvC,EAAsB,CACpB,aACA,UACA,YACD,CAAC,CACL,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,QAAQ,KAAK,IAAI,CAEb,GACN"}
1
+ {"version":3,"file":"impl-CcrCW-aY.mjs","names":[],"sources":["../src/commands/admin/chunk-csv/ui/plugin.ts","../src/commands/admin/chunk-csv/impl.ts"],"sourcesContent":["import {\n makeHeader,\n makeWorkerRows,\n type ChunkSlotProgress,\n type CommonCtx,\n type DashboardPlugin,\n} from '../../../../lib/pooling/index.js';\n\n/**\n * Header for chunk-csv (no extra totals block).\n *\n * @param ctx - Dashboard context.\n * @returns Header lines.\n */\nfunction renderHeader<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n // no extra lines — reuse the shared header as-is\n return makeHeader(ctx);\n}\n\n/**\n * Worker rows for chunk-csv — share the generic row renderer.\n *\n * @param ctx - Dashboard context.\n * @returns Array of strings, each representing one worker row.\n */\nfunction renderWorkers<TTotals>(ctx: CommonCtx<TTotals, ChunkSlotProgress>): string[] {\n return makeWorkerRows(ctx);\n}\n\nexport const chunkCsvPlugin: DashboardPlugin<unknown, ChunkSlotProgress> = {\n renderHeader,\n renderWorkers,\n // no extras\n};\n","import {\n CHILD_FLAG,\n type PoolHooks,\n runPool,\n computePoolSize,\n PoolCancelledError,\n resolveWorkerPath,\n} from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { collectCsvFilesOrExit } from '../../../lib/helpers/collectCsvFilesOrExit.js';\nimport {\n createExtraKeyHandler,\n dashboardPlugin,\n installInteractiveSwitcher,\n} from '../../../lib/pooling/index.js';\nimport { logger } from '../../../logger.js';\nimport { chunkCsvPlugin } from './ui/index.js';\nimport type { ChunkProgress, ChunkResult, ChunkTask } from './worker.js';\n\n/**\n * Totals aggregate for this command.\n * We don’t need custom counters since the runner already tracks\n * completed/failed counts in its header — so we just use an empty record.\n */\ntype Totals = Record<string, never>;\n\n/**\n * CLI flags accepted by the `chunk-csv` command.\n *\n * These are passed down from the CLI parser into the parent process.\n */\nexport type ChunkCsvCommandFlags = {\n directory: string;\n outputDir?: string;\n clearOutputDir: boolean;\n chunkSizeMB: number;\n concurrency?: number;\n viewerMode: boolean;\n};\n\n/**\n * Parent entrypoint for chunking many CSVs in parallel using the worker pool runner.\n *\n * Lifecycle:\n * 1) Discover CSV inputs (exit if none).\n * 2) Compute pool size (CPU-count heuristic or --concurrency).\n * 3) Build a FIFO queue of `ChunkTask`s.\n * 4) Define pool hooks to drive task assignment, progress, and result handling.\n * 5) Launch the pool with `runPool`, rendering via the `chunkCsvPlugin`.\n *\n * @param this - Bound CLI context (provides process exit + logging).\n * @param flags - CLI options for the run.\n */\nexport async function chunkCsv(this: LocalContext, flags: ChunkCsvCommandFlags): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { directory, outputDir, clearOutputDir, chunkSizeMB, concurrency, viewerMode } = flags;\n\n /* 1) Discover CSV inputs */\n const files = collectCsvFilesOrExit(directory, this);\n\n /* 2) Size the pool */\n const { poolSize, cpuCount } = computePoolSize(concurrency, files.length);\n\n logger.info(\n colors.green(\n `Chunking ${files.length} CSV file(s) with pool size ${poolSize} (CPU=${cpuCount})`,\n ),\n );\n\n /* 3) Prepare a simple FIFO queue of tasks (one per file). */\n const queue = files.map<ChunkTask>((filePath) => ({\n filePath,\n options: { outputDir, clearOutputDir, chunkSizeMB },\n }));\n\n /* 4) Define pool hooks to adapt runner to this command. */\n const hooks: PoolHooks<ChunkTask, ChunkProgress, ChunkResult, Totals> = {\n nextTask: () => queue.shift(),\n taskLabel: (t) => t.filePath,\n initTotals: () => ({}) as Totals,\n initSlotProgress: () => undefined,\n onProgress: (totals) => totals,\n onResult: (totals, res) => ({ totals, ok: !!res.ok }),\n // postProcess receives log context when viewerMode=true — we don’t need it here.\n postProcess: async () => {\n // nothing extra for chunk-csv\n },\n };\n\n /* 5) Launch the pool runner with our hooks and custom dashboard plugin. */\n await runPool({\n title: `Chunk CSV - ${directory}`,\n baseDir: directory || outputDir || process.cwd(),\n childFlag: CHILD_FLAG,\n childModulePath: resolveWorkerPath(import.meta.url, 'commands/admin/chunk-csv/worker.mjs'),\n poolSize,\n cpuCount,\n filesTotal: files.length,\n hooks,\n viewerMode,\n render: (input) => dashboardPlugin(input, chunkCsvPlugin, viewerMode),\n installInteractiveSwitcher: viewerMode\n ? undefined\n : ({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n setPaused,\n repaint: rp,\n }) =>\n installInteractiveSwitcher({\n workers,\n onCtrlC,\n getLogPaths,\n replayBytes: rb,\n replayWhich: rw,\n onAttach: () => setPaused(true),\n onDetach: () => {\n setPaused(false);\n rp();\n },\n onEnterAttachScreen: (id) => {\n setPaused(true);\n process.stdout.write('\\x1b[2J\\x1b[H');\n process.stdout.write(\n `Attached to worker ${id}. (Esc/Ctrl+] detach \\u2022 Ctrl+D EOF \\u2022 Ctrl+C SIGINT)\\n`,\n );\n },\n }),\n extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n createExtraKeyHandler({\n logsBySlot,\n repaint,\n setPaused,\n }),\n }).catch((err) => {\n if (err instanceof PoolCancelledError) {\n process.exit(130);\n }\n throw err;\n });\n}\n"],"mappings":"+XAcA,SAAS,EAAsB,EAAsD,CAEnF,OAAO,EAAW,EAAI,CASxB,SAAS,EAAuB,EAAsD,CACpF,OAAO,EAAe,EAAI,CAG5B,MAAa,EAA8D,CACzE,eACA,gBAED,CCuBD,eAAsB,EAA6B,EAA4C,CAC7F,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,YAAW,iBAAgB,cAAa,cAAa,cAAe,EAGjF,EAAQ,EAAsB,EAAW,KAAK,CAG9C,CAAE,WAAU,YAAa,EAAgB,EAAa,EAAM,OAAO,CAEzE,EAAO,KACL,EAAO,MACL,YAAY,EAAM,OAAO,8BAA8B,EAAS,QAAQ,EAAS,GAClF,CACF,CAGD,IAAM,EAAQ,EAAM,IAAgB,IAAc,CAChD,WACA,QAAS,CAAE,YAAW,iBAAgB,cAAa,CACpD,EAAE,CAiBH,MAAM,EAAQ,CACZ,MAAO,eAAe,IACtB,QAAS,GAAa,GAAa,QAAQ,KAAK,CAChD,UAAW,EACX,gBAAiB,EAAkB,OAAO,KAAK,IAAK,sCAAsC,CAC1F,WACA,WACA,WAAY,EAAM,OAClB,MAAA,CArBA,aAAgB,EAAM,OAAO,CAC7B,UAAY,GAAM,EAAE,SACpB,gBAAmB,EAAE,EACrB,qBAAwB,IAAA,GACxB,WAAa,GAAW,EACxB,UAAW,EAAQ,KAAS,CAAE,SAAQ,GAAI,CAAC,CAAC,EAAI,GAAI,EAEpD,YAAa,SAAY,GAcpB,CACL,aACA,OAAS,GAAU,EAAgB,EAAO,EAAgB,EAAW,CACrE,2BAA4B,EACxB,IAAA,IACC,CACC,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,YACA,QAAS,KAET,EAA2B,CACzB,UACA,UACA,cACA,YAAa,EACb,YAAa,EACb,aAAgB,EAAU,GAAK,CAC/B,aAAgB,CACd,EAAU,GAAM,CAChB,GAAI,EAEN,oBAAsB,GAAO,CAC3B,EAAU,GAAK,CACf,QAAQ,OAAO,MAAM,gBAAgB,CACrC,QAAQ,OAAO,MACb,sBAAsB,EAAG,gEAC1B,EAEJ,CAAC,CACR,iBAAkB,CAAE,aAAY,UAAS,eACvC,EAAsB,CACpB,aACA,UACA,YACD,CAAC,CACL,CAAC,CAAC,MAAO,GAAQ,CAIhB,MAHI,aAAe,GACjB,QAAQ,KAAK,IAAI,CAEb,GACN"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./streamPrivacyRequestsToCsv-S6KkzRmu.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import r from"colors";async function i({auth:i,transcendUrl:a,file:o,pageLimit:s,concurrency:c,actions:l,sombraAuth:u,skipRequestIdentifiers:d,statuses:f,createdAtBefore:p,createdAtAfter:m,updatedAtBefore:h,updatedAtAfter:g,showTests:_}){n(this.process.exit);let{filePaths:v,totalCount:y}=await t({transcendUrl:a,concurrency:c,pageLimit:s,actions:l,statuses:f,auth:i,sombraAuth:u,skipRequestIdentifiers:d,createdAtBefore:p,createdAtAfter:m,updatedAtBefore:h,updatedAtAfter:g,isTest:_,file:o});e.info(r.green(`Successfully wrote ${y} requests to ${v.length} file(s): ${v.join(`, `)}`))}export{i as _export};
2
- //# sourceMappingURL=impl-BE4fgip62.mjs.map
1
+ import{t as e}from"./logger-Ckep4QXn.mjs";import{t}from"./streamPrivacyRequestsToCsv-Qf83JD4N.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import r from"colors";async function i({auth:i,transcendUrl:a,file:o,pageLimit:s,concurrency:c,actions:l,sombraAuth:u,skipRequestIdentifiers:d,statuses:f,createdAtBefore:p,createdAtAfter:m,updatedAtBefore:h,updatedAtAfter:g,showTests:_}){n(this.process.exit);let{filePaths:v,totalCount:y}=await t({transcendUrl:a,concurrency:c,pageLimit:s,actions:l,statuses:f,auth:i,sombraAuth:u,skipRequestIdentifiers:d,createdAtBefore:p,createdAtAfter:m,updatedAtBefore:h,updatedAtAfter:g,isTest:_,file:o});e.info(r.green(`Successfully wrote ${y} requests to ${v.length} file(s): ${v.join(`, `)}`))}export{i as _export};
2
+ //# sourceMappingURL=impl-CdYy80RW2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-BE4fgip62.mjs","names":[],"sources":["../src/commands/request/export/impl.ts"],"sourcesContent":["import type { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { streamPrivacyRequestsToCsv } from '../../../lib/requests/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface ExportCommandFlags {\n auth: string;\n sombraAuth?: string;\n actions?: RequestAction[];\n statuses?: RequestStatus[];\n transcendUrl: string;\n file: string;\n concurrency: number;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n showTests?: boolean;\n skipRequestIdentifiers?: boolean;\n pageLimit: number;\n}\n\n// `export` is a reserved keyword, so we need to prefix it with an underscore\n// eslint-disable-next-line no-underscore-dangle\nexport async function _export(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n file,\n pageLimit,\n concurrency,\n actions,\n sombraAuth,\n skipRequestIdentifiers,\n statuses,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n showTests,\n }: ExportCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { filePaths, totalCount } = await streamPrivacyRequestsToCsv({\n transcendUrl,\n concurrency,\n pageLimit,\n actions,\n statuses,\n auth,\n sombraAuth,\n skipRequestIdentifiers,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isTest: showTests,\n file,\n });\n\n logger.info(\n colors.green(\n `Successfully wrote ${totalCount} requests to ` +\n `${filePaths.length} file(s): ${filePaths.join(', ')}`,\n ),\n );\n}\n"],"mappings":"kLA2BA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,YACA,cACA,UACA,aACA,yBACA,WACA,kBACA,iBACA,kBACA,iBACA,aAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,cAAe,MAAM,EAA2B,CACjE,eACA,cACA,YACA,UACA,WACA,OACA,aACA,yBACA,kBACA,iBACA,kBACA,iBACA,OAAQ,EACR,OACD,CAAC,CAEF,EAAO,KACL,EAAO,MACL,sBAAsB,EAAW,eAC5B,EAAU,OAAO,YAAY,EAAU,KAAK,KAAK,GACvD,CACF"}
1
+ {"version":3,"file":"impl-CdYy80RW2.mjs","names":[],"sources":["../src/commands/request/export/impl.ts"],"sourcesContent":["import type { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { streamPrivacyRequestsToCsv } from '../../../lib/requests/index.js';\nimport { logger } from '../../../logger.js';\n\nexport interface ExportCommandFlags {\n auth: string;\n sombraAuth?: string;\n actions?: RequestAction[];\n statuses?: RequestStatus[];\n transcendUrl: string;\n file: string;\n concurrency: number;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n showTests?: boolean;\n skipRequestIdentifiers?: boolean;\n pageLimit: number;\n}\n\n// `export` is a reserved keyword, so we need to prefix it with an underscore\n// eslint-disable-next-line no-underscore-dangle\nexport async function _export(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n file,\n pageLimit,\n concurrency,\n actions,\n sombraAuth,\n skipRequestIdentifiers,\n statuses,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n showTests,\n }: ExportCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n const { filePaths, totalCount } = await streamPrivacyRequestsToCsv({\n transcendUrl,\n concurrency,\n pageLimit,\n actions,\n statuses,\n auth,\n sombraAuth,\n skipRequestIdentifiers,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isTest: showTests,\n file,\n });\n\n logger.info(\n colors.green(\n `Successfully wrote ${totalCount} requests to ` +\n `${filePaths.length} file(s): ${filePaths.join(', ')}`,\n ),\n );\n}\n"],"mappings":"kLA2BA,eAAsB,EAEpB,CACE,OACA,eACA,OACA,YACA,cACA,UACA,aACA,yBACA,WACA,kBACA,iBACA,kBACA,iBACA,aAEa,CACf,EAAoB,KAAK,QAAQ,KAAK,CAEtC,GAAM,CAAE,YAAW,cAAe,MAAM,EAA2B,CACjE,eACA,cACA,YACA,UACA,WACA,OACA,aACA,yBACA,kBACA,iBACA,kBACA,iBACA,OAAQ,EACR,OACD,CAAC,CAEF,EAAO,KACL,EAAO,MACL,sBAAsB,EAAW,eAC5B,EAAU,OAAO,YAAY,EAAU,KAAK,KAAK,GACvD,CACF"}
@@ -1,2 +1,2 @@
1
- import{l as e}from"./constants-DLmuwAxY.mjs";import{t}from"./generateCrossAccountApiKeys-CN17E6qO.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{writeFileSync as r}from"node:fs";async function i({email:i,password:a,apiKeyTitle:o,file:s,scopes:c,deleteExistingApiKey:l,createNewApiKey:u,parentOrganizationId:d,transcendUrl:f}){n(this.process.exit);let{errors:p,apiKeys:m}=await t({transcendUrl:f,password:a,email:i,parentOrganizationId:d,deleteExistingApiKey:l,createNewApiKey:u,apiKeyTitle:o,scopes:c.map(t=>e[t].name)});r(s,`${JSON.stringify(m,null,2)}\n`),p.length>0&&this.process.exit(1)}export{i as generateApiKeys};
2
- //# sourceMappingURL=impl-D_wG-7a4.mjs.map
1
+ import{l as e}from"./constants-FvNUybuo.mjs";import{t}from"./generateCrossAccountApiKeys-CXyKrcUX.mjs";import{t as n}from"./done-input-validation-uqIgnJcw.mjs";import{writeFileSync as r}from"node:fs";async function i({email:i,password:a,apiKeyTitle:o,file:s,scopes:c,deleteExistingApiKey:l,createNewApiKey:u,parentOrganizationId:d,transcendUrl:f}){n(this.process.exit);let{errors:p,apiKeys:m}=await t({transcendUrl:f,password:a,email:i,parentOrganizationId:d,deleteExistingApiKey:l,createNewApiKey:u,apiKeyTitle:o,scopes:c.map(t=>e[t].name)});r(s,`${JSON.stringify(m,null,2)}\n`),p.length>0&&this.process.exit(1)}export{i as generateApiKeys};
2
+ //# sourceMappingURL=impl-D-e909Cm.mjs.map