@transcend-io/cli 12.0.0 → 12.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +162 -149
  2. package/dist/{app-CR3U95JW.mjs → app-BAx2hvcN.mjs} +20 -18
  3. package/dist/app-BAx2hvcN.mjs.map +1 -0
  4. package/dist/{approvePrivacyRequests-BDG82nlp.mjs → approvePrivacyRequests-B-4o7QMG.mjs} +2 -2
  5. package/dist/{approvePrivacyRequests-BDG82nlp.mjs.map → approvePrivacyRequests-B-4o7QMG.mjs.map} +1 -1
  6. package/dist/bin/bash-complete.mjs +1 -1
  7. package/dist/bin/cli.mjs +1 -1
  8. package/dist/bin/deprecated-command.mjs +1 -1
  9. package/dist/buildExamples-kR5_7dkU.mjs +2 -0
  10. package/dist/buildExamples-kR5_7dkU.mjs.map +1 -0
  11. package/dist/{buildXdiSyncEndpoint-FExEagKc.mjs → buildXdiSyncEndpoint-BSYwJ2vc.mjs} +2 -2
  12. package/dist/{buildXdiSyncEndpoint-FExEagKc.mjs.map → buildXdiSyncEndpoint-BSYwJ2vc.mjs.map} +1 -1
  13. package/dist/{bulkRestartRequests-OKwKXc52.mjs → bulkRestartRequests-DhOfMz0S.mjs} +2 -2
  14. package/dist/{bulkRestartRequests-OKwKXc52.mjs.map → bulkRestartRequests-DhOfMz0S.mjs.map} +1 -1
  15. package/dist/{bulkRetryEnrichers-Dl-n8AFF.mjs → bulkRetryEnrichers-Cj94ftnY.mjs} +2 -2
  16. package/dist/{bulkRetryEnrichers-Dl-n8AFF.mjs.map → bulkRetryEnrichers-Cj94ftnY.mjs.map} +1 -1
  17. package/dist/{cancelPrivacyRequests-BIgX5SDz.mjs → cancelPrivacyRequests-DgAhfcmg.mjs} +2 -2
  18. package/dist/{cancelPrivacyRequests-BIgX5SDz.mjs.map → cancelPrivacyRequests-DgAhfcmg.mjs.map} +1 -1
  19. package/dist/{command-X7lkPELf.mjs → command-gwG8sQwM.mjs} +2 -2
  20. package/dist/{command-X7lkPELf.mjs.map → command-gwG8sQwM.mjs.map} +1 -1
  21. package/dist/{constants-BRsj50Nb.mjs → constants-BCmVqlrM.mjs} +2 -2
  22. package/dist/{constants-BRsj50Nb.mjs.map → constants-BCmVqlrM.mjs.map} +1 -1
  23. package/dist/constants-DlH2vWm_.mjs +2 -0
  24. package/dist/constants-DlH2vWm_.mjs.map +1 -0
  25. package/dist/{createPoolingCommandUi-CyPZ3GqN.mjs → createPoolingCommandUi-ByyTeJx5.mjs} +2 -2
  26. package/dist/{createPoolingCommandUi-CyPZ3GqN.mjs.map → createPoolingCommandUi-ByyTeJx5.mjs.map} +1 -1
  27. package/dist/{downloadPrivacyRequestFiles-EBySRnvd.mjs → downloadPrivacyRequestFiles-yiE6NzXz.mjs} +2 -2
  28. package/dist/{downloadPrivacyRequestFiles-EBySRnvd.mjs.map → downloadPrivacyRequestFiles-yiE6NzXz.mjs.map} +1 -1
  29. package/dist/{extractClientError-DUJxHv07.mjs → extractClientError-BQgmnp3e.mjs} +2 -2
  30. package/dist/{extractClientError-DUJxHv07.mjs.map → extractClientError-BQgmnp3e.mjs.map} +1 -1
  31. package/dist/{fuzzyMatchColumns-2NmQqCZI.mjs → fuzzyMatchColumns-D18n9Beu.mjs} +2 -2
  32. package/dist/{fuzzyMatchColumns-2NmQqCZI.mjs.map → fuzzyMatchColumns-D18n9Beu.mjs.map} +1 -1
  33. package/dist/{generateCrossAccountApiKeys-pWTrIUE6.mjs → generateCrossAccountApiKeys-CoSsZwSz.mjs} +2 -2
  34. package/dist/{generateCrossAccountApiKeys-pWTrIUE6.mjs.map → generateCrossAccountApiKeys-CoSsZwSz.mjs.map} +1 -1
  35. package/dist/{impl-Dr_l_SLd.mjs → impl-4WoLxjdU.mjs} +2 -2
  36. package/dist/{impl-Dr_l_SLd.mjs.map → impl-4WoLxjdU.mjs.map} +1 -1
  37. package/dist/{impl-D1f9mJL_.mjs → impl-BCP4X_zk.mjs} +2 -2
  38. package/dist/{impl-D1f9mJL_.mjs.map → impl-BCP4X_zk.mjs.map} +1 -1
  39. package/dist/{impl-DXbxO2VJ.mjs → impl-BFSZEQ2s.mjs} +2 -2
  40. package/dist/{impl-DXbxO2VJ.mjs.map → impl-BFSZEQ2s.mjs.map} +1 -1
  41. package/dist/{impl-BdTxFv63.mjs → impl-BJnxahnW.mjs} +2 -2
  42. package/dist/{impl-BdTxFv63.mjs.map → impl-BJnxahnW.mjs.map} +1 -1
  43. package/dist/{impl-iD6Fknfe.mjs → impl-BKKBmXv4.mjs} +2 -2
  44. package/dist/{impl-iD6Fknfe.mjs.map → impl-BKKBmXv4.mjs.map} +1 -1
  45. package/dist/{impl-DtpgD_as.mjs → impl-BM2SWSKF.mjs} +2 -2
  46. package/dist/{impl-DtpgD_as.mjs.map → impl-BM2SWSKF.mjs.map} +1 -1
  47. package/dist/{impl-CrdqsTUy.mjs → impl-BMX6B40F.mjs} +2 -2
  48. package/dist/{impl-CrdqsTUy.mjs.map → impl-BMX6B40F.mjs.map} +1 -1
  49. package/dist/{impl-7rdGuHOC.mjs → impl-BRCAL4RM.mjs} +2 -2
  50. package/dist/{impl-7rdGuHOC.mjs.map → impl-BRCAL4RM.mjs.map} +1 -1
  51. package/dist/{impl-DxQ9yj3H.mjs → impl-BaGN4J-w.mjs} +2 -2
  52. package/dist/{impl-DxQ9yj3H.mjs.map → impl-BaGN4J-w.mjs.map} +1 -1
  53. package/dist/impl-Bf2Qli6c2.mjs +421 -0
  54. package/dist/{impl-DQcgEx7V2.mjs.map → impl-Bf2Qli6c2.mjs.map} +1 -1
  55. package/dist/{impl-DJcNhpbx.mjs → impl-BrdCuU0I.mjs} +2 -2
  56. package/dist/{impl-DJcNhpbx.mjs.map → impl-BrdCuU0I.mjs.map} +1 -1
  57. package/dist/{impl-Cxprr2hw.mjs → impl-C0R2azuF.mjs} +2 -2
  58. package/dist/{impl-Cxprr2hw.mjs.map → impl-C0R2azuF.mjs.map} +1 -1
  59. package/dist/{impl-B7l4bLG5.mjs → impl-C1hh_5On.mjs} +2 -2
  60. package/dist/{impl-B7l4bLG5.mjs.map → impl-C1hh_5On.mjs.map} +1 -1
  61. package/dist/{impl-Do2TNA3-.mjs → impl-C1vn0Y7f.mjs} +2 -2
  62. package/dist/{impl-Do2TNA3-.mjs.map → impl-C1vn0Y7f.mjs.map} +1 -1
  63. package/dist/impl-C36c5NfN.mjs +2 -0
  64. package/dist/impl-C36c5NfN.mjs.map +1 -0
  65. package/dist/{impl-DcL-8NEa2.mjs → impl-C54oUOeM2.mjs} +2 -2
  66. package/dist/{impl-DcL-8NEa2.mjs.map → impl-C54oUOeM2.mjs.map} +1 -1
  67. package/dist/{impl-HUfaARep.mjs → impl-CKg5Xu-r.mjs} +2 -2
  68. package/dist/{impl-HUfaARep.mjs.map → impl-CKg5Xu-r.mjs.map} +1 -1
  69. package/dist/{impl-B440iuvL.mjs → impl-ClhMRgQZ.mjs} +3 -3
  70. package/dist/{impl-B440iuvL.mjs.map → impl-ClhMRgQZ.mjs.map} +1 -1
  71. package/dist/{impl-BWPPVXG3.mjs → impl-CoqCyj7e.mjs} +3 -3
  72. package/dist/{impl-BWPPVXG3.mjs.map → impl-CoqCyj7e.mjs.map} +1 -1
  73. package/dist/impl-CuDZY6y7.mjs +2 -0
  74. package/dist/impl-CuDZY6y7.mjs.map +1 -0
  75. package/dist/{impl-DQG1pMzD2.mjs → impl-Cvyc-iTI2.mjs} +2 -2
  76. package/dist/{impl-DQG1pMzD2.mjs.map → impl-Cvyc-iTI2.mjs.map} +1 -1
  77. package/dist/impl-CwBa15M42.mjs +3 -0
  78. package/dist/impl-CwBa15M42.mjs.map +1 -0
  79. package/dist/{impl-BLQDgwxL.mjs → impl-CxpGBeJ0.mjs} +2 -2
  80. package/dist/{impl-BLQDgwxL.mjs.map → impl-CxpGBeJ0.mjs.map} +1 -1
  81. package/dist/{impl-CWP6AXSb.mjs → impl-CyDdvH5a.mjs} +2 -2
  82. package/dist/{impl-CWP6AXSb.mjs.map → impl-CyDdvH5a.mjs.map} +1 -1
  83. package/dist/{impl-vmLq6HCI.mjs → impl-D0cf-epj.mjs} +2 -2
  84. package/dist/{impl-vmLq6HCI.mjs.map → impl-D0cf-epj.mjs.map} +1 -1
  85. package/dist/{impl-CieztjdM.mjs → impl-D3gqip90.mjs} +2 -2
  86. package/dist/{impl-CieztjdM.mjs.map → impl-D3gqip90.mjs.map} +1 -1
  87. package/dist/{impl-wBcVYHlA.mjs → impl-D8YS5Bge.mjs} +2 -2
  88. package/dist/{impl-wBcVYHlA.mjs.map → impl-D8YS5Bge.mjs.map} +1 -1
  89. package/dist/{impl-1SsreZWo.mjs → impl-DCF3CF3O.mjs} +2 -2
  90. package/dist/{impl-1SsreZWo.mjs.map → impl-DCF3CF3O.mjs.map} +1 -1
  91. package/dist/impl-DE_cRfz52.mjs +2 -0
  92. package/dist/impl-DE_cRfz52.mjs.map +1 -0
  93. package/dist/impl-DG-041kN.mjs +3 -0
  94. package/dist/impl-DG-041kN.mjs.map +1 -0
  95. package/dist/{impl-B2ZXtnpX.mjs → impl-DNRA5i0w.mjs} +2 -2
  96. package/dist/{impl-B2ZXtnpX.mjs.map → impl-DNRA5i0w.mjs.map} +1 -1
  97. package/dist/{impl-Ds-gQfdc.mjs → impl-DSPxdc-T.mjs} +2 -2
  98. package/dist/{impl-Ds-gQfdc.mjs.map → impl-DSPxdc-T.mjs.map} +1 -1
  99. package/dist/{impl-FerHBNJx2.mjs → impl-DbddBTRj2.mjs} +2 -2
  100. package/dist/{impl-FerHBNJx2.mjs.map → impl-DbddBTRj2.mjs.map} +1 -1
  101. package/dist/{impl-eeS2lVi5.mjs → impl-DdUe8ClA.mjs} +2 -2
  102. package/dist/{impl-eeS2lVi5.mjs.map → impl-DdUe8ClA.mjs.map} +1 -1
  103. package/dist/{impl-CudSYx-g.mjs → impl-Dl8xSx8K.mjs} +2 -2
  104. package/dist/{impl-CudSYx-g.mjs.map → impl-Dl8xSx8K.mjs.map} +1 -1
  105. package/dist/{impl-DRKPx_I9.mjs → impl-DqnzZv43.mjs} +2 -2
  106. package/dist/{impl-DRKPx_I9.mjs.map → impl-DqnzZv43.mjs.map} +1 -1
  107. package/dist/{impl-D-a5xGld.mjs → impl-DrlfmH8g.mjs} +3 -3
  108. package/dist/{impl-D-a5xGld.mjs.map → impl-DrlfmH8g.mjs.map} +1 -1
  109. package/dist/{impl-DTadLabu.mjs → impl-F2lRJEqw.mjs} +2 -2
  110. package/dist/{impl-DTadLabu.mjs.map → impl-F2lRJEqw.mjs.map} +1 -1
  111. package/dist/{impl-CU38kdj8.mjs → impl-LDY2dgtc.mjs} +2 -2
  112. package/dist/{impl-CU38kdj8.mjs.map → impl-LDY2dgtc.mjs.map} +1 -1
  113. package/dist/{impl-C_Ifcb00.mjs → impl-OXGlZyUo.mjs} +2 -2
  114. package/dist/{impl-C_Ifcb00.mjs.map → impl-OXGlZyUo.mjs.map} +1 -1
  115. package/dist/{impl-Cb42aI60.mjs → impl-WJBuS_0m.mjs} +2 -2
  116. package/dist/{impl-Cb42aI60.mjs.map → impl-WJBuS_0m.mjs.map} +1 -1
  117. package/dist/{impl-DqHEIzpj.mjs → impl-agm4lpyq.mjs} +5 -5
  118. package/dist/{impl-DqHEIzpj.mjs.map → impl-agm4lpyq.mjs.map} +1 -1
  119. package/dist/impl-defjX-97.mjs +3 -0
  120. package/dist/impl-defjX-97.mjs.map +1 -0
  121. package/dist/{impl-DtnYcktN.mjs → impl-f59q7WnK.mjs} +2 -2
  122. package/dist/{impl-DtnYcktN.mjs.map → impl-f59q7WnK.mjs.map} +1 -1
  123. package/dist/{impl-DiwxYcux.mjs → impl-pA1b-G6B.mjs} +2 -2
  124. package/dist/{impl-DiwxYcux.mjs.map → impl-pA1b-G6B.mjs.map} +1 -1
  125. package/dist/{impl-D1UogVAq.mjs → impl-tYHONQMu.mjs} +2 -2
  126. package/dist/{impl-D1UogVAq.mjs.map → impl-tYHONQMu.mjs.map} +1 -1
  127. package/dist/{impl-CspH2ZWx.mjs → impl-u1nIo2-E.mjs} +2 -2
  128. package/dist/{impl-CspH2ZWx.mjs.map → impl-u1nIo2-E.mjs.map} +1 -1
  129. package/dist/index.d.mts +7 -3
  130. package/dist/index.d.mts.map +1 -1
  131. package/dist/index.mjs +2 -2
  132. package/dist/{inquirer-BU5IpgA8.mjs → inquirer-jzIQWAvq.mjs} +2 -2
  133. package/dist/{inquirer-BU5IpgA8.mjs.map → inquirer-jzIQWAvq.mjs.map} +1 -1
  134. package/dist/{markRequestDataSiloIdsCompleted-BYNMCkhy.mjs → markRequestDataSiloIdsCompleted-B-Dgme2r.mjs} +2 -2
  135. package/dist/{markRequestDataSiloIdsCompleted-BYNMCkhy.mjs.map → markRequestDataSiloIdsCompleted-B-Dgme2r.mjs.map} +1 -1
  136. package/dist/{markSilentPrivacyRequests-gKYivzH1.mjs → markSilentPrivacyRequests-CPU4Q2lF.mjs} +2 -2
  137. package/dist/{markSilentPrivacyRequests-gKYivzH1.mjs.map → markSilentPrivacyRequests-CPU4Q2lF.mjs.map} +1 -1
  138. package/dist/{mergeTranscendInputs-D1CvxQu0.mjs → mergeTranscendInputs-B7WjxYMN.mjs} +3 -3
  139. package/dist/{mergeTranscendInputs-D1CvxQu0.mjs.map → mergeTranscendInputs-B7WjxYMN.mjs.map} +1 -1
  140. package/dist/{notifyPrivacyRequestsAdditionalTime-DbERhQ1Q.mjs → notifyPrivacyRequestsAdditionalTime-BWsm5Y5K.mjs} +2 -2
  141. package/dist/{notifyPrivacyRequestsAdditionalTime-DbERhQ1Q.mjs.map → notifyPrivacyRequestsAdditionalTime-BWsm5Y5K.mjs.map} +1 -1
  142. package/dist/{policy-bundle-manifest-BZnBMZQq.mjs → policy-bundle-manifest-BDey6EBs.mjs} +3 -3
  143. package/dist/{policy-bundle-manifest-BZnBMZQq.mjs.map → policy-bundle-manifest-BDey6EBs.mjs.map} +1 -1
  144. package/dist/{policy-project-discovery-C29UxWwt.mjs → policy-project-discovery-DV5PnFJq.mjs} +71 -68
  145. package/dist/policy-project-discovery-DV5PnFJq.mjs.map +1 -0
  146. package/dist/policy-scaffold-config-DtRELUZx.mjs +76 -0
  147. package/dist/policy-scaffold-config-DtRELUZx.mjs.map +1 -0
  148. package/dist/printResult-Dmwv78e7.mjs +33 -0
  149. package/dist/printResult-Dmwv78e7.mjs.map +1 -0
  150. package/dist/{pullAllDatapoints-Bm-Orhse.mjs → pullAllDatapoints-CNqQSSmF.mjs} +3 -3
  151. package/dist/{pullAllDatapoints-Bm-Orhse.mjs.map → pullAllDatapoints-CNqQSSmF.mjs.map} +1 -1
  152. package/dist/pullChunkedCustomSiloOutstandingIdentifiers-BaHp-jxs.mjs +2 -0
  153. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-DTGQOw--.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-BaHp-jxs.mjs.map} +1 -1
  154. package/dist/{pullManualEnrichmentIdentifiersToCsv-DMC5CQtE.mjs → pullManualEnrichmentIdentifiersToCsv-CiEFIvl_.mjs} +2 -2
  155. package/dist/{pullManualEnrichmentIdentifiersToCsv-DMC5CQtE.mjs.map → pullManualEnrichmentIdentifiersToCsv-CiEFIvl_.mjs.map} +1 -1
  156. package/dist/{pushCronIdentifiersFromCsv-DhS2z8IG.mjs → pushCronIdentifiersFromCsv-DeS78zyp.mjs} +2 -2
  157. package/dist/{pushCronIdentifiersFromCsv-DhS2z8IG.mjs.map → pushCronIdentifiersFromCsv-DeS78zyp.mjs.map} +1 -1
  158. package/dist/pushManualEnrichmentIdentifiersFromCsv-B3iVwuvs.mjs +2 -0
  159. package/dist/{pushManualEnrichmentIdentifiersFromCsv-BTJGOmdU.mjs.map → pushManualEnrichmentIdentifiersFromCsv-B3iVwuvs.mjs.map} +1 -1
  160. package/dist/{removeUnverifiedRequestIdentifiers-BkAcUZZN.mjs → removeUnverifiedRequestIdentifiers-qS5A_eRZ.mjs} +2 -2
  161. package/dist/{removeUnverifiedRequestIdentifiers-BkAcUZZN.mjs.map → removeUnverifiedRequestIdentifiers-qS5A_eRZ.mjs.map} +1 -1
  162. package/dist/resolveBundleIdByName-BPrMkU0w.mjs +2 -0
  163. package/dist/resolveBundleIdByName-BPrMkU0w.mjs.map +1 -0
  164. package/dist/resolvePolicyBundleVersion-BrVz4LKN.mjs +2 -0
  165. package/dist/resolvePolicyBundleVersion-BrVz4LKN.mjs.map +1 -0
  166. package/dist/{retryRequestDataSilos-BoPmcB8-.mjs → retryRequestDataSilos-Cxaka-kA.mjs} +2 -2
  167. package/dist/{retryRequestDataSilos-BoPmcB8-.mjs.map → retryRequestDataSilos-Cxaka-kA.mjs.map} +1 -1
  168. package/dist/{skipPreflightJobs-DkBdYw-r.mjs → skipPreflightJobs-FdIm_Imj.mjs} +2 -2
  169. package/dist/{skipPreflightJobs-DkBdYw-r.mjs.map → skipPreflightJobs-FdIm_Imj.mjs.map} +1 -1
  170. package/dist/{skipRequestDataSilos-BRFiokix.mjs → skipRequestDataSilos-MTbj-OfW.mjs} +2 -2
  171. package/dist/{skipRequestDataSilos-BRFiokix.mjs.map → skipRequestDataSilos-MTbj-OfW.mjs.map} +1 -1
  172. package/dist/{streamPrivacyRequestsToCsv-Bt-H5J-y.mjs → streamPrivacyRequestsToCsv-BVzYSXNY.mjs} +2 -2
  173. package/dist/{streamPrivacyRequestsToCsv-Bt-H5J-y.mjs.map → streamPrivacyRequestsToCsv-BVzYSXNY.mjs.map} +1 -1
  174. package/dist/{syncCodePackages-CPkEukDm.mjs → syncCodePackages-DJnrcX5l.mjs} +2 -2
  175. package/dist/{syncCodePackages-CPkEukDm.mjs.map → syncCodePackages-DJnrcX5l.mjs.map} +1 -1
  176. package/dist/updateConsentManagerVersionToLatest-Udi7Iazb.mjs +2 -0
  177. package/dist/{updateConsentManagerVersionToLatest-DWblAwus.mjs.map → updateConsentManagerVersionToLatest-Udi7Iazb.mjs.map} +1 -1
  178. package/dist/{uploadConsents-D7Vg8ZRW.mjs → uploadConsents-w7FE65Zg.mjs} +2 -2
  179. package/dist/{uploadConsents-D7Vg8ZRW.mjs.map → uploadConsents-w7FE65Zg.mjs.map} +1 -1
  180. package/dist/uploadPrivacyRequestsFromCsv-B__QsguT.mjs +2 -0
  181. package/dist/uploadPrivacyRequestsFromCsv-B__QsguT.mjs.map +1 -0
  182. package/package.json +5 -5
  183. package/dist/app-CR3U95JW.mjs.map +0 -1
  184. package/dist/buildExamples-B6BdW0FD.mjs +0 -2
  185. package/dist/buildExamples-B6BdW0FD.mjs.map +0 -1
  186. package/dist/constants-qvGk0wlN.mjs +0 -2
  187. package/dist/constants-qvGk0wlN.mjs.map +0 -1
  188. package/dist/impl-BqTMPbwc2.mjs +0 -2
  189. package/dist/impl-BqTMPbwc2.mjs.map +0 -1
  190. package/dist/impl-CAoIp9Nl2.mjs +0 -3
  191. package/dist/impl-CAoIp9Nl2.mjs.map +0 -1
  192. package/dist/impl-Cee7Q1Ne.mjs +0 -2
  193. package/dist/impl-Cee7Q1Ne.mjs.map +0 -1
  194. package/dist/impl-DQcgEx7V2.mjs +0 -298
  195. package/dist/impl-DezV3QMo.mjs +0 -3
  196. package/dist/impl-DezV3QMo.mjs.map +0 -1
  197. package/dist/impl-btKJ1-VJ.mjs +0 -3
  198. package/dist/impl-btKJ1-VJ.mjs.map +0 -1
  199. package/dist/impl-ijoNwhGI.mjs +0 -2
  200. package/dist/impl-ijoNwhGI.mjs.map +0 -1
  201. package/dist/policy-project-discovery-C29UxWwt.mjs.map +0 -1
  202. package/dist/policy-scaffold-config-BUKAyPad.mjs +0 -76
  203. package/dist/policy-scaffold-config-BUKAyPad.mjs.map +0 -1
  204. package/dist/printResult-C2K9ODeE.mjs +0 -33
  205. package/dist/printResult-C2K9ODeE.mjs.map +0 -1
  206. package/dist/pullChunkedCustomSiloOutstandingIdentifiers-DTGQOw--.mjs +0 -2
  207. package/dist/pushManualEnrichmentIdentifiersFromCsv-BTJGOmdU.mjs +0 -2
  208. package/dist/resolveBundleIdByName-Dm_o5_bg.mjs +0 -2
  209. package/dist/resolveBundleIdByName-Dm_o5_bg.mjs.map +0 -1
  210. package/dist/resolvePolicyBundleVersion-DRUwe7fA.mjs +0 -2
  211. package/dist/resolvePolicyBundleVersion-DRUwe7fA.mjs.map +0 -1
  212. package/dist/updateConsentManagerVersionToLatest-DWblAwus.mjs +0 -2
  213. package/dist/uploadPrivacyRequestsFromCsv-B_hQwIn6.mjs +0 -2
  214. package/dist/uploadPrivacyRequestsFromCsv-B_hQwIn6.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DJcNhpbx.mjs","names":[],"sources":["../src/commands/admin/generate-api-keys/impl.ts"],"sourcesContent":["import { ScopeName } from '@transcend-io/privacy-types';\n\nimport { SCOPES_BY_TITLE } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { generateCrossAccountApiKeys } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\n\n// Command flag interface\nexport interface GenerateApiKeysCommandFlags {\n email: string;\n password: string;\n apiKeyTitle: string;\n file: string;\n scopes: string[];\n deleteExistingApiKey: boolean;\n createNewApiKey: boolean;\n parentOrganizationId?: string;\n transcendUrl: string;\n}\n\n// Command implementation\nexport async function generateApiKeys(\n this: LocalContext,\n {\n email,\n password,\n apiKeyTitle,\n file,\n scopes,\n deleteExistingApiKey,\n createNewApiKey,\n parentOrganizationId,\n transcendUrl,\n }: GenerateApiKeysCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const scopeNames = scopes.map((scopeTitle) => SCOPES_BY_TITLE[scopeTitle].name as ScopeName);\n\n // Upload privacy requests\n const { errors, apiKeys } = await generateCrossAccountApiKeys({\n transcendUrl,\n password,\n email,\n parentOrganizationId,\n deleteExistingApiKey,\n createNewApiKey,\n apiKeyTitle,\n scopes: scopeNames,\n });\n\n // Write to disk\n this.fs.writeFileSync(file, `${JSON.stringify(apiKeys, null, 2)}\\n`);\n if (errors.length > 0) {\n this.process.exit(1);\n }\n}\n"],"mappings":"gKAqBA,eAAsB,EAEpB,CACE,QACA,WACA,cACA,OACA,SACA,uBACA,kBACA,uBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAKjC,GAAM,CAAE,SAAQ,WAAY,MAAM,EAA4B,CAC5D,eACA,WACA,QACA,uBACA,uBACA,kBACA,cACA,OAXiB,EAAO,IAAK,GAAe,EAAgB,GAAY,KAWtD,CACnB,CAAC,CAGF,KAAK,GAAG,cAAc,EAAM,GAAG,KAAK,UAAU,EAAS,KAAM,EAAE,CAAC,IAAI,CAChE,EAAO,OAAS,GAClB,KAAK,QAAQ,KAAK,EAAE"}
