@transcend-io/cli 10.1.0 → 10.2.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 (262) hide show
  1. package/dist/{app-Cx8-4u8K.mjs → app-DLzaZHc8.mjs} +20 -20
  2. package/dist/{app-Cx8-4u8K.mjs.map → app-DLzaZHc8.mjs.map} +1 -1
  3. package/dist/{approvePrivacyRequests-Bjq5cPSI.mjs → approvePrivacyRequests-BlUcYXpH.mjs} +2 -2
  4. package/dist/{approvePrivacyRequests-Bjq5cPSI.mjs.map → approvePrivacyRequests-BlUcYXpH.mjs.map} +1 -1
  5. package/dist/bin/bash-complete.mjs +1 -1
  6. package/dist/bin/cli.mjs +1 -1
  7. package/dist/bin/deprecated-command.mjs +1 -1
  8. package/dist/{buildXdiSyncEndpoint-DWs9ImOw.mjs → buildXdiSyncEndpoint-D5GxPH6o.mjs} +2 -2
  9. package/dist/{buildXdiSyncEndpoint-DWs9ImOw.mjs.map → buildXdiSyncEndpoint-D5GxPH6o.mjs.map} +1 -1
  10. package/dist/bulkRestartRequests-DILDBdc1.mjs +2 -0
  11. package/dist/bulkRestartRequests-DILDBdc1.mjs.map +1 -0
  12. package/dist/bulkRetryEnrichers-CjSz1472.mjs +2 -0
  13. package/dist/bulkRetryEnrichers-CjSz1472.mjs.map +1 -0
  14. package/dist/cancelPrivacyRequests-BWJZmZVY.mjs +2 -0
  15. package/dist/cancelPrivacyRequests-BWJZmZVY.mjs.map +1 -0
  16. package/dist/{collectCsvFilesOrExit-D-csvd13.mjs → collectCsvFilesOrExit-CbtyKAzu.mjs} +1 -1
  17. package/dist/{collectCsvFilesOrExit-D-csvd13.mjs.map → collectCsvFilesOrExit-CbtyKAzu.mjs.map} +1 -1
  18. package/dist/{collectParquetFilesOrExit-C8qT5_57.mjs → collectParquetFilesOrExit-BJiAyaQ5.mjs} +1 -1
  19. package/dist/{collectParquetFilesOrExit-C8qT5_57.mjs.map → collectParquetFilesOrExit-BJiAyaQ5.mjs.map} +1 -1
  20. package/dist/{command-rzZKmlky.mjs → command-BMa3UWax.mjs} +2 -2
  21. package/dist/{command-rzZKmlky.mjs.map → command-BMa3UWax.mjs.map} +1 -1
  22. package/dist/commands/admin/parquet-to-csv/worker.mjs +1 -1
  23. package/dist/{consentManagersToBusinessEntities-D1bdBgnA.mjs → consentManagersToBusinessEntities-BdKDganK.mjs} +1 -1
  24. package/dist/{consentManagersToBusinessEntities-D1bdBgnA.mjs.map → consentManagersToBusinessEntities-BdKDganK.mjs.map} +1 -1
  25. package/dist/{constants-mjLYTIJm.mjs → constants-BmwXDQu9.mjs} +2 -2
  26. package/dist/{constants-mjLYTIJm.mjs.map → constants-BmwXDQu9.mjs.map} +1 -1
  27. package/dist/{constants-DYbzl8QH.mjs → constants-ClkQQhJs.mjs} +1 -1
  28. package/dist/{constants-DYbzl8QH.mjs.map → constants-ClkQQhJs.mjs.map} +1 -1
  29. package/dist/{constants-XOsAW1__.mjs → constants-TpID7AXE.mjs} +2 -2
  30. package/dist/{constants-XOsAW1__.mjs.map → constants-TpID7AXE.mjs.map} +1 -1
  31. package/dist/{createExtraKeyHandler-Jp5XpTJi.mjs → createExtraKeyHandler-BO4lu0HO.mjs} +2 -2
  32. package/dist/{createExtraKeyHandler-Jp5XpTJi.mjs.map → createExtraKeyHandler-BO4lu0HO.mjs.map} +1 -1
  33. package/dist/{dataFlowsToDataSilos-DUj1NhOt.mjs → dataFlowsToDataSilos-Ca2DtTsd.mjs} +1 -1
  34. package/dist/{dataFlowsToDataSilos-DUj1NhOt.mjs.map → dataFlowsToDataSilos-Ca2DtTsd.mjs.map} +1 -1
  35. package/dist/{done-input-validation-C5rgR0Wr.mjs → done-input-validation-BcNBxhEs.mjs} +1 -1
  36. package/dist/{done-input-validation-C5rgR0Wr.mjs.map → done-input-validation-BcNBxhEs.mjs.map} +1 -1
  37. package/dist/{downloadPrivacyRequestFiles-GUbd_PRc.mjs → downloadPrivacyRequestFiles-8DtRUNXp.mjs} +2 -2
  38. package/dist/{downloadPrivacyRequestFiles-GUbd_PRc.mjs.map → downloadPrivacyRequestFiles-8DtRUNXp.mjs.map} +1 -1
  39. package/dist/{extractClientError-X9wJVqGq.mjs → extractClientError-i-Tw_az7.mjs} +1 -1
  40. package/dist/{extractClientError-X9wJVqGq.mjs.map → extractClientError-i-Tw_az7.mjs.map} +1 -1
  41. package/dist/{fetchAllRequests-xGgt_STo.mjs → fetchAllRequests-CHHdyb4Q.mjs} +2 -2
  42. package/dist/{fetchAllRequests-xGgt_STo.mjs.map → fetchAllRequests-CHHdyb4Q.mjs.map} +1 -1
  43. package/dist/generateCrossAccountApiKeys-D6hg9146.mjs +2 -0
  44. package/dist/generateCrossAccountApiKeys-D6hg9146.mjs.map +1 -0
  45. package/dist/{impl-ogUHfunr.mjs → impl--VlanXjT.mjs} +2 -2
  46. package/dist/{impl-ogUHfunr.mjs.map → impl--VlanXjT.mjs.map} +1 -1
  47. package/dist/{impl-B-PzeHxN.mjs → impl-3VLH9aat.mjs} +2 -2
  48. package/dist/{impl-B-PzeHxN.mjs.map → impl-3VLH9aat.mjs.map} +1 -1
  49. package/dist/{impl-DfVep2mE.mjs → impl-6mCOBlSD.mjs} +2 -2
  50. package/dist/{impl-DfVep2mE.mjs.map → impl-6mCOBlSD.mjs.map} +1 -1
  51. package/dist/impl-AEjPyfhu.mjs +2 -0
  52. package/dist/impl-AEjPyfhu.mjs.map +1 -0
  53. package/dist/{impl-CZsYoSZQ.mjs → impl-BC17WMY4.mjs} +2 -2
  54. package/dist/{impl-CZsYoSZQ.mjs.map → impl-BC17WMY4.mjs.map} +1 -1
  55. package/dist/{impl-yvc0y1uO.mjs → impl-BECek1in.mjs} +2 -2
  56. package/dist/{impl-yvc0y1uO.mjs.map → impl-BECek1in.mjs.map} +1 -1
  57. package/dist/{impl-B6TXE2oE.mjs → impl-BKvcmB7W.mjs} +2 -2
  58. package/dist/{impl-B6TXE2oE.mjs.map → impl-BKvcmB7W.mjs.map} +1 -1
  59. package/dist/impl-BNDNzc2I.mjs +2 -0
  60. package/dist/impl-BNDNzc2I.mjs.map +1 -0
  61. package/dist/{impl-Cy8-6_Oo2.mjs → impl-BTZOd3VN.mjs} +2 -2
  62. package/dist/impl-BTZOd3VN.mjs.map +1 -0
  63. package/dist/{impl-BffzTHKU.mjs → impl-BXb07jBU.mjs} +2 -2
  64. package/dist/{impl-BffzTHKU.mjs.map → impl-BXb07jBU.mjs.map} +1 -1
  65. package/dist/{impl-BBnnC5xq.mjs → impl-BaHZqboi.mjs} +2 -2
  66. package/dist/{impl-BBnnC5xq.mjs.map → impl-BaHZqboi.mjs.map} +1 -1
  67. package/dist/{impl-BSKl6rC6.mjs → impl-BhnojAfL.mjs} +2 -2
  68. package/dist/{impl-BSKl6rC6.mjs.map → impl-BhnojAfL.mjs.map} +1 -1
  69. package/dist/{impl-CqH3YYuv.mjs → impl-BjCQSRLu.mjs} +2 -2
  70. package/dist/{impl-CqH3YYuv.mjs.map → impl-BjCQSRLu.mjs.map} +1 -1
  71. package/dist/{impl-Cpndlxar.mjs → impl-BjIylEKQ.mjs} +2 -2
  72. package/dist/{impl-Cpndlxar.mjs.map → impl-BjIylEKQ.mjs.map} +1 -1
  73. package/dist/{impl-DKAV-8XC.mjs → impl-BsecIND0.mjs} +2 -2
  74. package/dist/{impl-DKAV-8XC.mjs.map → impl-BsecIND0.mjs.map} +1 -1
  75. package/dist/{impl-Dw9uW5zy2.mjs → impl-BtIsgTGn.mjs} +2 -2
  76. package/dist/impl-BtIsgTGn.mjs.map +1 -0
  77. package/dist/{impl-BMnXA_Vd.mjs → impl-BuvbXmXj.mjs} +2 -2
  78. package/dist/{impl-BMnXA_Vd.mjs.map → impl-BuvbXmXj.mjs.map} +1 -1
  79. package/dist/{impl-BBKJIP0Q.mjs → impl-C71CkarV.mjs} +2 -2
  80. package/dist/{impl-BBKJIP0Q.mjs.map → impl-C71CkarV.mjs.map} +1 -1
  81. package/dist/{impl-CpJljZV2.mjs → impl-CIYSnaMG.mjs} +2 -2
  82. package/dist/{impl-CpJljZV2.mjs.map → impl-CIYSnaMG.mjs.map} +1 -1
  83. package/dist/{impl-DhXQb3bm.mjs → impl-CLznNZ5F.mjs} +2 -2
  84. package/dist/{impl-DhXQb3bm.mjs.map → impl-CLznNZ5F.mjs.map} +1 -1
  85. package/dist/{impl-BGGm947r2.mjs → impl-CR6tW9Jz.mjs} +2 -2
  86. package/dist/impl-CR6tW9Jz.mjs.map +1 -0
  87. package/dist/{impl-CPIMsZg-.mjs → impl-CScy-GrG.mjs} +2 -2
  88. package/dist/{impl-CPIMsZg-.mjs.map → impl-CScy-GrG.mjs.map} +1 -1
  89. package/dist/{impl-uwkj-RbF.mjs → impl-CYS38cQM.mjs} +2 -2
  90. package/dist/{impl-uwkj-RbF.mjs.map → impl-CYS38cQM.mjs.map} +1 -1
  91. package/dist/{impl-BVnfUDUm.mjs → impl-Cw3_0zqC.mjs} +2 -2
  92. package/dist/{impl-BVnfUDUm.mjs.map → impl-Cw3_0zqC.mjs.map} +1 -1
  93. package/dist/{impl-D_AxguFh2.mjs → impl-CxwEMQhw.mjs} +2 -2
  94. package/dist/impl-CxwEMQhw.mjs.map +1 -0
  95. package/dist/{impl-DaK9UOwL.mjs → impl-CzvCA0Ev.mjs} +2 -2
  96. package/dist/{impl-DaK9UOwL.mjs.map → impl-CzvCA0Ev.mjs.map} +1 -1
  97. package/dist/{impl-StdJMCiM.mjs → impl-DAkBsgQN.mjs} +2 -2
  98. package/dist/{impl-StdJMCiM.mjs.map → impl-DAkBsgQN.mjs.map} +1 -1
  99. package/dist/{impl-iGMjSniP.mjs → impl-DAu079Yl.mjs} +2 -2
  100. package/dist/{impl-iGMjSniP.mjs.map → impl-DAu079Yl.mjs.map} +1 -1
  101. package/dist/{impl-BKrNGF2F.mjs → impl-DTaM3UE3.mjs} +2 -2
  102. package/dist/{impl-BKrNGF2F.mjs.map → impl-DTaM3UE3.mjs.map} +1 -1
  103. package/dist/{impl-CnHiD4zU.mjs → impl-DWiE5RsV.mjs} +2 -2
  104. package/dist/{impl-CnHiD4zU.mjs.map → impl-DWiE5RsV.mjs.map} +1 -1
  105. package/dist/{impl-CODwodEc.mjs → impl-DXHqqWJb.mjs} +2 -2
  106. package/dist/{impl-CODwodEc.mjs.map → impl-DXHqqWJb.mjs.map} +1 -1
  107. package/dist/impl-DZicly6r.mjs +2 -0
  108. package/dist/{impl-BVHfSIVG.mjs.map → impl-DZicly6r.mjs.map} +1 -1
  109. package/dist/{impl-CvJtt8H2.mjs → impl-DbGCApR_.mjs} +2 -2
  110. package/dist/{impl-CvJtt8H2.mjs.map → impl-DbGCApR_.mjs.map} +1 -1
  111. package/dist/{impl-BxOydpyJ.mjs → impl-DgG4lZ9T.mjs} +2 -2
  112. package/dist/{impl-BxOydpyJ.mjs.map → impl-DgG4lZ9T.mjs.map} +1 -1
  113. package/dist/{impl-DpwyYsfg.mjs → impl-Dik9I7Bz.mjs} +2 -2
  114. package/dist/{impl-DpwyYsfg.mjs.map → impl-Dik9I7Bz.mjs.map} +1 -1
  115. package/dist/impl-Djlx-Dqj.mjs +2 -0
  116. package/dist/impl-Djlx-Dqj.mjs.map +1 -0
  117. package/dist/{impl-CC0rkA9s.mjs → impl-DmQAAT-u.mjs} +2 -2
  118. package/dist/{impl-CC0rkA9s.mjs.map → impl-DmQAAT-u.mjs.map} +1 -1
  119. package/dist/{impl-C3DXXn8M.mjs → impl-DpuPyy-w.mjs} +2 -2
  120. package/dist/{impl-C3DXXn8M.mjs.map → impl-DpuPyy-w.mjs.map} +1 -1
  121. package/dist/{impl-C-u5h8We.mjs → impl-Du8quB1O.mjs} +2 -2
  122. package/dist/{impl-C-u5h8We.mjs.map → impl-Du8quB1O.mjs.map} +1 -1
  123. package/dist/{impl-BRiRfzgu.mjs → impl-OxHej0UO.mjs} +2 -2
  124. package/dist/{impl-BRiRfzgu.mjs.map → impl-OxHej0UO.mjs.map} +1 -1
  125. package/dist/{impl-DJ4VCAcc.mjs → impl-c7VvcNpZ.mjs} +2 -2
  126. package/dist/{impl-DJ4VCAcc.mjs.map → impl-c7VvcNpZ.mjs.map} +1 -1
  127. package/dist/{impl-DvrSuAJv.mjs → impl-fZQxhZRu.mjs} +2 -2
  128. package/dist/{impl-DvrSuAJv.mjs.map → impl-fZQxhZRu.mjs.map} +1 -1
  129. package/dist/{impl-DpGVNllB.mjs → impl-xtlx25UP.mjs} +2 -2
  130. package/dist/{impl-DpGVNllB.mjs.map → impl-xtlx25UP.mjs.map} +1 -1
  131. package/dist/{impl-Cw10WeUv.mjs → impl-yMumZUUX.mjs} +2 -2
  132. package/dist/{impl-Cw10WeUv.mjs.map → impl-yMumZUUX.mjs.map} +1 -1
  133. package/dist/index.d.mts +895 -1698
  134. package/dist/index.d.mts.map +1 -1
  135. package/dist/index.mjs +4 -4
  136. package/dist/index.mjs.map +1 -1
  137. package/dist/{inquirer-DyRwhvoh.mjs → inquirer-BqZXFEt1.mjs} +2 -2
  138. package/dist/{inquirer-DyRwhvoh.mjs.map → inquirer-BqZXFEt1.mjs.map} +1 -1
  139. package/dist/{listFiles-Odj7j2E1.mjs → listFiles-D2wMHnEr.mjs} +1 -1
  140. package/dist/{listFiles-Odj7j2E1.mjs.map → listFiles-D2wMHnEr.mjs.map} +1 -1
  141. package/dist/markRequestDataSiloIdsCompleted-sDBo1vUD.mjs +2 -0
  142. package/dist/markRequestDataSiloIdsCompleted-sDBo1vUD.mjs.map +1 -0
  143. package/dist/{markSilentPrivacyRequests-ytCzpUkY.mjs → markSilentPrivacyRequests-Cmn1fxHI.mjs} +2 -2
  144. package/dist/{markSilentPrivacyRequests-ytCzpUkY.mjs.map → markSilentPrivacyRequests-Cmn1fxHI.mjs.map} +1 -1
  145. package/dist/notifyPrivacyRequestsAdditionalTime-CmhFE4b0.mjs +2 -0
  146. package/dist/notifyPrivacyRequestsAdditionalTime-CmhFE4b0.mjs.map +1 -0
  147. package/dist/{parquetToCsvOneFile-bgEgRoAi.mjs → parquetToCsvOneFile-B84XXInh.mjs} +1 -1
  148. package/dist/{parquetToCsvOneFile-bgEgRoAi.mjs.map → parquetToCsvOneFile-B84XXInh.mjs.map} +1 -1
  149. package/dist/{parseAttributesFromString-B8h4DudO.mjs → parseAttributesFromString-D1Yl0xwT.mjs} +2 -2
  150. package/dist/{parseAttributesFromString-B8h4DudO.mjs.map → parseAttributesFromString-D1Yl0xwT.mjs.map} +1 -1
  151. package/dist/parseVariablesFromString-BeKOGw5n.mjs +3 -0
  152. package/dist/parseVariablesFromString-BeKOGw5n.mjs.map +1 -0
  153. package/dist/pullAllDatapoints-Bbmky50p.mjs +45 -0
  154. package/dist/pullAllDatapoints-Bbmky50p.mjs.map +1 -0
  155. package/dist/pullChunkedCustomSiloOutstandingIdentifiers-QRET4M0x.mjs +2 -0
  156. package/dist/pullChunkedCustomSiloOutstandingIdentifiers-QRET4M0x.mjs.map +1 -0
  157. package/dist/{pullConsentManagerMetrics-BO0hYPDG.mjs → pullConsentManagerMetrics-zKgjc3Ap.mjs} +1 -1
  158. package/dist/{pullConsentManagerMetrics-BO0hYPDG.mjs.map → pullConsentManagerMetrics-zKgjc3Ap.mjs.map} +1 -1
  159. package/dist/pullManualEnrichmentIdentifiersToCsv-8I6PgBQc.mjs +2 -0
  160. package/dist/pullManualEnrichmentIdentifiersToCsv-8I6PgBQc.mjs.map +1 -0
  161. package/dist/pullTranscendConfiguration-DjOELnPo.mjs +58 -0
  162. package/dist/pullTranscendConfiguration-DjOELnPo.mjs.map +1 -0
  163. package/dist/{pullUnstructuredSubDataPointRecommendations-jE-tdoVK.mjs → pullUnstructuredSubDataPointRecommendations-D0z-vPgq.mjs} +3 -3
  164. package/dist/{pullUnstructuredSubDataPointRecommendations-jE-tdoVK.mjs.map → pullUnstructuredSubDataPointRecommendations-D0z-vPgq.mjs.map} +1 -1
  165. package/dist/{pushCronIdentifiersFromCsv-D9Hzna0W.mjs → pushCronIdentifiersFromCsv-CBb2FvPD.mjs} +2 -2
  166. package/dist/{pushCronIdentifiersFromCsv-D9Hzna0W.mjs.map → pushCronIdentifiersFromCsv-CBb2FvPD.mjs.map} +1 -1
  167. package/dist/{pushManualEnrichmentIdentifiersFromCsv-BiR7PS_d.mjs → pushManualEnrichmentIdentifiersFromCsv-DYQq7hsN.mjs} +2 -2
  168. package/dist/{pushManualEnrichmentIdentifiersFromCsv-BiR7PS_d.mjs.map → pushManualEnrichmentIdentifiersFromCsv-DYQq7hsN.mjs.map} +1 -1
  169. package/dist/{readCsv-0PIlJQCN.mjs → readCsv-C4TyEs-r.mjs} +1 -1
  170. package/dist/{readCsv-0PIlJQCN.mjs.map → readCsv-C4TyEs-r.mjs.map} +1 -1
  171. package/dist/removeUnverifiedRequestIdentifiers-VCbL2BXD.mjs +2 -0
  172. package/dist/removeUnverifiedRequestIdentifiers-VCbL2BXD.mjs.map +1 -0
  173. package/dist/{request-SLqRySNU.mjs → request-DfkRPQFr.mjs} +1 -1
  174. package/dist/{request-SLqRySNU.mjs.map → request-DfkRPQFr.mjs.map} +1 -1
  175. package/dist/retryRequestDataSilos-BCe-WGdL.mjs +2 -0
  176. package/dist/retryRequestDataSilos-BCe-WGdL.mjs.map +1 -0
  177. package/dist/skipPreflightJobs-Bc0--Bvs.mjs +2 -0
  178. package/dist/skipPreflightJobs-Bc0--Bvs.mjs.map +1 -0
  179. package/dist/skipRequestDataSilos-BHbAQkpb.mjs +2 -0
  180. package/dist/skipRequestDataSilos-BHbAQkpb.mjs.map +1 -0
  181. package/dist/streamPrivacyRequestsToCsv-eB3gNhol.mjs +2 -0
  182. package/dist/streamPrivacyRequestsToCsv-eB3gNhol.mjs.map +1 -0
  183. package/dist/{syncCodePackages-BOS5foh6.mjs → syncCodePackages-CAk_Hjyl.mjs} +1 -1
  184. package/dist/{syncCodePackages-BOS5foh6.mjs.map → syncCodePackages-CAk_Hjyl.mjs.map} +1 -1
  185. package/dist/updateConsentManagerVersionToLatest-D6i1Xh6o.mjs +2 -0
  186. package/dist/updateConsentManagerVersionToLatest-D6i1Xh6o.mjs.map +1 -0
  187. package/dist/{uploadConsents-BP5XILuw.mjs → uploadConsents-BTM49EbZ.mjs} +2 -2
  188. package/dist/{uploadConsents-BP5XILuw.mjs.map → uploadConsents-BTM49EbZ.mjs.map} +1 -1
  189. package/dist/{uploadCookiesFromCsv-B42cZgYW.mjs → uploadCookiesFromCsv-DoC9rtEF.mjs} +2 -2
  190. package/dist/{uploadCookiesFromCsv-B42cZgYW.mjs.map → uploadCookiesFromCsv-DoC9rtEF.mjs.map} +1 -1
  191. package/dist/{uploadDataFlowsFromCsv-D2V567pP.mjs → uploadDataFlowsFromCsv-DL1-cAit.mjs} +2 -2
  192. package/dist/{uploadDataFlowsFromCsv-D2V567pP.mjs.map → uploadDataFlowsFromCsv-DL1-cAit.mjs.map} +1 -1
  193. package/dist/uploadPrivacyRequestsFromCsv-wXm4H4FH.mjs +2 -0
  194. package/dist/uploadPrivacyRequestsFromCsv-wXm4H4FH.mjs.map +1 -0
  195. package/dist/{validateTranscendAuth-DCwAtgvh.mjs → validateTranscendAuth-Cuh2Qfdl.mjs} +1 -1
  196. package/dist/{validateTranscendAuth-DCwAtgvh.mjs.map → validateTranscendAuth-Cuh2Qfdl.mjs.map} +1 -1
  197. package/dist/{writeCsv-Da8NUe1V.mjs → writeCsv-C4pjXGsD.mjs} +1 -1
  198. package/dist/{writeCsv-Da8NUe1V.mjs.map → writeCsv-C4pjXGsD.mjs.map} +1 -1
  199. package/package.json +8 -8
  200. package/dist/RequestDataSilo-Rrc2dL9g.mjs +0 -54
  201. package/dist/RequestDataSilo-Rrc2dL9g.mjs.map +0 -1
  202. package/dist/bulkRestartRequests-sie3tM3W.mjs +0 -2
  203. package/dist/bulkRestartRequests-sie3tM3W.mjs.map +0 -1
  204. package/dist/bulkRetryEnrichers-C1RrxiTR.mjs +0 -2
  205. package/dist/bulkRetryEnrichers-C1RrxiTR.mjs.map +0 -1
  206. package/dist/cancelPrivacyRequests-DmvFijq_.mjs +0 -2
  207. package/dist/cancelPrivacyRequests-DmvFijq_.mjs.map +0 -1
  208. package/dist/dataSilo-Dvi8-PkH.mjs +0 -302
  209. package/dist/dataSilo-Dvi8-PkH.mjs.map +0 -1
  210. package/dist/dataSubject-CF784Ug0.mjs +0 -92
  211. package/dist/dataSubject-CF784Ug0.mjs.map +0 -1
  212. package/dist/fetchAllRequestEnrichers-Bt97Bb7F.mjs +0 -42
  213. package/dist/fetchAllRequestEnrichers-Bt97Bb7F.mjs.map +0 -1
  214. package/dist/fetchAllRequestIdentifiers-BXx3rSee.mjs +0 -10
  215. package/dist/fetchAllRequestIdentifiers-BXx3rSee.mjs.map +0 -1
  216. package/dist/fetchRequestDataSilo-0UvyeL60.mjs +0 -2
  217. package/dist/fetchRequestDataSilo-0UvyeL60.mjs.map +0 -1
  218. package/dist/fetchRequestFilesForRequest-CJH2iB-P.mjs +0 -33
  219. package/dist/fetchRequestFilesForRequest-CJH2iB-P.mjs.map +0 -1
  220. package/dist/generateCrossAccountApiKeys-DztJoLQS.mjs +0 -2
  221. package/dist/generateCrossAccountApiKeys-DztJoLQS.mjs.map +0 -1
  222. package/dist/impl-BGGm947r2.mjs.map +0 -1
  223. package/dist/impl-BVHfSIVG.mjs +0 -2
  224. package/dist/impl-BfeWet_F2.mjs +0 -2
  225. package/dist/impl-BfeWet_F2.mjs.map +0 -1
  226. package/dist/impl-Cy8-6_Oo2.mjs.map +0 -1
  227. package/dist/impl-D_AxguFh2.mjs.map +0 -1
  228. package/dist/impl-Dw9uW5zy2.mjs.map +0 -1
  229. package/dist/impl-PdIU1pLr2.mjs +0 -2
  230. package/dist/impl-PdIU1pLr2.mjs.map +0 -1
  231. package/dist/impl-daUiLV3c.mjs +0 -2
  232. package/dist/impl-daUiLV3c.mjs.map +0 -1
  233. package/dist/markRequestDataSiloIdsCompleted-DJSICILv.mjs +0 -2
  234. package/dist/markRequestDataSiloIdsCompleted-DJSICILv.mjs.map +0 -1
  235. package/dist/notifyPrivacyRequestsAdditionalTime-D8v68eAg.mjs +0 -2
  236. package/dist/notifyPrivacyRequestsAdditionalTime-D8v68eAg.mjs.map +0 -1
  237. package/dist/parseVariablesFromString-CvoeZZ75.mjs +0 -23
  238. package/dist/parseVariablesFromString-CvoeZZ75.mjs.map +0 -1
  239. package/dist/pullAllDatapoints-CqgqXRbp.mjs +0 -45
  240. package/dist/pullAllDatapoints-CqgqXRbp.mjs.map +0 -1
  241. package/dist/pullChunkedCustomSiloOutstandingIdentifiers-DaYEDZ66.mjs +0 -2
  242. package/dist/pullChunkedCustomSiloOutstandingIdentifiers-DaYEDZ66.mjs.map +0 -1
  243. package/dist/pullManualEnrichmentIdentifiersToCsv-BNuhsG20.mjs +0 -2
  244. package/dist/pullManualEnrichmentIdentifiersToCsv-BNuhsG20.mjs.map +0 -1
  245. package/dist/pullTranscendConfiguration-DSyMRyPe.mjs +0 -58
  246. package/dist/pullTranscendConfiguration-DSyMRyPe.mjs.map +0 -1
  247. package/dist/removeUnverifiedRequestIdentifiers-B0Gx09XN.mjs +0 -35
  248. package/dist/removeUnverifiedRequestIdentifiers-B0Gx09XN.mjs.map +0 -1
  249. package/dist/retryRequestDataSilos-DFjFhhC0.mjs +0 -2
  250. package/dist/retryRequestDataSilos-DFjFhhC0.mjs.map +0 -1
  251. package/dist/skipPreflightJobs-Bm8lZZk-.mjs +0 -2
  252. package/dist/skipPreflightJobs-Bm8lZZk-.mjs.map +0 -1
  253. package/dist/skipRequestDataSilos-B5FByYTj.mjs +0 -2
  254. package/dist/skipRequestDataSilos-B5FByYTj.mjs.map +0 -1
  255. package/dist/streamPrivacyRequestsToCsv-CBzh80oQ.mjs +0 -2
  256. package/dist/streamPrivacyRequestsToCsv-CBzh80oQ.mjs.map +0 -1
  257. package/dist/syncEnrichers-C9HcWCrs.mjs +0 -3
  258. package/dist/syncEnrichers-C9HcWCrs.mjs.map +0 -1
  259. package/dist/updateConsentManagerVersionToLatest-X1HAM_IX.mjs +0 -2
  260. package/dist/updateConsentManagerVersionToLatest-X1HAM_IX.mjs.map +0 -1
  261. package/dist/uploadPrivacyRequestsFromCsv-Czc3vGfJ.mjs +0 -2
  262. package/dist/uploadPrivacyRequestsFromCsv-Czc3vGfJ.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"constants-mjLYTIJm.mjs","names":[],"sources":["../src/lib/code-scanning/integrations/cocoaPods.ts","../src/lib/code-scanning/integrations/gradle.ts","../src/lib/code-scanning/integrations/javascriptPackageJson.ts","../src/lib/code-scanning/integrations/pythonRequirementsTxt.ts","../src/lib/code-scanning/integrations/gemfile.ts","../src/lib/code-scanning/integrations/pubspec.ts","../src/lib/code-scanning/integrations/composerJson.ts","../src/lib/code-scanning/integrations/swift.ts","../src/lib/code-scanning/integrations/kotlin.ts","../src/lib/code-scanning/constants.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { CodePackageSdk } from '../../../codecs.js';\nimport { CodeScanningConfig } from '../types.js';\n\nconst POD_TARGET_REGEX = /target ('|\")(.*?)('|\")/;\nconst POD_PACKAGE_REGEX = /pod ('|\")(.*?)('|\")(, ('|\")~> (.+?)('|\")|)/;\n\nexport const cocoaPods: CodeScanningConfig = {\n supportedFiles: ['Podfile'],\n ignoreDirs: ['Pods', 'Build'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(POD_TARGET_REGEX, 'g'),\n matches: ['quote1', 'name', 'quote2'],\n },\n fileContents,\n );\n const packages = findAllWithRegex(\n {\n value: new RegExp(POD_PACKAGE_REGEX, 'g'),\n matches: ['quote1', 'name', 'quote2', 'extra', 'quote3', 'version', 'quote4'],\n },\n fileContents,\n );\n\n const deps: CodePackageSdk[] = targets.map((target, ind) => ({\n name: target.name,\n type: CodePackageType.CocoaPods,\n softwareDevelopmentKits: packages\n .filter(\n (pkg) =>\n pkg.matchIndex > target.matchIndex &&\n (!targets[ind + 1] || pkg.matchIndex < targets[ind + 1].matchIndex),\n )\n .map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n })),\n }));\n\n return deps;\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { CodeScanningConfig } from '../types.js';\n\nconst GRADLE_IMPLEMENTATION_REGEX = /implementation( *)('|\")(.+?):(.+?):(.+?|)('|\")/;\nconst GRADLE_PLUGIN_REGEX = /apply plugin: *('|\")(.+?)(:(.+?)|)('|\")/;\nconst GRADLE_IMPLEMENTATION_GROUP_REGEX =\n /implementation group:( *)('|\")(.+?)('|\"),( *)name:( *)('|\")(.+?)('|\"),( *)version:( *)('|\")(.+?)('|\")/;\nconst GRADLE_APPLICATION_NAME_REGEX = /applicationId( *)\"(.+?)\"/;\n\n/**\n * So far, there are three ways of defining dependencies that is supported\n * implementation group: 'org.eclipse.jdt', name: 'org.eclipse.jdt.core', version: '3.28.0'\n * or\n * implementation 'com.google.firebase:firebase-analytics:18.0.0'\n * or\n * apply plugin: 'com.google.gms.google-services'\n *\n * single and double quotes are both recognized\n */\nexport const gradle: CodeScanningConfig = {\n supportedFiles: ['build.gradle**'],\n ignoreDirs: ['gradle-app.setting', 'gradle-wrapper.jar', 'gradle-wrapper.properties'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(GRADLE_IMPLEMENTATION_REGEX, 'g'),\n matches: ['space', 'quote1', 'name', 'path', 'version', 'quote2'],\n },\n fileContents,\n );\n const targetPlugins = findAllWithRegex(\n {\n value: new RegExp(GRADLE_PLUGIN_REGEX, 'g'),\n matches: ['quote1', 'name', 'group', 'version', 'quote2'],\n },\n fileContents,\n );\n const targetGroups = findAllWithRegex(\n {\n value: new RegExp(GRADLE_IMPLEMENTATION_GROUP_REGEX, 'g'),\n matches: [\n 'space1',\n 'quote1',\n 'group',\n 'quote2',\n 'space2',\n 'space3',\n 'quote3',\n 'name',\n 'quote4',\n 'space4',\n 'space5',\n 'quote5',\n 'version',\n 'quote6',\n ],\n },\n fileContents,\n );\n const applications = findAllWithRegex(\n {\n value: new RegExp(GRADLE_APPLICATION_NAME_REGEX, 'g'),\n matches: ['space', 'name'],\n },\n fileContents,\n );\n if (applications.length > 1) {\n throw new Error(`Expected only one applicationId per file: ${filePath}`);\n }\n\n return [\n {\n name: applications[0]?.name || directory.split('/').pop()!,\n softwareDevelopmentKits: [...targets, ...targetGroups, ...targetPlugins].map((target) => ({\n name: target.name,\n version: target.version || undefined,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageSdk } from '../../../codecs.js';\nimport { CodeScanningConfig } from '../types.js';\n\nexport const javascriptPackageJson: CodeScanningConfig = {\n supportedFiles: ['package.json'],\n ignoreDirs: ['node_modules', 'serverless-build', 'lambda-build'],\n scanFunction: (filePath) => {\n const file = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const asJson = JSON.parse(file);\n const {\n name,\n description,\n dependencies = {},\n devDependencies = {},\n optionalDependencies = {},\n } = asJson;\n return [\n {\n // name of the package\n name: name || directory.split('/').pop()!,\n description,\n softwareDevelopmentKits: [\n ...Object.entries(dependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n }),\n ),\n ...Object.entries(devDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n isDevDependency: true,\n }),\n ),\n ...Object.entries(optionalDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n }),\n ),\n ],\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { listFiles } from '../../api-keys/index.js';\nimport { CodeScanningConfig } from '../types.js';\n\nconst REQUIREMENTS_PACKAGE_MATCH = /(.+?)(=+)(.+)/;\nconst PACKAGE_NAME = /name *= *('|\")(.+?)('|\")/;\nconst PACKAGE_DESCRIPTION = /description *= *('|\")(.+?)('|\")/;\n\nexport const pythonRequirementsTxt: CodeScanningConfig = {\n supportedFiles: ['requirements.txt'],\n ignoreDirs: ['build', 'lib', 'lib64'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const filesInFolder = listFiles(directory);\n\n // parse setup file for name\n const setupFile = filesInFolder.find((file) => file === 'setup.py');\n const setupFileContents = setupFile\n ? readFileSync(join(directory, setupFile), 'utf-8')\n : undefined;\n const packageName = setupFileContents\n ? (PACKAGE_NAME.exec(setupFileContents) || [])[2]\n : undefined;\n const packageDescription = setupFileContents\n ? (PACKAGE_DESCRIPTION.exec(setupFileContents) || [])[2]\n : undefined;\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(REQUIREMENTS_PACKAGE_MATCH, 'g'),\n matches: ['name', 'equals', 'version'],\n },\n fileContents,\n );\n\n return [\n {\n name: packageName || directory.split('/').pop()!,\n description: packageDescription || undefined,\n type: CodePackageType.RequirementsTxt,\n softwareDevelopmentKits: targets.map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { listFiles } from '../../api-keys/index.js';\nimport { CodeScanningConfig } from '../types.js';\n\nconst GEM_PACKAGE_REGEX = /gem *('|\")(.+?)('|\")(, *('|\")(.+?)('|\")|)/;\nconst GEMFILE_PACKAGE_NAME_REGEX = /spec\\.name *= *('|\")(.+?)('|\")/;\nconst GEMFILE_PACKAGE_DESCRIPTION_REGEX = /spec\\.description *= *('|\")(.+?)('|\")/;\nconst GEMFILE_PACKAGE_SUMMARY_REGEX = /spec\\.summary *= *('|\")(.+?)('|\")/;\n\nexport const gemfile: CodeScanningConfig = {\n supportedFiles: ['Gemfile'],\n ignoreDirs: ['bin'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const filesInFolder = listFiles(directory);\n\n // parse gemspec file for name\n const gemspec = filesInFolder.find((file) => file === '.gemspec');\n const gemspecContents = gemspec ? readFileSync(gemspec, 'utf-8') : undefined;\n const gemfileName = gemspecContents\n ? (GEMFILE_PACKAGE_NAME_REGEX.exec(gemspecContents) || [])[2]\n : undefined;\n const gemfileDescription = gemspecContents\n ? (GEMFILE_PACKAGE_DESCRIPTION_REGEX.exec(gemspecContents) ||\n GEMFILE_PACKAGE_SUMMARY_REGEX.exec(gemspecContents) ||\n [])[1]\n : undefined;\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(GEM_PACKAGE_REGEX, 'g'),\n matches: ['quote1', 'name', 'quote2', 'hasVersion', 'quote3', 'version', 'quote4'],\n },\n fileContents,\n );\n\n return [\n {\n name: gemfileName || directory.split('/').pop()!,\n description: gemfileDescription || undefined,\n type: CodePackageType.RequirementsTxt,\n softwareDevelopmentKits: targets.map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport yaml from 'js-yaml';\n\nimport { CodeScanningConfig } from '../types.js';\n\n/**\n * Remove YAML comments from a string\n *\n * @param yamlString - YAML string\n * @returns String without comments\n */\nfunction removeYAMLComments(yamlString: string): string {\n return yamlString\n .split('\\n')\n .map((line) => {\n // Remove inline comments\n const commentIndex = line.indexOf('#');\n if (commentIndex > -1) {\n // Check if '#' is not inside a string\n if (\n !line.substring(0, commentIndex).includes('\"') &&\n !line.substring(0, commentIndex).includes(\"'\")\n ) {\n return line.substring(0, commentIndex).trim();\n }\n }\n return line;\n })\n .filter((line) => line.length > 0)\n .join('\\n');\n}\n\nexport const pubspec: CodeScanningConfig = {\n supportedFiles: ['pubspec.yml'],\n ignoreDirs: ['build'],\n scanFunction: (filePath) => {\n const directory = dirname(filePath);\n const fileContents = readFileSync(filePath, 'utf-8');\n const {\n name,\n description,\n dev_dependencies = {},\n dependencies = {},\n } = yaml.load(removeYAMLComments(fileContents)) as {\n /** Name */\n name?: string;\n /** Description */\n description?: string;\n /** Dev dependencies */\n dev_dependencies?: { [k in string]: number | Record<string, string> };\n /** Dependencies */\n dependencies?: { [k in string]: number | Record<string, string> };\n };\n return [\n {\n name: name || directory.split('/').pop()!,\n description,\n type: CodePackageType.RequirementsTxt,\n softwareDevelopmentKits: [\n ...Object.entries(dependencies).map(([name, version]) => ({\n name,\n version:\n typeof version === 'string'\n ? version\n : typeof version === 'number'\n ? version.toString()\n : version?.sdk,\n })),\n ...Object.entries(dev_dependencies).map(([name, version]) => ({\n name,\n version:\n typeof version === 'string'\n ? version\n : typeof version === 'number'\n ? version.toString()\n : version?.sdk,\n isDevDependency: true,\n })),\n ],\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageSdk } from '../../../codecs.js';\nimport { CodeScanningConfig } from '../types.js';\n\nexport const composerJson: CodeScanningConfig = {\n supportedFiles: ['composer.json'],\n ignoreDirs: ['vendor', 'node_modules', 'cache', 'build', 'dist'],\n scanFunction: (filePath) => {\n const file = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const asJson = JSON.parse(file);\n const {\n name,\n description,\n require: requireDependencies = {},\n 'require-dev': requiredDevDependencies = {},\n } = asJson;\n return [\n {\n // name of the package\n name: name || directory.split('/').pop()!,\n description,\n softwareDevelopmentKits: [\n ...Object.entries(requireDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n }),\n ),\n ...Object.entries(requiredDevDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n isDevDependency: true,\n }),\n ),\n ],\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport * as t from 'io-ts';\n\nimport { CodeScanningConfig } from '../types.js';\n\nconst SwiftPackage = t.type({\n pins: t.array(\n t.type({\n identity: t.string,\n kind: t.string,\n location: t.string,\n state: t.intersection([\n t.type({\n revision: t.string,\n }),\n t.partial({\n version: t.union([t.string, t.undefined, t.null]),\n }),\n ]),\n }),\n ),\n version: t.number,\n});\n\nconst SwiftPackageV1 = t.type({\n object: t.type({\n pins: t.array(\n t.type({\n package: t.string,\n repositoryURL: t.string,\n state: t.intersection([\n t.type({\n branch: t.union([t.string, t.undefined, t.null]),\n revision: t.string,\n }),\n t.partial({\n version: t.union([t.string, t.undefined, t.null]),\n }),\n ]),\n }),\n ),\n }),\n version: t.number,\n});\n\nexport const swift: CodeScanningConfig = {\n supportedFiles: ['Package.resolved'],\n ignoreDirs: [],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n\n // Attempt latest version first\n try {\n const parsed = decodeCodec(SwiftPackage, fileContents);\n const splitPath = dirname(filePath).split('/');\n const originalName = splitPath[splitPath.length - 1];\n let name = originalName;\n if (name === 'swiftpm') {\n name = splitPath[splitPath.length - 2];\n if (name === 'xcshareddata') {\n name = splitPath[splitPath.length - 3];\n } else if (!name) {\n name = originalName;\n }\n if (name === 'project.xcworkspace') {\n name = splitPath[splitPath.length - 4];\n }\n }\n return [\n {\n name,\n type: CodePackageType.Swift,\n softwareDevelopmentKits: parsed.pins.map((target) => ({\n name: target.identity,\n version: target.state.version || undefined,\n })),\n },\n ];\n } catch (e) {\n // Throw non codec errors\n if (!e?.message?.includes('Failed to decode codec')) {\n throw e;\n }\n\n // Attempt v1\n try {\n const parsed = decodeCodec(SwiftPackageV1, fileContents);\n return [\n {\n name: dirname(filePath).split('/').pop() || '', // TODO pull from Package.swift ->> name if possible\n type: CodePackageType.Swift,\n softwareDevelopmentKits: parsed.object.pins.map((target) => ({\n name: target.package,\n version: target.state.version || undefined,\n })),\n },\n ];\n } catch (e2) {\n if (!e2?.message?.includes('Failed to decode codec')) {\n throw e2;\n }\n throw e;\n }\n }\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { CodeScanningConfig } from '../types.js';\n\n/**\n * Kotlin DSL (build.gradle.kts) dependency & plugin parsing\n */\n\nconst KTS_DEP_CONFIGS =\n // eslint-disable-next-line max-len\n '(implementation|api|kapt|ksp|debugImplementation|releaseImplementation|androidTestImplementation|testImplementation|compileOnly|runtimeOnly)';\n\n// e.g. implementation(\"com.google.firebase:firebase-analytics:18.0.0\")\nconst KTS_DEP_STRING_COORDS_REGEX = new RegExp(\n `${KTS_DEP_CONFIGS}\\\\s*\\\\(\\\\s*[\"']([^\"':\\\\s]+):([^\"':\\\\s]+):?([^\"']*)[\"']\\\\s*\\\\)`,\n 'g',\n);\n// captures: [1]=config, [2]=group, [3]=artifact, [4]=version (may be '')\n\n// e.g. implementation(platform(\"com.google.firebase:firebase-bom:33.1.2\"))\nconst KTS_DEP_PLATFORM_REGEX = new RegExp(\n `${KTS_DEP_CONFIGS}\\\\s*\\\\(\\\\s*platform\\\\(\\\\s*[\"']([^\"':\\\\s]+):([^\"':\\\\s]+):?([^\"']*)[\"']\\\\s*\\\\)\\\\s*\\\\)`,\n 'g',\n);\n\n// e.g. implementation(libs.androidx.appcompat) / implementation(libs[\"androidx-core-ktx\"])\nconst KTS_DEP_LIBS_ALIAS_REGEX = new RegExp(\n `${KTS_DEP_CONFIGS}\\\\s*\\\\(\\\\s*libs(?:\\\\.[\\\\w\\\\-\\\\.]+|\\\\[[\"'][^\"']+[\"']\\\\])\\\\s*\\\\)`,\n 'g',\n);\n\n// Plugins:\n// plugins { id(\"com.google.gms.google-services\") version \"4.4.2\" apply false }\n// plugins { id(\"org.jetbrains.kotlin.android\") }\n// apply(plugin = \"newrelic\")\n// plugins { alias(libs.plugins.kotlin.android) }\nconst KTS_PLUGIN_ID_REGEX = /id\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)(?:\\s*version\\s*[\"']([^\"']+)[\"'])?/g;\nconst KTS_PLUGIN_APPLY_REGEX = /apply\\s*\\(\\s*plugin\\s*=\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\nconst KTS_PLUGIN_ALIAS_REGEX =\n /plugins\\s*\\{[^}]*alias\\s*\\(\\s*libs(?:\\.plugins)?(?:\\.[\\w\\-.]+|\\[[\"'][^\"']+[\"']\\])\\s*\\)[^}]*\\}/g;\n\n// applicationId in Kotlin DSL:\n// applicationId = \"com.foo.bar\"\n// applicationId(\"com.foo.bar\")\nconst KTS_APPLICATION_ID_EQ_REGEX = /applicationId\\s*=\\s*[\"']([^\"']+)[\"']/g;\nconst KTS_APPLICATION_ID_CALL_REGEX = /applicationId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\n\n/**\n * Input dep entry (partial)\n */\ntype DepInput = {\n /** Name of the dependency */\n name: string;\n /** Version of the dependency */\n version?: string;\n};\n\n/**\n * Helper to normalize a parsed dep entry\n *\n * @param name - name\n * @param version - version\n * @returns normalized entry\n */\nfunction depEntry(name: string, version?: string): DepInput {\n const v = version && version.trim().length > 0 && version !== '_' ? version.trim() : undefined;\n return { name, version: v };\n}\n\nexport const kotlin: CodeScanningConfig = {\n supportedFiles: ['**/build.gradle.kts', '**/*.gradle.kts'],\n ignoreDirs: ['gradle-app.setting', 'gradle-wrapper.jar', 'gradle-wrapper.properties'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n\n // ---------- applicationId ----------\n const appIds = [\n ...findAllWithRegex({ value: KTS_APPLICATION_ID_EQ_REGEX, matches: ['name'] }, fileContents),\n ...findAllWithRegex(\n { value: KTS_APPLICATION_ID_CALL_REGEX, matches: ['name'] },\n fileContents,\n ),\n ];\n if (appIds.length > 1) {\n throw new Error(`Expected only one applicationId per file: ${filePath}`);\n }\n const appName = appIds[0]?.name || directory.split('/').pop()!;\n\n // ---------- dependencies ----------\n const deps: Array<DepInput> = [];\n\n // \"group:artifact:version\"\n for (const m of fileContents.matchAll(KTS_DEP_STRING_COORDS_REGEX)) {\n const [, , group, artifact, version] = m;\n deps.push(depEntry(`${group}:${artifact}`, version));\n }\n\n // platform(\"group:artifact:version\")\n for (const m of fileContents.matchAll(KTS_DEP_PLATFORM_REGEX)) {\n const [, , group, artifact, version] = m;\n // Record as regular coord (you may prefer to tag as BoM separately)\n deps.push(depEntry(`${group}:${artifact}`, version));\n }\n\n // libs aliases (version catalogs) — keep alias as name, unknown version\n for (const m of fileContents.matchAll(KTS_DEP_LIBS_ALIAS_REGEX)) {\n // Grab the exact token as name (best-effort)\n const token = m[0]\n .replace(/^[^(]+\\(\\s*/, '')\n .replace(/\\)\\s*$/, '')\n .trim(); // e.g., libs.androidx.appcompat or libs[\"androidx-core-ktx\"]\n deps.push(depEntry(token));\n }\n\n // ---------- plugins ----------\n const plugins: Array<DepInput> = [];\n\n for (const m of fileContents.matchAll(KTS_PLUGIN_ID_REGEX)) {\n const [, pid, pver] = m;\n plugins.push(depEntry(pid, pver));\n }\n\n for (const m of fileContents.matchAll(KTS_PLUGIN_APPLY_REGEX)) {\n const [, pid] = m;\n plugins.push(depEntry(pid));\n }\n\n // alias(libs.plugins...) — keep alias token (no version)\n if (KTS_PLUGIN_ALIAS_REGEX.test(fileContents)) {\n // Collect all alias lines to preserve identifiers; light parse:\n const aliasMatches = fileContents.matchAll(\n /alias\\s*\\(\\s*(libs(?:\\.plugins)?(?:\\.[\\w\\-.]+|\\[[\"'][^\"']+[\"']\\]))\\s*\\)/g,\n );\n for (const m of aliasMatches) {\n plugins.push(depEntry(m[1]));\n }\n }\n\n // ---------- compose final list ----------\n // Merge deps + plugins as \"softwareDevelopmentKits\"\n const softwareDevelopmentKits = [...deps, ...plugins]\n // de-dup by name+version\n .reduce(\n (acc, cur) => {\n const key = `${cur.name}@@${cur.version || ''}`;\n if (!acc.map.has(key)) {\n acc.map.set(key, cur);\n acc.list.push(cur);\n }\n return acc;\n },\n {\n map: new Map<string, DepInput>(),\n list: [] as Array<DepInput>,\n },\n ).list;\n\n return [\n {\n name: appName,\n softwareDevelopmentKits,\n },\n ];\n },\n};\n","import { CodePackageType } from '@transcend-io/privacy-types';\n\nimport {\n cocoaPods,\n gradle,\n javascriptPackageJson,\n gemfile,\n composerJson,\n pubspec,\n swift,\n kotlin,\n pythonRequirementsTxt,\n} from './integrations/index.js';\nimport { CodeScanningConfig } from './types.js';\n\n/**\n * @deprecated TODO: https://transcend.height.app/T-32325 - use code scanning instead\n */\nexport const SILO_DISCOVERY_CONFIGS: {\n [k in string]: CodeScanningConfig;\n} = {\n cocoaPods,\n gradle,\n javascriptPackageJson,\n pythonRequirementsTxt,\n gemfile,\n pubspec,\n swift,\n};\n\nexport const CODE_SCANNING_CONFIGS: {\n [k in CodePackageType]: CodeScanningConfig;\n} = {\n [CodePackageType.CocoaPods]: cocoaPods,\n [CodePackageType.Gradle]: gradle,\n [CodePackageType.PackageJson]: javascriptPackageJson,\n [CodePackageType.RequirementsTxt]: pythonRequirementsTxt,\n [CodePackageType.Gemfile]: gemfile,\n [CodePackageType.Pubspec]: pubspec,\n [CodePackageType.ComposerJson]: composerJson,\n [CodePackageType.Swift]: swift,\n [CodePackageType.Kotlin]: kotlin,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"constants-BmwXDQu9.mjs","names":[],"sources":["../src/lib/code-scanning/integrations/cocoaPods.ts","../src/lib/code-scanning/integrations/gradle.ts","../src/lib/code-scanning/integrations/javascriptPackageJson.ts","../src/lib/code-scanning/integrations/pythonRequirementsTxt.ts","../src/lib/code-scanning/integrations/gemfile.ts","../src/lib/code-scanning/integrations/pubspec.ts","../src/lib/code-scanning/integrations/composerJson.ts","../src/lib/code-scanning/integrations/swift.ts","../src/lib/code-scanning/integrations/kotlin.ts","../src/lib/code-scanning/constants.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { CodePackageSdk } from '../../../codecs.js';\nimport { CodeScanningConfig } from '../types.js';\n\nconst POD_TARGET_REGEX = /target ('|\")(.*?)('|\")/;\nconst POD_PACKAGE_REGEX = /pod ('|\")(.*?)('|\")(, ('|\")~> (.+?)('|\")|)/;\n\nexport const cocoaPods: CodeScanningConfig = {\n supportedFiles: ['Podfile'],\n ignoreDirs: ['Pods', 'Build'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(POD_TARGET_REGEX, 'g'),\n matches: ['quote1', 'name', 'quote2'],\n },\n fileContents,\n );\n const packages = findAllWithRegex(\n {\n value: new RegExp(POD_PACKAGE_REGEX, 'g'),\n matches: ['quote1', 'name', 'quote2', 'extra', 'quote3', 'version', 'quote4'],\n },\n fileContents,\n );\n\n const deps: CodePackageSdk[] = targets.map((target, ind) => ({\n name: target.name,\n type: CodePackageType.CocoaPods,\n softwareDevelopmentKits: packages\n .filter(\n (pkg) =>\n pkg.matchIndex > target.matchIndex &&\n (!targets[ind + 1] || pkg.matchIndex < targets[ind + 1].matchIndex),\n )\n .map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n })),\n }));\n\n return deps;\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { CodeScanningConfig } from '../types.js';\n\nconst GRADLE_IMPLEMENTATION_REGEX = /implementation( *)('|\")(.+?):(.+?):(.+?|)('|\")/;\nconst GRADLE_PLUGIN_REGEX = /apply plugin: *('|\")(.+?)(:(.+?)|)('|\")/;\nconst GRADLE_IMPLEMENTATION_GROUP_REGEX =\n /implementation group:( *)('|\")(.+?)('|\"),( *)name:( *)('|\")(.+?)('|\"),( *)version:( *)('|\")(.+?)('|\")/;\nconst GRADLE_APPLICATION_NAME_REGEX = /applicationId( *)\"(.+?)\"/;\n\n/**\n * So far, there are three ways of defining dependencies that is supported\n * implementation group: 'org.eclipse.jdt', name: 'org.eclipse.jdt.core', version: '3.28.0'\n * or\n * implementation 'com.google.firebase:firebase-analytics:18.0.0'\n * or\n * apply plugin: 'com.google.gms.google-services'\n *\n * single and double quotes are both recognized\n */\nexport const gradle: CodeScanningConfig = {\n supportedFiles: ['build.gradle**'],\n ignoreDirs: ['gradle-app.setting', 'gradle-wrapper.jar', 'gradle-wrapper.properties'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(GRADLE_IMPLEMENTATION_REGEX, 'g'),\n matches: ['space', 'quote1', 'name', 'path', 'version', 'quote2'],\n },\n fileContents,\n );\n const targetPlugins = findAllWithRegex(\n {\n value: new RegExp(GRADLE_PLUGIN_REGEX, 'g'),\n matches: ['quote1', 'name', 'group', 'version', 'quote2'],\n },\n fileContents,\n );\n const targetGroups = findAllWithRegex(\n {\n value: new RegExp(GRADLE_IMPLEMENTATION_GROUP_REGEX, 'g'),\n matches: [\n 'space1',\n 'quote1',\n 'group',\n 'quote2',\n 'space2',\n 'space3',\n 'quote3',\n 'name',\n 'quote4',\n 'space4',\n 'space5',\n 'quote5',\n 'version',\n 'quote6',\n ],\n },\n fileContents,\n );\n const applications = findAllWithRegex(\n {\n value: new RegExp(GRADLE_APPLICATION_NAME_REGEX, 'g'),\n matches: ['space', 'name'],\n },\n fileContents,\n );\n if (applications.length > 1) {\n throw new Error(`Expected only one applicationId per file: ${filePath}`);\n }\n\n return [\n {\n name: applications[0]?.name || directory.split('/').pop()!,\n softwareDevelopmentKits: [...targets, ...targetGroups, ...targetPlugins].map((target) => ({\n name: target.name,\n version: target.version || undefined,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageSdk } from '../../../codecs.js';\nimport { CodeScanningConfig } from '../types.js';\n\nexport const javascriptPackageJson: CodeScanningConfig = {\n supportedFiles: ['package.json'],\n ignoreDirs: ['node_modules', 'serverless-build', 'lambda-build'],\n scanFunction: (filePath) => {\n const file = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const asJson = JSON.parse(file);\n const {\n name,\n description,\n dependencies = {},\n devDependencies = {},\n optionalDependencies = {},\n } = asJson;\n return [\n {\n // name of the package\n name: name || directory.split('/').pop()!,\n description,\n softwareDevelopmentKits: [\n ...Object.entries(dependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n }),\n ),\n ...Object.entries(devDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n isDevDependency: true,\n }),\n ),\n ...Object.entries(optionalDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n }),\n ),\n ],\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { listFiles } from '../../api-keys/index.js';\nimport { CodeScanningConfig } from '../types.js';\n\nconst REQUIREMENTS_PACKAGE_MATCH = /(.+?)(=+)(.+)/;\nconst PACKAGE_NAME = /name *= *('|\")(.+?)('|\")/;\nconst PACKAGE_DESCRIPTION = /description *= *('|\")(.+?)('|\")/;\n\nexport const pythonRequirementsTxt: CodeScanningConfig = {\n supportedFiles: ['requirements.txt'],\n ignoreDirs: ['build', 'lib', 'lib64'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const filesInFolder = listFiles(directory);\n\n // parse setup file for name\n const setupFile = filesInFolder.find((file) => file === 'setup.py');\n const setupFileContents = setupFile\n ? readFileSync(join(directory, setupFile), 'utf-8')\n : undefined;\n const packageName = setupFileContents\n ? (PACKAGE_NAME.exec(setupFileContents) || [])[2]\n : undefined;\n const packageDescription = setupFileContents\n ? (PACKAGE_DESCRIPTION.exec(setupFileContents) || [])[2]\n : undefined;\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(REQUIREMENTS_PACKAGE_MATCH, 'g'),\n matches: ['name', 'equals', 'version'],\n },\n fileContents,\n );\n\n return [\n {\n name: packageName || directory.split('/').pop()!,\n description: packageDescription || undefined,\n type: CodePackageType.RequirementsTxt,\n softwareDevelopmentKits: targets.map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { listFiles } from '../../api-keys/index.js';\nimport { CodeScanningConfig } from '../types.js';\n\nconst GEM_PACKAGE_REGEX = /gem *('|\")(.+?)('|\")(, *('|\")(.+?)('|\")|)/;\nconst GEMFILE_PACKAGE_NAME_REGEX = /spec\\.name *= *('|\")(.+?)('|\")/;\nconst GEMFILE_PACKAGE_DESCRIPTION_REGEX = /spec\\.description *= *('|\")(.+?)('|\")/;\nconst GEMFILE_PACKAGE_SUMMARY_REGEX = /spec\\.summary *= *('|\")(.+?)('|\")/;\n\nexport const gemfile: CodeScanningConfig = {\n supportedFiles: ['Gemfile'],\n ignoreDirs: ['bin'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const filesInFolder = listFiles(directory);\n\n // parse gemspec file for name\n const gemspec = filesInFolder.find((file) => file === '.gemspec');\n const gemspecContents = gemspec ? readFileSync(gemspec, 'utf-8') : undefined;\n const gemfileName = gemspecContents\n ? (GEMFILE_PACKAGE_NAME_REGEX.exec(gemspecContents) || [])[2]\n : undefined;\n const gemfileDescription = gemspecContents\n ? (GEMFILE_PACKAGE_DESCRIPTION_REGEX.exec(gemspecContents) ||\n GEMFILE_PACKAGE_SUMMARY_REGEX.exec(gemspecContents) ||\n [])[1]\n : undefined;\n\n const targets = findAllWithRegex(\n {\n value: new RegExp(GEM_PACKAGE_REGEX, 'g'),\n matches: ['quote1', 'name', 'quote2', 'hasVersion', 'quote3', 'version', 'quote4'],\n },\n fileContents,\n );\n\n return [\n {\n name: gemfileName || directory.split('/').pop()!,\n description: gemfileDescription || undefined,\n type: CodePackageType.RequirementsTxt,\n softwareDevelopmentKits: targets.map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport yaml from 'js-yaml';\n\nimport { CodeScanningConfig } from '../types.js';\n\n/**\n * Remove YAML comments from a string\n *\n * @param yamlString - YAML string\n * @returns String without comments\n */\nfunction removeYAMLComments(yamlString: string): string {\n return yamlString\n .split('\\n')\n .map((line) => {\n // Remove inline comments\n const commentIndex = line.indexOf('#');\n if (commentIndex > -1) {\n // Check if '#' is not inside a string\n if (\n !line.substring(0, commentIndex).includes('\"') &&\n !line.substring(0, commentIndex).includes(\"'\")\n ) {\n return line.substring(0, commentIndex).trim();\n }\n }\n return line;\n })\n .filter((line) => line.length > 0)\n .join('\\n');\n}\n\nexport const pubspec: CodeScanningConfig = {\n supportedFiles: ['pubspec.yml'],\n ignoreDirs: ['build'],\n scanFunction: (filePath) => {\n const directory = dirname(filePath);\n const fileContents = readFileSync(filePath, 'utf-8');\n const {\n name,\n description,\n dev_dependencies = {},\n dependencies = {},\n } = yaml.load(removeYAMLComments(fileContents)) as {\n /** Name */\n name?: string;\n /** Description */\n description?: string;\n /** Dev dependencies */\n dev_dependencies?: { [k in string]: number | Record<string, string> };\n /** Dependencies */\n dependencies?: { [k in string]: number | Record<string, string> };\n };\n return [\n {\n name: name || directory.split('/').pop()!,\n description,\n type: CodePackageType.RequirementsTxt,\n softwareDevelopmentKits: [\n ...Object.entries(dependencies).map(([name, version]) => ({\n name,\n version:\n typeof version === 'string'\n ? version\n : typeof version === 'number'\n ? version.toString()\n : version?.sdk,\n })),\n ...Object.entries(dev_dependencies).map(([name, version]) => ({\n name,\n version:\n typeof version === 'string'\n ? version\n : typeof version === 'number'\n ? version.toString()\n : version?.sdk,\n isDevDependency: true,\n })),\n ],\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageSdk } from '../../../codecs.js';\nimport { CodeScanningConfig } from '../types.js';\n\nexport const composerJson: CodeScanningConfig = {\n supportedFiles: ['composer.json'],\n ignoreDirs: ['vendor', 'node_modules', 'cache', 'build', 'dist'],\n scanFunction: (filePath) => {\n const file = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n const asJson = JSON.parse(file);\n const {\n name,\n description,\n require: requireDependencies = {},\n 'require-dev': requiredDevDependencies = {},\n } = asJson;\n return [\n {\n // name of the package\n name: name || directory.split('/').pop()!,\n description,\n softwareDevelopmentKits: [\n ...Object.entries(requireDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n }),\n ),\n ...Object.entries(requiredDevDependencies).map(\n ([name, version]): CodePackageSdk => ({\n name,\n version: typeof version === 'string' ? version : undefined,\n isDevDependency: true,\n }),\n ),\n ],\n },\n ];\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport * as t from 'io-ts';\n\nimport { CodeScanningConfig } from '../types.js';\n\nconst SwiftPackage = t.type({\n pins: t.array(\n t.type({\n identity: t.string,\n kind: t.string,\n location: t.string,\n state: t.intersection([\n t.type({\n revision: t.string,\n }),\n t.partial({\n version: t.union([t.string, t.undefined, t.null]),\n }),\n ]),\n }),\n ),\n version: t.number,\n});\n\nconst SwiftPackageV1 = t.type({\n object: t.type({\n pins: t.array(\n t.type({\n package: t.string,\n repositoryURL: t.string,\n state: t.intersection([\n t.type({\n branch: t.union([t.string, t.undefined, t.null]),\n revision: t.string,\n }),\n t.partial({\n version: t.union([t.string, t.undefined, t.null]),\n }),\n ]),\n }),\n ),\n }),\n version: t.number,\n});\n\nexport const swift: CodeScanningConfig = {\n supportedFiles: ['Package.resolved'],\n ignoreDirs: [],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n\n // Attempt latest version first\n try {\n const parsed = decodeCodec(SwiftPackage, fileContents);\n const splitPath = dirname(filePath).split('/');\n const originalName = splitPath[splitPath.length - 1];\n let name = originalName;\n if (name === 'swiftpm') {\n name = splitPath[splitPath.length - 2];\n if (name === 'xcshareddata') {\n name = splitPath[splitPath.length - 3];\n } else if (!name) {\n name = originalName;\n }\n if (name === 'project.xcworkspace') {\n name = splitPath[splitPath.length - 4];\n }\n }\n return [\n {\n name,\n type: CodePackageType.Swift,\n softwareDevelopmentKits: parsed.pins.map((target) => ({\n name: target.identity,\n version: target.state.version || undefined,\n })),\n },\n ];\n } catch (e) {\n // Throw non codec errors\n if (!e?.message?.includes('Failed to decode codec')) {\n throw e;\n }\n\n // Attempt v1\n try {\n const parsed = decodeCodec(SwiftPackageV1, fileContents);\n return [\n {\n name: dirname(filePath).split('/').pop() || '', // TODO pull from Package.swift ->> name if possible\n type: CodePackageType.Swift,\n softwareDevelopmentKits: parsed.object.pins.map((target) => ({\n name: target.package,\n version: target.state.version || undefined,\n })),\n },\n ];\n } catch (e2) {\n if (!e2?.message?.includes('Failed to decode codec')) {\n throw e2;\n }\n throw e;\n }\n }\n },\n};\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { findAllWithRegex } from '@transcend-io/type-utils';\n\nimport { CodeScanningConfig } from '../types.js';\n\n/**\n * Kotlin DSL (build.gradle.kts) dependency & plugin parsing\n */\n\nconst KTS_DEP_CONFIGS =\n // eslint-disable-next-line max-len\n '(implementation|api|kapt|ksp|debugImplementation|releaseImplementation|androidTestImplementation|testImplementation|compileOnly|runtimeOnly)';\n\n// e.g. implementation(\"com.google.firebase:firebase-analytics:18.0.0\")\nconst KTS_DEP_STRING_COORDS_REGEX = new RegExp(\n `${KTS_DEP_CONFIGS}\\\\s*\\\\(\\\\s*[\"']([^\"':\\\\s]+):([^\"':\\\\s]+):?([^\"']*)[\"']\\\\s*\\\\)`,\n 'g',\n);\n// captures: [1]=config, [2]=group, [3]=artifact, [4]=version (may be '')\n\n// e.g. implementation(platform(\"com.google.firebase:firebase-bom:33.1.2\"))\nconst KTS_DEP_PLATFORM_REGEX = new RegExp(\n `${KTS_DEP_CONFIGS}\\\\s*\\\\(\\\\s*platform\\\\(\\\\s*[\"']([^\"':\\\\s]+):([^\"':\\\\s]+):?([^\"']*)[\"']\\\\s*\\\\)\\\\s*\\\\)`,\n 'g',\n);\n\n// e.g. implementation(libs.androidx.appcompat) / implementation(libs[\"androidx-core-ktx\"])\nconst KTS_DEP_LIBS_ALIAS_REGEX = new RegExp(\n `${KTS_DEP_CONFIGS}\\\\s*\\\\(\\\\s*libs(?:\\\\.[\\\\w\\\\-\\\\.]+|\\\\[[\"'][^\"']+[\"']\\\\])\\\\s*\\\\)`,\n 'g',\n);\n\n// Plugins:\n// plugins { id(\"com.google.gms.google-services\") version \"4.4.2\" apply false }\n// plugins { id(\"org.jetbrains.kotlin.android\") }\n// apply(plugin = \"newrelic\")\n// plugins { alias(libs.plugins.kotlin.android) }\nconst KTS_PLUGIN_ID_REGEX = /id\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)(?:\\s*version\\s*[\"']([^\"']+)[\"'])?/g;\nconst KTS_PLUGIN_APPLY_REGEX = /apply\\s*\\(\\s*plugin\\s*=\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\nconst KTS_PLUGIN_ALIAS_REGEX =\n /plugins\\s*\\{[^}]*alias\\s*\\(\\s*libs(?:\\.plugins)?(?:\\.[\\w\\-.]+|\\[[\"'][^\"']+[\"']\\])\\s*\\)[^}]*\\}/g;\n\n// applicationId in Kotlin DSL:\n// applicationId = \"com.foo.bar\"\n// applicationId(\"com.foo.bar\")\nconst KTS_APPLICATION_ID_EQ_REGEX = /applicationId\\s*=\\s*[\"']([^\"']+)[\"']/g;\nconst KTS_APPLICATION_ID_CALL_REGEX = /applicationId\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\n\n/**\n * Input dep entry (partial)\n */\ntype DepInput = {\n /** Name of the dependency */\n name: string;\n /** Version of the dependency */\n version?: string;\n};\n\n/**\n * Helper to normalize a parsed dep entry\n *\n * @param name - name\n * @param version - version\n * @returns normalized entry\n */\nfunction depEntry(name: string, version?: string): DepInput {\n const v = version && version.trim().length > 0 && version !== '_' ? version.trim() : undefined;\n return { name, version: v };\n}\n\nexport const kotlin: CodeScanningConfig = {\n supportedFiles: ['**/build.gradle.kts', '**/*.gradle.kts'],\n ignoreDirs: ['gradle-app.setting', 'gradle-wrapper.jar', 'gradle-wrapper.properties'],\n scanFunction: (filePath) => {\n const fileContents = readFileSync(filePath, 'utf-8');\n const directory = dirname(filePath);\n\n // ---------- applicationId ----------\n const appIds = [\n ...findAllWithRegex({ value: KTS_APPLICATION_ID_EQ_REGEX, matches: ['name'] }, fileContents),\n ...findAllWithRegex(\n { value: KTS_APPLICATION_ID_CALL_REGEX, matches: ['name'] },\n fileContents,\n ),\n ];\n if (appIds.length > 1) {\n throw new Error(`Expected only one applicationId per file: ${filePath}`);\n }\n const appName = appIds[0]?.name || directory.split('/').pop()!;\n\n // ---------- dependencies ----------\n const deps: Array<DepInput> = [];\n\n // \"group:artifact:version\"\n for (const m of fileContents.matchAll(KTS_DEP_STRING_COORDS_REGEX)) {\n const [, , group, artifact, version] = m;\n deps.push(depEntry(`${group}:${artifact}`, version));\n }\n\n // platform(\"group:artifact:version\")\n for (const m of fileContents.matchAll(KTS_DEP_PLATFORM_REGEX)) {\n const [, , group, artifact, version] = m;\n // Record as regular coord (you may prefer to tag as BoM separately)\n deps.push(depEntry(`${group}:${artifact}`, version));\n }\n\n // libs aliases (version catalogs) — keep alias as name, unknown version\n for (const m of fileContents.matchAll(KTS_DEP_LIBS_ALIAS_REGEX)) {\n // Grab the exact token as name (best-effort)\n const token = m[0]\n .replace(/^[^(]+\\(\\s*/, '')\n .replace(/\\)\\s*$/, '')\n .trim(); // e.g., libs.androidx.appcompat or libs[\"androidx-core-ktx\"]\n deps.push(depEntry(token));\n }\n\n // ---------- plugins ----------\n const plugins: Array<DepInput> = [];\n\n for (const m of fileContents.matchAll(KTS_PLUGIN_ID_REGEX)) {\n const [, pid, pver] = m;\n plugins.push(depEntry(pid, pver));\n }\n\n for (const m of fileContents.matchAll(KTS_PLUGIN_APPLY_REGEX)) {\n const [, pid] = m;\n plugins.push(depEntry(pid));\n }\n\n // alias(libs.plugins...) — keep alias token (no version)\n if (KTS_PLUGIN_ALIAS_REGEX.test(fileContents)) {\n // Collect all alias lines to preserve identifiers; light parse:\n const aliasMatches = fileContents.matchAll(\n /alias\\s*\\(\\s*(libs(?:\\.plugins)?(?:\\.[\\w\\-.]+|\\[[\"'][^\"']+[\"']\\]))\\s*\\)/g,\n );\n for (const m of aliasMatches) {\n plugins.push(depEntry(m[1]));\n }\n }\n\n // ---------- compose final list ----------\n // Merge deps + plugins as \"softwareDevelopmentKits\"\n const softwareDevelopmentKits = [...deps, ...plugins]\n // de-dup by name+version\n .reduce(\n (acc, cur) => {\n const key = `${cur.name}@@${cur.version || ''}`;\n if (!acc.map.has(key)) {\n acc.map.set(key, cur);\n acc.list.push(cur);\n }\n return acc;\n },\n {\n map: new Map<string, DepInput>(),\n list: [] as Array<DepInput>,\n },\n ).list;\n\n return [\n {\n name: appName,\n softwareDevelopmentKits,\n },\n ];\n },\n};\n","import { CodePackageType } from '@transcend-io/privacy-types';\n\nimport {\n cocoaPods,\n gradle,\n javascriptPackageJson,\n gemfile,\n composerJson,\n pubspec,\n swift,\n kotlin,\n pythonRequirementsTxt,\n} from './integrations/index.js';\nimport { CodeScanningConfig } from './types.js';\n\n/**\n * @deprecated TODO: https://transcend.height.app/T-32325 - use code scanning instead\n */\nexport const SILO_DISCOVERY_CONFIGS: {\n [k in string]: CodeScanningConfig;\n} = {\n cocoaPods,\n gradle,\n javascriptPackageJson,\n pythonRequirementsTxt,\n gemfile,\n pubspec,\n swift,\n};\n\nexport const CODE_SCANNING_CONFIGS: {\n [k in CodePackageType]: CodeScanningConfig;\n} = {\n [CodePackageType.CocoaPods]: cocoaPods,\n [CodePackageType.Gradle]: gradle,\n [CodePackageType.PackageJson]: javascriptPackageJson,\n [CodePackageType.RequirementsTxt]: pythonRequirementsTxt,\n [CodePackageType.Gemfile]: gemfile,\n [CodePackageType.Pubspec]: pubspec,\n [CodePackageType.ComposerJson]: composerJson,\n [CodePackageType.Swift]: swift,\n [CodePackageType.Kotlin]: kotlin,\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  import{CompletedRequestStatus as e,IsoCountryCode as t,IsoCountrySubdivisionCode as n,RequestAction as r}from"@transcend-io/privacy-types";import{applyEnum as i,valuesOf as a}from"@transcend-io/type-utils";import{LOCALE_KEY as o}from"@transcend-io/internationalization";import*as s from"io-ts";const c=`[NONE]`,l=`[APPLY VALUE TO ALL ROWS]`,u=`<blank>`,d=[`email`,`coreIdentifier`];let f=function(e){return e.Email=`email`,e.CoreIdentifier=`coreIdentifier`,e.RequestType=`requestType`,e.SubjectType=`subjectType`,e.Locale=`locale`,e.Country=`country`,e.CountrySubDivision=`countrySubDivision`,e.RequestStatus=`requestStatus`,e.CreatedAt=`createdAt`,e.DataSiloIds=`dataSiloIds`,e}({});const p={[f.Email]:!1,[f.CoreIdentifier]:!0,[f.RequestType]:!0,[f.SubjectType]:!0,[f.RequestStatus]:!1,[f.CreatedAt]:!1,[f.DataSiloIds]:!1,[f.Locale]:!1,[f.Country]:!1,[f.CountrySubDivision]:!1},m={[f.RequestType]:!0,[f.SubjectType]:!0},h=s.type({columnNames:s.partial(i(f,()=>s.string)),identifierNames:s.record(s.string,s.string),attributeNames:s.record(s.string,s.string),requestTypeToRequestAction:s.record(s.string,a(r)),subjectTypeToSubjectName:s.record(s.string,s.string),languageToLocale:s.record(s.string,a(o)),regionToCountry:s.record(s.string,a({...t,[c]:c})),regionToCountrySubDivision:s.record(s.string,a({...n,[c]:c})),statusToRequestStatus:s.record(s.string,a({...e,[c]:c}))}),g=s.type({id:s.string,link:s.string,rowIndex:s.number,coreIdentifier:s.string,attemptedAt:s.string}),_=s.type({failingRequests:s.array(s.record(s.string,s.any)),successfulRequests:s.array(g),duplicateRequests:s.array(s.type({rowIndex:s.number,coreIdentifier:s.string,attemptedAt:s.string}))});export{_ as a,p as c,h as i,c as l,l as n,f as o,m as r,d as s,u as t,g as u};
2
- //# sourceMappingURL=constants-DYbzl8QH.mjs.map
2
+ //# sourceMappingURL=constants-ClkQQhJs.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants-DYbzl8QH.mjs","names":[],"sources":["../src/lib/requests/constants.ts"],"sourcesContent":["import { LOCALE_KEY } from '@transcend-io/internationalization';\nimport {\n CompletedRequestStatus,\n RequestAction,\n IsoCountryCode,\n IsoCountrySubdivisionCode,\n} from '@transcend-io/privacy-types';\nimport { applyEnum, valuesOf } from '@transcend-io/type-utils';\nimport * as t from 'io-ts';\n\nexport const NONE = '[NONE]' as const;\nexport const BULK_APPLY = '[APPLY VALUE TO ALL ROWS]' as const;\nexport const BLANK = '<blank>' as const;\n\n/** These are uploaded at the top level of the request */\nexport const IDENTIFIER_BLOCK_LIST = ['email', 'coreIdentifier'];\n\n/**\n * Column names to map\n */\nexport enum ColumnName {\n /** The title of the email column */\n Email = 'email',\n /** The title of the core identifier column */\n CoreIdentifier = 'coreIdentifier',\n /** The title of the requestType column */\n RequestType = 'requestType',\n /** The title of the subjectType column */\n SubjectType = 'subjectType',\n /** The title of the locale column */\n Locale = 'locale',\n /** The country */\n Country = 'country',\n /** The country sub division */\n CountrySubDivision = 'countrySubDivision',\n /** The title of the requestStatus column */\n RequestStatus = 'requestStatus',\n /** The title of the createdAt column */\n CreatedAt = 'createdAt',\n /** The title of the dataSiloIds column */\n DataSiloIds = 'dataSiloIds',\n}\n\n/** These parameters are required in the Transcend DSR API */\nexport const IS_REQUIRED: { [k in ColumnName]: boolean } = {\n [ColumnName.Email]: false,\n [ColumnName.CoreIdentifier]: true,\n [ColumnName.RequestType]: true,\n [ColumnName.SubjectType]: true,\n [ColumnName.RequestStatus]: false,\n [ColumnName.CreatedAt]: false,\n [ColumnName.DataSiloIds]: false,\n [ColumnName.Locale]: false,\n [ColumnName.Country]: false,\n [ColumnName.CountrySubDivision]: false,\n};\n\n/** These parameters can be specified for the entire CSV set if needed */\nexport const CAN_APPLY_IN_BULK: { [k in ColumnName]?: boolean } = {\n [ColumnName.RequestType]: true,\n [ColumnName.SubjectType]: true,\n};\n\n// Cache state\nexport const CachedFileState = t.type({\n /** Mapping between the default request input column names and the CSV column name for that input */\n columnNames: t.partial(applyEnum(ColumnName, () => t.string)),\n /** Mapping between the identifier names and the CSV column name for that input */\n identifierNames: t.record(t.string, t.string),\n /** Mapping between the request attribute inputs and the CSV column name for that input */\n attributeNames: t.record(t.string, t.string),\n /** Mapping between CSV request type and Transcend Request Action */\n requestTypeToRequestAction: t.record(t.string, valuesOf(RequestAction)),\n /** Mapping between CSV data subject type and the name of the data subject in Transcend */\n subjectTypeToSubjectName: t.record(t.string, t.string),\n /** Mapping between language imported and Transcend locale code */\n languageToLocale: t.record(t.string, valuesOf(LOCALE_KEY)),\n /** Mapping between region and country code */\n regionToCountry: t.record(t.string, valuesOf({ ...IsoCountryCode, [NONE]: NONE })),\n /** Mapping between region and country sub division code */\n regionToCountrySubDivision: t.record(\n t.string,\n valuesOf({ ...IsoCountrySubdivisionCode, [NONE]: NONE }),\n ),\n /** Mapping between request status in import to Transcend request status */\n statusToRequestStatus: t.record(t.string, valuesOf({ ...CompletedRequestStatus, [NONE]: NONE })),\n});\n\n/** Type override */\nexport type CachedFileState = t.TypeOf<typeof CachedFileState>;\n\n/**\n * Successfully processed request\n */\nexport const SuccessfulRequest = t.type({\n id: t.string,\n link: t.string,\n rowIndex: t.number,\n coreIdentifier: t.string,\n attemptedAt: t.string,\n});\n\n/** Type override */\nexport type SuccessfulRequest = t.TypeOf<typeof SuccessfulRequest>;\n\n// Cache state\nexport const CachedRequestState = t.type({\n /** Set of privacy requests that failed to upload */\n failingRequests: t.array(t.record(t.string, t.any)),\n /** Successfully uploaded requests */\n successfulRequests: t.array(SuccessfulRequest),\n /** Duplicate requests */\n duplicateRequests: t.array(\n t.type({\n rowIndex: t.number,\n coreIdentifier: t.string,\n attemptedAt: t.string,\n }),\n ),\n});\n\n/** Type override */\nexport type CachedRequestState = t.TypeOf<typeof CachedRequestState>;\n"],"mappings":"sSAUA,MAAa,EAAO,SACP,EAAa,4BACb,EAAQ,UAGR,EAAwB,CAAC,QAAS,iBAAiB,CAKhE,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,MAAA,QAEA,EAAA,eAAA,iBAEA,EAAA,YAAA,cAEA,EAAA,YAAA,cAEA,EAAA,OAAA,SAEA,EAAA,QAAA,UAEA,EAAA,mBAAA,qBAEA,EAAA,cAAA,gBAEA,EAAA,UAAA,YAEA,EAAA,YAAA,oBACD,CAGD,MAAa,EAA8C,EACxD,EAAW,OAAQ,IACnB,EAAW,gBAAiB,IAC5B,EAAW,aAAc,IACzB,EAAW,aAAc,IACzB,EAAW,eAAgB,IAC3B,EAAW,WAAY,IACvB,EAAW,aAAc,IACzB,EAAW,QAAS,IACpB,EAAW,SAAU,IACrB,EAAW,oBAAqB,GAClC,CAGY,EAAqD,EAC/D,EAAW,aAAc,IACzB,EAAW,aAAc,GAC3B,CAGY,EAAkB,EAAE,KAAK,CAEpC,YAAa,EAAE,QAAQ,EAAU,MAAkB,EAAE,OAAO,CAAC,CAE7D,gBAAiB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAE7C,eAAgB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAE5C,2BAA4B,EAAE,OAAO,EAAE,OAAQ,EAAS,EAAc,CAAC,CAEvE,yBAA0B,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAEtD,iBAAkB,EAAE,OAAO,EAAE,OAAQ,EAAS,EAAW,CAAC,CAE1D,gBAAiB,EAAE,OAAO,EAAE,OAAQ,EAAS,CAAE,GAAG,GAAiB,GAAO,EAAM,CAAC,CAAC,CAElF,2BAA4B,EAAE,OAC5B,EAAE,OACF,EAAS,CAAE,GAAG,GAA4B,GAAO,EAAM,CAAC,CACzD,CAED,sBAAuB,EAAE,OAAO,EAAE,OAAQ,EAAS,CAAE,GAAG,GAAyB,GAAO,EAAM,CAAC,CAAC,CACjG,CAAC,CAQW,EAAoB,EAAE,KAAK,CACtC,GAAI,EAAE,OACN,KAAM,EAAE,OACR,SAAU,EAAE,OACZ,eAAgB,EAAE,OAClB,YAAa,EAAE,OAChB,CAAC,CAMW,EAAqB,EAAE,KAAK,CAEvC,gBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,OAAQ,EAAE,IAAI,CAAC,CAEnD,mBAAoB,EAAE,MAAM,EAAkB,CAE9C,kBAAmB,EAAE,MACnB,EAAE,KAAK,CACL,SAAU,EAAE,OACZ,eAAgB,EAAE,OAClB,YAAa,EAAE,OAChB,CAAC,CACH,CACF,CAAC"}
1
+ {"version":3,"file":"constants-ClkQQhJs.mjs","names":[],"sources":["../src/lib/requests/constants.ts"],"sourcesContent":["import { LOCALE_KEY } from '@transcend-io/internationalization';\nimport {\n CompletedRequestStatus,\n RequestAction,\n IsoCountryCode,\n IsoCountrySubdivisionCode,\n} from '@transcend-io/privacy-types';\nimport { applyEnum, valuesOf } from '@transcend-io/type-utils';\nimport * as t from 'io-ts';\n\nexport const NONE = '[NONE]' as const;\nexport const BULK_APPLY = '[APPLY VALUE TO ALL ROWS]' as const;\nexport const BLANK = '<blank>' as const;\n\n/** These are uploaded at the top level of the request */\nexport const IDENTIFIER_BLOCK_LIST = ['email', 'coreIdentifier'];\n\n/**\n * Column names to map\n */\nexport enum ColumnName {\n /** The title of the email column */\n Email = 'email',\n /** The title of the core identifier column */\n CoreIdentifier = 'coreIdentifier',\n /** The title of the requestType column */\n RequestType = 'requestType',\n /** The title of the subjectType column */\n SubjectType = 'subjectType',\n /** The title of the locale column */\n Locale = 'locale',\n /** The country */\n Country = 'country',\n /** The country sub division */\n CountrySubDivision = 'countrySubDivision',\n /** The title of the requestStatus column */\n RequestStatus = 'requestStatus',\n /** The title of the createdAt column */\n CreatedAt = 'createdAt',\n /** The title of the dataSiloIds column */\n DataSiloIds = 'dataSiloIds',\n}\n\n/** These parameters are required in the Transcend DSR API */\nexport const IS_REQUIRED: { [k in ColumnName]: boolean } = {\n [ColumnName.Email]: false,\n [ColumnName.CoreIdentifier]: true,\n [ColumnName.RequestType]: true,\n [ColumnName.SubjectType]: true,\n [ColumnName.RequestStatus]: false,\n [ColumnName.CreatedAt]: false,\n [ColumnName.DataSiloIds]: false,\n [ColumnName.Locale]: false,\n [ColumnName.Country]: false,\n [ColumnName.CountrySubDivision]: false,\n};\n\n/** These parameters can be specified for the entire CSV set if needed */\nexport const CAN_APPLY_IN_BULK: { [k in ColumnName]?: boolean } = {\n [ColumnName.RequestType]: true,\n [ColumnName.SubjectType]: true,\n};\n\n// Cache state\nexport const CachedFileState = t.type({\n /** Mapping between the default request input column names and the CSV column name for that input */\n columnNames: t.partial(applyEnum(ColumnName, () => t.string)),\n /** Mapping between the identifier names and the CSV column name for that input */\n identifierNames: t.record(t.string, t.string),\n /** Mapping between the request attribute inputs and the CSV column name for that input */\n attributeNames: t.record(t.string, t.string),\n /** Mapping between CSV request type and Transcend Request Action */\n requestTypeToRequestAction: t.record(t.string, valuesOf(RequestAction)),\n /** Mapping between CSV data subject type and the name of the data subject in Transcend */\n subjectTypeToSubjectName: t.record(t.string, t.string),\n /** Mapping between language imported and Transcend locale code */\n languageToLocale: t.record(t.string, valuesOf(LOCALE_KEY)),\n /** Mapping between region and country code */\n regionToCountry: t.record(t.string, valuesOf({ ...IsoCountryCode, [NONE]: NONE })),\n /** Mapping between region and country sub division code */\n regionToCountrySubDivision: t.record(\n t.string,\n valuesOf({ ...IsoCountrySubdivisionCode, [NONE]: NONE }),\n ),\n /** Mapping between request status in import to Transcend request status */\n statusToRequestStatus: t.record(t.string, valuesOf({ ...CompletedRequestStatus, [NONE]: NONE })),\n});\n\n/** Type override */\nexport type CachedFileState = t.TypeOf<typeof CachedFileState>;\n\n/**\n * Successfully processed request\n */\nexport const SuccessfulRequest = t.type({\n id: t.string,\n link: t.string,\n rowIndex: t.number,\n coreIdentifier: t.string,\n attemptedAt: t.string,\n});\n\n/** Type override */\nexport type SuccessfulRequest = t.TypeOf<typeof SuccessfulRequest>;\n\n// Cache state\nexport const CachedRequestState = t.type({\n /** Set of privacy requests that failed to upload */\n failingRequests: t.array(t.record(t.string, t.any)),\n /** Successfully uploaded requests */\n successfulRequests: t.array(SuccessfulRequest),\n /** Duplicate requests */\n duplicateRequests: t.array(\n t.type({\n rowIndex: t.number,\n coreIdentifier: t.string,\n attemptedAt: t.string,\n }),\n ),\n});\n\n/** Type override */\nexport type CachedRequestState = t.TypeOf<typeof CachedRequestState>;\n"],"mappings":"sSAUA,MAAa,EAAO,SACP,EAAa,4BACb,EAAQ,UAGR,EAAwB,CAAC,QAAS,iBAAiB,CAKhE,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,MAAA,QAEA,EAAA,eAAA,iBAEA,EAAA,YAAA,cAEA,EAAA,YAAA,cAEA,EAAA,OAAA,SAEA,EAAA,QAAA,UAEA,EAAA,mBAAA,qBAEA,EAAA,cAAA,gBAEA,EAAA,UAAA,YAEA,EAAA,YAAA,oBACD,CAGD,MAAa,EAA8C,EACxD,EAAW,OAAQ,IACnB,EAAW,gBAAiB,IAC5B,EAAW,aAAc,IACzB,EAAW,aAAc,IACzB,EAAW,eAAgB,IAC3B,EAAW,WAAY,IACvB,EAAW,aAAc,IACzB,EAAW,QAAS,IACpB,EAAW,SAAU,IACrB,EAAW,oBAAqB,GAClC,CAGY,EAAqD,EAC/D,EAAW,aAAc,IACzB,EAAW,aAAc,GAC3B,CAGY,EAAkB,EAAE,KAAK,CAEpC,YAAa,EAAE,QAAQ,EAAU,MAAkB,EAAE,OAAO,CAAC,CAE7D,gBAAiB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAE7C,eAAgB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAE5C,2BAA4B,EAAE,OAAO,EAAE,OAAQ,EAAS,EAAc,CAAC,CAEvE,yBAA0B,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAEtD,iBAAkB,EAAE,OAAO,EAAE,OAAQ,EAAS,EAAW,CAAC,CAE1D,gBAAiB,EAAE,OAAO,EAAE,OAAQ,EAAS,CAAE,GAAG,GAAiB,GAAO,EAAM,CAAC,CAAC,CAElF,2BAA4B,EAAE,OAC5B,EAAE,OACF,EAAS,CAAE,GAAG,GAA4B,GAAO,EAAM,CAAC,CACzD,CAED,sBAAuB,EAAE,OAAO,EAAE,OAAQ,EAAS,CAAE,GAAG,GAAyB,GAAO,EAAM,CAAC,CAAC,CACjG,CAAC,CAQW,EAAoB,EAAE,KAAK,CACtC,GAAI,EAAE,OACN,KAAM,EAAE,OACR,SAAU,EAAE,OACZ,eAAgB,EAAE,OAClB,YAAa,EAAE,OAChB,CAAC,CAMW,EAAqB,EAAE,KAAK,CAEvC,gBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,OAAQ,EAAE,IAAI,CAAC,CAEnD,mBAAoB,EAAE,MAAM,EAAkB,CAE9C,kBAAmB,EAAE,MACnB,EAAE,KAAK,CACL,SAAU,EAAE,OACZ,eAAgB,EAAE,OAClB,YAAa,EAAE,OAChB,CAAC,CACH,CACF,CAAC"}
@@ -1,2 +1,2 @@
1
- import{o as e}from"./enums-CyFTrzXY.mjs";import{ScopeName as t,TRANSCEND_SCOPES as n}from"@transcend-io/privacy-types";import{keyBy as r}from"lodash-es";var i=`10.1.0`,a=`A command line interface for programmatic operations across Transcend.`;const o=`transcend`,s=`https://app.transcend.io`,c=`${s}/infrastructure/integrations`,l=`${s}/data-map/data-inventory/data-points`,u=process.env.TRANSCEND_API_URL||`https://api.transcend.io`,d=process.env.TRANSCEND_CONSENT_API_URL||`https://consent.transcend.io`,f={[e.ApiKeys]:[t.ViewApiKeys],[e.Templates]:[t.ManageEmailTemplates],[e.DataSilos]:[t.ManageDataMap,t.ConnectDataSilos],[e.Enrichers]:[t.ManageRequestIdentities],[e.BusinessEntities]:[t.ManageDataInventory],[e.ProcessingActivities]:[t.ManageDataMap],[e.Identifiers]:[t.ManageRequestIdentities],[e.Attributes]:[t.ManageGlobalAttributes],[e.DataFlows]:[t.ManageDataFlow],[e.Cookies]:[t.ManageDataFlow],[e.ConsentManager]:[t.ManageConsentManagerDeveloperSettings],[e.Partitions]:[t.ManageConsentManagerDeveloperSettings],[e.Actions]:[t.ManageDataSubjectRequestSettings],[e.DataSubjects]:[t.ManageDataSubjectRequestSettings],[e.Prompts]:[t.ManagePrompts],[e.PromptPartials]:[t.ManagePrompts],[e.PromptGroups]:[t.ManagePrompts],[e.Agents]:[t.ManagePathfinder],[e.AgentFunctions]:[t.ManagePathfinder],[e.AgentFiles]:[t.ManagePathfinder],[e.Vendors]:[t.ManageDataInventory],[e.DataCategories]:[t.ManageDataInventory],[e.ProcessingPurposes]:[t.ManageDataInventory],[e.ActionItems]:[t.ManageAllActionItems,t.ViewGlobalAttributes],[e.ActionItemCollections]:[t.ManageActionItemCollections],[e.Teams]:[t.ManageAccessControl],[e.Messages]:[t.ManageIntlMessages],[e.PrivacyCenters]:[t.ManagePrivacyCenter],[e.Policies]:[t.ManagePolicies],[e.Assessments]:[t.ManageAssessments],[e.AssessmentTemplates]:[t.ManageAssessments],[e.Purposes]:[t.ManageConsentManager,t.ManagePreferenceStoreSettings],[e.SystemDiscovery]:[t.ManageDataMap]},p={[e.ApiKeys]:[t.ViewApiKeys],[e.Templates]:[t.ViewEmailTemplates],[e.DataSilos]:[t.ViewDataMap,t.ViewDataSubjectRequestSettings],[e.Enrichers]:[t.ViewRequestIdentitySettings],[e.BusinessEntities]:[t.ViewDataInventory],[e.ProcessingActivities]:[t.ViewDataInventory],[e.Identifiers]:[t.ViewRequestIdentitySettings],[e.Attributes]:[t.ViewGlobalAttributes],[e.DataFlows]:[t.ViewDataFlow],[e.Cookies]:[t.ViewDataFlow],[e.ConsentManager]:[t.ViewConsentManager],[e.Partitions]:[t.ViewConsentManager],[e.Actions]:[t.ViewDataSubjectRequestSettings],[e.DataSubjects]:[t.ViewDataSubjectRequestSettings],[e.Prompts]:[t.ViewPrompts],[e.PromptPartials]:[t.ViewPrompts],[e.PromptGroups]:[t.ViewPrompts],[e.Agents]:[t.ViewPathfinder],[e.AgentFunctions]:[t.ViewPathfinder],[e.AgentFiles]:[t.ViewPathfinder],[e.Vendors]:[t.ViewDataInventory],[e.DataCategories]:[t.ViewDataInventory],[e.ProcessingPurposes]:[t.ViewDataInventory],[e.ActionItemCollections]:[t.ViewAllActionItems],[e.ActionItems]:[t.ViewAllActionItems],[e.Teams]:[t.ViewScopes],[e.Messages]:[t.ViewIntlMessages],[e.PrivacyCenters]:[t.ViewPrivacyCenter],[e.Policies]:[t.ViewPolicies],[e.Assessments]:[t.ViewAssessments],[e.AssessmentTemplates]:[t.ViewAssessments],[e.Purposes]:[t.ViewConsentManager,t.ViewPreferenceStoreSettings],[e.SystemDiscovery]:[t.ViewDataMap]},m={[e.ApiKeys]:`api-keys`,[e.Attributes]:`attributes`,[e.DataFlows]:`data-flows`,[e.Cookies]:`cookies`,[e.ConsentManager]:`consent-manager`,[e.Partitions]:`partitions`,[e.Actions]:`actions`,[e.DataSubjects]:`data-subjects`,[e.BusinessEntities]:`business-entities`,[e.ProcessingActivities]:`processing-activities`,[e.Identifiers]:`identifiers`,[e.Enrichers]:`enrichers`,[e.DataSilos]:`data-silos`,[e.Templates]:`templates`,[e.Prompts]:`prompts`,[e.PromptPartials]:`prompt-partials`,[e.PromptGroups]:`prompt-groups`,[e.Agents]:`agents`,[e.AgentFunctions]:`agent-functions`,[e.AgentFiles]:`agent-files`,[e.Vendors]:`vendors`,[e.DataCategories]:`data-categories`,[e.ProcessingPurposes]:`processing-purposes`,[e.ActionItems]:`action-items`,[e.ActionItemCollections]:`action-item-collections`,[e.Teams]:`teams`,[e.Messages]:`messages`,[e.PrivacyCenters]:`privacy-center`,[e.Policies]:`policies`,[e.Assessments]:`assessments`,[e.AssessmentTemplates]:`assessment-templates`,[e.Purposes]:`purposes`,[e.SystemDiscovery]:`system-discovery`},h=r(Object.entries(n).map(([e,t])=>({...t,name:e})),`title`),g=Object.keys(h),_=new Set([429,502,500,504,329]),v=process.env.DEBUG===`1`;export{u as a,h as c,f as d,m as f,i as h,v as i,g as l,a as m,l as n,d as o,o as p,c as r,_ as s,s as t,p as u};
2
- //# sourceMappingURL=constants-XOsAW1__.mjs.map
1
+ import{o as e}from"./enums-CyFTrzXY.mjs";import{ScopeName as t,TRANSCEND_SCOPES as n}from"@transcend-io/privacy-types";import{keyBy as r}from"lodash-es";var i=`10.2.1`,a=`A command line interface for programmatic operations across Transcend.`;const o=`transcend`,s=`https://app.transcend.io`,c=`${s}/infrastructure/integrations`,l=`${s}/data-map/data-inventory/data-points`,u=process.env.TRANSCEND_API_URL||`https://api.transcend.io`,d=process.env.TRANSCEND_CONSENT_API_URL||`https://consent.transcend.io`,f={[e.ApiKeys]:[t.ViewApiKeys],[e.Templates]:[t.ManageEmailTemplates],[e.DataSilos]:[t.ManageDataMap,t.ConnectDataSilos],[e.Enrichers]:[t.ManageRequestIdentities],[e.BusinessEntities]:[t.ManageDataInventory],[e.ProcessingActivities]:[t.ManageDataMap],[e.Identifiers]:[t.ManageRequestIdentities],[e.Attributes]:[t.ManageGlobalAttributes],[e.DataFlows]:[t.ManageDataFlow],[e.Cookies]:[t.ManageDataFlow],[e.ConsentManager]:[t.ManageConsentManagerDeveloperSettings],[e.Partitions]:[t.ManageConsentManagerDeveloperSettings],[e.Actions]:[t.ManageDataSubjectRequestSettings],[e.DataSubjects]:[t.ManageDataSubjectRequestSettings],[e.Prompts]:[t.ManagePrompts],[e.PromptPartials]:[t.ManagePrompts],[e.PromptGroups]:[t.ManagePrompts],[e.Agents]:[t.ManagePathfinder],[e.AgentFunctions]:[t.ManagePathfinder],[e.AgentFiles]:[t.ManagePathfinder],[e.Vendors]:[t.ManageDataInventory],[e.DataCategories]:[t.ManageDataInventory],[e.ProcessingPurposes]:[t.ManageDataInventory],[e.ActionItems]:[t.ManageAllActionItems,t.ViewGlobalAttributes],[e.ActionItemCollections]:[t.ManageActionItemCollections],[e.Teams]:[t.ManageAccessControl],[e.Messages]:[t.ManageIntlMessages],[e.PrivacyCenters]:[t.ManagePrivacyCenter],[e.Policies]:[t.ManagePolicies],[e.Assessments]:[t.ManageAssessments],[e.AssessmentTemplates]:[t.ManageAssessments],[e.Purposes]:[t.ManageConsentManager,t.ManagePreferenceStoreSettings],[e.SystemDiscovery]:[t.ManageDataMap]},p={[e.ApiKeys]:[t.ViewApiKeys],[e.Templates]:[t.ViewEmailTemplates],[e.DataSilos]:[t.ViewDataMap,t.ViewDataSubjectRequestSettings],[e.Enrichers]:[t.ViewRequestIdentitySettings],[e.BusinessEntities]:[t.ViewDataInventory],[e.ProcessingActivities]:[t.ViewDataInventory],[e.Identifiers]:[t.ViewRequestIdentitySettings],[e.Attributes]:[t.ViewGlobalAttributes],[e.DataFlows]:[t.ViewDataFlow],[e.Cookies]:[t.ViewDataFlow],[e.ConsentManager]:[t.ViewConsentManager],[e.Partitions]:[t.ViewConsentManager],[e.Actions]:[t.ViewDataSubjectRequestSettings],[e.DataSubjects]:[t.ViewDataSubjectRequestSettings],[e.Prompts]:[t.ViewPrompts],[e.PromptPartials]:[t.ViewPrompts],[e.PromptGroups]:[t.ViewPrompts],[e.Agents]:[t.ViewPathfinder],[e.AgentFunctions]:[t.ViewPathfinder],[e.AgentFiles]:[t.ViewPathfinder],[e.Vendors]:[t.ViewDataInventory],[e.DataCategories]:[t.ViewDataInventory],[e.ProcessingPurposes]:[t.ViewDataInventory],[e.ActionItemCollections]:[t.ViewAllActionItems],[e.ActionItems]:[t.ViewAllActionItems],[e.Teams]:[t.ViewScopes],[e.Messages]:[t.ViewIntlMessages],[e.PrivacyCenters]:[t.ViewPrivacyCenter],[e.Policies]:[t.ViewPolicies],[e.Assessments]:[t.ViewAssessments],[e.AssessmentTemplates]:[t.ViewAssessments],[e.Purposes]:[t.ViewConsentManager,t.ViewPreferenceStoreSettings],[e.SystemDiscovery]:[t.ViewDataMap]},m={[e.ApiKeys]:`api-keys`,[e.Attributes]:`attributes`,[e.DataFlows]:`data-flows`,[e.Cookies]:`cookies`,[e.ConsentManager]:`consent-manager`,[e.Partitions]:`partitions`,[e.Actions]:`actions`,[e.DataSubjects]:`data-subjects`,[e.BusinessEntities]:`business-entities`,[e.ProcessingActivities]:`processing-activities`,[e.Identifiers]:`identifiers`,[e.Enrichers]:`enrichers`,[e.DataSilos]:`data-silos`,[e.Templates]:`templates`,[e.Prompts]:`prompts`,[e.PromptPartials]:`prompt-partials`,[e.PromptGroups]:`prompt-groups`,[e.Agents]:`agents`,[e.AgentFunctions]:`agent-functions`,[e.AgentFiles]:`agent-files`,[e.Vendors]:`vendors`,[e.DataCategories]:`data-categories`,[e.ProcessingPurposes]:`processing-purposes`,[e.ActionItems]:`action-items`,[e.ActionItemCollections]:`action-item-collections`,[e.Teams]:`teams`,[e.Messages]:`messages`,[e.PrivacyCenters]:`privacy-center`,[e.Policies]:`policies`,[e.Assessments]:`assessments`,[e.AssessmentTemplates]:`assessment-templates`,[e.Purposes]:`purposes`,[e.SystemDiscovery]:`system-discovery`},h=r(Object.entries(n).map(([e,t])=>({...t,name:e})),`title`),g=Object.keys(h),_=new Set([429,502,500,504,329]),v=process.env.DEBUG===`1`;export{u as a,h as c,f as d,m as f,i as h,v as i,g as l,a as m,l as n,d as o,o as p,c as r,_ as s,s as t,p as u};
2
+ //# sourceMappingURL=constants-TpID7AXE.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants-XOsAW1__.mjs","names":[],"sources":["../package.json","../src/constants.ts"],"sourcesContent":["","import { ScopeName, TRANSCEND_SCOPES, type ScopeDefinition } from '@transcend-io/privacy-types';\nimport { keyBy } from 'lodash-es';\n\nimport { TranscendInput } from './codecs.js';\nimport { TranscendPullResource } from './enums.js';\n\nexport { description, version } from '../package.json';\n/**\n * The name of the main binary for the CLI\n */\nexport const name = 'transcend';\n\nexport const ADMIN_DASH = 'https://app.transcend.io';\n\nexport const ADMIN_DASH_INTEGRATIONS = `${ADMIN_DASH}/infrastructure/integrations`;\nexport const ADMIN_DASH_DATAPOINTS = `${ADMIN_DASH}/data-map/data-inventory/data-points`;\n\n/**\n * Override default transcend API url using\n * TRANSCEND_API_URL=https://api.us.transcend.io transcend ...\n */\nexport const DEFAULT_TRANSCEND_API = process.env.TRANSCEND_API_URL || 'https://api.transcend.io';\n\n/**\n * Override default transcend API url using\n * TRANSCEND_CONSENT_API_URL=https://consent.us.transcend.io transcend ...\n */\nexport const DEFAULT_TRANSCEND_CONSENT_API =\n process.env.TRANSCEND_CONSENT_API_URL || 'https://consent.transcend.io';\n\n/**\n * Mapping between resource type and scopes required for cli\n */\nexport const TR_PUSH_RESOURCE_SCOPE_MAP: {\n [k in TranscendPullResource]: ScopeName[];\n} = {\n [TranscendPullResource.ApiKeys]: [ScopeName.ViewApiKeys],\n [TranscendPullResource.Templates]: [ScopeName.ManageEmailTemplates],\n [TranscendPullResource.DataSilos]: [ScopeName.ManageDataMap, ScopeName.ConnectDataSilos],\n [TranscendPullResource.Enrichers]: [ScopeName.ManageRequestIdentities],\n [TranscendPullResource.BusinessEntities]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.ProcessingActivities]: [ScopeName.ManageDataMap],\n [TranscendPullResource.Identifiers]: [ScopeName.ManageRequestIdentities],\n [TranscendPullResource.Attributes]: [ScopeName.ManageGlobalAttributes],\n [TranscendPullResource.DataFlows]: [ScopeName.ManageDataFlow],\n [TranscendPullResource.Cookies]: [ScopeName.ManageDataFlow],\n [TranscendPullResource.ConsentManager]: [ScopeName.ManageConsentManagerDeveloperSettings],\n [TranscendPullResource.Partitions]: [ScopeName.ManageConsentManagerDeveloperSettings],\n [TranscendPullResource.Actions]: [ScopeName.ManageDataSubjectRequestSettings],\n [TranscendPullResource.DataSubjects]: [ScopeName.ManageDataSubjectRequestSettings],\n [TranscendPullResource.Prompts]: [ScopeName.ManagePrompts],\n [TranscendPullResource.PromptPartials]: [ScopeName.ManagePrompts],\n [TranscendPullResource.PromptGroups]: [ScopeName.ManagePrompts],\n [TranscendPullResource.Agents]: [ScopeName.ManagePathfinder],\n [TranscendPullResource.AgentFunctions]: [ScopeName.ManagePathfinder],\n [TranscendPullResource.AgentFiles]: [ScopeName.ManagePathfinder],\n [TranscendPullResource.Vendors]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.DataCategories]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.ProcessingPurposes]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.ActionItems]: [\n ScopeName.ManageAllActionItems,\n ScopeName.ViewGlobalAttributes,\n ],\n [TranscendPullResource.ActionItemCollections]: [ScopeName.ManageActionItemCollections],\n [TranscendPullResource.Teams]: [ScopeName.ManageAccessControl],\n [TranscendPullResource.Messages]: [ScopeName.ManageIntlMessages],\n [TranscendPullResource.PrivacyCenters]: [ScopeName.ManagePrivacyCenter],\n [TranscendPullResource.Policies]: [ScopeName.ManagePolicies],\n [TranscendPullResource.Assessments]: [ScopeName.ManageAssessments],\n [TranscendPullResource.AssessmentTemplates]: [ScopeName.ManageAssessments],\n [TranscendPullResource.Purposes]: [\n ScopeName.ManageConsentManager,\n ScopeName.ManagePreferenceStoreSettings,\n ],\n [TranscendPullResource.SystemDiscovery]: [ScopeName.ManageDataMap],\n};\n\n/**\n * Mapping between resource type and scopes required for cli\n */\nexport const TR_PULL_RESOURCE_SCOPE_MAP: {\n [k in TranscendPullResource]: ScopeName[];\n} = {\n [TranscendPullResource.ApiKeys]: [ScopeName.ViewApiKeys],\n [TranscendPullResource.Templates]: [ScopeName.ViewEmailTemplates],\n [TranscendPullResource.DataSilos]: [\n ScopeName.ViewDataMap,\n ScopeName.ViewDataSubjectRequestSettings,\n ],\n [TranscendPullResource.Enrichers]: [ScopeName.ViewRequestIdentitySettings],\n [TranscendPullResource.BusinessEntities]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.ProcessingActivities]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.Identifiers]: [ScopeName.ViewRequestIdentitySettings],\n [TranscendPullResource.Attributes]: [ScopeName.ViewGlobalAttributes],\n [TranscendPullResource.DataFlows]: [ScopeName.ViewDataFlow],\n [TranscendPullResource.Cookies]: [ScopeName.ViewDataFlow],\n [TranscendPullResource.ConsentManager]: [ScopeName.ViewConsentManager],\n [TranscendPullResource.Partitions]: [ScopeName.ViewConsentManager],\n [TranscendPullResource.Actions]: [ScopeName.ViewDataSubjectRequestSettings],\n [TranscendPullResource.DataSubjects]: [ScopeName.ViewDataSubjectRequestSettings],\n [TranscendPullResource.Prompts]: [ScopeName.ViewPrompts],\n [TranscendPullResource.PromptPartials]: [ScopeName.ViewPrompts],\n [TranscendPullResource.PromptGroups]: [ScopeName.ViewPrompts],\n [TranscendPullResource.Agents]: [ScopeName.ViewPathfinder],\n [TranscendPullResource.AgentFunctions]: [ScopeName.ViewPathfinder],\n [TranscendPullResource.AgentFiles]: [ScopeName.ViewPathfinder],\n [TranscendPullResource.Vendors]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.DataCategories]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.ProcessingPurposes]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.ActionItemCollections]: [ScopeName.ViewAllActionItems],\n [TranscendPullResource.ActionItems]: [ScopeName.ViewAllActionItems],\n [TranscendPullResource.Teams]: [ScopeName.ViewScopes],\n [TranscendPullResource.Messages]: [ScopeName.ViewIntlMessages],\n [TranscendPullResource.PrivacyCenters]: [ScopeName.ViewPrivacyCenter],\n [TranscendPullResource.Policies]: [ScopeName.ViewPolicies],\n [TranscendPullResource.Assessments]: [ScopeName.ViewAssessments],\n [TranscendPullResource.AssessmentTemplates]: [ScopeName.ViewAssessments],\n [TranscendPullResource.Purposes]: [\n ScopeName.ViewConsentManager,\n ScopeName.ViewPreferenceStoreSettings,\n ],\n [TranscendPullResource.SystemDiscovery]: [ScopeName.ViewDataMap],\n};\n\nexport const TR_YML_RESOURCE_TO_FIELD_NAME: Record<TranscendPullResource, keyof TranscendInput> = {\n [TranscendPullResource.ApiKeys]: 'api-keys',\n [TranscendPullResource.Attributes]: 'attributes',\n [TranscendPullResource.DataFlows]: 'data-flows',\n [TranscendPullResource.Cookies]: 'cookies',\n [TranscendPullResource.ConsentManager]: 'consent-manager',\n [TranscendPullResource.Partitions]: 'partitions',\n [TranscendPullResource.Actions]: 'actions',\n [TranscendPullResource.DataSubjects]: 'data-subjects',\n [TranscendPullResource.BusinessEntities]: 'business-entities',\n [TranscendPullResource.ProcessingActivities]: 'processing-activities',\n [TranscendPullResource.Identifiers]: 'identifiers',\n [TranscendPullResource.Enrichers]: 'enrichers',\n [TranscendPullResource.DataSilos]: 'data-silos',\n [TranscendPullResource.Templates]: 'templates',\n [TranscendPullResource.Prompts]: 'prompts',\n [TranscendPullResource.PromptPartials]: 'prompt-partials',\n [TranscendPullResource.PromptGroups]: 'prompt-groups',\n [TranscendPullResource.Agents]: 'agents',\n [TranscendPullResource.AgentFunctions]: 'agent-functions',\n [TranscendPullResource.AgentFiles]: 'agent-files',\n [TranscendPullResource.Vendors]: 'vendors',\n [TranscendPullResource.DataCategories]: 'data-categories',\n [TranscendPullResource.ProcessingPurposes]: 'processing-purposes',\n [TranscendPullResource.ActionItems]: 'action-items',\n [TranscendPullResource.ActionItemCollections]: 'action-item-collections',\n [TranscendPullResource.Teams]: 'teams',\n [TranscendPullResource.Messages]: 'messages',\n [TranscendPullResource.PrivacyCenters]: 'privacy-center',\n [TranscendPullResource.Policies]: 'policies',\n [TranscendPullResource.Assessments]: 'assessments',\n [TranscendPullResource.AssessmentTemplates]: 'assessment-templates',\n [TranscendPullResource.Purposes]: 'purposes',\n [TranscendPullResource.SystemDiscovery]: 'system-discovery',\n};\n\nexport const SCOPES_BY_TITLE = keyBy(\n Object.entries(TRANSCEND_SCOPES).map(([name, value]) => ({\n ...value,\n name,\n })),\n 'title',\n) as Record<\n string,\n ScopeDefinition & {\n /** The camelCased name which identifies the scope */\n name: ScopeName;\n }\n>;\n\nexport const SCOPE_TITLES = Object.keys(SCOPES_BY_TITLE);\n\n/**\n * HTTP statuses that should be retried *in place* without splitting.\n * 429: Rate-limited\n * 502: Upstream/edge gateway error\n * 329: Reserved for custom infra (kept defensively)\n */\nexport const RETRYABLE_BATCH_STATUSES = new Set([429, 502, 500, 504, 329] as const);\n\n/**\n * Debugging\n */\nexport const DEBUG = process.env.DEBUG === '1';\n"],"mappings":"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"}
1
+ {"version":3,"file":"constants-TpID7AXE.mjs","names":[],"sources":["../package.json","../src/constants.ts"],"sourcesContent":["","import { ScopeName, TRANSCEND_SCOPES, type ScopeDefinition } from '@transcend-io/privacy-types';\nimport { keyBy } from 'lodash-es';\n\nimport { TranscendInput } from './codecs.js';\nimport { TranscendPullResource } from './enums.js';\n\nexport { description, version } from '../package.json';\n/**\n * The name of the main binary for the CLI\n */\nexport const name = 'transcend';\n\nexport const ADMIN_DASH = 'https://app.transcend.io';\n\nexport const ADMIN_DASH_INTEGRATIONS = `${ADMIN_DASH}/infrastructure/integrations`;\nexport const ADMIN_DASH_DATAPOINTS = `${ADMIN_DASH}/data-map/data-inventory/data-points`;\n\n/**\n * Override default transcend API url using\n * TRANSCEND_API_URL=https://api.us.transcend.io transcend ...\n */\nexport const DEFAULT_TRANSCEND_API = process.env.TRANSCEND_API_URL || 'https://api.transcend.io';\n\n/**\n * Override default transcend API url using\n * TRANSCEND_CONSENT_API_URL=https://consent.us.transcend.io transcend ...\n */\nexport const DEFAULT_TRANSCEND_CONSENT_API =\n process.env.TRANSCEND_CONSENT_API_URL || 'https://consent.transcend.io';\n\n/**\n * Mapping between resource type and scopes required for cli\n */\nexport const TR_PUSH_RESOURCE_SCOPE_MAP: {\n [k in TranscendPullResource]: ScopeName[];\n} = {\n [TranscendPullResource.ApiKeys]: [ScopeName.ViewApiKeys],\n [TranscendPullResource.Templates]: [ScopeName.ManageEmailTemplates],\n [TranscendPullResource.DataSilos]: [ScopeName.ManageDataMap, ScopeName.ConnectDataSilos],\n [TranscendPullResource.Enrichers]: [ScopeName.ManageRequestIdentities],\n [TranscendPullResource.BusinessEntities]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.ProcessingActivities]: [ScopeName.ManageDataMap],\n [TranscendPullResource.Identifiers]: [ScopeName.ManageRequestIdentities],\n [TranscendPullResource.Attributes]: [ScopeName.ManageGlobalAttributes],\n [TranscendPullResource.DataFlows]: [ScopeName.ManageDataFlow],\n [TranscendPullResource.Cookies]: [ScopeName.ManageDataFlow],\n [TranscendPullResource.ConsentManager]: [ScopeName.ManageConsentManagerDeveloperSettings],\n [TranscendPullResource.Partitions]: [ScopeName.ManageConsentManagerDeveloperSettings],\n [TranscendPullResource.Actions]: [ScopeName.ManageDataSubjectRequestSettings],\n [TranscendPullResource.DataSubjects]: [ScopeName.ManageDataSubjectRequestSettings],\n [TranscendPullResource.Prompts]: [ScopeName.ManagePrompts],\n [TranscendPullResource.PromptPartials]: [ScopeName.ManagePrompts],\n [TranscendPullResource.PromptGroups]: [ScopeName.ManagePrompts],\n [TranscendPullResource.Agents]: [ScopeName.ManagePathfinder],\n [TranscendPullResource.AgentFunctions]: [ScopeName.ManagePathfinder],\n [TranscendPullResource.AgentFiles]: [ScopeName.ManagePathfinder],\n [TranscendPullResource.Vendors]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.DataCategories]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.ProcessingPurposes]: [ScopeName.ManageDataInventory],\n [TranscendPullResource.ActionItems]: [\n ScopeName.ManageAllActionItems,\n ScopeName.ViewGlobalAttributes,\n ],\n [TranscendPullResource.ActionItemCollections]: [ScopeName.ManageActionItemCollections],\n [TranscendPullResource.Teams]: [ScopeName.ManageAccessControl],\n [TranscendPullResource.Messages]: [ScopeName.ManageIntlMessages],\n [TranscendPullResource.PrivacyCenters]: [ScopeName.ManagePrivacyCenter],\n [TranscendPullResource.Policies]: [ScopeName.ManagePolicies],\n [TranscendPullResource.Assessments]: [ScopeName.ManageAssessments],\n [TranscendPullResource.AssessmentTemplates]: [ScopeName.ManageAssessments],\n [TranscendPullResource.Purposes]: [\n ScopeName.ManageConsentManager,\n ScopeName.ManagePreferenceStoreSettings,\n ],\n [TranscendPullResource.SystemDiscovery]: [ScopeName.ManageDataMap],\n};\n\n/**\n * Mapping between resource type and scopes required for cli\n */\nexport const TR_PULL_RESOURCE_SCOPE_MAP: {\n [k in TranscendPullResource]: ScopeName[];\n} = {\n [TranscendPullResource.ApiKeys]: [ScopeName.ViewApiKeys],\n [TranscendPullResource.Templates]: [ScopeName.ViewEmailTemplates],\n [TranscendPullResource.DataSilos]: [\n ScopeName.ViewDataMap,\n ScopeName.ViewDataSubjectRequestSettings,\n ],\n [TranscendPullResource.Enrichers]: [ScopeName.ViewRequestIdentitySettings],\n [TranscendPullResource.BusinessEntities]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.ProcessingActivities]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.Identifiers]: [ScopeName.ViewRequestIdentitySettings],\n [TranscendPullResource.Attributes]: [ScopeName.ViewGlobalAttributes],\n [TranscendPullResource.DataFlows]: [ScopeName.ViewDataFlow],\n [TranscendPullResource.Cookies]: [ScopeName.ViewDataFlow],\n [TranscendPullResource.ConsentManager]: [ScopeName.ViewConsentManager],\n [TranscendPullResource.Partitions]: [ScopeName.ViewConsentManager],\n [TranscendPullResource.Actions]: [ScopeName.ViewDataSubjectRequestSettings],\n [TranscendPullResource.DataSubjects]: [ScopeName.ViewDataSubjectRequestSettings],\n [TranscendPullResource.Prompts]: [ScopeName.ViewPrompts],\n [TranscendPullResource.PromptPartials]: [ScopeName.ViewPrompts],\n [TranscendPullResource.PromptGroups]: [ScopeName.ViewPrompts],\n [TranscendPullResource.Agents]: [ScopeName.ViewPathfinder],\n [TranscendPullResource.AgentFunctions]: [ScopeName.ViewPathfinder],\n [TranscendPullResource.AgentFiles]: [ScopeName.ViewPathfinder],\n [TranscendPullResource.Vendors]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.DataCategories]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.ProcessingPurposes]: [ScopeName.ViewDataInventory],\n [TranscendPullResource.ActionItemCollections]: [ScopeName.ViewAllActionItems],\n [TranscendPullResource.ActionItems]: [ScopeName.ViewAllActionItems],\n [TranscendPullResource.Teams]: [ScopeName.ViewScopes],\n [TranscendPullResource.Messages]: [ScopeName.ViewIntlMessages],\n [TranscendPullResource.PrivacyCenters]: [ScopeName.ViewPrivacyCenter],\n [TranscendPullResource.Policies]: [ScopeName.ViewPolicies],\n [TranscendPullResource.Assessments]: [ScopeName.ViewAssessments],\n [TranscendPullResource.AssessmentTemplates]: [ScopeName.ViewAssessments],\n [TranscendPullResource.Purposes]: [\n ScopeName.ViewConsentManager,\n ScopeName.ViewPreferenceStoreSettings,\n ],\n [TranscendPullResource.SystemDiscovery]: [ScopeName.ViewDataMap],\n};\n\nexport const TR_YML_RESOURCE_TO_FIELD_NAME: Record<TranscendPullResource, keyof TranscendInput> = {\n [TranscendPullResource.ApiKeys]: 'api-keys',\n [TranscendPullResource.Attributes]: 'attributes',\n [TranscendPullResource.DataFlows]: 'data-flows',\n [TranscendPullResource.Cookies]: 'cookies',\n [TranscendPullResource.ConsentManager]: 'consent-manager',\n [TranscendPullResource.Partitions]: 'partitions',\n [TranscendPullResource.Actions]: 'actions',\n [TranscendPullResource.DataSubjects]: 'data-subjects',\n [TranscendPullResource.BusinessEntities]: 'business-entities',\n [TranscendPullResource.ProcessingActivities]: 'processing-activities',\n [TranscendPullResource.Identifiers]: 'identifiers',\n [TranscendPullResource.Enrichers]: 'enrichers',\n [TranscendPullResource.DataSilos]: 'data-silos',\n [TranscendPullResource.Templates]: 'templates',\n [TranscendPullResource.Prompts]: 'prompts',\n [TranscendPullResource.PromptPartials]: 'prompt-partials',\n [TranscendPullResource.PromptGroups]: 'prompt-groups',\n [TranscendPullResource.Agents]: 'agents',\n [TranscendPullResource.AgentFunctions]: 'agent-functions',\n [TranscendPullResource.AgentFiles]: 'agent-files',\n [TranscendPullResource.Vendors]: 'vendors',\n [TranscendPullResource.DataCategories]: 'data-categories',\n [TranscendPullResource.ProcessingPurposes]: 'processing-purposes',\n [TranscendPullResource.ActionItems]: 'action-items',\n [TranscendPullResource.ActionItemCollections]: 'action-item-collections',\n [TranscendPullResource.Teams]: 'teams',\n [TranscendPullResource.Messages]: 'messages',\n [TranscendPullResource.PrivacyCenters]: 'privacy-center',\n [TranscendPullResource.Policies]: 'policies',\n [TranscendPullResource.Assessments]: 'assessments',\n [TranscendPullResource.AssessmentTemplates]: 'assessment-templates',\n [TranscendPullResource.Purposes]: 'purposes',\n [TranscendPullResource.SystemDiscovery]: 'system-discovery',\n};\n\nexport const SCOPES_BY_TITLE = keyBy(\n Object.entries(TRANSCEND_SCOPES).map(([name, value]) => ({\n ...value,\n name,\n })),\n 'title',\n) as Record<\n string,\n ScopeDefinition & {\n /** The camelCased name which identifies the scope */\n name: ScopeName;\n }\n>;\n\nexport const SCOPE_TITLES = Object.keys(SCOPES_BY_TITLE);\n\n/**\n * HTTP statuses that should be retried *in place* without splitting.\n * 429: Rate-limited\n * 502: Upstream/edge gateway error\n * 329: Reserved for custom infra (kept defensively)\n */\nexport const RETRYABLE_BATCH_STATUSES = new Set([429, 502, 500, 504, 329] as const);\n\n/**\n * Debugging\n */\nexport const DEBUG = process.env.DEBUG === '1';\n"],"mappings":"mPCUA,MAAa,EAAO,YAEP,EAAa,2BAEb,EAA0B,GAAG,EAAW,8BACxC,EAAwB,GAAG,EAAW,sCAMtC,EAAwB,QAAQ,IAAI,mBAAqB,2BAMzD,EACX,QAAQ,IAAI,2BAA6B,+BAK9B,EAET,EACD,EAAsB,SAAU,CAAC,EAAU,YAAY,EACvD,EAAsB,WAAY,CAAC,EAAU,qBAAqB,EAClE,EAAsB,WAAY,CAAC,EAAU,cAAe,EAAU,iBAAiB,EACvF,EAAsB,WAAY,CAAC,EAAU,wBAAwB,EACrE,EAAsB,kBAAmB,CAAC,EAAU,oBAAoB,EACxE,EAAsB,sBAAuB,CAAC,EAAU,cAAc,EACtE,EAAsB,aAAc,CAAC,EAAU,wBAAwB,EACvE,EAAsB,YAAa,CAAC,EAAU,uBAAuB,EACrE,EAAsB,WAAY,CAAC,EAAU,eAAe,EAC5D,EAAsB,SAAU,CAAC,EAAU,eAAe,EAC1D,EAAsB,gBAAiB,CAAC,EAAU,sCAAsC,EACxF,EAAsB,YAAa,CAAC,EAAU,sCAAsC,EACpF,EAAsB,SAAU,CAAC,EAAU,iCAAiC,EAC5E,EAAsB,cAAe,CAAC,EAAU,iCAAiC,EACjF,EAAsB,SAAU,CAAC,EAAU,cAAc,EACzD,EAAsB,gBAAiB,CAAC,EAAU,cAAc,EAChE,EAAsB,cAAe,CAAC,EAAU,cAAc,EAC9D,EAAsB,QAAS,CAAC,EAAU,iBAAiB,EAC3D,EAAsB,gBAAiB,CAAC,EAAU,iBAAiB,EACnE,EAAsB,YAAa,CAAC,EAAU,iBAAiB,EAC/D,EAAsB,SAAU,CAAC,EAAU,oBAAoB,EAC/D,EAAsB,gBAAiB,CAAC,EAAU,oBAAoB,EACtE,EAAsB,oBAAqB,CAAC,EAAU,oBAAoB,EAC1E,EAAsB,aAAc,CACnC,EAAU,qBACV,EAAU,qBACX,EACA,EAAsB,uBAAwB,CAAC,EAAU,4BAA4B,EACrF,EAAsB,OAAQ,CAAC,EAAU,oBAAoB,EAC7D,EAAsB,UAAW,CAAC,EAAU,mBAAmB,EAC/D,EAAsB,gBAAiB,CAAC,EAAU,oBAAoB,EACtE,EAAsB,UAAW,CAAC,EAAU,eAAe,EAC3D,EAAsB,aAAc,CAAC,EAAU,kBAAkB,EACjE,EAAsB,qBAAsB,CAAC,EAAU,kBAAkB,EACzE,EAAsB,UAAW,CAChC,EAAU,qBACV,EAAU,8BACX,EACA,EAAsB,iBAAkB,CAAC,EAAU,cAAc,CACnE,CAKY,EAET,EACD,EAAsB,SAAU,CAAC,EAAU,YAAY,EACvD,EAAsB,WAAY,CAAC,EAAU,mBAAmB,EAChE,EAAsB,WAAY,CACjC,EAAU,YACV,EAAU,+BACX,EACA,EAAsB,WAAY,CAAC,EAAU,4BAA4B,EACzE,EAAsB,kBAAmB,CAAC,EAAU,kBAAkB,EACtE,EAAsB,sBAAuB,CAAC,EAAU,kBAAkB,EAC1E,EAAsB,aAAc,CAAC,EAAU,4BAA4B,EAC3E,EAAsB,YAAa,CAAC,EAAU,qBAAqB,EACnE,EAAsB,WAAY,CAAC,EAAU,aAAa,EAC1D,EAAsB,SAAU,CAAC,EAAU,aAAa,EACxD,EAAsB,gBAAiB,CAAC,EAAU,mBAAmB,EACrE,EAAsB,YAAa,CAAC,EAAU,mBAAmB,EACjE,EAAsB,SAAU,CAAC,EAAU,+BAA+B,EAC1E,EAAsB,cAAe,CAAC,EAAU,+BAA+B,EAC/E,EAAsB,SAAU,CAAC,EAAU,YAAY,EACvD,EAAsB,gBAAiB,CAAC,EAAU,YAAY,EAC9D,EAAsB,cAAe,CAAC,EAAU,YAAY,EAC5D,EAAsB,QAAS,CAAC,EAAU,eAAe,EACzD,EAAsB,gBAAiB,CAAC,EAAU,eAAe,EACjE,EAAsB,YAAa,CAAC,EAAU,eAAe,EAC7D,EAAsB,SAAU,CAAC,EAAU,kBAAkB,EAC7D,EAAsB,gBAAiB,CAAC,EAAU,kBAAkB,EACpE,EAAsB,oBAAqB,CAAC,EAAU,kBAAkB,EACxE,EAAsB,uBAAwB,CAAC,EAAU,mBAAmB,EAC5E,EAAsB,aAAc,CAAC,EAAU,mBAAmB,EAClE,EAAsB,OAAQ,CAAC,EAAU,WAAW,EACpD,EAAsB,UAAW,CAAC,EAAU,iBAAiB,EAC7D,EAAsB,gBAAiB,CAAC,EAAU,kBAAkB,EACpE,EAAsB,UAAW,CAAC,EAAU,aAAa,EACzD,EAAsB,aAAc,CAAC,EAAU,gBAAgB,EAC/D,EAAsB,qBAAsB,CAAC,EAAU,gBAAgB,EACvE,EAAsB,UAAW,CAChC,EAAU,mBACV,EAAU,4BACX,EACA,EAAsB,iBAAkB,CAAC,EAAU,YAAY,CACjE,CAEY,EAAqF,EAC/F,EAAsB,SAAU,YAChC,EAAsB,YAAa,cACnC,EAAsB,WAAY,cAClC,EAAsB,SAAU,WAChC,EAAsB,gBAAiB,mBACvC,EAAsB,YAAa,cACnC,EAAsB,SAAU,WAChC,EAAsB,cAAe,iBACrC,EAAsB,kBAAmB,qBACzC,EAAsB,sBAAuB,yBAC7C,EAAsB,aAAc,eACpC,EAAsB,WAAY,aAClC,EAAsB,WAAY,cAClC,EAAsB,WAAY,aAClC,EAAsB,SAAU,WAChC,EAAsB,gBAAiB,mBACvC,EAAsB,cAAe,iBACrC,EAAsB,QAAS,UAC/B,EAAsB,gBAAiB,mBACvC,EAAsB,YAAa,eACnC,EAAsB,SAAU,WAChC,EAAsB,gBAAiB,mBACvC,EAAsB,oBAAqB,uBAC3C,EAAsB,aAAc,gBACpC,EAAsB,uBAAwB,2BAC9C,EAAsB,OAAQ,SAC9B,EAAsB,UAAW,YACjC,EAAsB,gBAAiB,kBACvC,EAAsB,UAAW,YACjC,EAAsB,aAAc,eACpC,EAAsB,qBAAsB,wBAC5C,EAAsB,UAAW,YACjC,EAAsB,iBAAkB,mBAC1C,CAEY,EAAkB,EAC7B,OAAO,QAAQ,EAAiB,CAAC,KAAK,CAAC,EAAM,MAAY,CACvD,GAAG,EACH,OACD,EAAE,CACH,QACD,CAQY,EAAe,OAAO,KAAK,EAAgB,CAQ3C,EAA2B,IAAI,IAAI,CAAC,IAAK,IAAK,IAAK,IAAK,IAAI,CAAU,CAKtE,EAAQ,QAAQ,IAAI,QAAU"}
@@ -1,4 +1,4 @@
1
- import{i as e}from"./constants-XOsAW1__.mjs";import{createReadStream as t,readFileSync as n,statSync as r}from"node:fs";import{basename as i}from"node:path";import a from"colors";import*as o from"node:readline";function s(e,t,r){process.stdout.write(`\x1B[2J\x1B[H`);let i=e=>/\b(ERROR|uncaughtException|unhandledRejection)\b/i.test(e),a=e=>/\b(WARN|WARNING)\b/i.test(e),o=[];for(let[,s]of e){if(!s)continue;let e=[];for(let n of t)n===`out`&&s.outPath&&e.push({path:s.outPath,src:`out`}),n===`err`&&s.errPath&&e.push({path:s.errPath,src:`err`}),n===`structured`&&s.structuredPath&&e.push({path:s.structuredPath,src:`structured`}),s.warnPath&&n===`warn`&&e.push({path:s.warnPath,src:`warn`}),s.infoPath&&n===`info`&&e.push({path:s.infoPath,src:`info`});for(let{path:t,src:s}of e){let e=``;try{e=n(t,`utf8`)}catch{continue}for(let t of e.split(`
1
+ import{i as e}from"./constants-TpID7AXE.mjs";import{createReadStream as t,readFileSync as n,statSync as r}from"node:fs";import{basename as i}from"node:path";import a from"colors";import*as o from"node:readline";function s(e,t,r){process.stdout.write(`\x1B[2J\x1B[H`);let i=e=>/\b(ERROR|uncaughtException|unhandledRejection)\b/i.test(e),a=e=>/\b(WARN|WARNING)\b/i.test(e),o=[];for(let[,s]of e){if(!s)continue;let e=[];for(let n of t)n===`out`&&s.outPath&&e.push({path:s.outPath,src:`out`}),n===`err`&&s.errPath&&e.push({path:s.errPath,src:`err`}),n===`structured`&&s.structuredPath&&e.push({path:s.structuredPath,src:`structured`}),s.warnPath&&n===`warn`&&e.push({path:s.warnPath,src:`warn`}),s.infoPath&&n===`info`&&e.push({path:s.infoPath,src:`info`});for(let{path:t,src:s}of e){let e=``;try{e=n(t,`utf8`)}catch{continue}for(let t of e.split(`
2
2
  `)){if(!t)continue;let e=t.replace(/\x1B\[[0-9;]*m/g,``);if(r===`all`){o.push(t);continue}if(r===`error`){i(e)&&o.push(t);continue}if(a(e)||s===`err`&&!i(e)){o.push(t);continue}}}}o.sort((e,t)=>{let n=e.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)?.[0]??``,r=t.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)?.[0]??``;return n.localeCompare(r)}),process.stdout.write(`${o.join(`
3
3
  `)}\n`),process.stdout.write(`
4
4
  Press Esc/Ctrl+] to return to dashboard.
@@ -11,4 +11,4 @@ Press Esc/Ctrl+] to return to dashboard.
11
11
  `);!e.final&&r===p||(p=r,e.final?process.stdout.write(`\x1B[?25h`):(process.stdout.write(`\x1B[?25l`),o.cursorTo(process.stdout,0,0),o.clearScreenDown(process.stdout)),process.stdout.write(`${r}\n`))}function g(e){return typeof e==`number`?e.toLocaleString():`0`}function _(e,t=40){let n=Math.max(0,Math.min(100,Math.floor(e))),r=Math.floor(n/100*t);return`█`.repeat(r)+`░`.repeat(t-r)}function v(e){let t=[...e.workerState.values()].filter(e=>e.busy).length,n=e.filesCompleted+e.filesFailed;return{done:n,inProgress:t,pct:e.filesTotal===0?100:Math.floor(n/Math.max(1,e.filesTotal)*100)}}function y(e,t=[]){let{title:n,poolSize:r,cpuCount:i,filesTotal:o,filesCompleted:s,filesFailed:c,throughput:l}=e,{inProgress:u,pct:d}=v(e),f=[`${a.bold(n)} — ${r} workers ${a.dim(`(CPU avail: ${i})`)}`,`${a.dim(`Files`)} ${g(o)} ${a.dim(`Completed`)} ${g(s)} ${a.dim(`Failed`)} ${c?a.red(g(c)):g(c)} ${a.dim(`In-flight`)} ${g(u)}`,`[${_(d)}] ${d}%`];if(l){let t=l.jobsR10s>0||l.jobsR60s>0,n=Math.round((t?l.jobsR10s:l.r10s)*3600).toLocaleString(),r=Math.round((t?l.jobsR60s:l.r60s)*3600).toLocaleString(),i=t?`rec`:`files`,o=e.throughput?.successSoFar==null?``:` Newly uploaded: ${g(e.throughput.successSoFar)}`;f.push(a.cyan(`Throughput: ${n} ${i}/hr (1h: ${r} ${i}/hr)${o}`))}return t.length?f.concat(t):f}function b(e,t=e=>e?i(e):`-`){return[...e.workerState.entries()].map(([e,n])=>{let r=n.lastLevel===`error`?a.red(`ERROR `):n.lastLevel===`warn`?a.yellow(`WARN `):n.busy?a.green(`WORKING`):a.dim(`IDLE `),i=t(n.file),o=n.startedAt?`${Math.floor((Date.now()-n.startedAt)/1e3)}s`:`-`,s=n.progress?.processed??0,c=n.progress?.total??0,l=c>0?Math.floor(s/c*100):0;return` [w${e}] ${r} | ${i} | ${o} | [${c>0?_(l,18):` `.repeat(18)}] ${c>0?`${s.toLocaleString()}/${c.toLocaleString()} (${l}%)`:a.dim(`—`)}`})}function x(e){let{logsBySlot:t,repaint:n,setPaused:r,exportMgr:i,exportStatus:a,custom:o}=e,c=e=>{process.stdout.write(`${e}\n`)},l=(e,t)=>{let r=Date.now(),i=a?.[e]??{path:t};a&&(a[e]={path:t||i.path,savedAt:r,exported:!0},n())},u=!1,d=(e,i)=>{u||(u=!0,r(!0),process.stdout.write(`\x1B[2J\x1B[H`),process.stdout.write(`Combined logs viewer (press Esc or Ctrl+] to return)
12
12
 
13
13
  `),(async()=>{try{await s(t,e,i)}catch{u=!1,r(!1),n()}})())},f=(e,n)=>{if(i)try{let r=i.exportCombinedLogs(t,e);c(`\nWrote combined ${n} logs to: ${r}`),l(e,r)}catch{c(`\nFailed to write combined ${n} logs`)}};return e=>{let t=e.toString(`utf8`);if(t===`e`){d([`err`],`error`);return}if(t===`w`){d([`warn`,`err`],`warn`);return}if(t===`i`){d([`info`],`all`);return}if(t===`l`){d([`out`,`err`,`structured`],`all`);return}if(t===`E`){f(`error`,`error`);return}if(t===`W`){f(`warn`,`warn`);return}if(t===`I`){f(`info`,`info`);return}if(t===`A`){f(`all`,`ALL`);return}let i=o?.[t];if(i){i({noteExport:l,say:c});return}(t===`\x1B`||t===``)&&(u=!1,r(!1),n())}}export{f as a,h as i,y as n,b as r,x as t};
14
- //# sourceMappingURL=createExtraKeyHandler-Jp5XpTJi.mjs.map
14
+ //# sourceMappingURL=createExtraKeyHandler-BO4lu0HO.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"createExtraKeyHandler-Jp5XpTJi.mjs","names":[],"sources":["../src/lib/pooling/showCombinedLogs.ts","../src/lib/pooling/keymap.ts","../src/lib/pooling/replayFileTailToStdout.ts","../src/lib/pooling/workerIds.ts","../src/lib/pooling/installInteractiveSwitcher.ts","../src/lib/pooling/dashboardPlugin.ts","../src/lib/pooling/uiPlugins.ts","../src/lib/pooling/createExtraKeyHandler.ts"],"sourcesContent":["/* eslint-disable no-continue, no-control-regex */\nimport { readFileSync } from 'node:fs';\n\nimport type { WorkerLogPaths } from '@transcend-io/utils';\n\n/**\n * Log locations\n */\nexport type LogLocation = 'out' | 'err' | 'structured' | 'warn' | 'info';\n\n/**\n * Which logs to show in the combined output.\n * Can include 'out' (stdout), 'err' (stderr), 'structured' (\n */\nexport type WhichLogs = Array<LogLocation>;\n\n/**\n * Show combined logs from all worker processes.\n *\n * @param slotLogPaths - Map of worker IDs to their log file paths.\n * @param whichList - one or more sources to include (e.g., ['err','out'])\n * @param filterLevel - 'error', 'warn', or 'all' to filter log levels.\n */\nexport function showCombinedLogs(\n slotLogPaths: Map<number, WorkerLogPaths | undefined>,\n whichList: WhichLogs,\n filterLevel: 'error' | 'warn' | 'all',\n): void {\n process.stdout.write('\\x1b[2J\\x1b[H');\n\n const isError = (t: string): boolean =>\n /\\b(ERROR|uncaughtException|unhandledRejection)\\b/i.test(t);\n const isWarnTag = (t: string): boolean => /\\b(WARN|WARNING)\\b/i.test(t);\n\n const lines: string[] = [];\n\n for (const [, paths] of slotLogPaths) {\n if (!paths) continue;\n\n const files: Array<{\n /** Absolute file path to read from */\n path: string;\n /** Source type for this file, used for classification */\n src: LogLocation;\n }> = [];\n for (const which of whichList) {\n if (which === 'out' && paths.outPath) {\n files.push({ path: paths.outPath, src: 'out' });\n }\n if (which === 'err' && paths.errPath) {\n files.push({ path: paths.errPath, src: 'err' });\n }\n if (which === 'structured' && paths.structuredPath) {\n files.push({ path: paths.structuredPath, src: 'structured' });\n }\n if (paths.warnPath && which === 'warn') {\n files.push({ path: paths.warnPath, src: 'warn' });\n }\n if (paths.infoPath && which === 'info') {\n files.push({ path: paths.infoPath, src: 'info' });\n }\n }\n\n for (const { path, src } of files) {\n let text = '';\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n continue;\n }\n\n for (const ln of text.split('\\n')) {\n if (!ln) continue;\n\n const clean = ln.replace(/\\x1B\\[[0-9;]*m/g, '');\n\n if (filterLevel === 'all') {\n lines.push(ln);\n continue;\n }\n\n if (filterLevel === 'error') {\n if (isError(clean)) lines.push(ln);\n continue;\n }\n\n // filterLevel === 'warn'\n // Accept:\n // - explicit WARN tag anywhere\n // - OR lines from stderr that are NOT explicit errors (many warn libs print to stderr)\n // - OR lines containing the word \"warning\" (common in some libs)\n if (isWarnTag(clean) || (src === 'err' && !isError(clean))) {\n lines.push(ln);\n continue;\n }\n }\n }\n }\n\n // simple time-sort; each worker often prefixes ISO timestamps\n lines.sort((a, b) => {\n const ta = a.match(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)?.[0] ?? '';\n const tb = b.match(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)?.[0] ?? '';\n return ta.localeCompare(tb);\n });\n\n process.stdout.write(`${lines.join('\\n')}\\n`);\n process.stdout.write('\\nPress Esc/Ctrl+] to return to dashboard.\\n');\n}\n/* eslint-enable no-continue, no-control-regex */\n","import type * as readline from 'node:readline';\n\n/**\n * Map a key press to an action in the interactive dashboard.\n */\nexport type Action =\n | {\n /** Indicates attaching to a session by id. */\n type: 'ATTACH';\n /** The id of the session to attach to. */\n id: number;\n }\n | {\n /** Indicates cycling through sessions. */\n type: 'CYCLE';\n /** The direction to cycle: +1 for next, -1 for previous. */\n delta: number;\n }\n | {\n /** Indicates detaching from the current session. */\n type: 'DETACH';\n }\n | {\n /** Indicates the Ctrl+C key combination was pressed. */\n type: 'CTRL_C';\n }\n | {\n /** Indicates the Ctrl+D key combination was pressed. */\n type: 'CTRL_D';\n }\n | {\n /** Indicates quitting the dashboard. */\n type: 'QUIT';\n }\n | {\n /** Forwards an unhandled key sequence. */\n type: 'FORWARD';\n /** The key sequence to forward. */\n sequence: string;\n };\n\n/**\n * Map a key press to an action in the interactive dashboard.\n *\n * @param str - The string representation of the key press.\n * @param key - The key object containing details about the key press.\n * @param mode - The current mode of the dashboard, either 'dashboard' or 'attached'.\n * @returns An Action object representing the mapped action, or null if no action is mapped.\n */\nexport function keymap(\n str: string,\n key: readline.Key,\n mode: 'dashboard' | 'attached',\n): Action | null {\n if (key.ctrl && key.name === 'c') return { type: 'CTRL_C' };\n\n if (mode === 'dashboard') {\n if (key.name && /^[0-9]$/.test(key.name)) {\n return { type: 'ATTACH', id: Number(key.name) };\n }\n if (key.name === 'tab' && !key.shift) return { type: 'CYCLE', delta: +1 };\n if (key.name === 'tab' && key.shift) return { type: 'CYCLE', delta: -1 };\n if (key.name === 'q') return { type: 'QUIT' };\n return null;\n }\n\n // attached\n if (key.name === 'escape' || (key.ctrl && key.name === ']')) {\n return { type: 'DETACH' };\n }\n if (key.ctrl && key.name === 'd') return { type: 'CTRL_D' };\n\n const sequence = key.sequence ?? str ?? '';\n return sequence ? { type: 'FORWARD', sequence } : null;\n}\n","import { createReadStream, statSync } from 'node:fs';\n\n/**\n * Replay the tail of a file to stdout.\n *\n * @param path - The absolute path to the file to read.\n * @param maxBytes - The maximum number of bytes to read from the end of the file.\n * @param write - A function to write the output to stdout.\n */\nexport async function replayFileTailToStdout(\n path: string,\n maxBytes: number,\n write: (s: string) => void,\n): Promise<void> {\n await new Promise<void>((resolve) => {\n try {\n const st = statSync(path);\n const start = Math.max(0, st.size - maxBytes);\n const stream = createReadStream(path, { start, encoding: 'utf8' });\n stream.on('data', (chunk) => write(chunk as string));\n stream.on('end', () => resolve());\n stream.on('error', () => resolve());\n } catch {\n resolve();\n }\n });\n}\n","import type { ChildProcess } from 'node:child_process';\n\n/**\n * Get the sorted list of worker IDs from a map of ChildProcess instances.\n *\n * @param m - Map of worker IDs to ChildProcess instances.\n * @returns Sorted array of worker IDs.\n */\nexport function getWorkerIds(m: Map<number, ChildProcess>): number[] {\n return [...m.keys()].sort((a, b) => a - b);\n}\n\n/**\n * Cycles through an array of numeric IDs, returning the next ID based on a delta.\n *\n * If the `current` ID is not provided or not found in the array, the first ID is used as the starting point.\n * The function then moves forward or backward in the array by `delta` positions, wrapping around if necessary.\n *\n * @param ids - Array of numeric IDs to cycle through.\n * @param current - The current ID to start cycling from. If `null` or not found, starts from the first ID.\n * @param delta - The number of positions to move forward (positive) or backward (negative) in the array.\n * @returns The next ID in the array after cycling, or `null` if the array is empty.\n */\nexport function cycleWorkers(ids: number[], current: number | null, delta: number): number | null {\n if (!ids.length) return null;\n const cur = current == null ? ids[0] : current;\n let i = ids.indexOf(cur);\n if (i === -1) i = 0;\n i = (i + delta + ids.length) % ids.length;\n return ids[i]!;\n}\n","import type { ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\n\nimport type { WorkerLogPaths } from '@transcend-io/utils';\n\nimport { DEBUG } from '../../constants.js';\nimport { keymap } from './keymap.js';\nimport { replayFileTailToStdout } from './replayFileTailToStdout.js';\nimport type { WhichLogs } from './showCombinedLogs.js';\nimport { cycleWorkers, getWorkerIds } from './workerIds.js';\n\n/**\n * Key action types for the interactive switcher\n */\nexport type InteractiveDashboardMode = 'dashboard' | 'attached';\n\nexport interface SwitcherPorts {\n /** Standard input stream */\n stdin: NodeJS.ReadStream;\n /** Standard output stream */\n stdout: NodeJS.WriteStream;\n /** Standard error stream */\n stderr: NodeJS.WriteStream;\n}\n\n/**\n * Install an interactive switcher for managing worker processes.\n *\n * @param opts - Options for the switcher\n * @returns A cleanup function to remove the switcher\n */\nexport function installInteractiveSwitcher(opts: {\n /** Registry of live workers by id */\n workers: Map<number, ChildProcess>;\n /** Hooks */\n onAttach?: (id: number) => void;\n /** Optional detach handler */\n onDetach?: () => void;\n /** Optional Ctrl+C handler for parent graceful shutdown in dashboard */\n onCtrlC?: () => void; // parent graceful shutdown in dashboard\n /** Provide log paths so we can replay the tail on attach */\n getLogPaths?: (id: number) => WorkerLogPaths | undefined;\n /** How many bytes to replay from the end of each file (default 200 KB) */\n replayBytes?: number;\n /** Which logs to replay first (default ['out','err']) */\n replayWhich?: WhichLogs;\n /** Print a small banner/clear screen before replaying (optional) */\n onEnterAttachScreen?: (id: number) => void;\n /** Optional stdio ports for testing; defaults to process stdio */\n ports?: SwitcherPorts;\n}): () => void {\n const {\n workers,\n onAttach,\n onDetach,\n onCtrlC,\n getLogPaths,\n replayBytes = 200 * 1024,\n replayWhich = ['out', 'err'],\n onEnterAttachScreen,\n ports,\n } = opts;\n\n const stdin = ports?.stdin ?? process.stdin;\n const stdout = ports?.stdout ?? process.stdout;\n const stderr = ports?.stderr ?? process.stderr;\n\n const d = (...a: unknown[]): void => {\n if (DEBUG) {\n try {\n (ports?.stderr ?? process.stderr).write(`[keys] ${a.map(String).join(' ')}\\n`);\n } catch {\n // noop\n }\n }\n };\n\n if (!stdin.isTTY) {\n // Not a TTY; return a no-op cleanup\n return () => {\n // noop\n };\n }\n\n readline.emitKeypressEvents(stdin);\n stdin.setRawMode?.(true);\n\n let mode: InteractiveDashboardMode = 'dashboard';\n let focus: number | null = null;\n\n // live mirroring handlers while attached\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let outHandler: ((chunk: any) => void) | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let errHandler: ((chunk: any) => void) | null = null;\n\n /**\n * Cycle through worker IDs, wrapping around.\n *\n * @param id - The current worker ID to start cycling from.\n * @returns The next worker ID after cycling, or null if no workers are available.\n */\n async function replayLogs(id: number): Promise<void> {\n if (!getLogPaths) return;\n const paths = getLogPaths(id);\n if (!paths) return;\n\n const toReplay: string[] = [];\n for (const which of replayWhich) {\n if (which === 'out') toReplay.push(paths.outPath);\n if (which === 'err') toReplay.push(paths.errPath);\n if (which === 'structured') toReplay.push(paths.structuredPath);\n }\n\n if (toReplay.length) {\n stdout.write('\\n------------ replay ------------\\n');\n for (const p of toReplay) {\n stdout.write(`\\n--- ${p} (last ~${Math.floor(replayBytes / 1024)}KB) ---\\n`);\n await replayFileTailToStdout(p, replayBytes, (s) => stdout.write(s));\n }\n stdout.write('\\n--------------------------------\\n\\n');\n }\n }\n\n const attach = async (id: number): Promise<void> => {\n d('attach()', `id=${id}`); // at function entry\n\n const w = workers.get(id);\n if (!w) return;\n\n // Detach any previous focus\n if (mode === 'attached') detach();\n\n mode = 'attached';\n focus = id;\n\n // UX: clear + banner\n onEnterAttachScreen?.(id);\n\n onAttach?.(id); // prints “Attached to worker …” and clears\n await replayLogs(id); // now the tail stays visible\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outHandler = (chunk: any) => stdout.write(chunk);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errHandler = (chunk: any) => stderr.write(chunk);\n w.stdout?.on('data', outHandler);\n w.stderr?.on('data', errHandler);\n\n // auto-detach if child exits\n const onExit = (): void => {\n if (focus === id) detach();\n };\n w.once('exit', onExit);\n };\n\n const detach = (): void => {\n d('detach()', `id=${focus}`); // at function entry\n\n if (focus == null) return;\n const id = focus;\n const w = workers.get(id);\n if (w) {\n if (outHandler) w.stdout?.off('data', outHandler);\n if (errHandler) w.stderr?.off('data', errHandler);\n }\n outHandler = null;\n errHandler = null;\n focus = null;\n mode = 'dashboard';\n onDetach?.();\n };\n\n const onKey = (str: string, key: readline.Key): void => {\n d(\n 'keypress',\n JSON.stringify({\n str,\n name: key.name,\n seq: key.sequence,\n ctrl: key.ctrl,\n meta: key.meta,\n shift: key.shift,\n mode,\n }),\n );\n const act = keymap(str, key, mode);\n d('mapped', JSON.stringify(act));\n\n if (!act) return;\n\n // eslint-disable-next-line default-case\n switch (act.type) {\n case 'CTRL_C': {\n d('CTRL_C');\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.kill('SIGINT');\n } catch {\n // noop\n }\n // optional: auto-detach so second Ctrl+C exits parent\n detach();\n return;\n }\n onCtrlC?.();\n return;\n }\n\n case 'ATTACH': {\n d('ATTACH', `id=${act.id}`, `has=${workers.has(act.id)}`);\n\n if (mode !== 'dashboard') return;\n // eslint-disable-next-line no-void\n if (workers.has(act.id)) void attach(act.id);\n return;\n }\n\n case 'CYCLE': {\n d('CYCLE', `delta=${act.delta}`);\n if (mode !== 'dashboard') return;\n const next = cycleWorkers(getWorkerIds(workers), focus, act.delta);\n // eslint-disable-next-line no-void\n if (next != null) void attach(next);\n return;\n }\n\n case 'QUIT': {\n if (mode !== 'dashboard') return;\n onCtrlC?.();\n return;\n }\n\n case 'DETACH': {\n d('DETACH');\n if (mode === 'attached') detach();\n return;\n }\n\n case 'CTRL_D': {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.end();\n } catch {\n // noop\n }\n }\n return;\n }\n\n case 'FORWARD': {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.write(act.sequence);\n } catch {\n // noop\n }\n }\n }\n }\n };\n\n // Raw bytes fallback (usually not hit because keypress handles it)\n const onData = (chunk: Buffer): void => {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.write(chunk);\n } catch {\n // noop\n }\n }\n };\n\n const cleanup = (): void => {\n stdin.off('keypress', onKey);\n stdin.off('data', onData);\n stdin.setRawMode?.(false);\n stdout.write('\\x1b[?25h');\n };\n\n stdin.on('keypress', onKey);\n stdin.on('data', onData);\n\n return cleanup;\n}\n","// lib/pooling/dashboardPlugin.ts\nimport * as readline from 'node:readline';\n\nimport type { ObjByString } from '@transcend-io/type-utils';\nimport type { SlotState } from '@transcend-io/utils';\nimport colors from 'colors';\n\n/**\n * A dashboard plugin defines how to render the worker pool UI.\n * Commands can supply a plugin to customize:\n * - The header block (summary stats, title, etc.)\n * - Per-worker rows (one line per worker slot)\n * - Optional extras (artifact exports, breakdowns, footers)\n *\n * @template TTotals - The shape of the aggregate totals object maintained by the command.\n */\nexport interface DashboardPlugin<TTotals, TSlotState extends ObjByString> {\n /**\n * Render the header block of the dashboard.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one line in the header.\n */\n renderHeader: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n\n /**\n * Render per-worker rows, usually one line per worker slot.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one row in the workers section.\n */\n renderWorkers: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n\n /**\n * Render any optional extra blocks that appear after the worker rows.\n * Useful for printing export paths, aggregated metrics, breakdowns, etc.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one additional line.\n */\n renderExtras?: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n}\n\n/**\n * Shared context object passed into all render methods of a {@link DashboardPlugin}.\n *\n * @template TTotals - The shape of the aggregate totals object maintained by the command.\n */\nexport type CommonCtx<TTotals, TSlotState extends ObjByString> = {\n /** Human-readable title for the dashboard (e.g., \"Parallel uploader\"). */\n title: string;\n\n /** Number of worker processes spawned in the pool. */\n poolSize: number;\n\n /** Logical CPU count, included for informational display. */\n cpuCount: number;\n\n /** Total number of \"files\" or logical units the command expects to process. */\n filesTotal: number;\n\n /** Count of successfully completed files/tasks. */\n filesCompleted: number;\n\n /** Count of failed files/tasks. */\n filesFailed: number;\n\n /**\n * State of each worker slot, keyed by worker id.\n * Includes busy flag, file label, start time, last log badge, and progress.\n */\n workerState: Map<number, SlotState<TSlotState>>;\n\n /**\n * Aggregate totals maintained by the command’s hook logic.\n * Domain-specific metrics (e.g., rows uploaded, bytes processed) can be surfaced here.\n */\n totals: TTotals;\n\n /**\n * Throughput metrics tracked by the runner:\n * - successSoFar: convenience alias for completed count\n * - r10s: completions/sec averaged over last 10s\n * - r60s: completions/sec averaged over last 60s\n */\n throughput: {\n /** Cumulative count of successful completions so far. */\n successSoFar: number;\n /** Recent file-level throughput rate over the last 10 seconds. */\n r10s: number;\n /** Recent file-level throughput rate over the last 60 seconds. */\n r60s: number;\n /** Recent job/record-level throughput rate over the last 10 seconds. */\n jobsR10s: number;\n /** Recent job/record-level throughput rate over the last 60 seconds. */\n jobsR60s: number;\n };\n\n /** True when the pool has fully drained and all workers have exited. */\n final: boolean;\n\n /**\n * Optional export status payload provided by the command.\n * Useful for rendering artifact paths or \"latest export\" summaries.\n */\n exportStatus?: Record<string, unknown>;\n};\n\n/** The most recently rendered frame, cached to suppress flicker from duplicate renders. */\nlet lastFrame = '';\n\n/**\n * Generate the hotkeys hint string that appears at the bottom of the dashboard.\n *\n * @param poolSize - The number of worker slots in the pool.\n * @param final - Whether the run has completed.\n * @returns A dimmed string listing the supported hotkeys for attach/detach/quit.\n */\nexport const hotkeysHint = (poolSize: number, final: boolean): string => {\n const maxDigit = Math.min(poolSize - 1, 9);\n const digitRange = poolSize <= 1 ? '0' : `0-${maxDigit}`;\n const extra = poolSize > 10 ? ' (Tab/Shift+Tab for ≥10)' : '';\n return final\n ? colors.dim(\n 'Run complete — digits to view logs • Tab/Shift+Tab cycle • Esc/Ctrl+] detach • q to quit',\n )\n : colors.dim(\n `Hotkeys: [${digitRange}] attach${extra} • e=errors • w=warnings • i=info • l=logs • ` +\n 'Tab/Shift+Tab • Esc/Ctrl+] detach • Ctrl+C exit',\n );\n};\n\n/**\n * Render the dashboard using a supplied {@link DashboardPlugin}.\n *\n * The frame is composed of:\n * - Header lines\n * - A blank separator\n * - Worker rows\n * - A blank separator\n * - Hotkeys hint\n * - Optional extras (if plugin supplies them)\n *\n * Optimizations:\n * - Suppresses re-renders if the frame is identical to the previous frame (flicker-free).\n * - Hides the terminal cursor during live updates, restoring it when final.\n *\n * @param ctx - Shared context containing pool state, worker state, totals, throughput, etc.\n * @param plugin - The plugin that defines how to render the header, workers, and optional extras.\n * @param viewerMode - If true, renders in viewer mode (no ability to switch between files).\n */\nexport function dashboardPlugin<TTotals, TSlotState extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlotState>,\n plugin: DashboardPlugin<TTotals, TSlotState>,\n viewerMode = false,\n): void {\n const frame = [\n ...plugin.renderHeader(ctx),\n '',\n ...plugin.renderWorkers(ctx),\n ...(viewerMode ? [] : ['', hotkeysHint(ctx.poolSize, ctx.final)]),\n ...(plugin.renderExtras ? [''].concat(plugin.renderExtras(ctx)) : []),\n ].join('\\n');\n\n // Skip duplicate renders during live runs to avoid flicker.\n if (!ctx.final && frame === lastFrame) return;\n lastFrame = frame;\n\n if (!ctx.final) {\n // Hide cursor and repaint in place\n process.stdout.write('\\x1b[?25l');\n readline.cursorTo(process.stdout, 0, 0);\n readline.clearScreenDown(process.stdout);\n } else {\n // Restore cursor on final render\n process.stdout.write('\\x1b[?25h');\n }\n process.stdout.write(`${frame}\\n`);\n}\n","import { basename } from 'node:path';\n\nimport type { ObjByString } from '@transcend-io/type-utils';\nimport colors from 'colors';\n\nimport type { CommonCtx } from './dashboardPlugin.js';\n\n/**\n * Progress snapshot for a worker slot in the chunk-csv command.\n */\nexport type ChunkSlotProgress = {\n /** Absolute path of the file being processed by this worker. */\n filePath?: string;\n /** Number of rows processed so far in this file. */\n processed?: number;\n /** Optional total number of rows in the file (if known). */\n total?: number;\n};\n\n/**\n * Format a number safely for display.\n *\n * @param n - The number to format (or `undefined`).\n * @returns A localized string representation, or \"0\".\n */\nexport function fmtNum(n: number | undefined): string {\n return typeof n === 'number' ? n.toLocaleString() : '0';\n}\n\n/**\n * Draw a horizontal bar of length `width` filled to `pct` percent.\n *\n * @param pct - Percentage 0..100.\n * @param width - Number of characters in the bar.\n * @returns A string like \"████░░░░\".\n */\nexport function pctBar(pct: number, width = 40): string {\n const clamped = Math.max(0, Math.min(100, Math.floor(pct)));\n const filled = Math.floor((clamped / 100) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\n/**\n * Compute pool-wide progress values needed by headers.\n *\n * @param ctx - Dashboard context containing pool state, worker state, totals, etc.\n * @returns An object with `done`, `inProgress`, and `pct` properties.\n */\nexport function poolProgress<TTotals, TSlot extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlot>,\n): {\n /** Count of successfully completed files/tasks. */\n done: number;\n /** Count of currently in-progress files/tasks. */\n inProgress: number;\n /** Percentage of completion (0-100). */\n pct: number;\n} {\n const inProgress = [...ctx.workerState.values()].filter((s) => s.busy).length;\n const done = ctx.filesCompleted + ctx.filesFailed;\n const pct = ctx.filesTotal === 0 ? 100 : Math.floor((done / Math.max(1, ctx.filesTotal)) * 100);\n return { done, inProgress, pct };\n}\n\n/**\n * Compose the common header lines (title, pool stats, progress bar, throughput).\n *\n * @param ctx - Dashboard context.\n * @param extraLines - Optional extra lines (e.g., totals block).\n * @returns Header lines.\n */\nexport function makeHeader<TTotals, TSlot extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlot>,\n extraLines: string[] = [],\n): string[] {\n const { title, poolSize, cpuCount, filesTotal, filesCompleted, filesFailed, throughput } = ctx;\n const { inProgress, pct } = poolProgress(ctx);\n\n const lines: string[] = [\n `${colors.bold(title)} — ${poolSize} workers ${colors.dim(`(CPU avail: ${cpuCount})`)}`,\n `${colors.dim('Files')} ${fmtNum(filesTotal)} ${colors.dim(\n 'Completed',\n )} ${fmtNum(filesCompleted)} ${colors.dim('Failed')} ${\n filesFailed ? colors.red(fmtNum(filesFailed)) : fmtNum(filesFailed)\n } ${colors.dim('In-flight')} ${fmtNum(inProgress)}`,\n `[${pctBar(pct)}] ${pct}%`,\n ];\n\n if (throughput) {\n const jobsActive = throughput.jobsR10s > 0 || throughput.jobsR60s > 0;\n const perHour10 = Math.round(\n (jobsActive ? throughput.jobsR10s : throughput.r10s) * 3600,\n ).toLocaleString();\n const perHour60 = Math.round(\n (jobsActive ? throughput.jobsR60s : throughput.r60s) * 3600,\n ).toLocaleString();\n const unit = jobsActive ? 'rec' : 'files';\n const suffix =\n ctx.throughput?.successSoFar != null\n ? ` Newly uploaded: ${fmtNum(ctx.throughput.successSoFar)}`\n : '';\n lines.push(\n colors.cyan(`Throughput: ${perHour10} ${unit}/hr (1h: ${perHour60} ${unit}/hr)${suffix}`),\n );\n }\n\n return extraLines.length ? lines.concat(extraLines) : lines;\n}\n\n/**\n * Render per-worker rows with a compact progress bar and status badge.\n *\n * @param ctx - Dashboard context (slot progress type must have processed/total?).\n * @param getFileLabel - Optional: override how the filename is shown.\n * @returns Array of strings, each representing one worker row.\n */\nexport function makeWorkerRows<TTotals, TSlot extends Omit<ChunkSlotProgress, 'filePath'>>(\n ctx: CommonCtx<TTotals, TSlot>,\n getFileLabel: (file: string | null | undefined) => string = (file) =>\n file ? basename(file) : '-',\n): string[] {\n const miniWidth = 18;\n\n return [...ctx.workerState.entries()].map(([id, s]) => {\n const badge =\n s.lastLevel === 'error'\n ? colors.red('ERROR ')\n : s.lastLevel === 'warn'\n ? colors.yellow('WARN ')\n : s.busy\n ? colors.green('WORKING')\n : colors.dim('IDLE ');\n\n const fname = getFileLabel(s.file);\n const elapsed = s.startedAt ? `${Math.floor((Date.now() - s.startedAt) / 1000)}s` : '-';\n\n const processed = s.progress?.processed ?? 0;\n const total = s.progress?.total ?? 0;\n const pctw = total > 0 ? Math.floor((processed / total) * 100) : 0;\n const mini = total > 0 ? pctBar(pctw, miniWidth) : ' '.repeat(miniWidth);\n const miniTxt =\n total > 0\n ? `${processed.toLocaleString()}/${total.toLocaleString()} (${pctw}%)`\n : colors.dim('—');\n\n return ` [w${id}] ${badge} | ${fname} | ${elapsed} | [${mini}] ${miniTxt}`;\n });\n}\n","import type { ExportStatusMap, SlotPaths } from '@transcend-io/utils';\n\nimport { showCombinedLogs, type LogLocation } from './showCombinedLogs.js';\n\n/** Severity filter applied by the viewer. */\ntype ViewLevel = 'error' | 'warn' | 'all';\n\n/**\n * Options for {@link createExtraKeyHandler}.\n */\nexport type CreateExtraKeyHandlerOpts = {\n /**\n * Per-slot log file paths maintained by the runner; used to stream or export logs.\n */\n logsBySlot: SlotPaths;\n\n /**\n * Request an immediate dashboard repaint (e.g., after updating export status).\n */\n repaint: () => void;\n\n /**\n * Pause/unpause dashboard repainting. The handler pauses while a viewer is open\n * to prevent the dashboard from overwriting the viewer output, then resumes on exit.\n */\n setPaused: (p: boolean) => void;\n\n /**\n * Optional export manager to enable uppercase export keys:\n * - `E` (errors) • `W` (warnings) • `I` (info) • `A` (all)\n *\n * Provide this only if your command supports writing combined log files.\n */\n exportMgr?: {\n /** Destination directory for exported artifacts. */\n exportsDir: string;\n /**\n * Write a combined log file for the selected severity and return the absolute path.\n *\n * @param logs - Log paths to combine.\n * @param which - Severity selection.\n * @returns Absolute path to the written file.\n */\n exportCombinedLogs: (logs: SlotPaths, which: 'error' | 'warn' | 'info' | 'all') => string;\n };\n\n /**\n * Optional “Exports” status map. If provided, the handler updates timestamps\n * when exports are written so your dashboard panel can reflect “last saved” times.\n */\n exportStatus?: ExportStatusMap;\n\n /**\n * Optional custom key bindings for command-specific actions.\n * Each handler receives helpers to print messages and to update the exports panel.\n *\n * Example:\n * ```ts\n * custom: {\n * F: async ({ say, noteExport }) => {\n * const p = await writeFailingUpdatesCsv(...);\n * say(`Wrote failing updates to: ${p}`);\n * noteExport('failuresCsv', p);\n * }\n * }\n * ```\n */\n custom?: Record<\n string,\n (ctx: {\n /** Update {@link exportStatus} (if present) and repaint the dashboard. */\n noteExport: (slot: keyof ExportStatusMap, absPath: string) => void;\n /** Print a line to stdout, automatically newline-terminated. */\n say: (s: string) => void;\n }) => void | Promise<void>\n >;\n};\n\n/**\n * Create a keypress handler for interactive viewers/exports.\n * Shared handler for \"extra\" keyboard shortcuts used by the interactive dashboard.\n *\n * It wires:\n * - **Viewers (lowercase):** `e` (errors), `w` (warnings), `i` (info), `l` (all)\n * - **Exports (uppercase, optional):** `E` (errors), `W` (warnings), `I` (info), `A` (all)\n * - **Dismiss:** `Esc` or `Ctrl+]` exits a viewer and returns to the dashboard\n * - **Custom keys (optional):** Provide a `custom` map to handle command-specific bindings\n *\n * Usage (inside `runPool({... extraKeyHandler })`):\n * ```ts\n * extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n * createExtraKeyHandler({ logsBySlot, repaint, setPaused })\n * ```\n *\n * If you also want export hotkeys + an \"Exports\" panel:\n * ```ts\n * extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n * createExtraKeyHandler({\n * logsBySlot, repaint, setPaused,\n * exportMgr, // enables E/W/I/A\n * exportStatus, // keeps panel timestamps up to date\n * custom: { // optional, e.g. 'F' to export a CSV\n * F: async ({ say, noteExport }) => { ... }\n * }\n * })\n * ```\n *\n * @param opts - Configuration for viewers, exports, and custom keys.\n * @returns A `(buf: Buffer) => void` handler suitable for `process.stdin.on('data', ...)`.\n */\nexport function createExtraKeyHandler(opts: CreateExtraKeyHandlerOpts): (buf: Buffer) => void {\n const { logsBySlot, repaint, setPaused, exportMgr, exportStatus, custom } = opts;\n\n const say = (s: string): void => {\n process.stdout.write(`${s}\\n`);\n };\n\n /**\n * Record that an export was written and trigger a repaint so the dashboard’s\n * \"Exports\" panel shows the updated timestamp/path.\n *\n * @param slot - Slot name in {@link ExportStatusMap} (e.g., \"error\", \"warn\", etc.).\n * @param p - Absolute path to the exported file.\n */\n const noteExport = (slot: keyof ExportStatusMap, p: string): void => {\n const now = Date.now();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cur: any = exportStatus?.[slot] ?? { path: p };\n if (exportStatus) {\n exportStatus[slot] = {\n path: p || cur.path,\n savedAt: now,\n exported: true,\n };\n repaint();\n }\n };\n\n let viewing = false; // optional guard to prevent stacking viewers\n\n /**\n * Show an inline combined log viewer for the selected sources/level.\n * Pauses dashboard repaint to keep the viewer visible until the user exits.\n *\n * @param sources - Log sources to include (e.g., \"err\", \"warn\", \"info\").\n * @param level - Severity level to filter by (e.g., \"error\", \"warn\", \"all\").\n */\n const view = (sources: LogLocation[], level: ViewLevel): void => {\n if (viewing) return;\n viewing = true;\n setPaused(true);\n\n // optional UX: clear screen and show a hint\n process.stdout.write('\\x1b[2J\\x1b[H'); // clear+home\n process.stdout.write('Combined logs viewer (press Esc or Ctrl+] to return)\\n\\n');\n\n (async () => {\n try {\n await showCombinedLogs(logsBySlot, sources, level);\n // NOTE: do NOT unpause here; ESC will handle it.\n } catch {\n // If showCombinedLogs throws, recover and unpause\n viewing = false;\n setPaused(false);\n repaint();\n }\n })();\n };\n\n /**\n * Export combined logs (if an export manager was provided).\n *\n * @param which - Severity to export (e.g., \"error\", \"warn\", \"info\", \"all\").\n * @param label - Human-readable label for the export (e.g., \"error\", \"warn\").\n */\n const exportCombined = (which: 'error' | 'warn' | 'info' | 'all', label: string): void => {\n if (!exportMgr) return;\n try {\n const p = exportMgr.exportCombinedLogs(logsBySlot, which);\n say(`\\nWrote combined ${label} logs to: ${p}`);\n noteExport(which as keyof ExportStatusMap, p);\n } catch {\n say(`\\nFailed to write combined ${label} logs`);\n }\n };\n\n // The keypress handler the runner will attach to stdin.\n return (buf: Buffer): void => {\n const s = buf.toString('utf8');\n\n // Viewers (lowercase)\n if (s === 'e') {\n view(['err'], 'error');\n return;\n }\n if (s === 'w') {\n view(['warn', 'err'], 'warn');\n return;\n }\n if (s === 'i') {\n view(['info'], 'all');\n return;\n }\n if (s === 'l') {\n view(['out', 'err', 'structured'], 'all');\n return;\n }\n\n // Exports (uppercase) — enabled only when exportMgr is present\n if (s === 'E') {\n exportCombined('error', 'error');\n return;\n }\n if (s === 'W') {\n exportCombined('warn', 'warn');\n return;\n }\n if (s === 'I') {\n exportCombined('info', 'info');\n return;\n }\n if (s === 'A') {\n exportCombined('all', 'ALL');\n return;\n }\n\n // Command-specific bindings\n const fn = custom?.[s];\n if (fn) {\n fn({ noteExport, say });\n return;\n }\n\n // Exit a viewer (Esc / Ctrl+]) — resume dashboard\n if (s === '\\x1b' || s === '\\x1d') {\n viewing = false;\n setPaused(false);\n repaint();\n }\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createExtraKeyHandler-BO4lu0HO.mjs","names":[],"sources":["../src/lib/pooling/showCombinedLogs.ts","../src/lib/pooling/keymap.ts","../src/lib/pooling/replayFileTailToStdout.ts","../src/lib/pooling/workerIds.ts","../src/lib/pooling/installInteractiveSwitcher.ts","../src/lib/pooling/dashboardPlugin.ts","../src/lib/pooling/uiPlugins.ts","../src/lib/pooling/createExtraKeyHandler.ts"],"sourcesContent":["/* eslint-disable no-continue, no-control-regex */\nimport { readFileSync } from 'node:fs';\n\nimport type { WorkerLogPaths } from '@transcend-io/utils';\n\n/**\n * Log locations\n */\nexport type LogLocation = 'out' | 'err' | 'structured' | 'warn' | 'info';\n\n/**\n * Which logs to show in the combined output.\n * Can include 'out' (stdout), 'err' (stderr), 'structured' (\n */\nexport type WhichLogs = Array<LogLocation>;\n\n/**\n * Show combined logs from all worker processes.\n *\n * @param slotLogPaths - Map of worker IDs to their log file paths.\n * @param whichList - one or more sources to include (e.g., ['err','out'])\n * @param filterLevel - 'error', 'warn', or 'all' to filter log levels.\n */\nexport function showCombinedLogs(\n slotLogPaths: Map<number, WorkerLogPaths | undefined>,\n whichList: WhichLogs,\n filterLevel: 'error' | 'warn' | 'all',\n): void {\n process.stdout.write('\\x1b[2J\\x1b[H');\n\n const isError = (t: string): boolean =>\n /\\b(ERROR|uncaughtException|unhandledRejection)\\b/i.test(t);\n const isWarnTag = (t: string): boolean => /\\b(WARN|WARNING)\\b/i.test(t);\n\n const lines: string[] = [];\n\n for (const [, paths] of slotLogPaths) {\n if (!paths) continue;\n\n const files: Array<{\n /** Absolute file path to read from */\n path: string;\n /** Source type for this file, used for classification */\n src: LogLocation;\n }> = [];\n for (const which of whichList) {\n if (which === 'out' && paths.outPath) {\n files.push({ path: paths.outPath, src: 'out' });\n }\n if (which === 'err' && paths.errPath) {\n files.push({ path: paths.errPath, src: 'err' });\n }\n if (which === 'structured' && paths.structuredPath) {\n files.push({ path: paths.structuredPath, src: 'structured' });\n }\n if (paths.warnPath && which === 'warn') {\n files.push({ path: paths.warnPath, src: 'warn' });\n }\n if (paths.infoPath && which === 'info') {\n files.push({ path: paths.infoPath, src: 'info' });\n }\n }\n\n for (const { path, src } of files) {\n let text = '';\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n continue;\n }\n\n for (const ln of text.split('\\n')) {\n if (!ln) continue;\n\n const clean = ln.replace(/\\x1B\\[[0-9;]*m/g, '');\n\n if (filterLevel === 'all') {\n lines.push(ln);\n continue;\n }\n\n if (filterLevel === 'error') {\n if (isError(clean)) lines.push(ln);\n continue;\n }\n\n // filterLevel === 'warn'\n // Accept:\n // - explicit WARN tag anywhere\n // - OR lines from stderr that are NOT explicit errors (many warn libs print to stderr)\n // - OR lines containing the word \"warning\" (common in some libs)\n if (isWarnTag(clean) || (src === 'err' && !isError(clean))) {\n lines.push(ln);\n continue;\n }\n }\n }\n }\n\n // simple time-sort; each worker often prefixes ISO timestamps\n lines.sort((a, b) => {\n const ta = a.match(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)?.[0] ?? '';\n const tb = b.match(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)?.[0] ?? '';\n return ta.localeCompare(tb);\n });\n\n process.stdout.write(`${lines.join('\\n')}\\n`);\n process.stdout.write('\\nPress Esc/Ctrl+] to return to dashboard.\\n');\n}\n/* eslint-enable no-continue, no-control-regex */\n","import type * as readline from 'node:readline';\n\n/**\n * Map a key press to an action in the interactive dashboard.\n */\nexport type Action =\n | {\n /** Indicates attaching to a session by id. */\n type: 'ATTACH';\n /** The id of the session to attach to. */\n id: number;\n }\n | {\n /** Indicates cycling through sessions. */\n type: 'CYCLE';\n /** The direction to cycle: +1 for next, -1 for previous. */\n delta: number;\n }\n | {\n /** Indicates detaching from the current session. */\n type: 'DETACH';\n }\n | {\n /** Indicates the Ctrl+C key combination was pressed. */\n type: 'CTRL_C';\n }\n | {\n /** Indicates the Ctrl+D key combination was pressed. */\n type: 'CTRL_D';\n }\n | {\n /** Indicates quitting the dashboard. */\n type: 'QUIT';\n }\n | {\n /** Forwards an unhandled key sequence. */\n type: 'FORWARD';\n /** The key sequence to forward. */\n sequence: string;\n };\n\n/**\n * Map a key press to an action in the interactive dashboard.\n *\n * @param str - The string representation of the key press.\n * @param key - The key object containing details about the key press.\n * @param mode - The current mode of the dashboard, either 'dashboard' or 'attached'.\n * @returns An Action object representing the mapped action, or null if no action is mapped.\n */\nexport function keymap(\n str: string,\n key: readline.Key,\n mode: 'dashboard' | 'attached',\n): Action | null {\n if (key.ctrl && key.name === 'c') return { type: 'CTRL_C' };\n\n if (mode === 'dashboard') {\n if (key.name && /^[0-9]$/.test(key.name)) {\n return { type: 'ATTACH', id: Number(key.name) };\n }\n if (key.name === 'tab' && !key.shift) return { type: 'CYCLE', delta: +1 };\n if (key.name === 'tab' && key.shift) return { type: 'CYCLE', delta: -1 };\n if (key.name === 'q') return { type: 'QUIT' };\n return null;\n }\n\n // attached\n if (key.name === 'escape' || (key.ctrl && key.name === ']')) {\n return { type: 'DETACH' };\n }\n if (key.ctrl && key.name === 'd') return { type: 'CTRL_D' };\n\n const sequence = key.sequence ?? str ?? '';\n return sequence ? { type: 'FORWARD', sequence } : null;\n}\n","import { createReadStream, statSync } from 'node:fs';\n\n/**\n * Replay the tail of a file to stdout.\n *\n * @param path - The absolute path to the file to read.\n * @param maxBytes - The maximum number of bytes to read from the end of the file.\n * @param write - A function to write the output to stdout.\n */\nexport async function replayFileTailToStdout(\n path: string,\n maxBytes: number,\n write: (s: string) => void,\n): Promise<void> {\n await new Promise<void>((resolve) => {\n try {\n const st = statSync(path);\n const start = Math.max(0, st.size - maxBytes);\n const stream = createReadStream(path, { start, encoding: 'utf8' });\n stream.on('data', (chunk) => write(chunk as string));\n stream.on('end', () => resolve());\n stream.on('error', () => resolve());\n } catch {\n resolve();\n }\n });\n}\n","import type { ChildProcess } from 'node:child_process';\n\n/**\n * Get the sorted list of worker IDs from a map of ChildProcess instances.\n *\n * @param m - Map of worker IDs to ChildProcess instances.\n * @returns Sorted array of worker IDs.\n */\nexport function getWorkerIds(m: Map<number, ChildProcess>): number[] {\n return [...m.keys()].sort((a, b) => a - b);\n}\n\n/**\n * Cycles through an array of numeric IDs, returning the next ID based on a delta.\n *\n * If the `current` ID is not provided or not found in the array, the first ID is used as the starting point.\n * The function then moves forward or backward in the array by `delta` positions, wrapping around if necessary.\n *\n * @param ids - Array of numeric IDs to cycle through.\n * @param current - The current ID to start cycling from. If `null` or not found, starts from the first ID.\n * @param delta - The number of positions to move forward (positive) or backward (negative) in the array.\n * @returns The next ID in the array after cycling, or `null` if the array is empty.\n */\nexport function cycleWorkers(ids: number[], current: number | null, delta: number): number | null {\n if (!ids.length) return null;\n const cur = current == null ? ids[0] : current;\n let i = ids.indexOf(cur);\n if (i === -1) i = 0;\n i = (i + delta + ids.length) % ids.length;\n return ids[i]!;\n}\n","import type { ChildProcess } from 'node:child_process';\nimport * as readline from 'node:readline';\n\nimport type { WorkerLogPaths } from '@transcend-io/utils';\n\nimport { DEBUG } from '../../constants.js';\nimport { keymap } from './keymap.js';\nimport { replayFileTailToStdout } from './replayFileTailToStdout.js';\nimport type { WhichLogs } from './showCombinedLogs.js';\nimport { cycleWorkers, getWorkerIds } from './workerIds.js';\n\n/**\n * Key action types for the interactive switcher\n */\nexport type InteractiveDashboardMode = 'dashboard' | 'attached';\n\nexport interface SwitcherPorts {\n /** Standard input stream */\n stdin: NodeJS.ReadStream;\n /** Standard output stream */\n stdout: NodeJS.WriteStream;\n /** Standard error stream */\n stderr: NodeJS.WriteStream;\n}\n\n/**\n * Install an interactive switcher for managing worker processes.\n *\n * @param opts - Options for the switcher\n * @returns A cleanup function to remove the switcher\n */\nexport function installInteractiveSwitcher(opts: {\n /** Registry of live workers by id */\n workers: Map<number, ChildProcess>;\n /** Hooks */\n onAttach?: (id: number) => void;\n /** Optional detach handler */\n onDetach?: () => void;\n /** Optional Ctrl+C handler for parent graceful shutdown in dashboard */\n onCtrlC?: () => void; // parent graceful shutdown in dashboard\n /** Provide log paths so we can replay the tail on attach */\n getLogPaths?: (id: number) => WorkerLogPaths | undefined;\n /** How many bytes to replay from the end of each file (default 200 KB) */\n replayBytes?: number;\n /** Which logs to replay first (default ['out','err']) */\n replayWhich?: WhichLogs;\n /** Print a small banner/clear screen before replaying (optional) */\n onEnterAttachScreen?: (id: number) => void;\n /** Optional stdio ports for testing; defaults to process stdio */\n ports?: SwitcherPorts;\n}): () => void {\n const {\n workers,\n onAttach,\n onDetach,\n onCtrlC,\n getLogPaths,\n replayBytes = 200 * 1024,\n replayWhich = ['out', 'err'],\n onEnterAttachScreen,\n ports,\n } = opts;\n\n const stdin = ports?.stdin ?? process.stdin;\n const stdout = ports?.stdout ?? process.stdout;\n const stderr = ports?.stderr ?? process.stderr;\n\n const d = (...a: unknown[]): void => {\n if (DEBUG) {\n try {\n (ports?.stderr ?? process.stderr).write(`[keys] ${a.map(String).join(' ')}\\n`);\n } catch {\n // noop\n }\n }\n };\n\n if (!stdin.isTTY) {\n // Not a TTY; return a no-op cleanup\n return () => {\n // noop\n };\n }\n\n readline.emitKeypressEvents(stdin);\n stdin.setRawMode?.(true);\n\n let mode: InteractiveDashboardMode = 'dashboard';\n let focus: number | null = null;\n\n // live mirroring handlers while attached\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let outHandler: ((chunk: any) => void) | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let errHandler: ((chunk: any) => void) | null = null;\n\n /**\n * Cycle through worker IDs, wrapping around.\n *\n * @param id - The current worker ID to start cycling from.\n * @returns The next worker ID after cycling, or null if no workers are available.\n */\n async function replayLogs(id: number): Promise<void> {\n if (!getLogPaths) return;\n const paths = getLogPaths(id);\n if (!paths) return;\n\n const toReplay: string[] = [];\n for (const which of replayWhich) {\n if (which === 'out') toReplay.push(paths.outPath);\n if (which === 'err') toReplay.push(paths.errPath);\n if (which === 'structured') toReplay.push(paths.structuredPath);\n }\n\n if (toReplay.length) {\n stdout.write('\\n------------ replay ------------\\n');\n for (const p of toReplay) {\n stdout.write(`\\n--- ${p} (last ~${Math.floor(replayBytes / 1024)}KB) ---\\n`);\n await replayFileTailToStdout(p, replayBytes, (s) => stdout.write(s));\n }\n stdout.write('\\n--------------------------------\\n\\n');\n }\n }\n\n const attach = async (id: number): Promise<void> => {\n d('attach()', `id=${id}`); // at function entry\n\n const w = workers.get(id);\n if (!w) return;\n\n // Detach any previous focus\n if (mode === 'attached') detach();\n\n mode = 'attached';\n focus = id;\n\n // UX: clear + banner\n onEnterAttachScreen?.(id);\n\n onAttach?.(id); // prints “Attached to worker …” and clears\n await replayLogs(id); // now the tail stays visible\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outHandler = (chunk: any) => stdout.write(chunk);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errHandler = (chunk: any) => stderr.write(chunk);\n w.stdout?.on('data', outHandler);\n w.stderr?.on('data', errHandler);\n\n // auto-detach if child exits\n const onExit = (): void => {\n if (focus === id) detach();\n };\n w.once('exit', onExit);\n };\n\n const detach = (): void => {\n d('detach()', `id=${focus}`); // at function entry\n\n if (focus == null) return;\n const id = focus;\n const w = workers.get(id);\n if (w) {\n if (outHandler) w.stdout?.off('data', outHandler);\n if (errHandler) w.stderr?.off('data', errHandler);\n }\n outHandler = null;\n errHandler = null;\n focus = null;\n mode = 'dashboard';\n onDetach?.();\n };\n\n const onKey = (str: string, key: readline.Key): void => {\n d(\n 'keypress',\n JSON.stringify({\n str,\n name: key.name,\n seq: key.sequence,\n ctrl: key.ctrl,\n meta: key.meta,\n shift: key.shift,\n mode,\n }),\n );\n const act = keymap(str, key, mode);\n d('mapped', JSON.stringify(act));\n\n if (!act) return;\n\n // eslint-disable-next-line default-case\n switch (act.type) {\n case 'CTRL_C': {\n d('CTRL_C');\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.kill('SIGINT');\n } catch {\n // noop\n }\n // optional: auto-detach so second Ctrl+C exits parent\n detach();\n return;\n }\n onCtrlC?.();\n return;\n }\n\n case 'ATTACH': {\n d('ATTACH', `id=${act.id}`, `has=${workers.has(act.id)}`);\n\n if (mode !== 'dashboard') return;\n // eslint-disable-next-line no-void\n if (workers.has(act.id)) void attach(act.id);\n return;\n }\n\n case 'CYCLE': {\n d('CYCLE', `delta=${act.delta}`);\n if (mode !== 'dashboard') return;\n const next = cycleWorkers(getWorkerIds(workers), focus, act.delta);\n // eslint-disable-next-line no-void\n if (next != null) void attach(next);\n return;\n }\n\n case 'QUIT': {\n if (mode !== 'dashboard') return;\n onCtrlC?.();\n return;\n }\n\n case 'DETACH': {\n d('DETACH');\n if (mode === 'attached') detach();\n return;\n }\n\n case 'CTRL_D': {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.end();\n } catch {\n // noop\n }\n }\n return;\n }\n\n case 'FORWARD': {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.write(act.sequence);\n } catch {\n // noop\n }\n }\n }\n }\n };\n\n // Raw bytes fallback (usually not hit because keypress handles it)\n const onData = (chunk: Buffer): void => {\n if (mode === 'attached' && focus != null) {\n const w = workers.get(focus);\n try {\n w?.stdin?.write(chunk);\n } catch {\n // noop\n }\n }\n };\n\n const cleanup = (): void => {\n stdin.off('keypress', onKey);\n stdin.off('data', onData);\n stdin.setRawMode?.(false);\n stdout.write('\\x1b[?25h');\n };\n\n stdin.on('keypress', onKey);\n stdin.on('data', onData);\n\n return cleanup;\n}\n","// lib/pooling/dashboardPlugin.ts\nimport * as readline from 'node:readline';\n\nimport type { ObjByString } from '@transcend-io/type-utils';\nimport type { SlotState } from '@transcend-io/utils';\nimport colors from 'colors';\n\n/**\n * A dashboard plugin defines how to render the worker pool UI.\n * Commands can supply a plugin to customize:\n * - The header block (summary stats, title, etc.)\n * - Per-worker rows (one line per worker slot)\n * - Optional extras (artifact exports, breakdowns, footers)\n *\n * @template TTotals - The shape of the aggregate totals object maintained by the command.\n */\nexport interface DashboardPlugin<TTotals, TSlotState extends ObjByString> {\n /**\n * Render the header block of the dashboard.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one line in the header.\n */\n renderHeader: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n\n /**\n * Render per-worker rows, usually one line per worker slot.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one row in the workers section.\n */\n renderWorkers: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n\n /**\n * Render any optional extra blocks that appear after the worker rows.\n * Useful for printing export paths, aggregated metrics, breakdowns, etc.\n *\n * @param ctx - Context with pool/worker state, totals, and metadata.\n * @returns An array of strings, each representing one additional line.\n */\n renderExtras?: (ctx: CommonCtx<TTotals, TSlotState>) => string[];\n}\n\n/**\n * Shared context object passed into all render methods of a {@link DashboardPlugin}.\n *\n * @template TTotals - The shape of the aggregate totals object maintained by the command.\n */\nexport type CommonCtx<TTotals, TSlotState extends ObjByString> = {\n /** Human-readable title for the dashboard (e.g., \"Parallel uploader\"). */\n title: string;\n\n /** Number of worker processes spawned in the pool. */\n poolSize: number;\n\n /** Logical CPU count, included for informational display. */\n cpuCount: number;\n\n /** Total number of \"files\" or logical units the command expects to process. */\n filesTotal: number;\n\n /** Count of successfully completed files/tasks. */\n filesCompleted: number;\n\n /** Count of failed files/tasks. */\n filesFailed: number;\n\n /**\n * State of each worker slot, keyed by worker id.\n * Includes busy flag, file label, start time, last log badge, and progress.\n */\n workerState: Map<number, SlotState<TSlotState>>;\n\n /**\n * Aggregate totals maintained by the command’s hook logic.\n * Domain-specific metrics (e.g., rows uploaded, bytes processed) can be surfaced here.\n */\n totals: TTotals;\n\n /**\n * Throughput metrics tracked by the runner:\n * - successSoFar: convenience alias for completed count\n * - r10s: completions/sec averaged over last 10s\n * - r60s: completions/sec averaged over last 60s\n */\n throughput: {\n /** Cumulative count of successful completions so far. */\n successSoFar: number;\n /** Recent file-level throughput rate over the last 10 seconds. */\n r10s: number;\n /** Recent file-level throughput rate over the last 60 seconds. */\n r60s: number;\n /** Recent job/record-level throughput rate over the last 10 seconds. */\n jobsR10s: number;\n /** Recent job/record-level throughput rate over the last 60 seconds. */\n jobsR60s: number;\n };\n\n /** True when the pool has fully drained and all workers have exited. */\n final: boolean;\n\n /**\n * Optional export status payload provided by the command.\n * Useful for rendering artifact paths or \"latest export\" summaries.\n */\n exportStatus?: Record<string, unknown>;\n};\n\n/** The most recently rendered frame, cached to suppress flicker from duplicate renders. */\nlet lastFrame = '';\n\n/**\n * Generate the hotkeys hint string that appears at the bottom of the dashboard.\n *\n * @param poolSize - The number of worker slots in the pool.\n * @param final - Whether the run has completed.\n * @returns A dimmed string listing the supported hotkeys for attach/detach/quit.\n */\nexport const hotkeysHint = (poolSize: number, final: boolean): string => {\n const maxDigit = Math.min(poolSize - 1, 9);\n const digitRange = poolSize <= 1 ? '0' : `0-${maxDigit}`;\n const extra = poolSize > 10 ? ' (Tab/Shift+Tab for ≥10)' : '';\n return final\n ? colors.dim(\n 'Run complete — digits to view logs • Tab/Shift+Tab cycle • Esc/Ctrl+] detach • q to quit',\n )\n : colors.dim(\n `Hotkeys: [${digitRange}] attach${extra} • e=errors • w=warnings • i=info • l=logs • ` +\n 'Tab/Shift+Tab • Esc/Ctrl+] detach • Ctrl+C exit',\n );\n};\n\n/**\n * Render the dashboard using a supplied {@link DashboardPlugin}.\n *\n * The frame is composed of:\n * - Header lines\n * - A blank separator\n * - Worker rows\n * - A blank separator\n * - Hotkeys hint\n * - Optional extras (if plugin supplies them)\n *\n * Optimizations:\n * - Suppresses re-renders if the frame is identical to the previous frame (flicker-free).\n * - Hides the terminal cursor during live updates, restoring it when final.\n *\n * @param ctx - Shared context containing pool state, worker state, totals, throughput, etc.\n * @param plugin - The plugin that defines how to render the header, workers, and optional extras.\n * @param viewerMode - If true, renders in viewer mode (no ability to switch between files).\n */\nexport function dashboardPlugin<TTotals, TSlotState extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlotState>,\n plugin: DashboardPlugin<TTotals, TSlotState>,\n viewerMode = false,\n): void {\n const frame = [\n ...plugin.renderHeader(ctx),\n '',\n ...plugin.renderWorkers(ctx),\n ...(viewerMode ? [] : ['', hotkeysHint(ctx.poolSize, ctx.final)]),\n ...(plugin.renderExtras ? [''].concat(plugin.renderExtras(ctx)) : []),\n ].join('\\n');\n\n // Skip duplicate renders during live runs to avoid flicker.\n if (!ctx.final && frame === lastFrame) return;\n lastFrame = frame;\n\n if (!ctx.final) {\n // Hide cursor and repaint in place\n process.stdout.write('\\x1b[?25l');\n readline.cursorTo(process.stdout, 0, 0);\n readline.clearScreenDown(process.stdout);\n } else {\n // Restore cursor on final render\n process.stdout.write('\\x1b[?25h');\n }\n process.stdout.write(`${frame}\\n`);\n}\n","import { basename } from 'node:path';\n\nimport type { ObjByString } from '@transcend-io/type-utils';\nimport colors from 'colors';\n\nimport type { CommonCtx } from './dashboardPlugin.js';\n\n/**\n * Progress snapshot for a worker slot in the chunk-csv command.\n */\nexport type ChunkSlotProgress = {\n /** Absolute path of the file being processed by this worker. */\n filePath?: string;\n /** Number of rows processed so far in this file. */\n processed?: number;\n /** Optional total number of rows in the file (if known). */\n total?: number;\n};\n\n/**\n * Format a number safely for display.\n *\n * @param n - The number to format (or `undefined`).\n * @returns A localized string representation, or \"0\".\n */\nexport function fmtNum(n: number | undefined): string {\n return typeof n === 'number' ? n.toLocaleString() : '0';\n}\n\n/**\n * Draw a horizontal bar of length `width` filled to `pct` percent.\n *\n * @param pct - Percentage 0..100.\n * @param width - Number of characters in the bar.\n * @returns A string like \"████░░░░\".\n */\nexport function pctBar(pct: number, width = 40): string {\n const clamped = Math.max(0, Math.min(100, Math.floor(pct)));\n const filled = Math.floor((clamped / 100) * width);\n return '█'.repeat(filled) + '░'.repeat(width - filled);\n}\n\n/**\n * Compute pool-wide progress values needed by headers.\n *\n * @param ctx - Dashboard context containing pool state, worker state, totals, etc.\n * @returns An object with `done`, `inProgress`, and `pct` properties.\n */\nexport function poolProgress<TTotals, TSlot extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlot>,\n): {\n /** Count of successfully completed files/tasks. */\n done: number;\n /** Count of currently in-progress files/tasks. */\n inProgress: number;\n /** Percentage of completion (0-100). */\n pct: number;\n} {\n const inProgress = [...ctx.workerState.values()].filter((s) => s.busy).length;\n const done = ctx.filesCompleted + ctx.filesFailed;\n const pct = ctx.filesTotal === 0 ? 100 : Math.floor((done / Math.max(1, ctx.filesTotal)) * 100);\n return { done, inProgress, pct };\n}\n\n/**\n * Compose the common header lines (title, pool stats, progress bar, throughput).\n *\n * @param ctx - Dashboard context.\n * @param extraLines - Optional extra lines (e.g., totals block).\n * @returns Header lines.\n */\nexport function makeHeader<TTotals, TSlot extends ObjByString>(\n ctx: CommonCtx<TTotals, TSlot>,\n extraLines: string[] = [],\n): string[] {\n const { title, poolSize, cpuCount, filesTotal, filesCompleted, filesFailed, throughput } = ctx;\n const { inProgress, pct } = poolProgress(ctx);\n\n const lines: string[] = [\n `${colors.bold(title)} — ${poolSize} workers ${colors.dim(`(CPU avail: ${cpuCount})`)}`,\n `${colors.dim('Files')} ${fmtNum(filesTotal)} ${colors.dim(\n 'Completed',\n )} ${fmtNum(filesCompleted)} ${colors.dim('Failed')} ${\n filesFailed ? colors.red(fmtNum(filesFailed)) : fmtNum(filesFailed)\n } ${colors.dim('In-flight')} ${fmtNum(inProgress)}`,\n `[${pctBar(pct)}] ${pct}%`,\n ];\n\n if (throughput) {\n const jobsActive = throughput.jobsR10s > 0 || throughput.jobsR60s > 0;\n const perHour10 = Math.round(\n (jobsActive ? throughput.jobsR10s : throughput.r10s) * 3600,\n ).toLocaleString();\n const perHour60 = Math.round(\n (jobsActive ? throughput.jobsR60s : throughput.r60s) * 3600,\n ).toLocaleString();\n const unit = jobsActive ? 'rec' : 'files';\n const suffix =\n ctx.throughput?.successSoFar != null\n ? ` Newly uploaded: ${fmtNum(ctx.throughput.successSoFar)}`\n : '';\n lines.push(\n colors.cyan(`Throughput: ${perHour10} ${unit}/hr (1h: ${perHour60} ${unit}/hr)${suffix}`),\n );\n }\n\n return extraLines.length ? lines.concat(extraLines) : lines;\n}\n\n/**\n * Render per-worker rows with a compact progress bar and status badge.\n *\n * @param ctx - Dashboard context (slot progress type must have processed/total?).\n * @param getFileLabel - Optional: override how the filename is shown.\n * @returns Array of strings, each representing one worker row.\n */\nexport function makeWorkerRows<TTotals, TSlot extends Omit<ChunkSlotProgress, 'filePath'>>(\n ctx: CommonCtx<TTotals, TSlot>,\n getFileLabel: (file: string | null | undefined) => string = (file) =>\n file ? basename(file) : '-',\n): string[] {\n const miniWidth = 18;\n\n return [...ctx.workerState.entries()].map(([id, s]) => {\n const badge =\n s.lastLevel === 'error'\n ? colors.red('ERROR ')\n : s.lastLevel === 'warn'\n ? colors.yellow('WARN ')\n : s.busy\n ? colors.green('WORKING')\n : colors.dim('IDLE ');\n\n const fname = getFileLabel(s.file);\n const elapsed = s.startedAt ? `${Math.floor((Date.now() - s.startedAt) / 1000)}s` : '-';\n\n const processed = s.progress?.processed ?? 0;\n const total = s.progress?.total ?? 0;\n const pctw = total > 0 ? Math.floor((processed / total) * 100) : 0;\n const mini = total > 0 ? pctBar(pctw, miniWidth) : ' '.repeat(miniWidth);\n const miniTxt =\n total > 0\n ? `${processed.toLocaleString()}/${total.toLocaleString()} (${pctw}%)`\n : colors.dim('—');\n\n return ` [w${id}] ${badge} | ${fname} | ${elapsed} | [${mini}] ${miniTxt}`;\n });\n}\n","import type { ExportStatusMap, SlotPaths } from '@transcend-io/utils';\n\nimport { showCombinedLogs, type LogLocation } from './showCombinedLogs.js';\n\n/** Severity filter applied by the viewer. */\ntype ViewLevel = 'error' | 'warn' | 'all';\n\n/**\n * Options for {@link createExtraKeyHandler}.\n */\nexport type CreateExtraKeyHandlerOpts = {\n /**\n * Per-slot log file paths maintained by the runner; used to stream or export logs.\n */\n logsBySlot: SlotPaths;\n\n /**\n * Request an immediate dashboard repaint (e.g., after updating export status).\n */\n repaint: () => void;\n\n /**\n * Pause/unpause dashboard repainting. The handler pauses while a viewer is open\n * to prevent the dashboard from overwriting the viewer output, then resumes on exit.\n */\n setPaused: (p: boolean) => void;\n\n /**\n * Optional export manager to enable uppercase export keys:\n * - `E` (errors) • `W` (warnings) • `I` (info) • `A` (all)\n *\n * Provide this only if your command supports writing combined log files.\n */\n exportMgr?: {\n /** Destination directory for exported artifacts. */\n exportsDir: string;\n /**\n * Write a combined log file for the selected severity and return the absolute path.\n *\n * @param logs - Log paths to combine.\n * @param which - Severity selection.\n * @returns Absolute path to the written file.\n */\n exportCombinedLogs: (logs: SlotPaths, which: 'error' | 'warn' | 'info' | 'all') => string;\n };\n\n /**\n * Optional “Exports” status map. If provided, the handler updates timestamps\n * when exports are written so your dashboard panel can reflect “last saved” times.\n */\n exportStatus?: ExportStatusMap;\n\n /**\n * Optional custom key bindings for command-specific actions.\n * Each handler receives helpers to print messages and to update the exports panel.\n *\n * Example:\n * ```ts\n * custom: {\n * F: async ({ say, noteExport }) => {\n * const p = await writeFailingUpdatesCsv(...);\n * say(`Wrote failing updates to: ${p}`);\n * noteExport('failuresCsv', p);\n * }\n * }\n * ```\n */\n custom?: Record<\n string,\n (ctx: {\n /** Update {@link exportStatus} (if present) and repaint the dashboard. */\n noteExport: (slot: keyof ExportStatusMap, absPath: string) => void;\n /** Print a line to stdout, automatically newline-terminated. */\n say: (s: string) => void;\n }) => void | Promise<void>\n >;\n};\n\n/**\n * Create a keypress handler for interactive viewers/exports.\n * Shared handler for \"extra\" keyboard shortcuts used by the interactive dashboard.\n *\n * It wires:\n * - **Viewers (lowercase):** `e` (errors), `w` (warnings), `i` (info), `l` (all)\n * - **Exports (uppercase, optional):** `E` (errors), `W` (warnings), `I` (info), `A` (all)\n * - **Dismiss:** `Esc` or `Ctrl+]` exits a viewer and returns to the dashboard\n * - **Custom keys (optional):** Provide a `custom` map to handle command-specific bindings\n *\n * Usage (inside `runPool({... extraKeyHandler })`):\n * ```ts\n * extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n * createExtraKeyHandler({ logsBySlot, repaint, setPaused })\n * ```\n *\n * If you also want export hotkeys + an \"Exports\" panel:\n * ```ts\n * extraKeyHandler: ({ logsBySlot, repaint, setPaused }) =>\n * createExtraKeyHandler({\n * logsBySlot, repaint, setPaused,\n * exportMgr, // enables E/W/I/A\n * exportStatus, // keeps panel timestamps up to date\n * custom: { // optional, e.g. 'F' to export a CSV\n * F: async ({ say, noteExport }) => { ... }\n * }\n * })\n * ```\n *\n * @param opts - Configuration for viewers, exports, and custom keys.\n * @returns A `(buf: Buffer) => void` handler suitable for `process.stdin.on('data', ...)`.\n */\nexport function createExtraKeyHandler(opts: CreateExtraKeyHandlerOpts): (buf: Buffer) => void {\n const { logsBySlot, repaint, setPaused, exportMgr, exportStatus, custom } = opts;\n\n const say = (s: string): void => {\n process.stdout.write(`${s}\\n`);\n };\n\n /**\n * Record that an export was written and trigger a repaint so the dashboard’s\n * \"Exports\" panel shows the updated timestamp/path.\n *\n * @param slot - Slot name in {@link ExportStatusMap} (e.g., \"error\", \"warn\", etc.).\n * @param p - Absolute path to the exported file.\n */\n const noteExport = (slot: keyof ExportStatusMap, p: string): void => {\n const now = Date.now();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cur: any = exportStatus?.[slot] ?? { path: p };\n if (exportStatus) {\n exportStatus[slot] = {\n path: p || cur.path,\n savedAt: now,\n exported: true,\n };\n repaint();\n }\n };\n\n let viewing = false; // optional guard to prevent stacking viewers\n\n /**\n * Show an inline combined log viewer for the selected sources/level.\n * Pauses dashboard repaint to keep the viewer visible until the user exits.\n *\n * @param sources - Log sources to include (e.g., \"err\", \"warn\", \"info\").\n * @param level - Severity level to filter by (e.g., \"error\", \"warn\", \"all\").\n */\n const view = (sources: LogLocation[], level: ViewLevel): void => {\n if (viewing) return;\n viewing = true;\n setPaused(true);\n\n // optional UX: clear screen and show a hint\n process.stdout.write('\\x1b[2J\\x1b[H'); // clear+home\n process.stdout.write('Combined logs viewer (press Esc or Ctrl+] to return)\\n\\n');\n\n (async () => {\n try {\n await showCombinedLogs(logsBySlot, sources, level);\n // NOTE: do NOT unpause here; ESC will handle it.\n } catch {\n // If showCombinedLogs throws, recover and unpause\n viewing = false;\n setPaused(false);\n repaint();\n }\n })();\n };\n\n /**\n * Export combined logs (if an export manager was provided).\n *\n * @param which - Severity to export (e.g., \"error\", \"warn\", \"info\", \"all\").\n * @param label - Human-readable label for the export (e.g., \"error\", \"warn\").\n */\n const exportCombined = (which: 'error' | 'warn' | 'info' | 'all', label: string): void => {\n if (!exportMgr) return;\n try {\n const p = exportMgr.exportCombinedLogs(logsBySlot, which);\n say(`\\nWrote combined ${label} logs to: ${p}`);\n noteExport(which as keyof ExportStatusMap, p);\n } catch {\n say(`\\nFailed to write combined ${label} logs`);\n }\n };\n\n // The keypress handler the runner will attach to stdin.\n return (buf: Buffer): void => {\n const s = buf.toString('utf8');\n\n // Viewers (lowercase)\n if (s === 'e') {\n view(['err'], 'error');\n return;\n }\n if (s === 'w') {\n view(['warn', 'err'], 'warn');\n return;\n }\n if (s === 'i') {\n view(['info'], 'all');\n return;\n }\n if (s === 'l') {\n view(['out', 'err', 'structured'], 'all');\n return;\n }\n\n // Exports (uppercase) — enabled only when exportMgr is present\n if (s === 'E') {\n exportCombined('error', 'error');\n return;\n }\n if (s === 'W') {\n exportCombined('warn', 'warn');\n return;\n }\n if (s === 'I') {\n exportCombined('info', 'info');\n return;\n }\n if (s === 'A') {\n exportCombined('all', 'ALL');\n return;\n }\n\n // Command-specific bindings\n const fn = custom?.[s];\n if (fn) {\n fn({ noteExport, say });\n return;\n }\n\n // Exit a viewer (Esc / Ctrl+]) — resume dashboard\n if (s === '\\x1b' || s === '\\x1d') {\n viewing = false;\n setPaused(false);\n repaint();\n }\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  import{union as e}from"lodash-es";function t(t,{adTechPurposes:n=[`SaleOfInfo`],serviceToTitle:r,serviceToSupportedIntegration:i}){let a=[],o=[],s={};t.forEach(t=>{let{service:r,attributes:i=[]}=t;if(!r||r===`internalService`)return;let c=i.find(e=>e.key===`Found on Domain`);c&&(s[r]||(s[r]=[]),s[r].push(...c.values.map(e=>e.replace(`https://`,``).replace(`http://`,``))),s[r]=[...new Set(s[r])]),e(t.trackingPurposes,n).length>0?(o.push(r),a.includes(r)&&(a=a.filter(e=>e!==r))):o.includes(r)||a.push(r)});let c=[...new Set(o)].map(e=>({title:r[e],...i[e]?{integrationName:e}:{integrationName:`promptAPerson`,"outer-type":e},attributes:[{key:`Tech Type`,values:[`Ad Tech`]},{key:`Found On Domain`,values:s[e]||[]}]}));return{siteTechDataSilos:[...new Set(a)].map(e=>({title:r[e],...i[e]?{integrationName:e}:{integrationName:`promptAPerson`,outerType:e},attributes:[{key:`Tech Type`,values:[`Site Tech`]},{key:`Found On Domain`,values:s[e]||[]}]})),adTechDataSilos:c}}export{t};
2
- //# sourceMappingURL=dataFlowsToDataSilos-DUj1NhOt.mjs.map
2
+ //# sourceMappingURL=dataFlowsToDataSilos-Ca2DtTsd.mjs.map