1
+ {"version":3,"file":"impl-BrdCuU0I.mjs","names":[],"sources":["../src/commands/admin/generate-api-keys/impl.ts"],"sourcesContent":["import { ScopeName } from '@transcend-io/privacy-types';\n\nimport { SCOPES_BY_TITLE } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { generateCrossAccountApiKeys } from '../../../lib/api-keys/index.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\n\n// Command flag interface\nexport interface GenerateApiKeysCommandFlags {\n email: string;\n password: string;\n apiKeyTitle: string;\n file: string;\n scopes: string[];\n deleteExistingApiKey: boolean;\n createNewApiKey: boolean;\n parentOrganizationId?: string;\n transcendUrl: string;\n}\n\n// Command implementation\nexport async function generateApiKeys(\n this: LocalContext,\n {\n email,\n password,\n apiKeyTitle,\n file,\n scopes,\n deleteExistingApiKey,\n createNewApiKey,\n parentOrganizationId,\n transcendUrl,\n }: GenerateApiKeysCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const scopeNames = scopes.map((scopeTitle) => SCOPES_BY_TITLE[scopeTitle].name as ScopeName);\n\n // Upload privacy requests\n const { errors, apiKeys } = await generateCrossAccountApiKeys({\n transcendUrl,\n password,\n email,\n parentOrganizationId,\n deleteExistingApiKey,\n createNewApiKey,\n apiKeyTitle,\n scopes: scopeNames,\n });\n\n // Write to disk\n this.fs.writeFileSync(file, `${JSON.stringify(apiKeys, null, 2)}\\n`);\n if (errors.length > 0) {\n this.process.exit(1);\n }\n}\n"],"mappings":"gKAqBA,eAAsB,EAEpB,CACE,QACA,WACA,cACA,OACA,SACA,uBACA,kBACA,uBACA,gBAEa,CACf,EAAoB,KAAK,QAAQ,CAKjC,GAAM,CAAE,SAAQ,WAAY,MAAM,EAA4B,CAC5D,eACA,WACA,QACA,uBACA,uBACA,kBACA,cACA,OAXiB,EAAO,IAAK,GAAe,EAAgB,GAAY,KAWtD,CACnB,CAAC,CAGF,KAAK,GAAG,cAAc,EAAM,GAAG,KAAK,UAAU,EAAS,KAAM,EAAE,CAAC,IAAI,CAChE,EAAO,OAAS,GAClB,KAAK,QAAQ,KAAK,EAAE"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./constants-BRsj50Nb.mjs";import{t}from"./logger-CPu6zbyQ.mjs";import{n}from"./syncCodePackages-CPkEukDm.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{t as i}from"./constants-DC_bBO09.mjs";import a from"colors";import o from"fast-glob";import{getEntries as s}from"@transcend-io/type-utils";import{buildTranscendGraphQLClient as c}from"@transcend-io/sdk";import{execSync as l}from"child_process";async function u({scanPath:e,ignoreDirs:n=[],repositoryName:r}){return(await Promise.all(s(i).map(async([i,s])=>{let{ignoreDirs:c,supportedFiles:l,scanFunction:u}=s,d=[...n,...c].filter(e=>e.length>0);try{let n=await o(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(a.magenta(`Scanning: ${n.length} files of type ${i}`));let s=n.map(t=>u(t).map(n=>({...n,relativePath:t.replace(`${e}/`,``)}))).flat();return t.info(a.green(`Found: ${s.length} packages and ${s.map(({softwareDevelopmentKits:e=[]})=>e).flat().length} sdks`)),s.map(e=>({...e,type:i,repositoryName:r}))}catch(e){throw Error(`Error scanning globs ${l} with error: ${e}`)}}))).flat()}const d=`A repository name must be provided. You can specify using --repositoryName=$REPO_NAME or by ensuring the command "git config --get remote.origin.url" returns the name of the repository`;async function f({auth:t,scanPath:i,ignoreDirs:o,repositoryName:s,transcendUrl:f}){r(this.process);let p=s;if(!p)try{let e=l(`cd ${i} && git config --get remote.origin.url`).toString(`utf-8`).trim();[p]=e.includes(`https:`)?e.split(`/`).slice(3).join(`/`).split(`.`):(e.split(`:`).pop()||``).split(`.`),p||(this.logger.error(a.red(d)),this.process.exit(1))}catch(e){this.logger.error(a.red(`${d} - Got error: ${e.message}`)),this.process.exit(1)}let m=c(f,t),h=await u({scanPath:i,ignoreDirs:o,repositoryName:p});await n(m,h);let g=new URL(e);g.pathname=`/code-scanning/code-packages`,this.logger.info(a.green(`Scan found ${h.length} packages at ${i}! View results at '${g.href}'`))}export{f as scanPackages};
2
- //# sourceMappingURL=impl-Cxprr2hw.mjs.map
1
+ import{t as e}from"./constants-BCmVqlrM.mjs";import{t}from"./logger-CPu6zbyQ.mjs";import{n}from"./syncCodePackages-DJnrcX5l.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{t as i}from"./constants-DC_bBO09.mjs";import a from"colors";import o from"fast-glob";import{getEntries as s}from"@transcend-io/type-utils";import{buildTranscendGraphQLClient as c}from"@transcend-io/sdk";import{execSync as l}from"child_process";async function u({scanPath:e,ignoreDirs:n=[],repositoryName:r}){return(await Promise.all(s(i).map(async([i,s])=>{let{ignoreDirs:c,supportedFiles:l,scanFunction:u}=s,d=[...n,...c].filter(e=>e.length>0);try{let n=await o(`${e}/**/${l.join(`|`)}`,{ignore:d.map(t=>`${e}/**/${t}`),unique:!0,onlyFiles:!0});t.info(a.magenta(`Scanning: ${n.length} files of type ${i}`));let s=n.map(t=>u(t).map(n=>({...n,relativePath:t.replace(`${e}/`,``)}))).flat();return t.info(a.green(`Found: ${s.length} packages and ${s.map(({softwareDevelopmentKits:e=[]})=>e).flat().length} sdks`)),s.map(e=>({...e,type:i,repositoryName:r}))}catch(e){throw Error(`Error scanning globs ${l} with error: ${e}`)}}))).flat()}const d=`A repository name must be provided. You can specify using --repositoryName=$REPO_NAME or by ensuring the command "git config --get remote.origin.url" returns the name of the repository`;async function f({auth:t,scanPath:i,ignoreDirs:o,repositoryName:s,transcendUrl:f}){r(this.process);let p=s;if(!p)try{let e=l(`cd ${i} && git config --get remote.origin.url`).toString(`utf-8`).trim();[p]=e.includes(`https:`)?e.split(`/`).slice(3).join(`/`).split(`.`):(e.split(`:`).pop()||``).split(`.`),p||(this.logger.error(a.red(d)),this.process.exit(1))}catch(e){this.logger.error(a.red(`${d} - Got error: ${e.message}`)),this.process.exit(1)}let m=c(f,t),h=await u({scanPath:i,ignoreDirs:o,repositoryName:p});await n(m,h);let g=new URL(e);g.pathname=`/code-scanning/code-packages`,this.logger.info(a.green(`Scan found ${h.length} packages at ${i}! View results at '${g.href}'`))}export{f as scanPackages};
2
+ //# sourceMappingURL=impl-C0R2azuF.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Cxprr2hw.mjs","names":[],"sources":["../src/lib/code-scanning/findCodePackagesInFolder.ts","../src/commands/inventory/scan-packages/impl.ts"],"sourcesContent":["import { getEntries } from '@transcend-io/type-utils';\nimport colors from 'colors';\nimport fastGlob from 'fast-glob';\n\nimport { CodePackageInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { CODE_SCANNING_CONFIGS } from './constants.js';\n\n/**\n * Helper to scan and discovery all of the code packages within a folder\n *\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findCodePackagesInFolder({\n scanPath,\n ignoreDirs = [],\n repositoryName,\n}: {\n /** The name of the github repository reporting packages for */\n repositoryName: string;\n /** Where to look for package.json files */\n scanPath: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs?: string[];\n}): Promise<CodePackageInput[]> {\n const allCodePackages = await Promise.all(\n getEntries(CODE_SCANNING_CONFIGS).map(async ([codePackageType, config]) => {\n const { ignoreDirs: configIgnoreDirs, supportedFiles, scanFunction } = config;\n const dirsToIgnore = [...ignoreDirs, ...configIgnoreDirs].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${supportedFiles.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(\n colors.magenta(`Scanning: ${filesToScan.length} files of type ${codePackageType}`),\n );\n const allPackages = filesToScan\n .map((filePath) =>\n scanFunction(filePath).map((result) => ({\n ...result,\n relativePath: filePath.replace(`${scanPath}/`, ''),\n })),\n )\n .flat();\n logger.info(\n colors.green(\n `Found: ${allPackages.length} packages and ${\n allPackages.map(({ softwareDevelopmentKits = [] }) => softwareDevelopmentKits).flat()\n .length\n } sdks`,\n ),\n );\n\n return allPackages.map(\n (pkg): CodePackageInput => ({\n ...pkg,\n type: codePackageType,\n repositoryName,\n }),\n );\n } catch (error) {\n throw new Error(`Error scanning globs ${supportedFiles} with error: ${error}`);\n }\n }),\n );\n\n return allCodePackages.flat();\n}\n","import { execSync } from 'child_process';\n\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findCodePackagesInFolder } from '../../../lib/code-scanning/index.js';\nimport { syncCodePackages } from '../../../lib/graphql/index.js';\n\nconst REPO_ERROR =\n 'A repository name must be provided. ' +\n 'You can specify using --repositoryName=$REPO_NAME or by ensuring the ' +\n 'command \"git config --get remote.origin.url\" returns the name of the repository';\n\nexport interface ScanPackagesCommandFlags {\n auth: string;\n scanPath: string;\n ignoreDirs?: string[];\n repositoryName?: string;\n transcendUrl: string;\n}\n\nexport async function scanPackages(\n this: LocalContext,\n { auth, scanPath, ignoreDirs, repositoryName, transcendUrl }: ScanPackagesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Ensure repository name is specified\n let gitRepositoryName = repositoryName;\n if (!gitRepositoryName) {\n try {\n const name = execSync(`cd ${scanPath} && git config --get remote.origin.url`);\n // Trim and parse the URL\n const url = name.toString('utf-8').trim();\n [gitRepositoryName] = !url.includes('https:')\n ? (url.split(':').pop() || '').split('.')\n : url.split('/').slice(3).join('/').split('.');\n if (!gitRepositoryName) {\n this.logger.error(colors.red(REPO_ERROR));\n this.process.exit(1);\n }\n } catch (err) {\n this.logger.error(colors.red(`${REPO_ERROR} - Got error: ${err.message}`));\n this.process.exit(1);\n }\n }\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Scan the codebase to discovery packages\n const results = await findCodePackagesInFolder({\n scanPath,\n ignoreDirs,\n repositoryName: gitRepositoryName,\n });\n\n // Report scan to Transcend\n await syncCodePackages(client, results);\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/code-scanning/code-packages';\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Scan found ${results.length} packages at ${scanPath}! ` + `View results at '${newUrl.href}'`,\n ),\n );\n}\n"],"mappings":"qbAcA,eAAsB,EAAyB,CAC7C,WACA,aAAa,EAAE,CACf,kBAQ8B,CA4C9B,OAAO,MA3CuB,QAAQ,IACpC,EAAW,EAAsB,CAAC,IAAI,MAAO,CAAC,EAAiB,KAAY,CACzE,GAAM,CAAE,WAAY,EAAkB,iBAAgB,gBAAiB,EACjE,EAAe,CAAC,GAAG,EAAY,GAAG,EAAiB,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CACzF,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KACL,EAAO,QAAQ,aAAa,EAAY,OAAO,iBAAiB,IAAkB,CACnF,CACD,IAAM,EAAc,EACjB,IAAK,GACJ,EAAa,EAAS,CAAC,IAAK,IAAY,CACtC,GAAG,EACH,aAAc,EAAS,QAAQ,GAAG,EAAS,GAAI,GAAG,CACnD,EAAE,CACJ,CACA,MAAM,CAUT,OATA,EAAO,KACL,EAAO,MACL,UAAU,EAAY,OAAO,gBAC3B,EAAY,KAAK,CAAE,0BAA0B,EAAE,IAAO,EAAwB,CAAC,MAAM,CAClF,OACJ,OACF,CACF,CAEM,EAAY,IAChB,IAA2B,CAC1B,GAAG,EACH,KAAM,EACN,iBACD,EACF,OACM,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAe,eAAe,IAAQ,GAEhF,CACH,EAEsB,MAAM,CC1D/B,MAAM,EACJ,2LAYF,eAAsB,EAEpB,CAAE,OAAM,WAAU,aAAY,iBAAgB,gBAC/B,CACf,EAAoB,KAAK,QAAQ,CAGjC,IAAI,EAAoB,EACxB,GAAI,CAAC,EACH,GAAI,CAGF,IAAM,EAFO,EAAS,MAAM,EAAS,wCAErB,CAAC,SAAS,QAAQ,CAAC,MAAM,CACzC,CAAC,GAAsB,EAAI,SAAS,SAAS,CAEzC,EAAI,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,EAD3C,EAAI,MAAM,IAAI,CAAC,KAAK,EAAI,IAAI,MAAM,IAAI,CAEtC,IACH,KAAK,OAAO,MAAM,EAAO,IAAI,EAAW,CAAC,CACzC,KAAK,QAAQ,KAAK,EAAE,QAEf,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,GAAG,EAAW,gBAAgB,EAAI,UAAU,CAAC,CAC1E,KAAK,QAAQ,KAAK,EAAE,CAKxB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAU,MAAM,EAAyB,CAC7C,WACA,aACA,eAAgB,EACjB,CAAC,CAGF,MAAM,EAAiB,EAAQ,EAAQ,CAEvC,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,+BAGlB,KAAK,OAAO,KACV,EAAO,MACL,cAAc,EAAQ,OAAO,eAAe,EAAS,qBAA0B,EAAO,KAAK,GAC5F,CACF"}
1
+ {"version":3,"file":"impl-C0R2azuF.mjs","names":[],"sources":["../src/lib/code-scanning/findCodePackagesInFolder.ts","../src/commands/inventory/scan-packages/impl.ts"],"sourcesContent":["import { getEntries } from '@transcend-io/type-utils';\nimport colors from 'colors';\nimport fastGlob from 'fast-glob';\n\nimport { CodePackageInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { CODE_SCANNING_CONFIGS } from './constants.js';\n\n/**\n * Helper to scan and discovery all of the code packages within a folder\n *\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findCodePackagesInFolder({\n scanPath,\n ignoreDirs = [],\n repositoryName,\n}: {\n /** The name of the github repository reporting packages for */\n repositoryName: string;\n /** Where to look for package.json files */\n scanPath: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs?: string[];\n}): Promise<CodePackageInput[]> {\n const allCodePackages = await Promise.all(\n getEntries(CODE_SCANNING_CONFIGS).map(async ([codePackageType, config]) => {\n const { ignoreDirs: configIgnoreDirs, supportedFiles, scanFunction } = config;\n const dirsToIgnore = [...ignoreDirs, ...configIgnoreDirs].filter((dir) => dir.length > 0);\n try {\n const filesToScan: string[] = await fastGlob(`${scanPath}/**/${supportedFiles.join('|')}`, {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n });\n logger.info(\n colors.magenta(`Scanning: ${filesToScan.length} files of type ${codePackageType}`),\n );\n const allPackages = filesToScan\n .map((filePath) =>\n scanFunction(filePath).map((result) => ({\n ...result,\n relativePath: filePath.replace(`${scanPath}/`, ''),\n })),\n )\n .flat();\n logger.info(\n colors.green(\n `Found: ${allPackages.length} packages and ${\n allPackages.map(({ softwareDevelopmentKits = [] }) => softwareDevelopmentKits).flat()\n .length\n } sdks`,\n ),\n );\n\n return allPackages.map(\n (pkg): CodePackageInput => ({\n ...pkg,\n type: codePackageType,\n repositoryName,\n }),\n );\n } catch (error) {\n throw new Error(`Error scanning globs ${supportedFiles} with error: ${error}`);\n }\n }),\n );\n\n return allCodePackages.flat();\n}\n","import { execSync } from 'child_process';\n\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\n\nimport { ADMIN_DASH } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { findCodePackagesInFolder } from '../../../lib/code-scanning/index.js';\nimport { syncCodePackages } from '../../../lib/graphql/index.js';\n\nconst REPO_ERROR =\n 'A repository name must be provided. ' +\n 'You can specify using --repositoryName=$REPO_NAME or by ensuring the ' +\n 'command \"git config --get remote.origin.url\" returns the name of the repository';\n\nexport interface ScanPackagesCommandFlags {\n auth: string;\n scanPath: string;\n ignoreDirs?: string[];\n repositoryName?: string;\n transcendUrl: string;\n}\n\nexport async function scanPackages(\n this: LocalContext,\n { auth, scanPath, ignoreDirs, repositoryName, transcendUrl }: ScanPackagesCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n // Ensure repository name is specified\n let gitRepositoryName = repositoryName;\n if (!gitRepositoryName) {\n try {\n const name = execSync(`cd ${scanPath} && git config --get remote.origin.url`);\n // Trim and parse the URL\n const url = name.toString('utf-8').trim();\n [gitRepositoryName] = !url.includes('https:')\n ? (url.split(':').pop() || '').split('.')\n : url.split('/').slice(3).join('/').split('.');\n if (!gitRepositoryName) {\n this.logger.error(colors.red(REPO_ERROR));\n this.process.exit(1);\n }\n } catch (err) {\n this.logger.error(colors.red(`${REPO_ERROR} - Got error: ${err.message}`));\n this.process.exit(1);\n }\n }\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Scan the codebase to discovery packages\n const results = await findCodePackagesInFolder({\n scanPath,\n ignoreDirs,\n repositoryName: gitRepositoryName,\n });\n\n // Report scan to Transcend\n await syncCodePackages(client, results);\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/code-scanning/code-packages';\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Scan found ${results.length} packages at ${scanPath}! ` + `View results at '${newUrl.href}'`,\n ),\n );\n}\n"],"mappings":"qbAcA,eAAsB,EAAyB,CAC7C,WACA,aAAa,EAAE,CACf,kBAQ8B,CA4C9B,OAAO,MA3CuB,QAAQ,IACpC,EAAW,EAAsB,CAAC,IAAI,MAAO,CAAC,EAAiB,KAAY,CACzE,GAAM,CAAE,WAAY,EAAkB,iBAAgB,gBAAiB,EACjE,EAAe,CAAC,GAAG,EAAY,GAAG,EAAiB,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CACzF,GAAI,CACF,IAAM,EAAwB,MAAM,EAAS,GAAG,EAAS,MAAM,EAAe,KAAK,IAAI,GAAI,CACzF,OAAQ,EAAa,IAAK,GAAgB,GAAG,EAAS,MAAM,IAAM,CAClE,OAAQ,GACR,UAAW,GACZ,CAAC,CACF,EAAO,KACL,EAAO,QAAQ,aAAa,EAAY,OAAO,iBAAiB,IAAkB,CACnF,CACD,IAAM,EAAc,EACjB,IAAK,GACJ,EAAa,EAAS,CAAC,IAAK,IAAY,CACtC,GAAG,EACH,aAAc,EAAS,QAAQ,GAAG,EAAS,GAAI,GAAG,CACnD,EAAE,CACJ,CACA,MAAM,CAUT,OATA,EAAO,KACL,EAAO,MACL,UAAU,EAAY,OAAO,gBAC3B,EAAY,KAAK,CAAE,0BAA0B,EAAE,IAAO,EAAwB,CAAC,MAAM,CAClF,OACJ,OACF,CACF,CAEM,EAAY,IAChB,IAA2B,CAC1B,GAAG,EACH,KAAM,EACN,iBACD,EACF,OACM,EAAO,CACd,MAAU,MAAM,wBAAwB,EAAe,eAAe,IAAQ,GAEhF,CACH,EAEsB,MAAM,CC1D/B,MAAM,EACJ,2LAYF,eAAsB,EAEpB,CAAE,OAAM,WAAU,aAAY,iBAAgB,gBAC/B,CACf,EAAoB,KAAK,QAAQ,CAGjC,IAAI,EAAoB,EACxB,GAAI,CAAC,EACH,GAAI,CAGF,IAAM,EAFO,EAAS,MAAM,EAAS,wCAErB,CAAC,SAAS,QAAQ,CAAC,MAAM,CACzC,CAAC,GAAsB,EAAI,SAAS,SAAS,CAEzC,EAAI,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,EAD3C,EAAI,MAAM,IAAI,CAAC,KAAK,EAAI,IAAI,MAAM,IAAI,CAEtC,IACH,KAAK,OAAO,MAAM,EAAO,IAAI,EAAW,CAAC,CACzC,KAAK,QAAQ,KAAK,EAAE,QAEf,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,GAAG,EAAW,gBAAgB,EAAI,UAAU,CAAC,CAC1E,KAAK,QAAQ,KAAK,EAAE,CAKxB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAU,MAAM,EAAyB,CAC7C,WACA,aACA,eAAgB,EACjB,CAAC,CAGF,MAAM,EAAiB,EAAQ,EAAQ,CAEvC,IAAM,EAAS,IAAI,IAAI,EAAW,CAClC,EAAO,SAAW,+BAGlB,KAAK,OAAO,KACV,EAAO,MACL,cAAc,EAAQ,OAAO,eAAe,EAAS,qBAA0B,EAAO,KAAK,GAC5F,CACF"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cancelPrivacyRequests-BIgX5SDz.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,actions:r,statuses:i=[],requestIds:a,silentModeBefore:o,createdAtBefore:s,createdAtAfter:c,updatedAtBefore:l,updatedAtAfter:u,cancellationTitle:d,transcendUrl:f,concurrency:p}){t(this.process),await e({transcendUrl:f,requestActions:r,auth:n,cancellationTitle:d,requestIds:a,statuses:i,concurrency:p,silentModeBefore:o?new Date(o):void 0,createdAtBefore:s?new Date(s):void 0,createdAtAfter:c?new Date(c):void 0,updatedAtBefore:l?new Date(l):void 0,updatedAtAfter:u?new Date(u):void 0})}export{n as cancel};
2
- //# sourceMappingURL=impl-B7l4bLG5.mjs.map
1
+ import{t as e}from"./cancelPrivacyRequests-DgAhfcmg.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({auth:n,actions:r,statuses:i=[],requestIds:a,silentModeBefore:o,createdAtBefore:s,createdAtAfter:c,updatedAtBefore:l,updatedAtAfter:u,cancellationTitle:d,transcendUrl:f,concurrency:p}){t(this.process),await e({transcendUrl:f,requestActions:r,auth:n,cancellationTitle:d,requestIds:a,statuses:i,concurrency:p,silentModeBefore:o?new Date(o):void 0,createdAtBefore:s?new Date(s):void 0,createdAtAfter:c?new Date(c):void 0,updatedAtBefore:l?new Date(l):void 0,updatedAtAfter:u?new Date(u):void 0})}export{n as cancel};
2
+ //# sourceMappingURL=impl-C1hh_5On.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-B7l4bLG5.mjs","names":[],"sources":["../src/commands/request/cancel/impl.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { cancelPrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface CancelCommandFlags {\n auth: string;\n actions: RequestAction[];\n statuses?: RequestStatus[];\n requestIds?: string[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n cancellationTitle: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function cancel(\n this: LocalContext,\n {\n auth,\n actions,\n statuses = [],\n requestIds,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n cancellationTitle,\n transcendUrl,\n concurrency,\n }: CancelCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await cancelPrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n cancellationTitle,\n requestIds,\n statuses,\n concurrency,\n silentModeBefore: silentModeBefore ? new Date(silentModeBefore) : undefined,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n updatedAtBefore: updatedAtBefore ? new Date(updatedAtBefore) : undefined,\n updatedAtAfter: updatedAtAfter ? new Date(updatedAtAfter) : undefined,\n });\n}\n"],"mappings":"6GAqBA,eAAsB,EAEpB,CACE,OACA,UACA,WAAW,EAAE,CACb,aACA,mBACA,kBACA,iBACA,kBACA,iBACA,oBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAsB,CAC1B,eACA,eAAgB,EAChB,OACA,oBACA,aACA,WACA,cACA,iBAAkB,EAAmB,IAAI,KAAK,EAAiB,CAAG,IAAA,GAClE,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC7D,CAAC"}
1
+ {"version":3,"file":"impl-C1hh_5On.mjs","names":[],"sources":["../src/commands/request/cancel/impl.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { cancelPrivacyRequests } from '../../../lib/requests/index.js';\n\nexport interface CancelCommandFlags {\n auth: string;\n actions: RequestAction[];\n statuses?: RequestStatus[];\n requestIds?: string[];\n silentModeBefore?: Date;\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n updatedAtBefore?: Date;\n updatedAtAfter?: Date;\n cancellationTitle: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function cancel(\n this: LocalContext,\n {\n auth,\n actions,\n statuses = [],\n requestIds,\n silentModeBefore,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n cancellationTitle,\n transcendUrl,\n concurrency,\n }: CancelCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await cancelPrivacyRequests({\n transcendUrl,\n requestActions: actions,\n auth,\n cancellationTitle,\n requestIds,\n statuses,\n concurrency,\n silentModeBefore: silentModeBefore ? new Date(silentModeBefore) : undefined,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n updatedAtBefore: updatedAtBefore ? new Date(updatedAtBefore) : undefined,\n updatedAtAfter: updatedAtAfter ? new Date(updatedAtAfter) : undefined,\n });\n}\n"],"mappings":"6GAqBA,eAAsB,EAEpB,CACE,OACA,UACA,WAAW,EAAE,CACb,aACA,mBACA,kBACA,iBACA,kBACA,iBACA,oBACA,eACA,eAEa,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAAsB,CAC1B,eACA,eAAgB,EAChB,OACA,oBACA,aACA,WACA,cACA,iBAAkB,EAAmB,IAAI,KAAK,EAAiB,CAAG,IAAA,GAClE,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC5D,gBAAiB,EAAkB,IAAI,KAAK,EAAgB,CAAG,IAAA,GAC/D,eAAgB,EAAiB,IAAI,KAAK,EAAe,CAAG,IAAA,GAC7D,CAAC"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./uploadPrivacyRequestsFromCsv-B_hQwIn6.mjs";import{t}from"./done-input-validation-LiTaCEzF.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),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-Do2TNA3-.mjs.map
1
+ import{t as e}from"./uploadPrivacyRequestsFromCsv-B__QsguT.mjs";import{t}from"./done-input-validation-LiTaCEzF.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),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-C1vn0Y7f.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-Do2TNA3-.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);\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,CAEjC,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-C1vn0Y7f.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);\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,CAEjC,MAAM,EAA6B,CACjC,gBACA,uBACA,OACA,OACA,aACA,cACA,eACA,0BACA,WAAY,EAAe,EAAW,CACtC,QACA,iBACA,WACA,qBACA,kBACA,SACA,SACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./policyEngineCliError-CZrOHhLv.mjs";import{i as t,n,t as r}from"./printResult-Dmwv78e7.mjs";import{t as i}from"./renderTable-CZP2roD1.mjs";import{n as a}from"./resolveBundleIdByName-BPrMkU0w.mjs";import{t as o}from"./done-input-validation-LiTaCEzF.mjs";import{t as s}from"./command-output-BJcDRXNr.mjs";import c from"colors";async function l({"remote-bundle-name":l,auth:u,"transcend-url":d,limit:f,after:p,json:m,debug:h=!1}){o(this.process),e(h);let g=t(d,u),_=s(this.logger,m),v=await a(g,l);if(!v)throw Error(`Policy bundle "${l}" was not found for this organization.`);_.info(c.green(`Listing versions for bundle "${l}"...`));let y={limit:f};p&&(y.after=p);let b=await n(g.get(`v1/policy-engine/policy-bundles/${v}/versions`,{searchParams:y}).json());r(this.process.stdout,{json:m,data:b,renderTable:()=>{if(b.nodes.length===0)return p?`No more versions for bundle "${l}" (end of results).`:`No versions found for bundle "${l}".`;let e=i([`id`,`version`,`createdAt`,`activatedAt`,`deactivatedAt`],b.nodes.map(e=>[e.id,e.version,e.createdAt,e.activatedAt??`-`,e.deactivatedAt??`-`]));return b.pageInfo.endCursor&&(e+=`\n\nafter: ${b.pageInfo.endCursor}`),e}})}export{l as versions};
2
+ //# sourceMappingURL=impl-C36c5NfN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impl-C36c5NfN.mjs","names":[],"sources":["../src/commands/policy/versions/impl.ts"],"sourcesContent":["import colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { selectCommandLogger } from '../../../lib/cli/command-output.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { EMPTY_CELL } from '../constants.js';\nimport {\n buildPolicyEngineClient,\n policyEngineRequest,\n printResult,\n renderTable,\n resolveBundleIdByName,\n setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { PolicyBundleVersionListResponse } from '../types.js';\n\n/** CLI flags for `transcend policy versions`. */\nexport interface VersionsCommandFlags {\n /** Tenant-unique bundle name */\n 'remote-bundle-name': string;\n /** Transcend API key */\n auth: string;\n /** Transcend API URL */\n 'transcend-url': string;\n /** Page size */\n limit: number;\n /** Cursor from a previous page's pageInfo.endCursor */\n after?: string;\n /** Print raw JSON response */\n json: boolean;\n /** Include technical error details when a command fails */\n debug?: boolean;\n}\n\n/**\n * List versions for a policy bundle.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function versions(\n this: LocalContext,\n {\n 'remote-bundle-name': bundleName,\n auth,\n 'transcend-url': transcendUrl,\n limit,\n after,\n json,\n debug = false,\n }: VersionsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n setPolicyEngineCliDebug(debug);\n\n const client = buildPolicyEngineClient(transcendUrl, auth);\n const commandLogger = selectCommandLogger(this.logger, json);\n const bundleId = await resolveBundleIdByName(client, bundleName);\n\n if (!bundleId) {\n throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n }\n\n commandLogger.info(colors.green(`Listing versions for bundle \"${bundleName}\"...`));\n\n const searchParams: Record<string, string | number> = { limit };\n if (after) {\n searchParams.after = after;\n }\n\n const body = await policyEngineRequest(\n client\n .get(`v1/policy-engine/policy-bundles/${bundleId}/versions`, {\n searchParams,\n })\n .json<PolicyBundleVersionListResponse>(),\n );\n\n printResult(this.process.stdout, {\n json,\n data: body,\n renderTable: () => {\n if (body.nodes.length === 0) {\n // Distinguish \"this page is empty because you paginated past the end\"\n // from \"the bundle genuinely has no versions\" — the latter is already\n // surfaced during version resolution upstream.\n return after\n ? `No more versions for bundle \"${bundleName}\" (end of results).`\n : `No versions found for bundle \"${bundleName}\".`;\n }\n\n const rows = body.nodes.map((version) => [\n version.id,\n version.version,\n version.createdAt,\n version.activatedAt ?? EMPTY_CELL,\n version.deactivatedAt ?? EMPTY_CELL,\n ]);\n\n let table = renderTable(['id', 'version', 'createdAt', 'activatedAt', 'deactivatedAt'], rows);\n if (body.pageInfo.endCursor) {\n table += `\\n\\nafter: ${body.pageInfo.endCursor}`;\n }\n return table;\n },\n });\n}\n"],"mappings":"yVAwCA,eAAsB,EAEpB,CACE,qBAAsB,EACtB,OACA,gBAAiB,EACjB,QACA,QACA,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,CACjC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CACpD,EAAgB,EAAoB,KAAK,OAAQ,EAAK,CACtD,EAAW,MAAM,EAAsB,EAAQ,EAAW,CAEhE,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,EAAc,KAAK,EAAO,MAAM,gCAAgC,EAAW,MAAM,CAAC,CAElF,IAAM,EAAgD,CAAE,QAAO,CAC3D,IACF,EAAa,MAAQ,GAGvB,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,mCAAmC,EAAS,WAAY,CAC3D,eACD,CAAC,CACD,MAAuC,CAC3C,CAED,EAAY,KAAK,QAAQ,OAAQ,CAC/B,OACA,KAAM,EACN,gBAAmB,CACjB,GAAI,EAAK,MAAM,SAAW,EAIxB,OAAO,EACH,gCAAgC,EAAW,qBAC3C,iCAAiC,EAAW,IAWlD,IAAI,EAAQ,EAAY,CAAC,KAAM,UAAW,YAAa,cAAe,gBAAgB,CARzE,EAAK,MAAM,IAAK,GAAY,CACvC,EAAQ,GACR,EAAQ,QACR,EAAQ,UACR,EAAQ,aAAA,IACR,EAAQ,eAAA,IACT,CAE2F,CAAC,CAI7F,OAHI,EAAK,SAAS,YAChB,GAAS,cAAc,EAAK,SAAS,aAEhC,GAEV,CAAC"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./constants-BRsj50Nb.mjs";import{s as t}from"./writeCsv-CNZrq3zU.mjs";import{t as n}from"./pullAllDatapoints-Bm-Orhse.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{groupBy as i,uniq as a}from"lodash-es";import o from"colors";import{buildTranscendGraphQLClient as s}from"@transcend-io/sdk";async function c({auth:c,file:l,transcendUrl:u,dataSiloIds:d,includeAttributes:f,includeGuessedCategories:p,parentCategories:m,subCategories:h=[]}){r(this.process);try{let e=await n(s(u,c),{dataSiloIds:d,includeGuessedCategories:p,parentCategories:m,includeAttributes:f,subCategories:h});this.logger.info(o.magenta(`Writing datapoints to file "${l}"...`));let r=[];await t(l,e.map(e=>{let t={"Property ID":e.id,"Data Silo":e.dataSilo.title,Object:e.dataPoint.name,"Object Path":e.dataPoint.path.join(`.`),Property:e.name,"Property Description":e.description,"Data Categories":e.categories.map(e=>`${e.category}:${e.name}`).join(`, `),"Guessed Category":e.pendingCategoryGuesses?.[0]?`${e.pendingCategoryGuesses[0].category.category}:${e.pendingCategoryGuesses[0].category.name}`:``,"Processing Purposes":e.purposes.map(e=>`${e.purpose}:${e.name}`).join(`, `),...Object.entries(i(e.attributeValues||[],({attributeKey:e})=>e.name)).reduce((e,[t,n])=>(e[t]=n.map(e=>e.name).join(`,`),e),{})};return r=a([...r,...Object.keys(t)]),t}),r)}catch(e){this.logger.error(o.red(`An error occurred syncing the datapoints: ${e.message}`)),this.process.exit(1)}this.logger.info(o.green(`Successfully synced datapoints to disk at ${l}! View at ${e}`))}export{c as pullDatapoints};
2
- //# sourceMappingURL=impl-DcL-8NEa2.mjs.map
1
+ import{n as e}from"./constants-BCmVqlrM.mjs";import{s as t}from"./writeCsv-CNZrq3zU.mjs";import{t as n}from"./pullAllDatapoints-CNqQSSmF.mjs";import{t as r}from"./done-input-validation-LiTaCEzF.mjs";import{groupBy as i,uniq as a}from"lodash-es";import o from"colors";import{buildTranscendGraphQLClient as s}from"@transcend-io/sdk";async function c({auth:c,file:l,transcendUrl:u,dataSiloIds:d,includeAttributes:f,includeGuessedCategories:p,parentCategories:m,subCategories:h=[]}){r(this.process);try{let e=await n(s(u,c),{dataSiloIds:d,includeGuessedCategories:p,parentCategories:m,includeAttributes:f,subCategories:h});this.logger.info(o.magenta(`Writing datapoints to file "${l}"...`));let r=[];await t(l,e.map(e=>{let t={"Property ID":e.id,"Data Silo":e.dataSilo.title,Object:e.dataPoint.name,"Object Path":e.dataPoint.path.join(`.`),Property:e.name,"Property Description":e.description,"Data Categories":e.categories.map(e=>`${e.category}:${e.name}`).join(`, `),"Guessed Category":e.pendingCategoryGuesses?.[0]?`${e.pendingCategoryGuesses[0].category.category}:${e.pendingCategoryGuesses[0].category.name}`:``,"Processing Purposes":e.purposes.map(e=>`${e.purpose}:${e.name}`).join(`, `),...Object.entries(i(e.attributeValues||[],({attributeKey:e})=>e.name)).reduce((e,[t,n])=>(e[t]=n.map(e=>e.name).join(`,`),e),{})};return r=a([...r,...Object.keys(t)]),t}),r)}catch(e){this.logger.error(o.red(`An error occurred syncing the datapoints: ${e.message}`)),this.process.exit(1)}this.logger.info(o.green(`Successfully synced datapoints to disk at ${l}! View at ${e}`))}export{c as pullDatapoints};
2
+ //# sourceMappingURL=impl-C54oUOeM2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-DcL-8NEa2.mjs","names":[],"sources":["../src/commands/inventory/pull-datapoints/impl.ts"],"sourcesContent":["import { DataCategoryType } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { uniq, groupBy } from 'lodash-es';\n\nimport { ADMIN_DASH_DATAPOINTS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { pullAllDatapoints } from '../../../lib/data-inventory/index.js';\nimport { writeLargeCsv } from '../../../lib/helpers/index.js';\n\nexport interface PullDatapointsCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n dataSiloIds?: string[];\n includeAttributes: boolean;\n includeGuessedCategories: boolean;\n parentCategories?: DataCategoryType[];\n subCategories?: string[];\n}\n\nexport async function pullDatapoints(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n dataSiloIds,\n includeAttributes,\n includeGuessedCategories,\n parentCategories,\n subCategories = [],\n }: PullDatapointsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n try {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const dataPoints = await pullAllDatapoints(client, {\n dataSiloIds,\n includeGuessedCategories,\n parentCategories,\n includeAttributes,\n subCategories, // TODO: https://transcend.height.app/T-40482 - do by name not ID\n });\n\n this.logger.info(colors.magenta(`Writing datapoints to file \"${file}\"...`));\n let headers: string[] = [];\n const inputs = dataPoints.map((point) => {\n const result = {\n 'Property ID': point.id,\n 'Data Silo': point.dataSilo.title,\n Object: point.dataPoint.name,\n 'Object Path': point.dataPoint.path.join('.'),\n Property: point.name,\n 'Property Description': point.description,\n 'Data Categories': point.categories\n .map((category) => `${category.category}:${category.name}`)\n .join(', '),\n 'Guessed Category': point.pendingCategoryGuesses?.[0]\n ? `${point.pendingCategoryGuesses![0]!.category.category}:${\n point.pendingCategoryGuesses![0]!.category.name\n }`\n : '',\n 'Processing Purposes': point.purposes\n .map((purpose) => `${purpose.purpose}:${purpose.name}`)\n .join(', '),\n ...Object.entries(\n groupBy(point.attributeValues || [], ({ attributeKey }) => attributeKey.name),\n ).reduce(\n (acc, [key, values]) => {\n acc[key] = values.map((value) => value.name).join(',');\n return acc;\n },\n {} as Record<string, string>,\n ),\n };\n headers = uniq([...headers, ...Object.keys(result)]);\n return result;\n });\n await writeLargeCsv(file, inputs, headers);\n } catch (err) {\n this.logger.error(colors.red(`An error occurred syncing the datapoints: ${err.message}`));\n this.process.exit(1);\n }\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Successfully synced datapoints to disk at ${file}! View at ${ADMIN_DASH_DATAPOINTS}`,\n ),\n );\n}\n"],"mappings":"2UAsBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,cACA,oBACA,2BACA,mBACA,gBAAgB,EAAE,EAEL,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAI,CAIF,IAAM,EAAa,MAAM,EAFV,EAA4B,EAAc,EAER,CAAE,CACjD,cACA,2BACA,mBACA,oBACA,gBACD,CAAC,CAEF,KAAK,OAAO,KAAK,EAAO,QAAQ,+BAA+B,EAAK,MAAM,CAAC,CAC3E,IAAI,EAAoB,EAAE,CAiC1B,MAAM,EAAc,EAhCL,EAAW,IAAK,GAAU,CACvC,IAAM,EAAS,CACb,cAAe,EAAM,GACrB,YAAa,EAAM,SAAS,MAC5B,OAAQ,EAAM,UAAU,KACxB,cAAe,EAAM,UAAU,KAAK,KAAK,IAAI,CAC7C,SAAU,EAAM,KAChB,uBAAwB,EAAM,YAC9B,kBAAmB,EAAM,WACtB,IAAK,GAAa,GAAG,EAAS,SAAS,GAAG,EAAS,OAAO,CAC1D,KAAK,KAAK,CACb,mBAAoB,EAAM,yBAAyB,GAC/C,GAAG,EAAM,uBAAwB,GAAI,SAAS,SAAS,GACrD,EAAM,uBAAwB,GAAI,SAAS,OAE7C,GACJ,sBAAuB,EAAM,SAC1B,IAAK,GAAY,GAAG,EAAQ,QAAQ,GAAG,EAAQ,OAAO,CACtD,KAAK,KAAK,CACb,GAAG,OAAO,QACR,EAAQ,EAAM,iBAAmB,EAAE,EAAG,CAAE,kBAAmB,EAAa,KAAK,CAC9E,CAAC,QACC,EAAK,CAAC,EAAK,MACV,EAAI,GAAO,EAAO,IAAK,GAAU,EAAM,KAAK,CAAC,KAAK,IAAI,CAC/C,GAET,EAAE,CACH,CACF,CAED,MADA,GAAU,EAAK,CAAC,GAAG,EAAS,GAAG,OAAO,KAAK,EAAO,CAAC,CAAC,CAC7C,GAEuB,CAAE,EAAQ,OACnC,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,6CAA6C,EAAI,UAAU,CAAC,CACzF,KAAK,QAAQ,KAAK,EAAE,CAItB,KAAK,OAAO,KACV,EAAO,MACL,6CAA6C,EAAK,YAAY,IAC/D,CACF"}
1
+ {"version":3,"file":"impl-C54oUOeM2.mjs","names":[],"sources":["../src/commands/inventory/pull-datapoints/impl.ts"],"sourcesContent":["import { DataCategoryType } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient } from '@transcend-io/sdk';\nimport colors from 'colors';\nimport { uniq, groupBy } from 'lodash-es';\n\nimport { ADMIN_DASH_DATAPOINTS } from '../../../constants.js';\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { pullAllDatapoints } from '../../../lib/data-inventory/index.js';\nimport { writeLargeCsv } from '../../../lib/helpers/index.js';\n\nexport interface PullDatapointsCommandFlags {\n auth: string;\n file: string;\n transcendUrl: string;\n dataSiloIds?: string[];\n includeAttributes: boolean;\n includeGuessedCategories: boolean;\n parentCategories?: DataCategoryType[];\n subCategories?: string[];\n}\n\nexport async function pullDatapoints(\n this: LocalContext,\n {\n auth,\n file,\n transcendUrl,\n dataSiloIds,\n includeAttributes,\n includeGuessedCategories,\n parentCategories,\n subCategories = [],\n }: PullDatapointsCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n try {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const dataPoints = await pullAllDatapoints(client, {\n dataSiloIds,\n includeGuessedCategories,\n parentCategories,\n includeAttributes,\n subCategories, // TODO: https://transcend.height.app/T-40482 - do by name not ID\n });\n\n this.logger.info(colors.magenta(`Writing datapoints to file \"${file}\"...`));\n let headers: string[] = [];\n const inputs = dataPoints.map((point) => {\n const result = {\n 'Property ID': point.id,\n 'Data Silo': point.dataSilo.title,\n Object: point.dataPoint.name,\n 'Object Path': point.dataPoint.path.join('.'),\n Property: point.name,\n 'Property Description': point.description,\n 'Data Categories': point.categories\n .map((category) => `${category.category}:${category.name}`)\n .join(', '),\n 'Guessed Category': point.pendingCategoryGuesses?.[0]\n ? `${point.pendingCategoryGuesses![0]!.category.category}:${\n point.pendingCategoryGuesses![0]!.category.name\n }`\n : '',\n 'Processing Purposes': point.purposes\n .map((purpose) => `${purpose.purpose}:${purpose.name}`)\n .join(', '),\n ...Object.entries(\n groupBy(point.attributeValues || [], ({ attributeKey }) => attributeKey.name),\n ).reduce(\n (acc, [key, values]) => {\n acc[key] = values.map((value) => value.name).join(',');\n return acc;\n },\n {} as Record<string, string>,\n ),\n };\n headers = uniq([...headers, ...Object.keys(result)]);\n return result;\n });\n await writeLargeCsv(file, inputs, headers);\n } catch (err) {\n this.logger.error(colors.red(`An error occurred syncing the datapoints: ${err.message}`));\n this.process.exit(1);\n }\n\n // Indicate success\n this.logger.info(\n colors.green(\n `Successfully synced datapoints to disk at ${file}! View at ${ADMIN_DASH_DATAPOINTS}`,\n ),\n );\n}\n"],"mappings":"2UAsBA,eAAsB,EAEpB,CACE,OACA,OACA,eACA,cACA,oBACA,2BACA,mBACA,gBAAgB,EAAE,EAEL,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAI,CAIF,IAAM,EAAa,MAAM,EAFV,EAA4B,EAAc,EAER,CAAE,CACjD,cACA,2BACA,mBACA,oBACA,gBACD,CAAC,CAEF,KAAK,OAAO,KAAK,EAAO,QAAQ,+BAA+B,EAAK,MAAM,CAAC,CAC3E,IAAI,EAAoB,EAAE,CAiC1B,MAAM,EAAc,EAhCL,EAAW,IAAK,GAAU,CACvC,IAAM,EAAS,CACb,cAAe,EAAM,GACrB,YAAa,EAAM,SAAS,MAC5B,OAAQ,EAAM,UAAU,KACxB,cAAe,EAAM,UAAU,KAAK,KAAK,IAAI,CAC7C,SAAU,EAAM,KAChB,uBAAwB,EAAM,YAC9B,kBAAmB,EAAM,WACtB,IAAK,GAAa,GAAG,EAAS,SAAS,GAAG,EAAS,OAAO,CAC1D,KAAK,KAAK,CACb,mBAAoB,EAAM,yBAAyB,GAC/C,GAAG,EAAM,uBAAwB,GAAI,SAAS,SAAS,GACrD,EAAM,uBAAwB,GAAI,SAAS,OAE7C,GACJ,sBAAuB,EAAM,SAC1B,IAAK,GAAY,GAAG,EAAQ,QAAQ,GAAG,EAAQ,OAAO,CACtD,KAAK,KAAK,CACb,GAAG,OAAO,QACR,EAAQ,EAAM,iBAAmB,EAAE,EAAG,CAAE,kBAAmB,EAAa,KAAK,CAC9E,CAAC,QACC,EAAK,CAAC,EAAK,MACV,EAAI,GAAO,EAAO,IAAK,GAAU,EAAM,KAAK,CAAC,KAAK,IAAI,CAC/C,GAET,EAAE,CACH,CACF,CAED,MADA,GAAU,EAAK,CAAC,GAAG,EAAS,GAAG,OAAO,KAAK,EAAO,CAAC,CAAC,CAC7C,GAEuB,CAAE,EAAQ,OACnC,EAAK,CACZ,KAAK,OAAO,MAAM,EAAO,IAAI,6CAA6C,EAAI,UAAU,CAAC,CACzF,KAAK,QAAQ,KAAK,EAAE,CAItB,KAAK,OAAO,KACV,EAAO,MACL,6CAA6C,EAAK,YAAY,IAC/D,CACF"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./pushCronIdentifiersFromCsv-DhS2z8IG.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o}){t(this.process),await e({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o})}export{n as markIdentifiersCompleted};
2
- //# sourceMappingURL=impl-HUfaARep.mjs.map
1
+ import{t as e}from"./pushCronIdentifiersFromCsv-DeS78zyp.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";async function n({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o}){t(this.process),await e({file:n,transcendUrl:r,auth:i,sombraAuth:a,dataSiloId:o})}export{n as markIdentifiersCompleted};
2
+ //# sourceMappingURL=impl-CKg5Xu-r.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-HUfaARep.mjs","names":[],"sources":["../src/commands/request/cron/mark-identifiers-completed/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushCronIdentifiersFromCsv } from '../../../../lib/cron/index.js';\n\nexport interface MarkIdentifiersCompletedCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n}\n\nexport async function markIdentifiersCompleted(\n this: LocalContext,\n { file, transcendUrl, auth, sombraAuth, dataSiloId }: MarkIdentifiersCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await pushCronIdentifiersFromCsv({\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n });\n}\n"],"mappings":"kHAYA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,aAAY,cACzB,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAA2B,CAC/B,OACA,eACA,OACA,aACA,aACD,CAAC"}
1
+ {"version":3,"file":"impl-CKg5Xu-r.mjs","names":[],"sources":["../src/commands/request/cron/mark-identifiers-completed/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context.js';\nimport { doneInputValidation } from '../../../../lib/cli/done-input-validation.js';\nimport { pushCronIdentifiersFromCsv } from '../../../../lib/cron/index.js';\n\nexport interface MarkIdentifiersCompletedCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n}\n\nexport async function markIdentifiersCompleted(\n this: LocalContext,\n { file, transcendUrl, auth, sombraAuth, dataSiloId }: MarkIdentifiersCompletedCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process);\n\n await pushCronIdentifiersFromCsv({\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n });\n}\n"],"mappings":"kHAYA,eAAsB,EAEpB,CAAE,OAAM,eAAc,OAAM,aAAY,cACzB,CACf,EAAoB,KAAK,QAAQ,CAEjC,MAAM,EAA2B,CAC/B,OACA,eACA,OACA,aACA,aACD,CAAC"}
@@ -1,3 +1,3 @@
1
- import{i as e,n as t,o as n,t as r}from"./policy-project-discovery-C29UxWwt.mjs";import{c as i,i as a,l as o,o as s,s as c}from"./policy-runtime-6jmkXlBk.mjs";import{n as l}from"./policy-bundle-manifest-BZnBMZQq.mjs";import{n as u}from"./inquirer-BU5IpgA8.mjs";import{t as d}from"./done-input-validation-LiTaCEzF.mjs";import{r as f}from"./prompts-BhXfYD6g.mjs";import{t as p}from"./run-captured-process-BjaSDWXG.mjs";import m from"node:path";import h from"colors";const g=[`manifest`,`opa-version`,`regal-version`,`format`,`opa-check`,`regal-lint`,`opa-test`],_={manifest:`Manifest and package roots`,"opa-version":`OPA 1.x`,"regal-version":`Regal`,format:`OPA formatting`,"opa-check":`OPA strict check`,"regal-lint":`Regal lint`,"opa-test":`OPA tests`};function v(e,t){return[e.stdout.trim(),e.stderr.trim()].filter(Boolean).join(`
2
- `)||t}function y(e,t){return[...new Set(e.split(/\r?\n/gu).map(e=>e.trim()).filter(Boolean).map(e=>m.isAbsolute(e)?m.relative(t,e).split(m.sep).join(`/`):e.split(m.sep).join(`/`)))].sort()}function b(e,t,n=t){return e.fs.readdirSync(n,{withFileTypes:!0}).sort((e,t)=>e.name.localeCompare(t.name)).flatMap(r=>{let i=m.join(n,r.name);return r.isDirectory()?b(e,t,i):!r.isFile()||!r.name.endsWith(`.rego`)?[]:[{path:m.relative(t,i).split(m.sep).join(`/`),contents:e.fs.readFileSync(i,`utf8`)}]})}function x(e,t){let n=t;for(;;){let t=m.join(n,`.regal`,`config.yaml`);if(e.fs.existsSync(t))return t;let r=m.join(n,`.regal.yaml`);if(e.fs.existsSync(r))return r;let i=m.dirname(n);if(i===n)return;n=i}}function S(e,t,n){n?e.logger.info(`${h.bold(n)}\n`):e.logger.info(`${h.bold(`Policy verification`)}\n`),t.checks.forEach(({name:n,status:r})=>{let i=r===`passed`?`PASS`:r===`failed`?`FAIL`:`SKIP`,a=r===`passed`?h.green(i):r===`failed`?h.red(i):h.yellow(i),o=n===`opa-version`&&t.tools.opa?` (${t.tools.opa})`:n===`regal-version`&&t.tools.regal?` (${t.tools.regal})`:``;e.logger.info(`${a} ${_[n]}${o}`)}),t.diagnostics.length>0&&e.logger.error(``),t.diagnostics.forEach(t=>{let n=t.path?`${t.path}: `:``;e.logger.error(h.red(`error [${t.code}]: ${n}${t.message}`))}),t.status===`passed`?(e.logger.info(``),e.logger.info(h.green(`Policy verification passed.`))):(e.logger.error(``),e.logger.error(h.red(`Policy verification failed.`)))}async function C({fix:e,noInteractive:t,json:r},d,p){let _=g.map(e=>({name:e,status:`skipped`})),S=[],C={version:1,status:`passed`,directory:d,fix:e,tools:{opa:null,regal:null},checks:_,unformattedFiles:[],fixedFiles:[],diagnostics:S},w=(e,t)=>{_.find(t=>t.name===e).status=t},T=(e,t,n)=>{S.push({code:e,severity:`error`,message:t,...n?{path:n}:{}})};if(!this.fs.existsSync(d)||!this.fs.statSync(d).isDirectory())return w(`manifest`,`failed`),T(`project.directory`,`Policy directory does not exist or is not a directory: ${d}`,m.relative(this.process.cwd(),d)),C.status=`failed`,C;let E=m.join(d,n);try{l(this.fs.existsSync(E)?this.fs.readFileSync(E,`utf8`):void 0,b(this,d)),w(`manifest`,`passed`)}catch(e){w(`manifest`,`failed`),T(`manifest.invalid`,e instanceof Error?e.message:String(e),m.relative(this.process.cwd(),E))}let D=await p(`opa`,[`version`],{cwd:d},this);if(D.error?.code===`ENOENT`)w(`opa-version`,`failed`),T(`opa.missing`,a);else{let e=`${D.stdout}\n${D.stderr}`,t=i(e);D.code!==0||t?(w(`opa-version`,`failed`),T(`opa.version`,t??v(D,`Unable to determine the installed OPA version.`))):(C.tools.opa=c(e).version,w(`opa-version`,`passed`))}let O=await p(`regal`,[`version`],{cwd:d},this);if(O.error?.code===`ENOENT`)w(`regal-version`,`failed`),T(`regal.missing`,s);else{let e=`${O.stdout}\n${O.stderr}`,t=o(e);O.code!==0||t?(w(`regal-version`,`failed`),T(`regal.version`,t??v(O,`Unable to determine the installed Regal version.`))):(C.tools.regal=c(e).version,w(`regal-version`,`passed`))}if(C.tools.opa){let n=await p(`opa`,[`fmt`,`--list`,d],{cwd:d},this);if(n.code!==0)w(`format`,`failed`),T(`opa.format`,v(n,`opa fmt --list failed with exit code ${n.code}`));else if(C.unformattedFiles=y(n.stdout,d),C.unformattedFiles.length===0)w(`format`,`passed`);else{let n=e,i=f({json:r,noInteractive:t},this.process.stdin.isTTY,this.process.stderr.isTTY);if(!r&&!e){this.logger.error(h.red(`Policy files are not formatted:`)),C.unformattedFiles.forEach(e=>{this.logger.error(h.red(` - ${e}`))});let e=await p(`opa`,[`fmt`,`--diff`,d],{cwd:d},this),t=e.stdout.trim()||e.stderr.trim();t&&(this.logger.error(``),this.logger.error(t))}if(!e&&i)try{n=await u({message:`Format the unformatted policy files listed above?`})}catch(e){let t=e instanceof Error?e.message:String(e);throw/force closed|prompt.*cancel|user.*close|SIGINT/iu.test(t)&&this.process.exit(130),e}if(n){let e=await p(`opa`,[`fmt`,`--write`,d],{cwd:d},this);e.code===0?(C.fixedFiles=[...C.unformattedFiles],w(`format`,`passed`)):(w(`format`,`failed`),T(`opa.format-fix`,v(e,`opa fmt --write failed with exit code ${e.code}`)))}else w(`format`,`failed`),T(`opa.format-required`,"Policy files are not formatted. Re-run `transcend policy lint --fix` to repair them.")}let i=await p(`opa`,[`check`,`--strict`,`--ignore`,`*_test.rego`,d],{cwd:d},this);i.code===0?w(`opa-check`,`passed`):(w(`opa-check`,`failed`),T(`opa.check`,v(i,`opa check failed with exit code ${i.code}`)))}if(C.tools.regal){let e=x(this,d),t=await p(`regal`,[`lint`,`--fail-level`,`warning`,...e?[`--config-file`,e]:[],d],{cwd:d},this);t.code===0?w(`regal-lint`,`passed`):(w(`regal-lint`,`failed`),T(`regal.lint`,v(t,`regal lint failed with exit code ${t.code}`)))}if(C.tools.opa){let e=await p(`opa`,[`test`,`--fail-on-empty`,`-b`,d],{cwd:d},this);e.code===0?w(`opa-test`,`passed`):(w(`opa-test`,`failed`),T(`opa.test`,v(e,`opa test --fail-on-empty -b failed with exit code ${e.code}`)))}return C.status=_.some(({status:e})=>e===`failed`)?`failed`:`passed`,C}async function w(n,i=r,a=p){d(this.process);let{fix:o=!1,noInteractive:s=!1,json:c=!1}=n,l=e(this.process.cwd(),i);if(!this.fs.existsSync(l)||!this.fs.statSync(l).isDirectory()){let e={version:1,status:`failed`,directory:l,fix:o,tools:{opa:null,regal:null},checks:g.map(e=>({name:e,status:e===`manifest`?`failed`:`skipped`})),unformattedFiles:[],fixedFiles:[],diagnostics:[{code:`project.directory`,severity:`error`,message:`Policy directory does not exist or is not a directory: ${l}`,path:m.relative(this.process.cwd(),l)}]};c?this.process.stdout.write(`${JSON.stringify(e)}\n`):S(this,e),this.process.exitCode=1;return}let u=t(this,l);if(u.length===0){let e={version:1,status:`failed`,directory:l,fix:o,tools:{opa:null,regal:null},checks:g.map(e=>({name:e,status:e===`manifest`?`failed`:`skipped`})),unformattedFiles:[],fixedFiles:[],diagnostics:[{code:`project.bundles`,severity:`error`,message:"No publishable policy bundles found. Add one with `transcend policy new`, or pass a directory that contains a `.manifest`.",path:m.relative(this.process.cwd(),l)||`.`}]};c?this.process.stdout.write(`${JSON.stringify(e)}\n`):S(this,e),this.process.exitCode=1;return}let f=[];for(let e of u)f.push(await C.call(this,{fix:o,noInteractive:s,json:c},e,a));let h=f.some(e=>e.status===`failed`);if(c)if(f.length===1)this.process.stdout.write(`${JSON.stringify(f[0])}\n`);else{let e={version:2,status:h?`failed`:`passed`,directory:l,fix:o,results:f};this.process.stdout.write(`${JSON.stringify(e)}\n`)}else f.length===1?S(this,f[0]):f.forEach((e,t)=>{t>0&&this.logger.info(``);let n=m.relative(this.process.cwd(),e.directory)||e.directory;S(this,e,`Policy verification — ${n}`)});h&&(this.process.exitCode=1)}export{w as lint};
3
- //# sourceMappingURL=impl-B440iuvL.mjs.map
1
+ import{c as e,i as t,n,t as r}from"./policy-project-discovery-DV5PnFJq.mjs";import{c as i,i as a,l as o,o as s,s as c}from"./policy-runtime-6jmkXlBk.mjs";import{n as l}from"./policy-bundle-manifest-BDey6EBs.mjs";import{n as u}from"./inquirer-jzIQWAvq.mjs";import{t as d}from"./done-input-validation-LiTaCEzF.mjs";import{r as f}from"./prompts-BhXfYD6g.mjs";import{t as p}from"./run-captured-process-BjaSDWXG.mjs";import m from"node:path";import h from"colors";const g=[`manifest`,`opa-version`,`regal-version`,`format`,`opa-check`,`regal-lint`,`opa-test`],_={manifest:`Manifest and package roots`,"opa-version":`OPA 1.x`,"regal-version":`Regal`,format:`OPA formatting`,"opa-check":`OPA strict check`,"regal-lint":`Regal lint`,"opa-test":`OPA tests`};function v(e,t){return[e.stdout.trim(),e.stderr.trim()].filter(Boolean).join(`
2
+ `)||t}function y(e,t){return[...new Set(e.split(/\r?\n/gu).map(e=>e.trim()).filter(Boolean).map(e=>m.isAbsolute(e)?m.relative(t,e).split(m.sep).join(`/`):e.split(m.sep).join(`/`)))].sort()}function b(e,t,n=t){return e.fs.readdirSync(n,{withFileTypes:!0}).sort((e,t)=>e.name.localeCompare(t.name)).flatMap(r=>{let i=m.join(n,r.name);return r.isDirectory()?b(e,t,i):!r.isFile()||!r.name.endsWith(`.rego`)?[]:[{path:m.relative(t,i).split(m.sep).join(`/`),contents:e.fs.readFileSync(i,`utf8`)}]})}function x(e,t){let n=t;for(;;){let t=m.join(n,`.regal`,`config.yaml`);if(e.fs.existsSync(t))return t;let r=m.join(n,`.regal.yaml`);if(e.fs.existsSync(r))return r;let i=m.dirname(n);if(i===n)return;n=i}}function S(e,t,n){n?e.logger.info(`${h.bold(n)}\n`):e.logger.info(`${h.bold(`Policy verification`)}\n`),t.checks.forEach(({name:n,status:r})=>{let i=r===`passed`?`PASS`:r===`failed`?`FAIL`:`SKIP`,a=r===`passed`?h.green(i):r===`failed`?h.red(i):h.yellow(i),o=n===`opa-version`&&t.tools.opa?` (${t.tools.opa})`:n===`regal-version`&&t.tools.regal?` (${t.tools.regal})`:``;e.logger.info(`${a} ${_[n]}${o}`)}),t.diagnostics.length>0&&e.logger.error(``),t.diagnostics.forEach(t=>{let n=t.path?`${t.path}: `:``;e.logger.error(h.red(`error [${t.code}]: ${n}${t.message}`))}),t.status===`passed`?(e.logger.info(``),e.logger.info(h.green(`Policy verification passed.`))):(e.logger.error(``),e.logger.error(h.red(`Policy verification failed.`)))}async function C({fix:t,noInteractive:n,json:r},d,p){let _=g.map(e=>({name:e,status:`skipped`})),S=[],C={version:1,status:`passed`,directory:d,fix:t,tools:{opa:null,regal:null},checks:_,unformattedFiles:[],fixedFiles:[],diagnostics:S},w=(e,t)=>{_.find(t=>t.name===e).status=t},T=(e,t,n)=>{S.push({code:e,severity:`error`,message:t,...n?{path:n}:{}})};if(!this.fs.existsSync(d)||!this.fs.statSync(d).isDirectory())return w(`manifest`,`failed`),T(`project.directory`,`Policy directory does not exist or is not a directory: ${d}`,m.relative(this.process.cwd(),d)),C.status=`failed`,C;let E=m.join(d,e);try{l(this.fs.existsSync(E)?this.fs.readFileSync(E,`utf8`):void 0,b(this,d)),w(`manifest`,`passed`)}catch(e){w(`manifest`,`failed`),T(`manifest.invalid`,e instanceof Error?e.message:String(e),m.relative(this.process.cwd(),E))}let D=await p(`opa`,[`version`],{cwd:d},this);if(D.error?.code===`ENOENT`)w(`opa-version`,`failed`),T(`opa.missing`,a);else{let e=`${D.stdout}\n${D.stderr}`,t=i(e);D.code!==0||t?(w(`opa-version`,`failed`),T(`opa.version`,t??v(D,`Unable to determine the installed OPA version.`))):(C.tools.opa=c(e).version,w(`opa-version`,`passed`))}let O=await p(`regal`,[`version`],{cwd:d},this);if(O.error?.code===`ENOENT`)w(`regal-version`,`failed`),T(`regal.missing`,s);else{let e=`${O.stdout}\n${O.stderr}`,t=o(e);O.code!==0||t?(w(`regal-version`,`failed`),T(`regal.version`,t??v(O,`Unable to determine the installed Regal version.`))):(C.tools.regal=c(e).version,w(`regal-version`,`passed`))}if(C.tools.opa){let e=await p(`opa`,[`fmt`,`--list`,d],{cwd:d},this);if(e.code!==0)w(`format`,`failed`),T(`opa.format`,v(e,`opa fmt --list failed with exit code ${e.code}`));else if(C.unformattedFiles=y(e.stdout,d),C.unformattedFiles.length===0)w(`format`,`passed`);else{let e=t,i=f({json:r,noInteractive:n},this.process.stdin.isTTY,this.process.stderr.isTTY);if(!r&&!t){this.logger.error(h.red(`Policy files are not formatted:`)),C.unformattedFiles.forEach(e=>{this.logger.error(h.red(` - ${e}`))});let e=await p(`opa`,[`fmt`,`--diff`,d],{cwd:d},this),t=e.stdout.trim()||e.stderr.trim();t&&(this.logger.error(``),this.logger.error(t))}if(!t&&i)try{e=await u({message:`Format the unformatted policy files listed above?`})}catch(e){let t=e instanceof Error?e.message:String(e);throw/force closed|prompt.*cancel|user.*close|SIGINT/iu.test(t)&&this.process.exit(130),e}if(e){let e=await p(`opa`,[`fmt`,`--write`,d],{cwd:d},this);e.code===0?(C.fixedFiles=[...C.unformattedFiles],w(`format`,`passed`)):(w(`format`,`failed`),T(`opa.format-fix`,v(e,`opa fmt --write failed with exit code ${e.code}`)))}else w(`format`,`failed`),T(`opa.format-required`,"Policy files are not formatted. Re-run `transcend policy lint --fix` to repair them.")}let i=await p(`opa`,[`check`,`--strict`,`--ignore`,`*_test.rego`,d],{cwd:d},this);i.code===0?w(`opa-check`,`passed`):(w(`opa-check`,`failed`),T(`opa.check`,v(i,`opa check failed with exit code ${i.code}`)))}if(C.tools.regal){let e=x(this,d),t=await p(`regal`,[`lint`,`--fail-level`,`warning`,...e?[`--config-file`,e]:[],d],{cwd:d},this);t.code===0?w(`regal-lint`,`passed`):(w(`regal-lint`,`failed`),T(`regal.lint`,v(t,`regal lint failed with exit code ${t.code}`)))}if(C.tools.opa){let e=await p(`opa`,[`test`,`--fail-on-empty`,`-b`,d],{cwd:d},this);e.code===0?w(`opa-test`,`passed`):(w(`opa-test`,`failed`),T(`opa.test`,v(e,`opa test --fail-on-empty -b failed with exit code ${e.code}`)))}return C.status=_.some(({status:e})=>e===`failed`)?`failed`:`passed`,C}async function w(e,i=r,a=p){d(this.process);let{fix:o=!1,noInteractive:s=!1,json:c=!1}=e,l=t(this.process.cwd(),i);if(!this.fs.existsSync(l)||!this.fs.statSync(l).isDirectory()){let e={version:1,status:`failed`,directory:l,fix:o,tools:{opa:null,regal:null},checks:g.map(e=>({name:e,status:e===`manifest`?`failed`:`skipped`})),unformattedFiles:[],fixedFiles:[],diagnostics:[{code:`project.directory`,severity:`error`,message:`Policy directory does not exist or is not a directory: ${l}`,path:m.relative(this.process.cwd(),l)}]};c?this.process.stdout.write(`${JSON.stringify(e)}\n`):S(this,e),this.process.exitCode=1;return}let u=n(this,l);if(u.length===0){let e={version:1,status:`failed`,directory:l,fix:o,tools:{opa:null,regal:null},checks:g.map(e=>({name:e,status:e===`manifest`?`failed`:`skipped`})),unformattedFiles:[],fixedFiles:[],diagnostics:[{code:`project.bundles`,severity:`error`,message:"No publishable policy bundles found. Add one with `transcend policy new`, or pass a directory that contains a `.manifest`.",path:m.relative(this.process.cwd(),l)||`.`}]};c?this.process.stdout.write(`${JSON.stringify(e)}\n`):S(this,e),this.process.exitCode=1;return}let f=[];for(let e of u)f.push(await C.call(this,{fix:o,noInteractive:s,json:c},e,a));let h=f.some(e=>e.status===`failed`);if(c)if(f.length===1)this.process.stdout.write(`${JSON.stringify(f[0])}\n`);else{let e={version:2,status:h?`failed`:`passed`,directory:l,fix:o,results:f};this.process.stdout.write(`${JSON.stringify(e)}\n`)}else f.length===1?S(this,f[0]):f.forEach((e,t)=>{t>0&&this.logger.info(``);let n=m.relative(this.process.cwd(),e.directory)||e.directory;S(this,e,`Policy verification — ${n}`)});h&&(this.process.exitCode=1)}export{w as lint};
3
+ //# sourceMappingURL=impl-ClhMRgQZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl-B440iuvL.mjs","names":[],"sources":["../src/lib/policy/policy-lint-model.ts","../src/lib/policy/policy-lint-output.ts","../src/commands/policy/lint/impl.ts"],"sourcesContent":["/** Stable policy lint result schema version. */\nexport const POLICY_LINT_RESULT_VERSION = 1;\n\n/** Stable multi-bundle lint result schema version. */\nexport const POLICY_LINT_MULTI_RESULT_VERSION = 2;\n\n/** Status of the full gate or an individual verification. */\nexport type PolicyLintStatus = 'passed' | 'failed' | 'skipped';\n\n/** One named policy verification. */\nexport interface PolicyLintCheck {\n /** Stable verification name. */\n name:\n | 'manifest'\n | 'opa-version'\n | 'regal-version'\n | 'format'\n | 'opa-check'\n | 'regal-lint'\n | 'opa-test';\n /** Verification outcome. */\n status: PolicyLintStatus;\n}\n\n/** Stable verification execution order. */\nexport const POLICY_LINT_CHECK_NAMES: PolicyLintCheck['name'][] = [\n 'manifest',\n 'opa-version',\n 'regal-version',\n 'format',\n 'opa-check',\n 'regal-lint',\n 'opa-test',\n];\n\n/** User-facing verification labels. */\nexport const POLICY_LINT_CHECK_LABELS: Readonly<Record<PolicyLintCheck['name'], string>> = {\n manifest: 'Manifest and package roots',\n 'opa-version': 'OPA 1.x',\n 'regal-version': 'Regal',\n format: 'OPA formatting',\n 'opa-check': 'OPA strict check',\n 'regal-lint': 'Regal lint',\n 'opa-test': 'OPA tests',\n};\n\n/** One machine-readable policy lint diagnostic. */\nexport interface PolicyLintDiagnostic {\n /** Stable diagnostic identifier. */\n code: string;\n /** Diagnostic severity. */\n severity: 'error';\n /** Human-readable detail, including captured tool output when available. */\n message: string;\n /** Optional path relative to the invocation directory. */\n path?: string;\n}\n\n/** Detected local policy tool versions. */\nexport interface PolicyLintTools {\n /** Detected OPA version, or null when missing or unsupported. */\n opa: string | null;\n /** Detected Regal version, or null when missing or unsupported. */\n regal: string | null;\n}\n\n/** Stable result emitted by `transcend policy lint --json` for one bundle. */\nexport interface PolicyLintResult {\n /** Result schema version. */\n version: typeof POLICY_LINT_RESULT_VERSION;\n /** Overall verification outcome. */\n status: Exclude<PolicyLintStatus, 'skipped'>;\n /** Absolute policy bundle directory. */\n directory: string;\n /** Whether formatting repair was explicitly requested. */\n fix: boolean;\n /** Detected supported tool versions. */\n tools: PolicyLintTools;\n /** Verification outcomes in stable execution order. */\n checks: PolicyLintCheck[];\n /** Files found to need OPA formatting, relative to the policy directory. */\n unformattedFiles: string[];\n /** Files repaired with OPA formatting, relative to the policy directory. */\n fixedFiles: string[];\n /** Ordered verification diagnostics. */\n diagnostics: PolicyLintDiagnostic[];\n}\n\n/**\n * Stable result when `transcend policy lint --json` verifies multiple bundles.\n *\n * Emitted only when the selected path is a workspace with more than one\n * publishable `*-bundle/` directory.\n */\nexport interface PolicyLintMultiResult {\n /** Result schema version. */\n version: typeof POLICY_LINT_MULTI_RESULT_VERSION;\n /** Overall verification outcome across all bundles. */\n status: Exclude<PolicyLintStatus, 'skipped'>;\n /** Absolute policy workspace directory that was searched. */\n directory: string;\n /** Whether formatting repair was explicitly requested. */\n fix: boolean;\n /** Per-bundle results in discovery order. */\n results: PolicyLintResult[];\n}\n","import path from 'node:path';\n\nimport type { CapturedProcessResult } from '../cli/run-captured-process.js';\n\n/**\n * Use captured tool output as a concise diagnostic.\n *\n * @param result - Captured process result\n * @param fallback - Message used when the tool emitted no output\n * @returns Diagnostic message\n */\nexport function getPolicyProcessFailureMessage(\n result: CapturedProcessResult,\n fallback: string,\n): string {\n const output = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join('\\n');\n return output || fallback;\n}\n\n/**\n * Convert absolute OPA formatter paths to stable project-relative paths.\n *\n * @param stdout - `opa fmt --list` output\n * @param projectDirectory - Absolute policy directory\n * @returns Sorted unique paths\n */\nexport function parseUnformattedPolicyFiles(stdout: string, projectDirectory: string): string[] {\n return [\n ...new Set(\n stdout\n .split(/\\r?\\n/gu)\n .map((file) => file.trim())\n .filter(Boolean)\n .map((file) =>\n path.isAbsolute(file)\n ? path.relative(projectDirectory, file).split(path.sep).join('/')\n : file.split(path.sep).join('/'),\n ),\n ),\n ].sort();\n}\n","import path from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport {\n runCapturedProcess,\n type CapturedProcessRunner,\n} from '../../../lib/cli/run-captured-process.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport {\n type PolicyBundleRegoFile,\n validatePolicyBundleContents,\n} from '../../../lib/policy/policy-bundle-manifest.js';\nimport {\n type PolicyLintCheck,\n type PolicyLintDiagnostic,\n type PolicyLintMultiResult,\n type PolicyLintResult,\n POLICY_LINT_CHECK_LABELS,\n POLICY_LINT_CHECK_NAMES,\n POLICY_LINT_MULTI_RESULT_VERSION,\n POLICY_LINT_RESULT_VERSION,\n} from '../../../lib/policy/policy-lint-model.js';\nimport {\n getPolicyProcessFailureMessage,\n parseUnformattedPolicyFiles,\n} from '../../../lib/policy/policy-lint-output.js';\nimport {\n DEFAULT_POLICY_PROJECT_DIRECTORY,\n discoverPolicyBundleDirectories,\n resolvePolicyProjectDirectory,\n} from '../../../lib/policy/policy-project-discovery.js';\nimport {\n OPA_MISSING_MESSAGE,\n parsePolicyToolVersion,\n REGAL_MISSING_MESSAGE,\n unsupportedOpaVersionMessage,\n unsupportedRegalVersionMessage,\n} from '../../../lib/policy/policy-runtime.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { isInteractivePromptInvocation } from '../../../lib/scaffolding/prompts.js';\n\n/** CLI flags for `transcend policy lint`. */\nexport interface LintCommandFlags {\n /** Apply OPA formatting. */\n fix: boolean;\n /** Disable the optional formatting confirmation. */\n noInteractive: boolean;\n /** Emit one stable JSON result on stdout. */\n json: boolean;\n}\n\n/**\n * Collect Rego source snapshots without following symlinks.\n *\n * @param context - CLI context\n * @param projectDirectory - Absolute policy directory\n * @param currentDirectory - Current recursive directory\n * @returns Deterministically ordered Rego snapshots\n */\nfunction collectRegoFiles(\n context: LocalContext,\n projectDirectory: string,\n currentDirectory: string = projectDirectory,\n): PolicyBundleRegoFile[] {\n return context.fs\n .readdirSync(currentDirectory, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name))\n .flatMap((entry) => {\n const absolutePath = path.join(currentDirectory, entry.name);\n if (entry.isDirectory()) {\n return collectRegoFiles(context, projectDirectory, absolutePath);\n }\n if (!entry.isFile() || !entry.name.endsWith('.rego')) {\n return [];\n }\n return [\n {\n path: path.relative(projectDirectory, absolutePath).split(path.sep).join('/'),\n contents: context.fs.readFileSync(absolutePath, 'utf8'),\n },\n ];\n });\n}\n\n/**\n * Resolve a Regal config file for a bundle, walking up to the workspace.\n *\n * @param context - CLI context\n * @param bundleDirectory - Absolute bundle directory\n * @returns Absolute config path, or undefined when none is found\n */\nfunction resolveRegalConfigFile(\n context: LocalContext,\n bundleDirectory: string,\n): string | undefined {\n let current = bundleDirectory;\n for (;;) {\n const nestedRegalConfig = path.join(current, '.regal', 'config.yaml');\n if (context.fs.existsSync(nestedRegalConfig)) {\n return nestedRegalConfig;\n }\n const rootRegalConfig = path.join(current, '.regal.yaml');\n if (context.fs.existsSync(rootRegalConfig)) {\n return rootRegalConfig;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n current = parent;\n }\n}\n\n/**\n * Render the terminal summary for a policy verification result.\n *\n * @param context - CLI context\n * @param result - Completed verification result\n * @param heading - Optional section heading when linting multiple bundles\n */\nfunction renderResult(context: LocalContext, result: PolicyLintResult, heading?: string): void {\n if (heading) {\n context.logger.info(`${colors.bold(heading)}\\n`);\n } else {\n context.logger.info(`${colors.bold('Policy verification')}\\n`);\n }\n result.checks.forEach(({ name, status }) => {\n const label = status === 'passed' ? 'PASS' : status === 'failed' ? 'FAIL' : 'SKIP';\n const styledLabel =\n status === 'passed'\n ? colors.green(label)\n : status === 'failed'\n ? colors.red(label)\n : colors.yellow(label);\n const version =\n name === 'opa-version' && result.tools.opa\n ? ` (${result.tools.opa})`\n : name === 'regal-version' && result.tools.regal\n ? ` (${result.tools.regal})`\n : '';\n context.logger.info(`${styledLabel} ${POLICY_LINT_CHECK_LABELS[name]}${version}`);\n });\n if (result.diagnostics.length > 0) {\n context.logger.error('');\n }\n result.diagnostics.forEach((diagnostic) => {\n const location = diagnostic.path ? `${diagnostic.path}: ` : '';\n context.logger.error(\n colors.red(`error [${diagnostic.code}]: ${location}${diagnostic.message}`),\n );\n });\n if (result.status === 'passed') {\n context.logger.info('');\n context.logger.info(colors.green('Policy verification passed.'));\n } else {\n context.logger.error('');\n context.logger.error(colors.red('Policy verification failed.'));\n }\n}\n\n/**\n * Verify one publishable policy bundle directory.\n *\n * @param context - CLI context\n * @param flags - Command flags\n * @param resolvedDir - Absolute bundle directory\n * @param runner - Captured subprocess runner\n * @returns Completed verification result\n */\nasync function lintBundle(\n this: LocalContext,\n { fix, noInteractive, json }: LintCommandFlags,\n resolvedDir: string,\n runner: CapturedProcessRunner,\n): Promise<PolicyLintResult> {\n const checks: PolicyLintCheck[] = POLICY_LINT_CHECK_NAMES.map((name) => ({\n name,\n status: 'skipped',\n }));\n const diagnostics: PolicyLintDiagnostic[] = [];\n const result: PolicyLintResult = {\n version: POLICY_LINT_RESULT_VERSION,\n status: 'passed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks,\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics,\n };\n const setStatus = (name: PolicyLintCheck['name'], status: PolicyLintCheck['status']): void => {\n checks.find((check) => check.name === name)!.status = status;\n };\n const addError = (code: string, message: string, diagnosticPath?: string): void => {\n diagnostics.push({\n code,\n severity: 'error',\n message,\n ...(diagnosticPath ? { path: diagnosticPath } : {}),\n });\n };\n\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n setStatus('manifest', 'failed');\n addError(\n 'project.directory',\n `Policy directory does not exist or is not a directory: ${resolvedDir}`,\n path.relative(this.process.cwd(), resolvedDir),\n );\n result.status = 'failed';\n return result;\n }\n\n const manifestPath = path.join(resolvedDir, POLICY_MANIFEST_FILENAME);\n try {\n validatePolicyBundleContents(\n this.fs.existsSync(manifestPath) ? this.fs.readFileSync(manifestPath, 'utf8') : undefined,\n collectRegoFiles(this, resolvedDir),\n );\n setStatus('manifest', 'passed');\n } catch (error) {\n setStatus('manifest', 'failed');\n addError(\n 'manifest.invalid',\n error instanceof Error ? error.message : String(error),\n path.relative(this.process.cwd(), manifestPath),\n );\n }\n\n const opaVersionResult = await runner('opa', ['version'], { cwd: resolvedDir }, this);\n if (opaVersionResult.error?.code === 'ENOENT') {\n setStatus('opa-version', 'failed');\n addError('opa.missing', OPA_MISSING_MESSAGE);\n } else {\n const opaVersionOutput = `${opaVersionResult.stdout}\\n${opaVersionResult.stderr}`;\n const unsupportedOpa = unsupportedOpaVersionMessage(opaVersionOutput);\n if (opaVersionResult.code !== 0 || unsupportedOpa) {\n setStatus('opa-version', 'failed');\n addError(\n 'opa.version',\n unsupportedOpa ??\n getPolicyProcessFailureMessage(\n opaVersionResult,\n 'Unable to determine the installed OPA version.',\n ),\n );\n } else {\n result.tools.opa = parsePolicyToolVersion(opaVersionOutput)!.version;\n setStatus('opa-version', 'passed');\n }\n }\n\n const regalVersionResult = await runner('regal', ['version'], { cwd: resolvedDir }, this);\n if (regalVersionResult.error?.code === 'ENOENT') {\n setStatus('regal-version', 'failed');\n addError('regal.missing', REGAL_MISSING_MESSAGE);\n } else {\n const regalVersionOutput = `${regalVersionResult.stdout}\\n${regalVersionResult.stderr}`;\n const unsupportedRegal = unsupportedRegalVersionMessage(regalVersionOutput);\n if (regalVersionResult.code !== 0 || unsupportedRegal) {\n setStatus('regal-version', 'failed');\n addError(\n 'regal.version',\n unsupportedRegal ??\n getPolicyProcessFailureMessage(\n regalVersionResult,\n 'Unable to determine the installed Regal version.',\n ),\n );\n } else {\n result.tools.regal = parsePolicyToolVersion(regalVersionOutput)!.version;\n setStatus('regal-version', 'passed');\n }\n }\n\n if (result.tools.opa) {\n const formatResult = await runner(\n 'opa',\n ['fmt', '--list', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (formatResult.code !== 0) {\n setStatus('format', 'failed');\n addError(\n 'opa.format',\n getPolicyProcessFailureMessage(\n formatResult,\n `opa fmt --list failed with exit code ${formatResult.code}`,\n ),\n );\n } else {\n result.unformattedFiles = parseUnformattedPolicyFiles(formatResult.stdout, resolvedDir);\n if (result.unformattedFiles.length === 0) {\n setStatus('format', 'passed');\n } else {\n let shouldFormat = fix;\n const interactive = isInteractivePromptInvocation(\n { json, noInteractive },\n this.process.stdin.isTTY,\n this.process.stderr.isTTY,\n );\n if (!json && !fix) {\n this.logger.error(colors.red('Policy files are not formatted:'));\n result.unformattedFiles.forEach((file) => {\n this.logger.error(colors.red(` - ${file}`));\n });\n const diffResult = await runner(\n 'opa',\n ['fmt', '--diff', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n const diff = diffResult.stdout.trim() || diffResult.stderr.trim();\n if (diff) {\n this.logger.error('');\n this.logger.error(diff);\n }\n }\n if (!fix && interactive) {\n try {\n shouldFormat = await inquirerConfirmBoolean({\n message: 'Format the unformatted policy files listed above?',\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/force closed|prompt.*cancel|user.*close|SIGINT/iu.test(message)) {\n this.process.exit(130);\n }\n throw error;\n }\n }\n if (shouldFormat) {\n const writeResult = await runner(\n 'opa',\n ['fmt', '--write', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (writeResult.code === 0) {\n result.fixedFiles = [...result.unformattedFiles];\n setStatus('format', 'passed');\n } else {\n setStatus('format', 'failed');\n addError(\n 'opa.format-fix',\n getPolicyProcessFailureMessage(\n writeResult,\n `opa fmt --write failed with exit code ${writeResult.code}`,\n ),\n );\n }\n } else {\n setStatus('format', 'failed');\n addError(\n 'opa.format-required',\n 'Policy files are not formatted. Re-run `transcend policy lint --fix` to repair them.',\n );\n }\n }\n }\n\n const checkResult = await runner(\n 'opa',\n ['check', '--strict', '--ignore', '*_test.rego', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (checkResult.code === 0) {\n setStatus('opa-check', 'passed');\n } else {\n setStatus('opa-check', 'failed');\n addError(\n 'opa.check',\n getPolicyProcessFailureMessage(\n checkResult,\n `opa check failed with exit code ${checkResult.code}`,\n ),\n );\n }\n }\n\n if (result.tools.regal) {\n const regalConfig = resolveRegalConfigFile(this, resolvedDir);\n const regalResult = await runner(\n 'regal',\n [\n 'lint',\n '--fail-level',\n 'warning',\n ...(regalConfig ? ['--config-file', regalConfig] : []),\n resolvedDir,\n ],\n { cwd: resolvedDir },\n this,\n );\n if (regalResult.code === 0) {\n setStatus('regal-lint', 'passed');\n } else {\n setStatus('regal-lint', 'failed');\n addError(\n 'regal.lint',\n getPolicyProcessFailureMessage(\n regalResult,\n `regal lint failed with exit code ${regalResult.code}`,\n ),\n );\n }\n }\n\n if (result.tools.opa) {\n const testResult = await runner(\n 'opa',\n ['test', '--fail-on-empty', '-b', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (testResult.code === 0) {\n setStatus('opa-test', 'passed');\n } else {\n setStatus('opa-test', 'failed');\n addError(\n 'opa.test',\n getPolicyProcessFailureMessage(\n testResult,\n `opa test --fail-on-empty -b failed with exit code ${testResult.code}`,\n ),\n );\n }\n }\n\n result.status = checks.some(({ status }) => status === 'failed') ? 'failed' : 'passed';\n return result;\n}\n\n/**\n * Verify local policy bundles with the shared upload contract, OPA, and Regal.\n *\n * With no directory (or the default workspace path), discovers every immediate\n * child that contains a `.manifest` and verifies each. Pass one bundle path to\n * verify a single publishable unit.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy workspace or bundle directory\n * @param runner - Captured subprocess runner\n */\nexport async function lint(\n this: LocalContext,\n flags: LintCommandFlags,\n directory: string = DEFAULT_POLICY_PROJECT_DIRECTORY,\n runner: CapturedProcessRunner = runCapturedProcess,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const { fix = false, noInteractive = false, json = false } = flags;\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n const missing: PolicyLintResult = {\n version: POLICY_LINT_RESULT_VERSION,\n status: 'failed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks: POLICY_LINT_CHECK_NAMES.map((name) => ({\n name,\n status: name === 'manifest' ? 'failed' : 'skipped',\n })),\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics: [\n {\n code: 'project.directory',\n severity: 'error',\n message: `Policy directory does not exist or is not a directory: ${resolvedDir}`,\n path: path.relative(this.process.cwd(), resolvedDir),\n },\n ],\n };\n if (json) {\n this.process.stdout.write(`${JSON.stringify(missing)}\\n`);\n } else {\n renderResult(this, missing);\n }\n this.process.exitCode = 1;\n return;\n }\n\n const bundleDirectories = discoverPolicyBundleDirectories(this, resolvedDir);\n if (bundleDirectories.length === 0) {\n const empty: PolicyLintResult = {\n version: POLICY_LINT_RESULT_VERSION,\n status: 'failed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks: POLICY_LINT_CHECK_NAMES.map((name) => ({\n name,\n status: name === 'manifest' ? 'failed' : 'skipped',\n })),\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics: [\n {\n code: 'project.bundles',\n severity: 'error',\n message:\n 'No publishable policy bundles found. Add one with `transcend policy new`, ' +\n 'or pass a directory that contains a `.manifest`.',\n path: path.relative(this.process.cwd(), resolvedDir) || '.',\n },\n ],\n };\n if (json) {\n this.process.stdout.write(`${JSON.stringify(empty)}\\n`);\n } else {\n renderResult(this, empty);\n }\n this.process.exitCode = 1;\n return;\n }\n\n const results: PolicyLintResult[] = [];\n for (const bundleDirectory of bundleDirectories) {\n results.push(\n await lintBundle.call(this, { fix, noInteractive, json }, bundleDirectory, runner),\n );\n }\n\n const failed = results.some((result) => result.status === 'failed');\n if (json) {\n if (results.length === 1) {\n this.process.stdout.write(`${JSON.stringify(results[0])}\\n`);\n } else {\n const multi: PolicyLintMultiResult = {\n version: POLICY_LINT_MULTI_RESULT_VERSION,\n status: failed ? 'failed' : 'passed',\n directory: resolvedDir,\n fix,\n results,\n };\n this.process.stdout.write(`${JSON.stringify(multi)}\\n`);\n }\n } else if (results.length === 1) {\n renderResult(this, results[0]!);\n } else {\n results.forEach((result, index) => {\n if (index > 0) {\n this.logger.info('');\n }\n const relative = path.relative(this.process.cwd(), result.directory) || result.directory;\n renderResult(this, result, `Policy verification — ${relative}`);\n });\n }\n\n if (failed) {\n this.process.exitCode = 1;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"impl-ClhMRgQZ.mjs","names":[],"sources":["../src/lib/policy/policy-lint-model.ts","../src/lib/policy/policy-lint-output.ts","../src/commands/policy/lint/impl.ts"],"sourcesContent":["/** Stable policy lint result schema version. */\nexport const POLICY_LINT_RESULT_VERSION = 1;\n\n/** Stable multi-bundle lint result schema version. */\nexport const POLICY_LINT_MULTI_RESULT_VERSION = 2;\n\n/** Status of the full gate or an individual verification. */\nexport type PolicyLintStatus = 'passed' | 'failed' | 'skipped';\n\n/** One named policy verification. */\nexport interface PolicyLintCheck {\n /** Stable verification name. */\n name:\n | 'manifest'\n | 'opa-version'\n | 'regal-version'\n | 'format'\n | 'opa-check'\n | 'regal-lint'\n | 'opa-test';\n /** Verification outcome. */\n status: PolicyLintStatus;\n}\n\n/** Stable verification execution order. */\nexport const POLICY_LINT_CHECK_NAMES: PolicyLintCheck['name'][] = [\n 'manifest',\n 'opa-version',\n 'regal-version',\n 'format',\n 'opa-check',\n 'regal-lint',\n 'opa-test',\n];\n\n/** User-facing verification labels. */\nexport const POLICY_LINT_CHECK_LABELS: Readonly<Record<PolicyLintCheck['name'], string>> = {\n manifest: 'Manifest and package roots',\n 'opa-version': 'OPA 1.x',\n 'regal-version': 'Regal',\n format: 'OPA formatting',\n 'opa-check': 'OPA strict check',\n 'regal-lint': 'Regal lint',\n 'opa-test': 'OPA tests',\n};\n\n/** One machine-readable policy lint diagnostic. */\nexport interface PolicyLintDiagnostic {\n /** Stable diagnostic identifier. */\n code: string;\n /** Diagnostic severity. */\n severity: 'error';\n /** Human-readable detail, including captured tool output when available. */\n message: string;\n /** Optional path relative to the invocation directory. */\n path?: string;\n}\n\n/** Detected local policy tool versions. */\nexport interface PolicyLintTools {\n /** Detected OPA version, or null when missing or unsupported. */\n opa: string | null;\n /** Detected Regal version, or null when missing or unsupported. */\n regal: string | null;\n}\n\n/** Stable result emitted by `transcend policy lint --json` for one bundle. */\nexport interface PolicyLintResult {\n /** Result schema version. */\n version: typeof POLICY_LINT_RESULT_VERSION;\n /** Overall verification outcome. */\n status: Exclude<PolicyLintStatus, 'skipped'>;\n /** Absolute policy bundle directory. */\n directory: string;\n /** Whether formatting repair was explicitly requested. */\n fix: boolean;\n /** Detected supported tool versions. */\n tools: PolicyLintTools;\n /** Verification outcomes in stable execution order. */\n checks: PolicyLintCheck[];\n /** Files found to need OPA formatting, relative to the policy directory. */\n unformattedFiles: string[];\n /** Files repaired with OPA formatting, relative to the policy directory. */\n fixedFiles: string[];\n /** Ordered verification diagnostics. */\n diagnostics: PolicyLintDiagnostic[];\n}\n\n/**\n * Stable result when `transcend policy lint --json` verifies multiple bundles.\n *\n * Emitted only when the selected path is a workspace with more than one\n * publishable `*-bundle/` directory.\n */\nexport interface PolicyLintMultiResult {\n /** Result schema version. */\n version: typeof POLICY_LINT_MULTI_RESULT_VERSION;\n /** Overall verification outcome across all bundles. */\n status: Exclude<PolicyLintStatus, 'skipped'>;\n /** Absolute policy workspace directory that was searched. */\n directory: string;\n /** Whether formatting repair was explicitly requested. */\n fix: boolean;\n /** Per-bundle results in discovery order. */\n results: PolicyLintResult[];\n}\n","import path from 'node:path';\n\nimport type { CapturedProcessResult } from '../cli/run-captured-process.js';\n\n/**\n * Use captured tool output as a concise diagnostic.\n *\n * @param result - Captured process result\n * @param fallback - Message used when the tool emitted no output\n * @returns Diagnostic message\n */\nexport function getPolicyProcessFailureMessage(\n result: CapturedProcessResult,\n fallback: string,\n): string {\n const output = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join('\\n');\n return output || fallback;\n}\n\n/**\n * Convert absolute OPA formatter paths to stable project-relative paths.\n *\n * @param stdout - `opa fmt --list` output\n * @param projectDirectory - Absolute policy directory\n * @returns Sorted unique paths\n */\nexport function parseUnformattedPolicyFiles(stdout: string, projectDirectory: string): string[] {\n return [\n ...new Set(\n stdout\n .split(/\\r?\\n/gu)\n .map((file) => file.trim())\n .filter(Boolean)\n .map((file) =>\n path.isAbsolute(file)\n ? path.relative(projectDirectory, file).split(path.sep).join('/')\n : file.split(path.sep).join('/'),\n ),\n ),\n ].sort();\n}\n","import path from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport {\n runCapturedProcess,\n type CapturedProcessRunner,\n} from '../../../lib/cli/run-captured-process.js';\nimport { inquirerConfirmBoolean } from '../../../lib/helpers/inquirer.js';\nimport {\n type PolicyBundleRegoFile,\n validatePolicyBundleContents,\n} from '../../../lib/policy/policy-bundle-manifest.js';\nimport {\n type PolicyLintCheck,\n type PolicyLintDiagnostic,\n type PolicyLintMultiResult,\n type PolicyLintResult,\n POLICY_LINT_CHECK_LABELS,\n POLICY_LINT_CHECK_NAMES,\n POLICY_LINT_MULTI_RESULT_VERSION,\n POLICY_LINT_RESULT_VERSION,\n} from '../../../lib/policy/policy-lint-model.js';\nimport {\n getPolicyProcessFailureMessage,\n parseUnformattedPolicyFiles,\n} from '../../../lib/policy/policy-lint-output.js';\nimport {\n DEFAULT_POLICY_PROJECT_DIRECTORY,\n discoverPolicyBundleDirectories,\n resolvePolicyProjectDirectory,\n} from '../../../lib/policy/policy-project-discovery.js';\nimport {\n OPA_MISSING_MESSAGE,\n parsePolicyToolVersion,\n REGAL_MISSING_MESSAGE,\n unsupportedOpaVersionMessage,\n unsupportedRegalVersionMessage,\n} from '../../../lib/policy/policy-runtime.js';\nimport { POLICY_MANIFEST_FILENAME } from '../../../lib/policy/policy-scaffold-templates.js';\nimport { isInteractivePromptInvocation } from '../../../lib/scaffolding/prompts.js';\n\n/** CLI flags for `transcend policy lint`. */\nexport interface LintCommandFlags {\n /** Apply OPA formatting. */\n fix: boolean;\n /** Disable the optional formatting confirmation. */\n noInteractive: boolean;\n /** Emit one stable JSON result on stdout. */\n json: boolean;\n}\n\n/**\n * Collect Rego source snapshots without following symlinks.\n *\n * @param context - CLI context\n * @param projectDirectory - Absolute policy directory\n * @param currentDirectory - Current recursive directory\n * @returns Deterministically ordered Rego snapshots\n */\nfunction collectRegoFiles(\n context: LocalContext,\n projectDirectory: string,\n currentDirectory: string = projectDirectory,\n): PolicyBundleRegoFile[] {\n return context.fs\n .readdirSync(currentDirectory, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name))\n .flatMap((entry) => {\n const absolutePath = path.join(currentDirectory, entry.name);\n if (entry.isDirectory()) {\n return collectRegoFiles(context, projectDirectory, absolutePath);\n }\n if (!entry.isFile() || !entry.name.endsWith('.rego')) {\n return [];\n }\n return [\n {\n path: path.relative(projectDirectory, absolutePath).split(path.sep).join('/'),\n contents: context.fs.readFileSync(absolutePath, 'utf8'),\n },\n ];\n });\n}\n\n/**\n * Resolve a Regal config file for a bundle, walking up to the workspace.\n *\n * @param context - CLI context\n * @param bundleDirectory - Absolute bundle directory\n * @returns Absolute config path, or undefined when none is found\n */\nfunction resolveRegalConfigFile(\n context: LocalContext,\n bundleDirectory: string,\n): string | undefined {\n let current = bundleDirectory;\n for (;;) {\n const nestedRegalConfig = path.join(current, '.regal', 'config.yaml');\n if (context.fs.existsSync(nestedRegalConfig)) {\n return nestedRegalConfig;\n }\n const rootRegalConfig = path.join(current, '.regal.yaml');\n if (context.fs.existsSync(rootRegalConfig)) {\n return rootRegalConfig;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n current = parent;\n }\n}\n\n/**\n * Render the terminal summary for a policy verification result.\n *\n * @param context - CLI context\n * @param result - Completed verification result\n * @param heading - Optional section heading when linting multiple bundles\n */\nfunction renderResult(context: LocalContext, result: PolicyLintResult, heading?: string): void {\n if (heading) {\n context.logger.info(`${colors.bold(heading)}\\n`);\n } else {\n context.logger.info(`${colors.bold('Policy verification')}\\n`);\n }\n result.checks.forEach(({ name, status }) => {\n const label = status === 'passed' ? 'PASS' : status === 'failed' ? 'FAIL' : 'SKIP';\n const styledLabel =\n status === 'passed'\n ? colors.green(label)\n : status === 'failed'\n ? colors.red(label)\n : colors.yellow(label);\n const version =\n name === 'opa-version' && result.tools.opa\n ? ` (${result.tools.opa})`\n : name === 'regal-version' && result.tools.regal\n ? ` (${result.tools.regal})`\n : '';\n context.logger.info(`${styledLabel} ${POLICY_LINT_CHECK_LABELS[name]}${version}`);\n });\n if (result.diagnostics.length > 0) {\n context.logger.error('');\n }\n result.diagnostics.forEach((diagnostic) => {\n const location = diagnostic.path ? `${diagnostic.path}: ` : '';\n context.logger.error(\n colors.red(`error [${diagnostic.code}]: ${location}${diagnostic.message}`),\n );\n });\n if (result.status === 'passed') {\n context.logger.info('');\n context.logger.info(colors.green('Policy verification passed.'));\n } else {\n context.logger.error('');\n context.logger.error(colors.red('Policy verification failed.'));\n }\n}\n\n/**\n * Verify one publishable policy bundle directory.\n *\n * @param context - CLI context\n * @param flags - Command flags\n * @param resolvedDir - Absolute bundle directory\n * @param runner - Captured subprocess runner\n * @returns Completed verification result\n */\nasync function lintBundle(\n this: LocalContext,\n { fix, noInteractive, json }: LintCommandFlags,\n resolvedDir: string,\n runner: CapturedProcessRunner,\n): Promise<PolicyLintResult> {\n const checks: PolicyLintCheck[] = POLICY_LINT_CHECK_NAMES.map((name) => ({\n name,\n status: 'skipped',\n }));\n const diagnostics: PolicyLintDiagnostic[] = [];\n const result: PolicyLintResult = {\n version: POLICY_LINT_RESULT_VERSION,\n status: 'passed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks,\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics,\n };\n const setStatus = (name: PolicyLintCheck['name'], status: PolicyLintCheck['status']): void => {\n checks.find((check) => check.name === name)!.status = status;\n };\n const addError = (code: string, message: string, diagnosticPath?: string): void => {\n diagnostics.push({\n code,\n severity: 'error',\n message,\n ...(diagnosticPath ? { path: diagnosticPath } : {}),\n });\n };\n\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n setStatus('manifest', 'failed');\n addError(\n 'project.directory',\n `Policy directory does not exist or is not a directory: ${resolvedDir}`,\n path.relative(this.process.cwd(), resolvedDir),\n );\n result.status = 'failed';\n return result;\n }\n\n const manifestPath = path.join(resolvedDir, POLICY_MANIFEST_FILENAME);\n try {\n validatePolicyBundleContents(\n this.fs.existsSync(manifestPath) ? this.fs.readFileSync(manifestPath, 'utf8') : undefined,\n collectRegoFiles(this, resolvedDir),\n );\n setStatus('manifest', 'passed');\n } catch (error) {\n setStatus('manifest', 'failed');\n addError(\n 'manifest.invalid',\n error instanceof Error ? error.message : String(error),\n path.relative(this.process.cwd(), manifestPath),\n );\n }\n\n const opaVersionResult = await runner('opa', ['version'], { cwd: resolvedDir }, this);\n if (opaVersionResult.error?.code === 'ENOENT') {\n setStatus('opa-version', 'failed');\n addError('opa.missing', OPA_MISSING_MESSAGE);\n } else {\n const opaVersionOutput = `${opaVersionResult.stdout}\\n${opaVersionResult.stderr}`;\n const unsupportedOpa = unsupportedOpaVersionMessage(opaVersionOutput);\n if (opaVersionResult.code !== 0 || unsupportedOpa) {\n setStatus('opa-version', 'failed');\n addError(\n 'opa.version',\n unsupportedOpa ??\n getPolicyProcessFailureMessage(\n opaVersionResult,\n 'Unable to determine the installed OPA version.',\n ),\n );\n } else {\n result.tools.opa = parsePolicyToolVersion(opaVersionOutput)!.version;\n setStatus('opa-version', 'passed');\n }\n }\n\n const regalVersionResult = await runner('regal', ['version'], { cwd: resolvedDir }, this);\n if (regalVersionResult.error?.code === 'ENOENT') {\n setStatus('regal-version', 'failed');\n addError('regal.missing', REGAL_MISSING_MESSAGE);\n } else {\n const regalVersionOutput = `${regalVersionResult.stdout}\\n${regalVersionResult.stderr}`;\n const unsupportedRegal = unsupportedRegalVersionMessage(regalVersionOutput);\n if (regalVersionResult.code !== 0 || unsupportedRegal) {\n setStatus('regal-version', 'failed');\n addError(\n 'regal.version',\n unsupportedRegal ??\n getPolicyProcessFailureMessage(\n regalVersionResult,\n 'Unable to determine the installed Regal version.',\n ),\n );\n } else {\n result.tools.regal = parsePolicyToolVersion(regalVersionOutput)!.version;\n setStatus('regal-version', 'passed');\n }\n }\n\n if (result.tools.opa) {\n const formatResult = await runner(\n 'opa',\n ['fmt', '--list', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (formatResult.code !== 0) {\n setStatus('format', 'failed');\n addError(\n 'opa.format',\n getPolicyProcessFailureMessage(\n formatResult,\n `opa fmt --list failed with exit code ${formatResult.code}`,\n ),\n );\n } else {\n result.unformattedFiles = parseUnformattedPolicyFiles(formatResult.stdout, resolvedDir);\n if (result.unformattedFiles.length === 0) {\n setStatus('format', 'passed');\n } else {\n let shouldFormat = fix;\n const interactive = isInteractivePromptInvocation(\n { json, noInteractive },\n this.process.stdin.isTTY,\n this.process.stderr.isTTY,\n );\n if (!json && !fix) {\n this.logger.error(colors.red('Policy files are not formatted:'));\n result.unformattedFiles.forEach((file) => {\n this.logger.error(colors.red(` - ${file}`));\n });\n const diffResult = await runner(\n 'opa',\n ['fmt', '--diff', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n const diff = diffResult.stdout.trim() || diffResult.stderr.trim();\n if (diff) {\n this.logger.error('');\n this.logger.error(diff);\n }\n }\n if (!fix && interactive) {\n try {\n shouldFormat = await inquirerConfirmBoolean({\n message: 'Format the unformatted policy files listed above?',\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/force closed|prompt.*cancel|user.*close|SIGINT/iu.test(message)) {\n this.process.exit(130);\n }\n throw error;\n }\n }\n if (shouldFormat) {\n const writeResult = await runner(\n 'opa',\n ['fmt', '--write', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (writeResult.code === 0) {\n result.fixedFiles = [...result.unformattedFiles];\n setStatus('format', 'passed');\n } else {\n setStatus('format', 'failed');\n addError(\n 'opa.format-fix',\n getPolicyProcessFailureMessage(\n writeResult,\n `opa fmt --write failed with exit code ${writeResult.code}`,\n ),\n );\n }\n } else {\n setStatus('format', 'failed');\n addError(\n 'opa.format-required',\n 'Policy files are not formatted. Re-run `transcend policy lint --fix` to repair them.',\n );\n }\n }\n }\n\n const checkResult = await runner(\n 'opa',\n ['check', '--strict', '--ignore', '*_test.rego', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (checkResult.code === 0) {\n setStatus('opa-check', 'passed');\n } else {\n setStatus('opa-check', 'failed');\n addError(\n 'opa.check',\n getPolicyProcessFailureMessage(\n checkResult,\n `opa check failed with exit code ${checkResult.code}`,\n ),\n );\n }\n }\n\n if (result.tools.regal) {\n const regalConfig = resolveRegalConfigFile(this, resolvedDir);\n const regalResult = await runner(\n 'regal',\n [\n 'lint',\n '--fail-level',\n 'warning',\n ...(regalConfig ? ['--config-file', regalConfig] : []),\n resolvedDir,\n ],\n { cwd: resolvedDir },\n this,\n );\n if (regalResult.code === 0) {\n setStatus('regal-lint', 'passed');\n } else {\n setStatus('regal-lint', 'failed');\n addError(\n 'regal.lint',\n getPolicyProcessFailureMessage(\n regalResult,\n `regal lint failed with exit code ${regalResult.code}`,\n ),\n );\n }\n }\n\n if (result.tools.opa) {\n const testResult = await runner(\n 'opa',\n ['test', '--fail-on-empty', '-b', resolvedDir],\n { cwd: resolvedDir },\n this,\n );\n if (testResult.code === 0) {\n setStatus('opa-test', 'passed');\n } else {\n setStatus('opa-test', 'failed');\n addError(\n 'opa.test',\n getPolicyProcessFailureMessage(\n testResult,\n `opa test --fail-on-empty -b failed with exit code ${testResult.code}`,\n ),\n );\n }\n }\n\n result.status = checks.some(({ status }) => status === 'failed') ? 'failed' : 'passed';\n return result;\n}\n\n/**\n * Verify local policy bundles with the shared upload contract, OPA, and Regal.\n *\n * With no directory (or the default workspace path), discovers every immediate\n * child that contains a `.manifest` and verifies each. Pass one bundle path to\n * verify a single publishable unit.\n *\n * @param this - CLI context\n * @param flags - Command flags\n * @param directory - Policy workspace or bundle directory\n * @param runner - Captured subprocess runner\n */\nexport async function lint(\n this: LocalContext,\n flags: LintCommandFlags,\n directory: string = DEFAULT_POLICY_PROJECT_DIRECTORY,\n runner: CapturedProcessRunner = runCapturedProcess,\n): Promise<void> {\n doneInputValidation(this.process);\n\n const { fix = false, noInteractive = false, json = false } = flags;\n const resolvedDir = resolvePolicyProjectDirectory(this.process.cwd(), directory);\n\n if (!this.fs.existsSync(resolvedDir) || !this.fs.statSync(resolvedDir).isDirectory()) {\n const missing: PolicyLintResult = {\n version: POLICY_LINT_RESULT_VERSION,\n status: 'failed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks: POLICY_LINT_CHECK_NAMES.map((name) => ({\n name,\n status: name === 'manifest' ? 'failed' : 'skipped',\n })),\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics: [\n {\n code: 'project.directory',\n severity: 'error',\n message: `Policy directory does not exist or is not a directory: ${resolvedDir}`,\n path: path.relative(this.process.cwd(), resolvedDir),\n },\n ],\n };\n if (json) {\n this.process.stdout.write(`${JSON.stringify(missing)}\\n`);\n } else {\n renderResult(this, missing);\n }\n this.process.exitCode = 1;\n return;\n }\n\n const bundleDirectories = discoverPolicyBundleDirectories(this, resolvedDir);\n if (bundleDirectories.length === 0) {\n const empty: PolicyLintResult = {\n version: POLICY_LINT_RESULT_VERSION,\n status: 'failed',\n directory: resolvedDir,\n fix,\n tools: { opa: null, regal: null },\n checks: POLICY_LINT_CHECK_NAMES.map((name) => ({\n name,\n status: name === 'manifest' ? 'failed' : 'skipped',\n })),\n unformattedFiles: [],\n fixedFiles: [],\n diagnostics: [\n {\n code: 'project.bundles',\n severity: 'error',\n message:\n 'No publishable policy bundles found. Add one with `transcend policy new`, ' +\n 'or pass a directory that contains a `.manifest`.',\n path: path.relative(this.process.cwd(), resolvedDir) || '.',\n },\n ],\n };\n if (json) {\n this.process.stdout.write(`${JSON.stringify(empty)}\\n`);\n } else {\n renderResult(this, empty);\n }\n this.process.exitCode = 1;\n return;\n }\n\n const results: PolicyLintResult[] = [];\n for (const bundleDirectory of bundleDirectories) {\n results.push(\n await lintBundle.call(this, { fix, noInteractive, json }, bundleDirectory, runner),\n );\n }\n\n const failed = results.some((result) => result.status === 'failed');\n if (json) {\n if (results.length === 1) {\n this.process.stdout.write(`${JSON.stringify(results[0])}\\n`);\n } else {\n const multi: PolicyLintMultiResult = {\n version: POLICY_LINT_MULTI_RESULT_VERSION,\n status: failed ? 'failed' : 'passed',\n directory: resolvedDir,\n fix,\n results,\n };\n this.process.stdout.write(`${JSON.stringify(multi)}\\n`);\n }\n } else if (results.length === 1) {\n renderResult(this, results[0]!);\n } else {\n results.forEach((result, index) => {\n if (index > 0) {\n this.logger.info('');\n }\n const relative = path.relative(this.process.cwd(), result.directory) || result.directory;\n renderResult(this, result, `Policy verification — ${relative}`);\n });\n }\n\n if (failed) {\n this.process.exitCode = 1;\n }\n}\n"],"mappings":"2cAyBA,MAAa,EAAqD,CAChE,WACA,cACA,gBACA,SACA,YACA,aACA,WACD,CAGY,EAA8E,CACzF,SAAU,6BACV,cAAe,UACf,gBAAiB,QACjB,OAAQ,iBACR,YAAa,mBACb,aAAc,aACd,WAAY,YACb,CCjCD,SAAgB,EACd,EACA,EACQ,CAER,MADe,CAAC,EAAO,OAAO,MAAM,CAAE,EAAO,OAAO,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK;EACpE,EAAI,EAUnB,SAAgB,EAA4B,EAAgB,EAAoC,CAC9F,MAAO,CACL,GAAG,IAAI,IACL,EACG,MAAM,UAAU,CAChB,IAAK,GAAS,EAAK,MAAM,CAAC,CAC1B,OAAO,QAAQ,CACf,IAAK,GACJ,EAAK,WAAW,EAAK,CACjB,EAAK,SAAS,EAAkB,EAAK,CAAC,MAAM,EAAK,IAAI,CAAC,KAAK,IAAI,CAC/D,EAAK,MAAM,EAAK,IAAI,CAAC,KAAK,IAAI,CACnC,CACJ,CACF,CAAC,MAAM,CCuBV,SAAS,EACP,EACA,EACA,EAA2B,EACH,CACxB,OAAO,EAAQ,GACZ,YAAY,EAAkB,CAAE,cAAe,GAAM,CAAC,CACtD,MAAM,EAAM,IAAU,EAAK,KAAK,cAAc,EAAM,KAAK,CAAC,CAC1D,QAAS,GAAU,CAClB,IAAM,EAAe,EAAK,KAAK,EAAkB,EAAM,KAAK,CAO5D,OANI,EAAM,aAAa,CACd,EAAiB,EAAS,EAAkB,EAAa,CAE9D,CAAC,EAAM,QAAQ,EAAI,CAAC,EAAM,KAAK,SAAS,QAAQ,CAC3C,EAAE,CAEJ,CACL,CACE,KAAM,EAAK,SAAS,EAAkB,EAAa,CAAC,MAAM,EAAK,IAAI,CAAC,KAAK,IAAI,CAC7E,SAAU,EAAQ,GAAG,aAAa,EAAc,OAAO,CACxD,CACF,EACD,CAUN,SAAS,EACP,EACA,EACoB,CACpB,IAAI,EAAU,EACd,OAAS,CACP,IAAM,EAAoB,EAAK,KAAK,EAAS,SAAU,cAAc,CACrE,GAAI,EAAQ,GAAG,WAAW,EAAkB,CAC1C,OAAO,EAET,IAAM,EAAkB,EAAK,KAAK,EAAS,cAAc,CACzD,GAAI,EAAQ,GAAG,WAAW,EAAgB,CACxC,OAAO,EAET,IAAM,EAAS,EAAK,QAAQ,EAAQ,CACpC,GAAI,IAAW,EACb,OAEF,EAAU,GAWd,SAAS,EAAa,EAAuB,EAA0B,EAAwB,CACzF,EACF,EAAQ,OAAO,KAAK,GAAG,EAAO,KAAK,EAAQ,CAAC,IAAI,CAEhD,EAAQ,OAAO,KAAK,GAAG,EAAO,KAAK,sBAAsB,CAAC,IAAI,CAEhE,EAAO,OAAO,SAAS,CAAE,OAAM,YAAa,CAC1C,IAAM,EAAQ,IAAW,SAAW,OAAS,IAAW,SAAW,OAAS,OACtE,EACJ,IAAW,SACP,EAAO,MAAM,EAAM,CACnB,IAAW,SACT,EAAO,IAAI,EAAM,CACjB,EAAO,OAAO,EAAM,CACtB,EACJ,IAAS,eAAiB,EAAO,MAAM,IACnC,KAAK,EAAO,MAAM,IAAI,GACtB,IAAS,iBAAmB,EAAO,MAAM,MACvC,KAAK,EAAO,MAAM,MAAM,GACxB,GACR,EAAQ,OAAO,KAAK,GAAG,EAAY,GAAG,EAAyB,KAAQ,IAAU,EACjF,CACE,EAAO,YAAY,OAAS,GAC9B,EAAQ,OAAO,MAAM,GAAG,CAE1B,EAAO,YAAY,QAAS,GAAe,CACzC,IAAM,EAAW,EAAW,KAAO,GAAG,EAAW,KAAK,IAAM,GAC5D,EAAQ,OAAO,MACb,EAAO,IAAI,UAAU,EAAW,KAAK,KAAK,IAAW,EAAW,UAAU,CAC3E,EACD,CACE,EAAO,SAAW,UACpB,EAAQ,OAAO,KAAK,GAAG,CACvB,EAAQ,OAAO,KAAK,EAAO,MAAM,8BAA8B,CAAC,GAEhE,EAAQ,OAAO,MAAM,GAAG,CACxB,EAAQ,OAAO,MAAM,EAAO,IAAI,8BAA8B,CAAC,EAanE,eAAe,EAEb,CAAE,MAAK,gBAAe,QACtB,EACA,EAC2B,CAC3B,IAAM,EAA4B,EAAwB,IAAK,IAAU,CACvE,OACA,OAAQ,UACT,EAAE,CACG,EAAsC,EAAE,CACxC,EAA2B,CAC/B,QAAA,EACA,OAAQ,SACR,UAAW,EACX,MACA,MAAO,CAAE,IAAK,KAAM,MAAO,KAAM,CACjC,SACA,iBAAkB,EAAE,CACpB,WAAY,EAAE,CACd,cACD,CACK,GAAa,EAA+B,IAA4C,CAC5F,EAAO,KAAM,GAAU,EAAM,OAAS,EAAK,CAAE,OAAS,GAElD,GAAY,EAAc,EAAiB,IAAkC,CACjF,EAAY,KAAK,CACf,OACA,SAAU,QACV,UACA,GAAI,EAAiB,CAAE,KAAM,EAAgB,CAAG,EAAE,CACnD,CAAC,EAGJ,GAAI,CAAC,KAAK,GAAG,WAAW,EAAY,EAAI,CAAC,KAAK,GAAG,SAAS,EAAY,CAAC,aAAa,CAQlF,OAPA,EAAU,WAAY,SAAS,CAC/B,EACE,oBACA,0DAA0D,IAC1D,EAAK,SAAS,KAAK,QAAQ,KAAK,CAAE,EAAY,CAC/C,CACD,EAAO,OAAS,SACT,EAGT,IAAM,EAAe,EAAK,KAAK,EAAa,EAAyB,CACrE,GAAI,CACF,EACE,KAAK,GAAG,WAAW,EAAa,CAAG,KAAK,GAAG,aAAa,EAAc,OAAO,CAAG,IAAA,GAChF,EAAiB,KAAM,EAAY,CACpC,CACD,EAAU,WAAY,SAAS,OACxB,EAAO,CACd,EAAU,WAAY,SAAS,CAC/B,EACE,mBACA,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CACtD,EAAK,SAAS,KAAK,QAAQ,KAAK,CAAE,EAAa,CAChD,CAGH,IAAM,EAAmB,MAAM,EAAO,MAAO,CAAC,UAAU,CAAE,CAAE,IAAK,EAAa,CAAE,KAAK,CACrF,GAAI,EAAiB,OAAO,OAAS,SACnC,EAAU,cAAe,SAAS,CAClC,EAAS,cAAe,EAAoB,KACvC,CACL,IAAM,EAAmB,GAAG,EAAiB,OAAO,IAAI,EAAiB,SACnE,EAAiB,EAA6B,EAAiB,CACjE,EAAiB,OAAS,GAAK,GACjC,EAAU,cAAe,SAAS,CAClC,EACE,cACA,GACE,EACE,EACA,iDACD,CACJ,GAED,EAAO,MAAM,IAAM,EAAuB,EAAiB,CAAE,QAC7D,EAAU,cAAe,SAAS,EAItC,IAAM,EAAqB,MAAM,EAAO,QAAS,CAAC,UAAU,CAAE,CAAE,IAAK,EAAa,CAAE,KAAK,CACzF,GAAI,EAAmB,OAAO,OAAS,SACrC,EAAU,gBAAiB,SAAS,CACpC,EAAS,gBAAiB,EAAsB,KAC3C,CACL,IAAM,EAAqB,GAAG,EAAmB,OAAO,IAAI,EAAmB,SACzE,EAAmB,EAA+B,EAAmB,CACvE,EAAmB,OAAS,GAAK,GACnC,EAAU,gBAAiB,SAAS,CACpC,EACE,gBACA,GACE,EACE,EACA,mDACD,CACJ,GAED,EAAO,MAAM,MAAQ,EAAuB,EAAmB,CAAE,QACjE,EAAU,gBAAiB,SAAS,EAIxC,GAAI,EAAO,MAAM,IAAK,CACpB,IAAM,EAAe,MAAM,EACzB,MACA,CAAC,MAAO,SAAU,EAAY,CAC9B,CAAE,IAAK,EAAa,CACpB,KACD,CACD,GAAI,EAAa,OAAS,EACxB,EAAU,SAAU,SAAS,CAC7B,EACE,aACA,EACE,EACA,wCAAwC,EAAa,OACtD,CACF,SAED,EAAO,iBAAmB,EAA4B,EAAa,OAAQ,EAAY,CACnF,EAAO,iBAAiB,SAAW,EACrC,EAAU,SAAU,SAAS,KACxB,CACL,IAAI,EAAe,EACb,EAAc,EAClB,CAAE,OAAM,gBAAe,CACvB,KAAK,QAAQ,MAAM,MACnB,KAAK,QAAQ,OAAO,MACrB,CACD,GAAI,CAAC,GAAQ,CAAC,EAAK,CACjB,KAAK,OAAO,MAAM,EAAO,IAAI,kCAAkC,CAAC,CAChE,EAAO,iBAAiB,QAAS,GAAS,CACxC,KAAK,OAAO,MAAM,EAAO,IAAI,OAAO,IAAO,CAAC,EAC5C,CACF,IAAM,EAAa,MAAM,EACvB,MACA,CAAC,MAAO,SAAU,EAAY,CAC9B,CAAE,IAAK,EAAa,CACpB,KACD,CACK,EAAO,EAAW,OAAO,MAAM,EAAI,EAAW,OAAO,MAAM,CAC7D,IACF,KAAK,OAAO,MAAM,GAAG,CACrB,KAAK,OAAO,MAAM,EAAK,EAG3B,GAAI,CAAC,GAAO,EACV,GAAI,CACF,EAAe,MAAM,EAAuB,CAC1C,QAAS,oDACV,CAAC,OACK,EAAO,CACd,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAItE,KAHI,mDAAmD,KAAK,EAAQ,EAClE,KAAK,QAAQ,KAAK,IAAI,CAElB,EAGV,GAAI,EAAc,CAChB,IAAM,EAAc,MAAM,EACxB,MACA,CAAC,MAAO,UAAW,EAAY,CAC/B,CAAE,IAAK,EAAa,CACpB,KACD,CACG,EAAY,OAAS,GACvB,EAAO,WAAa,CAAC,GAAG,EAAO,iBAAiB,CAChD,EAAU,SAAU,SAAS,GAE7B,EAAU,SAAU,SAAS,CAC7B,EACE,iBACA,EACE,EACA,yCAAyC,EAAY,OACtD,CACF,OAGH,EAAU,SAAU,SAAS,CAC7B,EACE,sBACA,uFACD,CAKP,IAAM,EAAc,MAAM,EACxB,MACA,CAAC,QAAS,WAAY,WAAY,cAAe,EAAY,CAC7D,CAAE,IAAK,EAAa,CACpB,KACD,CACG,EAAY,OAAS,EACvB,EAAU,YAAa,SAAS,EAEhC,EAAU,YAAa,SAAS,CAChC,EACE,YACA,EACE,EACA,mCAAmC,EAAY,OAChD,CACF,EAIL,GAAI,EAAO,MAAM,MAAO,CACtB,IAAM,EAAc,EAAuB,KAAM,EAAY,CACvD,EAAc,MAAM,EACxB,QACA,CACE,OACA,eACA,UACA,GAAI,EAAc,CAAC,gBAAiB,EAAY,CAAG,EAAE,CACrD,EACD,CACD,CAAE,IAAK,EAAa,CACpB,KACD,CACG,EAAY,OAAS,EACvB,EAAU,aAAc,SAAS,EAEjC,EAAU,aAAc,SAAS,CACjC,EACE,aACA,EACE,EACA,oCAAoC,EAAY,OACjD,CACF,EAIL,GAAI,EAAO,MAAM,IAAK,CACpB,IAAM,EAAa,MAAM,EACvB,MACA,CAAC,OAAQ,kBAAmB,KAAM,EAAY,CAC9C,CAAE,IAAK,EAAa,CACpB,KACD,CACG,EAAW,OAAS,EACtB,EAAU,WAAY,SAAS,EAE/B,EAAU,WAAY,SAAS,CAC/B,EACE,WACA,EACE,EACA,qDAAqD,EAAW,OACjE,CACF,EAKL,MADA,GAAO,OAAS,EAAO,MAAM,CAAE,YAAa,IAAW,SAAS,CAAG,SAAW,SACvE,EAeT,eAAsB,EAEpB,EACA,EAAoB,EACpB,EAAgC,EACjB,CACf,EAAoB,KAAK,QAAQ,CAEjC,GAAM,CAAE,MAAM,GAAO,gBAAgB,GAAO,OAAO,IAAU,EACvD,EAAc,EAA8B,KAAK,QAAQ,KAAK,CAAE,EAAU,CAEhF,GAAI,CAAC,KAAK,GAAG,WAAW,EAAY,EAAI,CAAC,KAAK,GAAG,SAAS,EAAY,CAAC,aAAa,CAAE,CACpF,IAAM,EAA4B,CAChC,QAAA,EACA,OAAQ,SACR,UAAW,EACX,MACA,MAAO,CAAE,IAAK,KAAM,MAAO,KAAM,CACjC,OAAQ,EAAwB,IAAK,IAAU,CAC7C,OACA,OAAQ,IAAS,WAAa,SAAW,UAC1C,EAAE,CACH,iBAAkB,EAAE,CACpB,WAAY,EAAE,CACd,YAAa,CACX,CACE,KAAM,oBACN,SAAU,QACV,QAAS,0DAA0D,IACnE,KAAM,EAAK,SAAS,KAAK,QAAQ,KAAK,CAAE,EAAY,CACrD,CACF,CACF,CACG,EACF,KAAK,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAQ,CAAC,IAAI,CAEzD,EAAa,KAAM,EAAQ,CAE7B,KAAK,QAAQ,SAAW,EACxB,OAGF,IAAM,EAAoB,EAAgC,KAAM,EAAY,CAC5E,GAAI,EAAkB,SAAW,EAAG,CAClC,IAAM,EAA0B,CAC9B,QAAA,EACA,OAAQ,SACR,UAAW,EACX,MACA,MAAO,CAAE,IAAK,KAAM,MAAO,KAAM,CACjC,OAAQ,EAAwB,IAAK,IAAU,CAC7C,OACA,OAAQ,IAAS,WAAa,SAAW,UAC1C,EAAE,CACH,iBAAkB,EAAE,CACpB,WAAY,EAAE,CACd,YAAa,CACX,CACE,KAAM,kBACN,SAAU,QACV,QACE,6HAEF,KAAM,EAAK,SAAS,KAAK,QAAQ,KAAK,CAAE,EAAY,EAAI,IACzD,CACF,CACF,CACG,EACF,KAAK,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAM,CAAC,IAAI,CAEvD,EAAa,KAAM,EAAM,CAE3B,KAAK,QAAQ,SAAW,EACxB,OAGF,IAAM,EAA8B,EAAE,CACtC,IAAK,IAAM,KAAmB,EAC5B,EAAQ,KACN,MAAM,EAAW,KAAK,KAAM,CAAE,MAAK,gBAAe,OAAM,CAAE,EAAiB,EAAO,CACnF,CAGH,IAAM,EAAS,EAAQ,KAAM,GAAW,EAAO,SAAW,SAAS,CACnE,GAAI,EACF,GAAI,EAAQ,SAAW,EACrB,KAAK,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAQ,GAAG,CAAC,IAAI,KACvD,CACL,IAAM,EAA+B,CACnC,QAAA,EACA,OAAQ,EAAS,SAAW,SAC5B,UAAW,EACX,MACA,UACD,CACD,KAAK,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAM,CAAC,IAAI,MAEhD,EAAQ,SAAW,EAC5B,EAAa,KAAM,EAAQ,GAAI,CAE/B,EAAQ,SAAS,EAAQ,IAAU,CAC7B,EAAQ,GACV,KAAK,OAAO,KAAK,GAAG,CAEtB,IAAM,EAAW,EAAK,SAAS,KAAK,QAAQ,KAAK,CAAE,EAAO,UAAU,EAAI,EAAO,UAC/E,EAAa,KAAM,EAAQ,yBAAyB,IAAW,EAC/D,CAGA,IACF,KAAK,QAAQ,SAAW"}
@@ -1,4 +1,4 @@
1
- import"./enums-OiLcZ26O.mjs";import{t as e}from"./logger-CPu6zbyQ.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";import{OneTrustEnrichedAssessment as n,OneTrustGetAssessmentResponse as r,OneTrustGetListOfAssessmentsResponse as i,OneTrustGetRiskResponse as a,OneTrustGetUserResponse as o}from"@transcend-io/privacy-types";import{keyBy as s,uniq as c}from"lodash-es";import l from"colors";import u,{createReadStream as d}from"node:fs";import f from"got";import{decodeCodec as p}from"@transcend-io/type-utils";import{IMPORT_ONE_TRUST_ASSESSMENT_FORMS as m,buildTranscendGraphQLClient as h,makeGraphQLRequest as g}from"@transcend-io/sdk";import{map as _,mapSeries as v}from"@transcend-io/utils";import y from"JSONStream";const b=({assessment:e,index:t,total:n,wrap:r=!0})=>{let i=``;(t===0||r)&&(i=`[
1
+ import"./enums-OiLcZ26O.mjs";import{t as e}from"./logger-CPu6zbyQ.mjs";import{t}from"./done-input-validation-LiTaCEzF.mjs";import{OneTrustEnrichedAssessment as n,OneTrustGetAssessmentResponse as r,OneTrustGetListOfAssessmentsResponse as i,OneTrustGetRiskResponse as a,OneTrustGetUserResponse as o}from"@transcend-io/privacy-types";import{keyBy as s,uniq as c}from"lodash-es";import l from"colors";import u,{createReadStream as d}from"node:fs";import{map as f,mapSeries as p}from"@transcend-io/utils";import m from"got";import{decodeCodec as h}from"@transcend-io/type-utils";import{IMPORT_ONE_TRUST_ASSESSMENT_FORMS as g,buildTranscendGraphQLClient as _,makeGraphQLRequest as v}from"@transcend-io/sdk";import y from"JSONStream";const b=({assessment:e,index:t,total:n,wrap:r=!0})=>{let i=``;(t===0||r)&&(i=`[
2
2
  `);let a=JSON.stringify(e),o=n&&t<n-1&&!r?`,`:``;return i=`${i+a+o}\n`,(n&&t===n-1||r)&&(i+=`
3
- ]`),i},x=({file:t,assessment:n,index:r,total:i})=>{e.info(l.magenta(`Writing enriched assessment ${r+1} of ${i} to file "${t}"...`)),r===0?u.writeFileSync(t,b({assessment:n,index:r,total:i,wrap:!1})):u.appendFileSync(t,b({assessment:n,index:r,total:i,wrap:!1}))},S=async({oneTrust:t})=>{let n=0,r=1,a=0,o=[];for(;n<r;){let{body:s}=await t.get(`api/assessment/v2/assessments?page=${n}&size=2000`),{page:c,content:l}=p(i,s);o.push(...l??[]),n===0&&(r=c?.totalPages??0,a=c?.totalElements??0),n+=1,e.info(`Fetched ${o.length} of ${a} assessments.`)}return o},C=async({oneTrust:e,assessmentId:t})=>{let{body:n}=await e.get(`api/assessment/v2/assessments/${t}/export?ExcludeSkippedQuestions=false`);return p(r,n)},w=async({oneTrust:e,riskId:t})=>{let{body:n}=await e.get(`api/risk/v2/risks/${t}`);return p(a,n)},T=async({oneTrust:e,userId:t})=>{let{body:n}=await e.get(`api/scim/v2/Users/${t}`);return p(o,n)},E=({assessment:e,assessmentDetails:t,riskDetails:n,creatorDetails:r,approversDetails:i,respondentsDetails:a})=>{let o=s(n,`id`),{sections:c,createdBy:l,...u}=t,d=c.map(e=>{let{questions:t,...n}=e,r=t.map(e=>{let{risks:t,...n}=e,r=(t??[]).map(e=>{let t=o[e.riskId];return{...e,...t,level:e.level,impactLevel:e.impactLevel??0}});return{...n,risks:r}});return{...n,questions:r}}),f={...l,active:r?.active??!1,userType:r?.userType??`Internal`,emails:r?.emails??[],title:r?.title??null,givenName:r?.name.givenName??null,familyName:r?.name.familyName??null},p=s(i,`id`),m=t.approvers.flatMap(e=>p[e.id]?[{...e,approver:{...e.approver,active:p[e.id].active,userType:p[e.id].userType,emails:p[e.id].emails,title:p[e.id].title,givenName:p[e.id].name.givenName??null,familyName:p[e.id].name.familyName??null}}]:[]),h=s(a,`id`),g=t.respondents.filter(e=>!e.name.includes(`@`)).flatMap(e=>h[e.id]?[{...e,active:h[e.id].active,userType:h[e.id].userType,emails:h[e.id].emails,title:h[e.id].title,givenName:h[e.id].name.givenName??null,familyName:h[e.id].name.familyName??null}]:[]);return{...e,...u,approvers:m,respondents:g,createdBy:f,sections:d}},D=async({transcend:t,assessment:n,total:r,index:i})=>{e.info(l.magenta(`Writing enriched assessment ${i+1} ${r?`of ${r} `:` `}to Transcend...`));let a={json:b({assessment:n,index:i,total:r})};try{await g(t,m,{variables:{input:a},logger:e})}catch(t){e.error(l.red(`Failed to sync assessment ${i+1} ${r?`of ${r} `:` `}to Transcend.\n\tAssessment Title: ${n.name}. Template Title: ${n.template.name}\n`),t)}},O=async({oneTrust:t,file:n,dryRun:r,transcend:i})=>{e.info(`Getting list of all assessments from OneTrust...`);let a=await S({oneTrust:t}),o={};await v(Array.from({length:Math.ceil(a.length/5)},(e,t)=>a.slice(t*5,(t+1)*5)),async(s,u)=>{let d=[];await _(s,async(n,r)=>{let i=5*u+r+1;e.info(`[assessment ${i} of ${a.length}]: fetching details...`);let{templateName:s,assessmentId:f}=n,p=await C({oneTrust:t,assessmentId:f}),m=p.createdBy.id,h=o[m];if(!h){e.info(`[assessment ${i} of ${a.length}]: fetching creator...`);try{h=await T({oneTrust:t,userId:m}),o[m]=h}catch(t){e.warn(l.yellow(`[assessment ${i} of ${a.length}]: failed to fetch form creator.\tcreatorId: ${m}. Assessment Title: ${n.name}. Template Title: ${s}`),t)}}let{approvers:g}=p,v=[];g.length>0&&(e.info(`[assessment ${i} of ${a.length}]: fetching approvers...`),v=await _(g.map(({id:e})=>e),async r=>{try{let e=o[r];return e||(e=await T({oneTrust:t,userId:r}),o[r]=e),[e]}catch(t){return e.warn(l.yellow(`[assessment ${i} of ${a.length}]: failed to fetch a form approver.\tapproverId: ${r}. Assessment Title: ${n.name}. Template Title: ${s}`),t),[]}},{concurrency:5}));let{respondents:y}=p,b=y.filter(e=>!e.name.includes(`@`)),x=[];b.length>0&&(e.info(`[assessment ${i} of ${a.length}]: fetching respondents...`),x=await _(b.map(({id:e})=>e),async r=>{try{let e=o[r];return e||(e=await T({oneTrust:t,userId:r}),o[r]=e),[e]}catch(t){return e.warn(l.yellow(`[assessment ${i} of ${a.length}]: failed to fetch a respondent.\trespondentId: ${r}. Assessment Title: ${n.name}. Template Title: ${s}`),t),[]}},{concurrency:5}));let S=[],D=c(p.sections.flatMap(e=>e.questions.flatMap(e=>(e.risks??[]).flatMap(e=>e.riskId))));D.length>0&&(e.info(`[assessment ${i} of ${a.length}]: fetching risks...`),S=await _(D,e=>w({oneTrust:t,riskId:e}),{concurrency:5}));let O=E({assessment:n,assessmentDetails:p,riskDetails:S,creatorDetails:h,approversDetails:v.flat(),respondentsDetails:x.flat()});d.push(O)},{concurrency:5}),await v(d,async(e,t)=>{let o=u*5+t;r&&n?x({assessment:e,index:o,total:a.length,file:n}):i&&await D({assessment:e,transcend:i,total:a.length,index:o})})})},k=({transcend:t,file:r})=>(e.info(`Getting list of all assessments from file ${r}...`),new Promise((i,a)=>{let o=d(r,{encoding:`utf-8`,highWaterMark:64*1024}),s=y.parse(`*`),c=0;o.pipe(s),s.on(`data`,async i=>{try{s.pause(),await D({assessment:p(n,i),transcend:t,index:c}),c+=1,s.resume()}catch(t){e.error(l.red(`Failed to parse the assessment ${c} from file '${r}': ${t.message}.`))}}),s.on(`end`,()=>{e.info(`Finished processing ${c} assessments from file ${r}`),i()}),s.on(`error`,t=>{e.error(l.red(`Error parsing file '${r}': ${t.message}`)),a(t)}),o.on(`error`,t=>{e.error(l.red(`Error reading file '${r}': ${t.message}`)),a(t)})})),A=({hostname:e,auth:t})=>f.extend({prefixUrl:`https://${e}`,headers:{accept:`application/json`,"content-type":`application/json`,authorization:`Bearer ${t}`}});async function j({hostname:e,oneTrustAuth:n,source:r,transcendAuth:i,transcendUrl:a,resource:o,file:s,dryRun:c,debug:u}){if(!c&&!i)throw Error('Must specify a "transcendAuth" parameter to sync resources to Transcend. e.g. --transcendAuth=${TRANSCEND_API_KEY}');if(c&&!s)throw Error(`Must set a "file" parameter when "dryRun" is "true". e.g. --file=./oneTrustAssessments.json`);if(s){let e=s.split(`.`);if(e.length<2)throw Error(`The "file" parameter has an invalid format. Expected a path with extensions. e.g. --file=./pathToFile.json.`);if(e.at(-1)!==`json`)throw Error(`Expected the format of the "file" parameters '${s}' to be 'json', but got '${e.at(-1)}'.`)}if(r===`oneTrust`){if(!e)throw Error(`Missing required parameter "hostname". e.g. --hostname=customer.my.onetrust.com`);if(!n)throw Error(`Missing required parameter "oneTrustAuth". e.g. --oneTrustAuth=$ONE_TRUST_AUTH_TOKEN`)}else{if(!s)throw Error(`Must specify a "file" parameter to read the OneTrust assessments from. e.g. --source=./oneTrustAssessments.json`);if(c)throw Error(`Cannot read and write to a file simultaneously. Emit the "source" parameter or set it to oneTrust if "dryRun" is enabled.`)}t(this.process);let d=e&&n?A({hostname:e,auth:n}):void 0,f=a&&i?h(a,i):void 0;try{o===`assessments`&&(r===`oneTrust`&&d?await O({oneTrust:d,file:s,dryRun:c,...f&&{transcend:f}}):r===`file`&&s&&f&&await k({file:s,transcend:f}))}catch(e){throw Error(`An error occurred syncing the resource ${o} from OneTrust: ${u?e.stack:e.message}`)}this.logger.info(l.green(`Successfully synced OneTrust ${o} to ${c?`disk at "${s}"`:`Transcend`}!`))}export{j as syncOt};
4
- //# sourceMappingURL=impl-BWPPVXG3.mjs.map
3
+ ]`),i},x=({file:t,assessment:n,index:r,total:i})=>{e.info(l.magenta(`Writing enriched assessment ${r+1} of ${i} to file "${t}"...`)),r===0?u.writeFileSync(t,b({assessment:n,index:r,total:i,wrap:!1})):u.appendFileSync(t,b({assessment:n,index:r,total:i,wrap:!1}))},S=async({oneTrust:t})=>{let n=0,r=1,a=0,o=[];for(;n<r;){let{body:s}=await t.get(`api/assessment/v2/assessments?page=${n}&size=2000`),{page:c,content:l}=h(i,s);o.push(...l??[]),n===0&&(r=c?.totalPages??0,a=c?.totalElements??0),n+=1,e.info(`Fetched ${o.length} of ${a} assessments.`)}return o},C=async({oneTrust:e,assessmentId:t})=>{let{body:n}=await e.get(`api/assessment/v2/assessments/${t}/export?ExcludeSkippedQuestions=false`);return h(r,n)},w=async({oneTrust:e,riskId:t})=>{let{body:n}=await e.get(`api/risk/v2/risks/${t}`);return h(a,n)},T=async({oneTrust:e,userId:t})=>{let{body:n}=await e.get(`api/scim/v2/Users/${t}`);return h(o,n)},E=({assessment:e,assessmentDetails:t,riskDetails:n,creatorDetails:r,approversDetails:i,respondentsDetails:a})=>{let o=s(n,`id`),{sections:c,createdBy:l,...u}=t,d=c.map(e=>{let{questions:t,...n}=e,r=t.map(e=>{let{risks:t,...n}=e,r=(t??[]).map(e=>{let t=o[e.riskId];return{...e,...t,level:e.level,impactLevel:e.impactLevel??0}});return{...n,risks:r}});return{...n,questions:r}}),f={...l,active:r?.active??!1,userType:r?.userType??`Internal`,emails:r?.emails??[],title:r?.title??null,givenName:r?.name.givenName??null,familyName:r?.name.familyName??null},p=s(i,`id`),m=t.approvers.flatMap(e=>p[e.id]?[{...e,approver:{...e.approver,active:p[e.id].active,userType:p[e.id].userType,emails:p[e.id].emails,title:p[e.id].title,givenName:p[e.id].name.givenName??null,familyName:p[e.id].name.familyName??null}}]:[]),h=s(a,`id`),g=t.respondents.filter(e=>!e.name.includes(`@`)).flatMap(e=>h[e.id]?[{...e,active:h[e.id].active,userType:h[e.id].userType,emails:h[e.id].emails,title:h[e.id].title,givenName:h[e.id].name.givenName??null,familyName:h[e.id].name.familyName??null}]:[]);return{...e,...u,approvers:m,respondents:g,createdBy:f,sections:d}},D=async({transcend:t,assessment:n,total:r,index:i})=>{e.info(l.magenta(`Writing enriched assessment ${i+1} ${r?`of ${r} `:` `}to Transcend...`));let a={json:b({assessment:n,index:i,total:r})};try{await v(t,g,{variables:{input:a},logger:e})}catch(t){e.error(l.red(`Failed to sync assessment ${i+1} ${r?`of ${r} `:` `}to Transcend.\n\tAssessment Title: ${n.name}. Template Title: ${n.template.name}\n`),t)}},O=async({oneTrust:t,file:n,dryRun:r,transcend:i})=>{e.info(`Getting list of all assessments from OneTrust...`);let a=await S({oneTrust:t}),o={};await p(Array.from({length:Math.ceil(a.length/5)},(e,t)=>a.slice(t*5,(t+1)*5)),async(s,u)=>{let d=[];await f(s,async(n,r)=>{let i=5*u+r+1;e.info(`[assessment ${i} of ${a.length}]: fetching details...`);let{templateName:s,assessmentId:p}=n,m=await C({oneTrust:t,assessmentId:p}),h=m.createdBy.id,g=o[h];if(!g){e.info(`[assessment ${i} of ${a.length}]: fetching creator...`);try{g=await T({oneTrust:t,userId:h}),o[h]=g}catch(t){e.warn(l.yellow(`[assessment ${i} of ${a.length}]: failed to fetch form creator.\tcreatorId: ${h}. Assessment Title: ${n.name}. Template Title: ${s}`),t)}}let{approvers:_}=m,v=[];_.length>0&&(e.info(`[assessment ${i} of ${a.length}]: fetching approvers...`),v=await f(_.map(({id:e})=>e),async r=>{try{let e=o[r];return e||(e=await T({oneTrust:t,userId:r}),o[r]=e),[e]}catch(t){return e.warn(l.yellow(`[assessment ${i} of ${a.length}]: failed to fetch a form approver.\tapproverId: ${r}. Assessment Title: ${n.name}. Template Title: ${s}`),t),[]}},{concurrency:5}));let{respondents:y}=m,b=y.filter(e=>!e.name.includes(`@`)),x=[];b.length>0&&(e.info(`[assessment ${i} of ${a.length}]: fetching respondents...`),x=await f(b.map(({id:e})=>e),async r=>{try{let e=o[r];return e||(e=await T({oneTrust:t,userId:r}),o[r]=e),[e]}catch(t){return e.warn(l.yellow(`[assessment ${i} of ${a.length}]: failed to fetch a respondent.\trespondentId: ${r}. Assessment Title: ${n.name}. Template Title: ${s}`),t),[]}},{concurrency:5}));let S=[],D=c(m.sections.flatMap(e=>e.questions.flatMap(e=>(e.risks??[]).flatMap(e=>e.riskId))));D.length>0&&(e.info(`[assessment ${i} of ${a.length}]: fetching risks...`),S=await f(D,e=>w({oneTrust:t,riskId:e}),{concurrency:5}));let O=E({assessment:n,assessmentDetails:m,riskDetails:S,creatorDetails:g,approversDetails:v.flat(),respondentsDetails:x.flat()});d.push(O)},{concurrency:5}),await p(d,async(e,t)=>{let o=u*5+t;r&&n?x({assessment:e,index:o,total:a.length,file:n}):i&&await D({assessment:e,transcend:i,total:a.length,index:o})})})},k=({transcend:t,file:r})=>(e.info(`Getting list of all assessments from file ${r}...`),new Promise((i,a)=>{let o=d(r,{encoding:`utf-8`,highWaterMark:64*1024}),s=y.parse(`*`),c=0;o.pipe(s),s.on(`data`,async i=>{try{s.pause(),await D({assessment:h(n,i),transcend:t,index:c}),c+=1,s.resume()}catch(t){e.error(l.red(`Failed to parse the assessment ${c} from file '${r}': ${t.message}.`))}}),s.on(`end`,()=>{e.info(`Finished processing ${c} assessments from file ${r}`),i()}),s.on(`error`,t=>{e.error(l.red(`Error parsing file '${r}': ${t.message}`)),a(t)}),o.on(`error`,t=>{e.error(l.red(`Error reading file '${r}': ${t.message}`)),a(t)})})),A=({hostname:e,auth:t})=>m.extend({prefixUrl:`https://${e}`,headers:{accept:`application/json`,"content-type":`application/json`,authorization:`Bearer ${t}`}});async function j({hostname:e,oneTrustAuth:n,source:r,transcendAuth:i,transcendUrl:a,resource:o,file:s,dryRun:c,debug:u}){if(!c&&!i)throw Error('Must specify a "transcendAuth" parameter to sync resources to Transcend. e.g. --transcendAuth=${TRANSCEND_API_KEY}');if(c&&!s)throw Error(`Must set a "file" parameter when "dryRun" is "true". e.g. --file=./oneTrustAssessments.json`);if(s){let e=s.split(`.`);if(e.length<2)throw Error(`The "file" parameter has an invalid format. Expected a path with extensions. e.g. --file=./pathToFile.json.`);if(e.at(-1)!==`json`)throw Error(`Expected the format of the "file" parameters '${s}' to be 'json', but got '${e.at(-1)}'.`)}if(r===`oneTrust`){if(!e)throw Error(`Missing required parameter "hostname". e.g. --hostname=customer.my.onetrust.com`);if(!n)throw Error(`Missing required parameter "oneTrustAuth". e.g. --oneTrustAuth=$ONE_TRUST_AUTH_TOKEN`)}else{if(!s)throw Error(`Must specify a "file" parameter to read the OneTrust assessments from. e.g. --source=./oneTrustAssessments.json`);if(c)throw Error(`Cannot read and write to a file simultaneously. Emit the "source" parameter or set it to oneTrust if "dryRun" is enabled.`)}t(this.process);let d=e&&n?A({hostname:e,auth:n}):void 0,f=a&&i?_(a,i):void 0;try{o===`assessments`&&(r===`oneTrust`&&d?await O({oneTrust:d,file:s,dryRun:c,...f&&{transcend:f}}):r===`file`&&s&&f&&await k({file:s,transcend:f}))}catch(e){throw Error(`An error occurred syncing the resource ${o} from OneTrust: ${u?e.stack:e.message}`)}this.logger.info(l.green(`Successfully synced OneTrust ${o} to ${c?`disk at "${s}"`:`Transcend`}!`))}export{j as syncOt};
4
+ //# sourceMappingURL=impl-CoqCyj7e.mjs.map