@transcend-io/cli 7.0.1 → 8.0.0-alpha.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 (271) hide show
  1. package/dist/bin/bash-complete.js +4 -0
  2. package/dist/bin/bash-complete.js.map +1 -0
  3. package/dist/bin/cli.js +3 -0
  4. package/dist/bin/cli.js.map +1 -0
  5. package/dist/bin/deprecated-command.js +7 -0
  6. package/dist/bin/deprecated-command.js.map +1 -0
  7. package/dist/chunk-26T4RUOI.js +12 -0
  8. package/dist/chunk-26T4RUOI.js.map +1 -0
  9. package/dist/chunk-2LCGZ77N.js +2 -0
  10. package/dist/chunk-2LCGZ77N.js.map +1 -0
  11. package/dist/chunk-2V6ABZRI.js +2 -0
  12. package/dist/chunk-2V6ABZRI.js.map +1 -0
  13. package/dist/chunk-347UQP43.js +2 -0
  14. package/dist/chunk-347UQP43.js.map +1 -0
  15. package/dist/chunk-43JWXG77.js +2 -0
  16. package/dist/chunk-43JWXG77.js.map +1 -0
  17. package/dist/chunk-4GLITB3Y.js +2 -0
  18. package/dist/chunk-4GLITB3Y.js.map +1 -0
  19. package/dist/chunk-65I2PF73.js +2 -0
  20. package/dist/chunk-65I2PF73.js.map +1 -0
  21. package/dist/chunk-72U6ETHG.js +2 -0
  22. package/dist/chunk-72U6ETHG.js.map +1 -0
  23. package/dist/chunk-ARVEJERC.js +2 -0
  24. package/dist/chunk-ARVEJERC.js.map +1 -0
  25. package/dist/chunk-CBAHSBSW.js +2 -0
  26. package/dist/{chunk-MQNOIHZN.cjs.map → chunk-CBAHSBSW.js.map} +1 -1
  27. package/dist/chunk-EZHASXA5.js +2 -0
  28. package/dist/chunk-EZHASXA5.js.map +1 -0
  29. package/dist/chunk-FHZRITAV.js +2 -0
  30. package/dist/chunk-FHZRITAV.js.map +1 -0
  31. package/dist/chunk-HJULYIHF.js +3 -0
  32. package/dist/chunk-HJULYIHF.js.map +1 -0
  33. package/dist/chunk-HOZXN2EM.js +94 -0
  34. package/dist/chunk-HOZXN2EM.js.map +1 -0
  35. package/dist/chunk-L5ULN3IT.js +2 -0
  36. package/dist/chunk-L5ULN3IT.js.map +1 -0
  37. package/dist/chunk-L7ZIX4SU.js +2 -0
  38. package/dist/chunk-L7ZIX4SU.js.map +1 -0
  39. package/dist/chunk-LAYHULHH.js +2 -0
  40. package/dist/chunk-LAYHULHH.js.map +1 -0
  41. package/dist/chunk-MA4JWWRO.js +6 -0
  42. package/dist/chunk-MA4JWWRO.js.map +1 -0
  43. package/dist/chunk-MK5T6DBK.js +2831 -0
  44. package/dist/chunk-MK5T6DBK.js.map +1 -0
  45. package/dist/chunk-N6JZHL5U.js +2 -0
  46. package/dist/chunk-N6JZHL5U.js.map +1 -0
  47. package/dist/chunk-NZZKRVAI.js +4 -0
  48. package/dist/chunk-NZZKRVAI.js.map +1 -0
  49. package/dist/chunk-OEB7WG3G.js +4 -0
  50. package/dist/chunk-OEB7WG3G.js.map +1 -0
  51. package/dist/chunk-SRLEEKKQ.js +9 -0
  52. package/dist/chunk-SRLEEKKQ.js.map +1 -0
  53. package/dist/chunk-WO5MQBXP.js +75 -0
  54. package/dist/chunk-WO5MQBXP.js.map +1 -0
  55. package/dist/impl-24IS3GIF.js +2 -0
  56. package/dist/impl-24IS3GIF.js.map +1 -0
  57. package/dist/impl-3YESYKVQ.js +2 -0
  58. package/dist/impl-3YESYKVQ.js.map +1 -0
  59. package/dist/impl-6MGNPY7O.js +2 -0
  60. package/dist/impl-6MGNPY7O.js.map +1 -0
  61. package/dist/impl-6SYXV3YI.js +2 -0
  62. package/dist/impl-6SYXV3YI.js.map +1 -0
  63. package/dist/impl-BVOF3W2V.js +4 -0
  64. package/dist/impl-BVOF3W2V.js.map +1 -0
  65. package/dist/impl-D4AEXEMN.js +12 -0
  66. package/dist/impl-D4AEXEMN.js.map +1 -0
  67. package/dist/impl-EAY4M3OY.js +2 -0
  68. package/dist/impl-EAY4M3OY.js.map +1 -0
  69. package/dist/impl-F4IQEKTF.js +9 -0
  70. package/dist/impl-F4IQEKTF.js.map +1 -0
  71. package/dist/impl-G4JGSVWD.js +2 -0
  72. package/dist/impl-G4JGSVWD.js.map +1 -0
  73. package/dist/impl-HFXHM3PH.js +2 -0
  74. package/dist/impl-HFXHM3PH.js.map +1 -0
  75. package/dist/impl-HMHOYOZZ.js +2 -0
  76. package/dist/impl-HMHOYOZZ.js.map +1 -0
  77. package/dist/impl-IU4EANSX.js +7 -0
  78. package/dist/impl-IU4EANSX.js.map +1 -0
  79. package/dist/impl-IWDHKBWZ.js +2 -0
  80. package/dist/impl-IWDHKBWZ.js.map +1 -0
  81. package/dist/impl-JFD2JMP6.js +2 -0
  82. package/dist/impl-JFD2JMP6.js.map +1 -0
  83. package/dist/impl-JH4VBMNT.js +2 -0
  84. package/dist/impl-JH4VBMNT.js.map +1 -0
  85. package/dist/impl-LSP4V37Z.js +6 -0
  86. package/dist/impl-LSP4V37Z.js.map +1 -0
  87. package/dist/impl-MIJFNSLS.js +2 -0
  88. package/dist/impl-MIJFNSLS.js.map +1 -0
  89. package/dist/impl-NL32KFH4.js +2 -0
  90. package/dist/impl-NL32KFH4.js.map +1 -0
  91. package/dist/impl-NLCPSIYZ.js +2 -0
  92. package/dist/impl-NLCPSIYZ.js.map +1 -0
  93. package/dist/impl-NXRQU2U5.js +6 -0
  94. package/dist/impl-NXRQU2U5.js.map +1 -0
  95. package/dist/impl-QEOVZIM5.js +2 -0
  96. package/dist/impl-QEOVZIM5.js.map +1 -0
  97. package/dist/impl-QRK4B3FD.js +2 -0
  98. package/dist/impl-QRK4B3FD.js.map +1 -0
  99. package/dist/impl-QZBKOJBQ.js +2 -0
  100. package/dist/impl-QZBKOJBQ.js.map +1 -0
  101. package/dist/impl-RFRQUKQY.js +2 -0
  102. package/dist/impl-RFRQUKQY.js.map +1 -0
  103. package/dist/impl-RIVVHWBR.js +2 -0
  104. package/dist/impl-RIVVHWBR.js.map +1 -0
  105. package/dist/impl-SJHU5PR7.js +2 -0
  106. package/dist/impl-SJHU5PR7.js.map +1 -0
  107. package/dist/impl-SYC5TORT.js +2 -0
  108. package/dist/impl-SYC5TORT.js.map +1 -0
  109. package/dist/impl-TP4QITXR.js +2 -0
  110. package/dist/impl-TP4QITXR.js.map +1 -0
  111. package/dist/impl-UOB7PV4W.js +2 -0
  112. package/dist/impl-UOB7PV4W.js.map +1 -0
  113. package/dist/impl-UUQ2BEZR.js +2 -0
  114. package/dist/impl-UUQ2BEZR.js.map +1 -0
  115. package/dist/impl-WH2I2JB7.js +2 -0
  116. package/dist/impl-WH2I2JB7.js.map +1 -0
  117. package/dist/impl-X6N6NFUV.js +6 -0
  118. package/dist/impl-X6N6NFUV.js.map +1 -0
  119. package/dist/impl-XF3OTAQZ.js +2 -0
  120. package/dist/impl-XF3OTAQZ.js.map +1 -0
  121. package/dist/impl-XH3KTZRN.js +2 -0
  122. package/dist/{impl-4WA4CEB2.cjs.map → impl-XH3KTZRN.js.map} +1 -1
  123. package/dist/impl-XQBTTRCU.js +2 -0
  124. package/dist/impl-XQBTTRCU.js.map +1 -0
  125. package/dist/impl-YA2HU57Y.js +2 -0
  126. package/dist/impl-YA2HU57Y.js.map +1 -0
  127. package/dist/impl-YEGS4G24.js +2 -0
  128. package/dist/impl-YEGS4G24.js.map +1 -0
  129. package/dist/impl-YNBHGQJK.js +2 -0
  130. package/dist/impl-YNBHGQJK.js.map +1 -0
  131. package/dist/impl-ZJL2YE7A.js +2 -0
  132. package/dist/impl-ZJL2YE7A.js.map +1 -0
  133. package/dist/{index.d.cts → index.d.ts} +1 -1
  134. package/dist/index.js +5 -0
  135. package/dist/index.js.map +1 -0
  136. package/package.json +45 -49
  137. package/dist/bin/bash-complete.cjs +0 -4
  138. package/dist/bin/bash-complete.cjs.map +0 -1
  139. package/dist/bin/cli.cjs +0 -3
  140. package/dist/bin/cli.cjs.map +0 -1
  141. package/dist/bin/deprecated-command.cjs +0 -7
  142. package/dist/bin/deprecated-command.cjs.map +0 -1
  143. package/dist/chunk-4J2KYJVS.cjs +0 -2
  144. package/dist/chunk-4J2KYJVS.cjs.map +0 -1
  145. package/dist/chunk-5SI74STE.cjs +0 -12
  146. package/dist/chunk-5SI74STE.cjs.map +0 -1
  147. package/dist/chunk-BY7W4UQF.cjs +0 -2
  148. package/dist/chunk-BY7W4UQF.cjs.map +0 -1
  149. package/dist/chunk-DF4YVZJQ.cjs +0 -94
  150. package/dist/chunk-DF4YVZJQ.cjs.map +0 -1
  151. package/dist/chunk-E4Y3D2JZ.cjs +0 -75
  152. package/dist/chunk-E4Y3D2JZ.cjs.map +0 -1
  153. package/dist/chunk-EG4L6YAJ.cjs +0 -2
  154. package/dist/chunk-EG4L6YAJ.cjs.map +0 -1
  155. package/dist/chunk-IBTP5OXE.cjs +0 -2
  156. package/dist/chunk-IBTP5OXE.cjs.map +0 -1
  157. package/dist/chunk-J72CSV4R.cjs +0 -2
  158. package/dist/chunk-J72CSV4R.cjs.map +0 -1
  159. package/dist/chunk-KOV2SQO2.cjs +0 -4
  160. package/dist/chunk-KOV2SQO2.cjs.map +0 -1
  161. package/dist/chunk-LL7YE3LT.cjs +0 -2
  162. package/dist/chunk-LL7YE3LT.cjs.map +0 -1
  163. package/dist/chunk-MQNOIHZN.cjs +0 -2
  164. package/dist/chunk-OL2YE5SK.cjs +0 -2
  165. package/dist/chunk-OL2YE5SK.cjs.map +0 -1
  166. package/dist/chunk-P6ZHBB6P.cjs +0 -3
  167. package/dist/chunk-P6ZHBB6P.cjs.map +0 -1
  168. package/dist/chunk-QUYFJVAC.cjs +0 -9
  169. package/dist/chunk-QUYFJVAC.cjs.map +0 -1
  170. package/dist/chunk-RPJHDKU6.cjs +0 -4
  171. package/dist/chunk-RPJHDKU6.cjs.map +0 -1
  172. package/dist/chunk-SAEKBZGF.cjs +0 -2
  173. package/dist/chunk-SAEKBZGF.cjs.map +0 -1
  174. package/dist/chunk-SDZR3H23.cjs +0 -2
  175. package/dist/chunk-SDZR3H23.cjs.map +0 -1
  176. package/dist/chunk-T462ONFX.cjs +0 -2
  177. package/dist/chunk-T462ONFX.cjs.map +0 -1
  178. package/dist/chunk-TD7ADMVO.cjs +0 -2
  179. package/dist/chunk-TD7ADMVO.cjs.map +0 -1
  180. package/dist/chunk-UEGX6GZ2.cjs +0 -2
  181. package/dist/chunk-UEGX6GZ2.cjs.map +0 -1
  182. package/dist/chunk-XXGX7FUC.cjs +0 -2
  183. package/dist/chunk-XXGX7FUC.cjs.map +0 -1
  184. package/dist/chunk-YVY4TZ2O.cjs +0 -2844
  185. package/dist/chunk-YVY4TZ2O.cjs.map +0 -1
  186. package/dist/chunk-ZUNVPK23.cjs +0 -2
  187. package/dist/chunk-ZUNVPK23.cjs.map +0 -1
  188. package/dist/chunk-ZVK4HIDF.cjs +0 -6
  189. package/dist/chunk-ZVK4HIDF.cjs.map +0 -1
  190. package/dist/impl-4WA4CEB2.cjs +0 -2
  191. package/dist/impl-7K57DEDR.cjs +0 -2
  192. package/dist/impl-7K57DEDR.cjs.map +0 -1
  193. package/dist/impl-AC2WQUNH.cjs +0 -2
  194. package/dist/impl-AC2WQUNH.cjs.map +0 -1
  195. package/dist/impl-B7WQMB3O.cjs +0 -2
  196. package/dist/impl-B7WQMB3O.cjs.map +0 -1
  197. package/dist/impl-DCTVGKDZ.cjs +0 -2
  198. package/dist/impl-DCTVGKDZ.cjs.map +0 -1
  199. package/dist/impl-DTFM3SWD.cjs +0 -2
  200. package/dist/impl-DTFM3SWD.cjs.map +0 -1
  201. package/dist/impl-GBTW2VLR.cjs +0 -2
  202. package/dist/impl-GBTW2VLR.cjs.map +0 -1
  203. package/dist/impl-HI27O5MJ.cjs +0 -4
  204. package/dist/impl-HI27O5MJ.cjs.map +0 -1
  205. package/dist/impl-I3RNGLKH.cjs +0 -2
  206. package/dist/impl-I3RNGLKH.cjs.map +0 -1
  207. package/dist/impl-IXNKRWC7.cjs +0 -2
  208. package/dist/impl-IXNKRWC7.cjs.map +0 -1
  209. package/dist/impl-IY2QSXYK.cjs +0 -2
  210. package/dist/impl-IY2QSXYK.cjs.map +0 -1
  211. package/dist/impl-KLXVHSVI.cjs +0 -2
  212. package/dist/impl-KLXVHSVI.cjs.map +0 -1
  213. package/dist/impl-L63MYKIO.cjs +0 -2
  214. package/dist/impl-L63MYKIO.cjs.map +0 -1
  215. package/dist/impl-LBZ5KQCA.cjs +0 -2
  216. package/dist/impl-LBZ5KQCA.cjs.map +0 -1
  217. package/dist/impl-LCGB6L6S.cjs +0 -2
  218. package/dist/impl-LCGB6L6S.cjs.map +0 -1
  219. package/dist/impl-MHMLFQYV.cjs +0 -2
  220. package/dist/impl-MHMLFQYV.cjs.map +0 -1
  221. package/dist/impl-MP7KOII5.cjs +0 -2
  222. package/dist/impl-MP7KOII5.cjs.map +0 -1
  223. package/dist/impl-MZEAMC6V.cjs +0 -2
  224. package/dist/impl-MZEAMC6V.cjs.map +0 -1
  225. package/dist/impl-N2Q4635G.cjs +0 -2
  226. package/dist/impl-N2Q4635G.cjs.map +0 -1
  227. package/dist/impl-NIMCX7UC.cjs +0 -2
  228. package/dist/impl-NIMCX7UC.cjs.map +0 -1
  229. package/dist/impl-NURZ5XJQ.cjs +0 -2
  230. package/dist/impl-NURZ5XJQ.cjs.map +0 -1
  231. package/dist/impl-NZFTTWVH.cjs +0 -7
  232. package/dist/impl-NZFTTWVH.cjs.map +0 -1
  233. package/dist/impl-O5UHTMMM.cjs +0 -6
  234. package/dist/impl-O5UHTMMM.cjs.map +0 -1
  235. package/dist/impl-PRYWCT7Y.cjs +0 -12
  236. package/dist/impl-PRYWCT7Y.cjs.map +0 -1
  237. package/dist/impl-RKMMHSRM.cjs +0 -2
  238. package/dist/impl-RKMMHSRM.cjs.map +0 -1
  239. package/dist/impl-RWHAQHPT.cjs +0 -2
  240. package/dist/impl-RWHAQHPT.cjs.map +0 -1
  241. package/dist/impl-SBE23MJO.cjs +0 -2
  242. package/dist/impl-SBE23MJO.cjs.map +0 -1
  243. package/dist/impl-SC4TK2TM.cjs +0 -2
  244. package/dist/impl-SC4TK2TM.cjs.map +0 -1
  245. package/dist/impl-TIBNP5YM.cjs +0 -6
  246. package/dist/impl-TIBNP5YM.cjs.map +0 -1
  247. package/dist/impl-UNB3DZOL.cjs +0 -2
  248. package/dist/impl-UNB3DZOL.cjs.map +0 -1
  249. package/dist/impl-V4UKISVS.cjs +0 -2
  250. package/dist/impl-V4UKISVS.cjs.map +0 -1
  251. package/dist/impl-V5ICYKCT.cjs +0 -6
  252. package/dist/impl-V5ICYKCT.cjs.map +0 -1
  253. package/dist/impl-VQGXD5O3.cjs +0 -2
  254. package/dist/impl-VQGXD5O3.cjs.map +0 -1
  255. package/dist/impl-X2YAN6YV.cjs +0 -9
  256. package/dist/impl-X2YAN6YV.cjs.map +0 -1
  257. package/dist/impl-XKATFWGB.cjs +0 -2
  258. package/dist/impl-XKATFWGB.cjs.map +0 -1
  259. package/dist/impl-XRRNIJUK.cjs +0 -2
  260. package/dist/impl-XRRNIJUK.cjs.map +0 -1
  261. package/dist/impl-Y3ZMWRT7.cjs +0 -2
  262. package/dist/impl-Y3ZMWRT7.cjs.map +0 -1
  263. package/dist/impl-YDPROAJW.cjs +0 -2
  264. package/dist/impl-YDPROAJW.cjs.map +0 -1
  265. package/dist/impl-YTAZCQDL.cjs +0 -2
  266. package/dist/impl-YTAZCQDL.cjs.map +0 -1
  267. package/dist/index.cjs +0 -5
  268. package/dist/index.cjs.map +0 -1
  269. /package/dist/bin/{bash-complete.d.cts → bash-complete.d.ts} +0 -0
  270. /package/dist/bin/{cli.d.cts → cli.d.ts} +0 -0
  271. /package/dist/bin/{deprecated-command.d.cts → deprecated-command.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"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/constants.ts","../src/lib/code-scanning/findCodePackagesInFolder.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { CodePackageSdk } from '../../../codecs';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\nimport { CodePackageType } from '@transcend-io/privacy-types';\n\nconst POD_TARGET_REGEX = /target ('|\")(.*?)('|\")/;\nconst POD_PACKAGE_REGEX = /pod ('|\")(.*?)('|\")(, ('|\")~> (.+?)('|\")|)/;\n\nexport const cocoaPods: CodeScanningConfig = {\n supportedFiles: ['Podfile'],\n ignoreDirs: ['Pods'],\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: [\n 'quote1',\n 'name',\n 'quote2',\n 'extra',\n 'quote3',\n 'version',\n 'quote4',\n ],\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 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\nimport { dirname } from 'path';\n\nconst GRADLE_IMPLEMENTATION_REGEX =\n /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: [\n 'gradle-app.setting',\n 'gradle-wrapper.jar',\n 'gradle-wrapper.properties',\n ],\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: [\n ...targets,\n ...targetGroups,\n ...targetPlugins,\n ].map((target) => ({\n name: target.name,\n version: target.version || undefined,\n })),\n },\n ];\n },\n};\n","import { readFileSync } from 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { CodePackageSdk } from '../../../codecs';\nimport { dirname } from 'path';\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 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\nimport { listFiles } from '../../api-keys';\nimport { dirname, join } from 'path';\nimport { CodePackageType } from '@transcend-io/privacy-types';\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 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { findAllWithRegex } from '@transcend-io/type-utils';\nimport { listFiles } from '../../api-keys';\nimport { dirname } from 'path';\nimport { CodePackageType } from '@transcend-io/privacy-types';\n\nconst GEM_PACKAGE_REGEX = /gem *('|\")(.+?)('|\")(, *('|\")(.+?)('|\")|)/;\nconst GEMFILE_PACKAGE_NAME_REGEX = /spec\\.name *= *('|\")(.+?)('|\")/;\nconst GEMFILE_PACKAGE_DESCRIPTION_REGEX =\n /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\n ? readFileSync(gemspec, 'utf-8')\n : 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: [\n 'quote1',\n 'name',\n 'quote2',\n 'hasVersion',\n 'quote3',\n 'version',\n 'quote4',\n ],\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 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport yaml from 'js-yaml';\nimport { dirname } from 'path';\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 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { CodePackageSdk } from '../../../codecs';\nimport { dirname } from 'path';\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 'fs';\nimport { CodeScanningConfig } from '../types';\nimport { CodePackageType } from '@transcend-io/privacy-types';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport * as t from 'io-ts';\nimport { dirname } from 'path';\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.type({\n revision: t.string,\n version: t.string,\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 const parsed = decodeCodec(SwiftPackage, fileContents);\n\n return [\n {\n name: dirname(filePath).split('/').pop() || '', // FIXME pull from Package.swift ->> name if possible\n type: CodePackageType.CocoaPods, // FIXME should be swift\n softwareDevelopmentKits: parsed.pins.map((target) => ({\n name: target.identity,\n version: target.state.version,\n })),\n },\n ];\n },\n};\n","import { CodeScanningConfig } from './types';\nimport {\n cocoaPods,\n gradle,\n javascriptPackageJson,\n gemfile,\n composerJson,\n pubspec,\n swift,\n pythonRequirementsTxt,\n} from './integrations';\nimport { CodePackageType } from '@transcend-io/privacy-types';\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};\n","import fastGlob from 'fast-glob';\nimport colors from 'colors';\nimport { CodePackageInput } from '../../codecs';\nimport { getEntries } from '@transcend-io/type-utils';\nimport { CODE_SCANNING_CONFIGS } from './constants';\nimport { logger } from '../../logger';\n\n/**\n * Helper to scan and discovery all of the code packages within a folder\n *\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findCodePackagesInFolder({\n scanPath,\n ignoreDirs = [],\n repositoryName,\n}: {\n /** The name of the github repository reporting packages for */\n repositoryName: string;\n /** Where to look for package.json files */\n scanPath: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs?: string[];\n}): Promise<CodePackageInput[]> {\n const allCodePackages = await Promise.all(\n getEntries(CODE_SCANNING_CONFIGS).map(async ([codePackageType, config]) => {\n const {\n ignoreDirs: configIgnoreDirs,\n supportedFiles,\n scanFunction,\n } = config;\n const dirsToIgnore = [...ignoreDirs, ...configIgnoreDirs].filter(\n (dir) => dir.length > 0,\n );\n try {\n const filesToScan: string[] = await fastGlob(\n `${scanPath}/**/${supportedFiles.join('|')}`,\n {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n },\n );\n logger.info(\n colors.magenta(\n `Scanning: ${filesToScan.length} files of type ${codePackageType}`,\n ),\n );\n const allPackages = filesToScan\n .map((filePath) =>\n scanFunction(filePath).map((result) => ({\n ...result,\n relativePath: filePath.replace(`${scanPath}/`, ''),\n })),\n )\n .flat();\n logger.info(\n colors.green(\n `Found: ${allPackages.length} packages and ${\n allPackages\n .map(\n ({ softwareDevelopmentKits = [] }) => softwareDevelopmentKits,\n )\n .flat().length\n } sdks`,\n ),\n );\n\n return allPackages.map(\n (pkg): CodePackageInput => ({\n ...pkg,\n type: codePackageType,\n repositoryName,\n }),\n );\n } catch (error) {\n throw new Error(\n `Error scanning globs ${supportedFiles} with error: ${error}`,\n );\n }\n }),\n );\n\n return allCodePackages.flat();\n}\n"],"mappings":"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","names":["readFileSync","findAllWithRegex","CodePackageType","POD_TARGET_REGEX","POD_PACKAGE_REGEX","cocoaPods","filePath","fileContents","targets","packages","target","ind","pkg","readFileSync","findAllWithRegex","dirname","GRADLE_IMPLEMENTATION_REGEX","GRADLE_PLUGIN_REGEX","GRADLE_IMPLEMENTATION_GROUP_REGEX","GRADLE_APPLICATION_NAME_REGEX","gradle","filePath","fileContents","directory","targets","targetPlugins","targetGroups","applications","target","readFileSync","dirname","javascriptPackageJson","filePath","file","directory","asJson","name","description","dependencies","devDependencies","optionalDependencies","version","readFileSync","findAllWithRegex","dirname","join","CodePackageType","REQUIREMENTS_PACKAGE_MATCH","PACKAGE_NAME","PACKAGE_DESCRIPTION","pythonRequirementsTxt","filePath","fileContents","readFileSync","directory","setupFile","listFiles","file","setupFileContents","packageName","packageDescription","targets","findAllWithRegex","pkg","readFileSync","findAllWithRegex","dirname","CodePackageType","GEM_PACKAGE_REGEX","GEMFILE_PACKAGE_NAME_REGEX","GEMFILE_PACKAGE_DESCRIPTION_REGEX","GEMFILE_PACKAGE_SUMMARY_REGEX","gemfile","filePath","fileContents","readFileSync","directory","gemspec","listFiles","file","gemspecContents","gemfileName","gemfileDescription","targets","findAllWithRegex","pkg","readFileSync","CodePackageType","yaml","dirname","removeYAMLComments","yamlString","line","commentIndex","pubspec","filePath","directory","fileContents","name","description","dev_dependencies","dependencies","version","readFileSync","dirname","composerJson","filePath","file","directory","asJson","name","description","requireDependencies","requiredDevDependencies","version","readFileSync","CodePackageType","decodeCodec","t","dirname","SwiftPackage","swift","filePath","fileContents","parsed","target","CodePackageType","SILO_DISCOVERY_CONFIGS","cocoaPods","gradle","javascriptPackageJson","pythonRequirementsTxt","gemfile","pubspec","swift","CODE_SCANNING_CONFIGS","composerJson","fastGlob","colors","getEntries","findCodePackagesInFolder","scanPath","ignoreDirs","repositoryName","getEntries","CODE_SCANNING_CONFIGS","codePackageType","config","configIgnoreDirs","supportedFiles","scanFunction","dirsToIgnore","dir","filesToScan","fastGlob","logger","colors","allPackages","filePath","result","softwareDevelopmentKits","pkg","error"]}
@@ -0,0 +1,4 @@
1
+ import{ea as o}from"./chunk-LAYHULHH.js";import{decodeCodec as c}from"@transcend-io/type-utils";import l from"js-yaml";import{readFileSync as m,writeFileSync as d}from"fs";var s=/<<parameters\.(.+?)>>/,i="parameters";function u(e,t,a=""){let r=e;if(Object.entries(t).forEach(([n,p])=>{r=r.split(`<<${i}.${n}>>`).join(p)}),s.test(r)){let[,n]=s.exec(r)||[];throw new Error(`Found variable that was not set: ${n}.
2
+ Make sure you are passing all parameters through the --${i}=${n}:value-for-param flag.
3
+ ${a}`)}return r}function b(e,t={}){let a=m(e,"utf-8"),r=u(a,t,`Also check that there are no extra variables defined in your yaml: ${e}`);return c(o,l.load(r))}function h(e,t){d(e,l.dump(c(o,t)))}export{s as a,i as b,u as c,b as d,h as e};
4
+ //# sourceMappingURL=chunk-OEB7WG3G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/readTranscendYaml.ts"],"sourcesContent":["import { decodeCodec, ObjByString } from '@transcend-io/type-utils';\nimport yaml from 'js-yaml';\nimport { readFileSync, writeFileSync } from 'fs';\nimport { TranscendInput } from '../codecs';\n\nexport const VARIABLE_PARAMETERS_REGEXP = /<<parameters\\.(.+?)>>/;\nexport const VARIABLE_PARAMETERS_NAME = 'parameters';\n\n/**\n * Function that replaces variables in a text file.\n * Throws error if there are variables that have not been replaced\n *\n * @param input - Input text\n * @param variables - Variables to replace\n * @param extraErrorMessage - Additional error message text\n * @returns Output text\n */\nexport function replaceVariablesInYaml(\n input: string,\n variables: ObjByString,\n extraErrorMessage = '',\n): string {\n let contents = input;\n // Replace variables\n Object.entries(variables).forEach(([name, value]) => {\n contents = contents\n .split(`<<${VARIABLE_PARAMETERS_NAME}.${name}>>`)\n .join(value);\n });\n\n // Throw error if unfilled variables\n if (VARIABLE_PARAMETERS_REGEXP.test(contents)) {\n const [, name] = VARIABLE_PARAMETERS_REGEXP.exec(contents) || [];\n throw new Error(\n `Found variable that was not set: ${name}.\nMake sure you are passing all parameters through the --${VARIABLE_PARAMETERS_NAME}=${name}:value-for-param flag.\n${extraErrorMessage}`,\n );\n }\n\n return contents;\n}\n\n/**\n * Read in the contents of a yaml file and validate that the shape\n * of the yaml file matches the codec API\n *\n * @param filePath - Path to yaml file\n * @param variables - Variables to fill in\n * @returns The contents of the yaml file, type-checked\n */\nexport function readTranscendYaml(\n filePath: string,\n variables: ObjByString = {},\n): TranscendInput {\n // Read in contents\n const fileContents = readFileSync(filePath, 'utf-8');\n\n // Replace variables\n const replacedVariables = replaceVariablesInYaml(\n fileContents,\n variables,\n `Also check that there are no extra variables defined in your yaml: ${filePath}`,\n );\n\n // Validate shape\n return decodeCodec(TranscendInput, yaml.load(replacedVariables));\n}\n\n/**\n * Write a Transcend configuration to disk\n *\n * @param filePath - Path to yaml file\n * @param input - The input to write out\n */\nexport function writeTranscendYaml(\n filePath: string,\n input: TranscendInput,\n): void {\n writeFileSync(filePath, yaml.dump(decodeCodec(TranscendInput, input)));\n}\n"],"mappings":"yCAAA,OAAS,eAAAA,MAAgC,2BACzC,OAAOC,MAAU,UACjB,OAAS,gBAAAC,EAAc,iBAAAC,MAAqB,KAGrC,IAAMC,EAA6B,wBAC7BC,EAA2B,aAWjC,SAASC,EACdC,EACAC,EACAC,EAAoB,GACZ,CACR,IAAIC,EAAWH,EASf,GAPA,OAAO,QAAQC,CAAS,EAAE,QAAQ,CAAC,CAACG,EAAMC,CAAK,IAAM,CACnDF,EAAWA,EACR,MAAM,KAAKL,CAAwB,IAAIM,CAAI,IAAI,EAC/C,KAAKC,CAAK,CACf,CAAC,EAGGR,EAA2B,KAAKM,CAAQ,EAAG,CAC7C,GAAM,CAAC,CAAEC,CAAI,EAAIP,EAA2B,KAAKM,CAAQ,GAAK,CAAC,EAC/D,MAAM,IAAI,MACR,oCAAoCC,CAAI;AAAA,yDACWN,CAAwB,IAAIM,CAAI;AAAA,EACvFF,CAAiB,EACf,CACF,CAEA,OAAOC,CACT,CAUO,SAASG,EACdC,EACAN,EAAyB,CAAC,EACV,CAEhB,IAAMO,EAAeC,EAAaF,EAAU,OAAO,EAG7CG,EAAoBX,EACxBS,EACAP,EACA,sEAAsEM,CAAQ,EAChF,EAGA,OAAOI,EAAYC,EAAgBC,EAAK,KAAKH,CAAiB,CAAC,CACjE,CAQO,SAASI,EACdP,EACAP,EACM,CACNe,EAAcR,EAAUM,EAAK,KAAKF,EAAYC,EAAgBZ,CAAK,CAAC,CAAC,CACvE","names":["decodeCodec","yaml","readFileSync","writeFileSync","VARIABLE_PARAMETERS_REGEXP","VARIABLE_PARAMETERS_NAME","replaceVariablesInYaml","input","variables","extraErrorMessage","contents","name","value","readTranscendYaml","filePath","fileContents","readFileSync","replacedVariables","decodeCodec","TranscendInput","yaml","writeTranscendYaml","writeFileSync"]}
@@ -0,0 +1,9 @@
1
+ import{e as o,f as i}from"./chunk-L5ULN3IT.js";import{d as n}from"./chunk-ARVEJERC.js";import{buildCommand as f,numberParser as m}from"@stricli/core";import{ConsentTrackerStatus as u}from"@transcend-io/privacy-types";import{ScopeName as c,TRANSCEND_SCOPES as s}from"@transcend-io/privacy-types";function h(e){if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e))throw new Error(`Invalid UUID format: ${e}`);return e}function a(e){try{return new URL(e).toString().replace(/\/$/,"")}catch{throw new Error(`Invalid URL format: ${e}`)}}function b(e){return e.split(",").map(r=>r.trim()).filter(r=>r.length>0)}function T(e){let r=new Date(e);if(Number.isNaN(r.getTime()))throw new TypeError(`Invalid date: ${e}. Try using the ISO 8601 format (YYYY-MM-DDTHH:MM:SS.SSSZ)`);return r}var l=({scopes:e,requiresSiloScope:r=!1})=>{let t={kind:"parsed",parse:String,brief:"The Transcend API key."};return r&&(t.brief+=" This key must be associated with the data silo(s) being operated on."),e==="Varies"?{...t,brief:`${t.brief} The scopes required will vary depending on the operation performed. If in doubt, the ${s[c.FullAdmin].title} scope will always work.`}:e.length===0?{...t,brief:`${t.brief} No scopes are required for this command.`}:{...t,brief:`${t.brief} Requires scopes: ${e.map(p=>`"${s[p].title}"`).join(", ")}`}},d=(e=o)=>({kind:"parsed",parse:a,brief:"URL of the Transcend backend. Use https://api.us.transcend.io for US hosting",default:e}),A=(e=i)=>({kind:"parsed",parse:a,brief:"URL of the Transcend consent backend. Use https://consent.us.transcend.io for US hosting",default:e}),U=()=>({kind:"parsed",parse:String,brief:"The Sombra internal key, use for additional authentication when self-hosting Sombra",optional:!0});var g=["dataSilos","enrichers","templates","apiKeys"],N=Object.values(u),L=f({loader:async()=>{let{pull:e}=await import("./impl-NXRQU2U5.js");return e},parameters:{flags:{auth:l({scopes:"Varies"}),resources:{kind:"enum",values:["all",...Object.values(n)],brief:`The different resource types to pull in. Defaults to ${g.join(",")}.`,variadic:",",optional:!0},file:{kind:"parsed",parse:String,brief:"Path to the YAML file to pull into",default:"./transcend.yml"},transcendUrl:d(),dataSiloIds:{kind:"parsed",parse:String,variadic:",",brief:"The UUIDs of the data silos that should be pulled into the YAML file",optional:!0},integrationNames:{kind:"parsed",parse:String,variadic:",",brief:"The types of integrations to pull down",optional:!0},trackerStatuses:{kind:"enum",values:Object.values(u),variadic:",",brief:"The statuses of consent manager trackers to pull down. Defaults to all statuses.",optional:!0},pageSize:{kind:"parsed",parse:m,brief:"The page size to use when paginating over the API",default:"50"},skipDatapoints:{kind:"boolean",brief:"When true, skip pulling in datapoints alongside data silo resource",default:!1},skipSubDatapoints:{kind:"boolean",brief:"When true, skip pulling in subDatapoints alongside data silo resource",default:!1},includeGuessedCategories:{kind:"boolean",brief:"When true, included guessed data categories that came from the content classifier",default:!1},debug:{kind:"boolean",brief:"Set to true to include debug logs while pulling the configuration",default:!1}}},docs:{brief:"Pull metadata from Transcend into transcend.yml",fullDescription:`Generates a transcend.yml by pulling the configuration from your Transcend instance.
2
+
3
+ The API key needs various scopes depending on the resources being pulled (see the CLI's README for more details).
4
+
5
+ This command can be helpful if you are looking to:
6
+
7
+ - Copy your data into another instance
8
+ - Generate a transcend.yml file as a starting point to maintain parts of your data inventory in code.`}});export{h as a,b,T as c,l as d,d as e,A as f,U as g,g as h,N as i,L as j};
9
+ //# sourceMappingURL=chunk-SRLEEKKQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/inventory/pull/command.ts","../src/lib/cli/common-parameters.ts","../src/lib/cli/parsers.ts"],"sourcesContent":["import { buildCommand, numberParser } from '@stricli/core';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport {\n createAuthParameter,\n createTranscendUrlParameter,\n} from '../../../lib/cli/common-parameters';\nimport { TranscendPullResource } from '../../../enums';\n\nexport const DEFAULT_TRANSCEND_PULL_RESOURCES = [\n TranscendPullResource.DataSilos,\n TranscendPullResource.Enrichers,\n TranscendPullResource.Templates,\n TranscendPullResource.ApiKeys,\n];\n\nexport const DEFAULT_CONSENT_TRACKER_STATUSES =\n Object.values(ConsentTrackerStatus);\n\nexport const pullCommand = buildCommand({\n loader: async () => {\n const { pull } = await import('./impl');\n return pull;\n },\n parameters: {\n flags: {\n auth: createAuthParameter({\n scopes: 'Varies',\n }),\n resources: {\n kind: 'enum',\n values: ['all', ...Object.values(TranscendPullResource)],\n brief: `The different resource types to pull in. Defaults to ${DEFAULT_TRANSCEND_PULL_RESOURCES.join(\n ',',\n )}.`,\n variadic: ',',\n optional: true,\n },\n file: {\n kind: 'parsed',\n parse: String,\n brief: 'Path to the YAML file to pull into',\n default: './transcend.yml',\n },\n transcendUrl: createTranscendUrlParameter(),\n dataSiloIds: {\n kind: 'parsed',\n parse: String,\n variadic: ',',\n brief:\n 'The UUIDs of the data silos that should be pulled into the YAML file',\n optional: true,\n },\n integrationNames: {\n kind: 'parsed',\n parse: String,\n variadic: ',',\n brief: 'The types of integrations to pull down',\n optional: true,\n },\n trackerStatuses: {\n kind: 'enum',\n values: Object.values(ConsentTrackerStatus),\n variadic: ',',\n brief:\n 'The statuses of consent manager trackers to pull down. Defaults to all statuses.',\n optional: true,\n },\n pageSize: {\n kind: 'parsed',\n parse: numberParser,\n brief: 'The page size to use when paginating over the API',\n default: '50',\n },\n skipDatapoints: {\n kind: 'boolean',\n brief:\n 'When true, skip pulling in datapoints alongside data silo resource',\n default: false,\n },\n skipSubDatapoints: {\n kind: 'boolean',\n brief:\n 'When true, skip pulling in subDatapoints alongside data silo resource',\n default: false,\n },\n includeGuessedCategories: {\n kind: 'boolean',\n brief:\n 'When true, included guessed data categories that came from the content classifier',\n default: false,\n },\n debug: {\n kind: 'boolean',\n brief:\n 'Set to true to include debug logs while pulling the configuration',\n default: false,\n },\n },\n },\n docs: {\n brief: 'Pull metadata from Transcend into transcend.yml',\n fullDescription: `Generates a transcend.yml by pulling the configuration from your Transcend instance.\n\nThe API key needs various scopes depending on the resources being pulled (see the CLI's README for more details).\n\nThis command can be helpful if you are looking to:\n\n- Copy your data into another instance\n- Generate a transcend.yml file as a starting point to maintain parts of your data inventory in code.`,\n },\n});\n","import { ScopeName, TRANSCEND_SCOPES } from '@transcend-io/privacy-types';\nimport { urlParser } from './parsers';\nimport {\n DEFAULT_TRANSCEND_API,\n DEFAULT_TRANSCEND_CONSENT_API,\n} from '../../constants';\nimport type { LocalContext } from '../../context';\nimport type { TypedFlagParameter } from '@stricli/core';\n\n/**\n * Common parameter builders for CLI commands\n * These reduce duplication and ensure consistency across commands\n */\n\n/**\n * Creates a standard authentication parameter\n *\n * @param root0 - The scopes and whether it requires a silo scope\n * @returns The parameter object\n */\nexport const createAuthParameter = ({\n scopes,\n requiresSiloScope = false,\n}: {\n /** The scopes required for the command */\n scopes: ScopeName[] | 'Varies';\n /** Whether the command requires a silo scope */\n requiresSiloScope?: boolean;\n}): TypedFlagParameter<string, LocalContext> => {\n const parameter = {\n kind: 'parsed' as const,\n parse: String,\n brief: 'The Transcend API key.',\n };\n\n if (requiresSiloScope) {\n parameter.brief +=\n ' This key must be associated with the data silo(s) being operated on.';\n }\n\n if (scopes === 'Varies') {\n return {\n ...parameter,\n brief: `${\n parameter.brief\n } The scopes required will vary depending on the operation performed. If in doubt, the ${\n TRANSCEND_SCOPES[ScopeName.FullAdmin].title\n } scope will always work.`,\n };\n }\n\n if (scopes.length === 0) {\n return {\n ...parameter,\n brief: `${parameter.brief} No scopes are required for this command.`,\n };\n }\n\n return {\n ...parameter,\n brief: `${parameter.brief} Requires scopes: ${scopes\n .map((s) => `\"${TRANSCEND_SCOPES[s].title}\"`)\n .join(', ')}`,\n };\n};\n\n/**\n * Creates a standard Transcend URL parameter\n *\n * @param defaultUrl - The default URL to use if not provided\n * @returns The parameter object\n */\nexport const createTranscendUrlParameter = (\n defaultUrl = DEFAULT_TRANSCEND_API,\n): TypedFlagParameter<string, LocalContext> => ({\n kind: 'parsed',\n parse: urlParser,\n brief:\n 'URL of the Transcend backend. Use https://api.us.transcend.io for US hosting',\n default: defaultUrl,\n});\n\n/**\n * Creates a standard Consent URL parameter\n *\n * @param defaultUrl - The default URL to use if not provided\n * @returns The parameter object\n */\nexport const createConsentUrlParameter = (\n defaultUrl = DEFAULT_TRANSCEND_CONSENT_API,\n): TypedFlagParameter<string, LocalContext> => ({\n kind: 'parsed',\n parse: urlParser,\n brief:\n 'URL of the Transcend consent backend. Use https://consent.us.transcend.io for US hosting',\n default: defaultUrl,\n});\n\n/**\n * Creates a standard Sombra authentication parameter\n *\n * @returns The parameter object\n */\nexport const createSombraAuthParameter = (): TypedFlagParameter<\n string | undefined,\n LocalContext\n> => ({\n kind: 'parsed',\n parse: String,\n brief:\n 'The Sombra internal key, use for additional authentication when self-hosting Sombra',\n optional: true,\n});\n","/**\n * Validates and returns a UUID string.\n *\n * @param input - The input string to validate as UUID\n * @returns The validated UUID string\n * @throws Error if input is not a valid UUID\n */\nexport function uuidParser(input: string): string {\n const uuidRegex =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n if (!uuidRegex.test(input)) {\n throw new Error(`Invalid UUID format: ${input}`);\n }\n return input;\n}\n\n/**\n * Validates and returns a URL string.\n *\n * @param input - The input string to validate as URL\n * @returns The validated URL string\n * @throws Error if input is not a valid URL\n */\nexport function urlParser(input: string): string {\n try {\n const url = new URL(input);\n return url.toString().replace(/\\/$/, '');\n } catch {\n throw new Error(`Invalid URL format: ${input}`);\n }\n}\n\n/**\n * Parse a comma-separated string to array.\n * NOTE: Prefer using `variadic` for list arguments instead of this function. This should only be used for arguments which have a default value.\n *\n * @param input - The comma-separated string to parse\n * @returns Array of trimmed, non-empty strings\n */\nexport function arrayParser(input: string): string[] {\n return input\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Parse a date string to a Date object.\n *\n * @param input - The date string to parse\n * @returns The parsed Date object\n * @throws TypeError if input is not a valid date\n */\nexport function dateParser(input: string): Date {\n const date = new Date(input);\n if (Number.isNaN(date.getTime())) {\n throw new TypeError(\n `Invalid date: ${input}. Try using the ISO 8601 format (YYYY-MM-DDTHH:MM:SS.SSSZ)`,\n );\n }\n return date;\n}\n"],"mappings":"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","names":["buildCommand","numberParser","ConsentTrackerStatus","ScopeName","TRANSCEND_SCOPES","uuidParser","input","urlParser","arrayParser","s","dateParser","date","createAuthParameter","scopes","requiresSiloScope","parameter","TRANSCEND_SCOPES","ScopeName","s","createTranscendUrlParameter","defaultUrl","DEFAULT_TRANSCEND_API","urlParser","createConsentUrlParameter","DEFAULT_TRANSCEND_CONSENT_API","createSombraAuthParameter","DEFAULT_TRANSCEND_PULL_RESOURCES","DEFAULT_CONSENT_TRACKER_STATUSES","ConsentTrackerStatus","pullCommand","buildCommand","pull","createAuthParameter","TranscendPullResource","createTranscendUrlParameter","numberParser"]}
@@ -0,0 +1,75 @@
1
+ import{_b as S,a as w,f as $,i as B,j as T,l as R}from"./chunk-MK5T6DBK.js";import{a as i}from"./chunk-43JWXG77.js";import{keyBy as O,uniq as A,chunk as U,sortBy as G}from"lodash-es";import{SubDataPointDataSubCategoryGuessStatus as _}from"@transcend-io/privacy-types";import h from"cli-progress";import{gql as L}from"graphql-request";import f from"colors";async function q(u,{dataSiloIds:e=[],includeGuessedCategories:l,includeAttributes:a,parentCategories:c=[],subCategories:t=[],pageSize:p=1e3}={}){let n=[],m=new Date().getTime(),d=new h.SingleBar({},h.Presets.shades_classic),s={...c.length>0?{category:c}:{},...t.length>0?{subCategoryIds:t}:{},...c.length+t.length>0&&!l?{status:_.Approved}:{},...e.length>0?{dataSilos:e}:{}},{subDataPoints:{totalCount:o}}=await S(u,$,{filterBy:s});i.info(f.magenta("[Step 1/3] Pulling in all subdatapoints")),d.start(o,0);let y=0,D=!1,r,b=0;do try{let{subDataPoints:{nodes:P}}=await S(u,L`
2
+ query TranscendCliSubDataPointCsvExport(
3
+ $filterBy: SubDataPointFiltersInput
4
+ $first: Int!
5
+ $offset: Int!
6
+ ) {
7
+ subDataPoints(
8
+ filterBy: $filterBy
9
+ first: $first
10
+ offset: $offset
11
+ useMaster: false
12
+ ) {
13
+ nodes {
14
+ id
15
+ name
16
+ description
17
+ dataPointId
18
+ dataSiloId
19
+ purposes {
20
+ name
21
+ purpose
22
+ }
23
+ categories {
24
+ name
25
+ category
26
+ }
27
+ ${l?`pendingCategoryGuesses {
28
+ category {
29
+ name
30
+ category
31
+ }
32
+ status
33
+ classifierVersion
34
+ }`:""}
35
+ ${a?`attributeValues {
36
+ attributeKey {
37
+ name
38
+ }
39
+ name
40
+ }`:""}
41
+ }
42
+ }
43
+ }
44
+ `,{first:p,offset:b,filterBy:{...s}});r=P[P.length-1]?.id,n.push(...P),D=P.length===p,y+=P.length,b+=P.length,d.update(y)}catch(P){throw i.error(f.red(`An error fetching subdatapoints for cursor ${r} and offset ${b}`)),P}while(D);d.stop();let C=new Date().getTime()-m,g=G(n,"name");return i.info(f.green(`Successfully pulled in ${g.length} subdatapoints in ${C/1e3} seconds!`)),g}async function F(u,{dataPointIds:e=[],pageSize:l=100}){let a=[],c=new Date().getTime(),t=new h.SingleBar({},h.Presets.shades_classic);i.info(f.magenta(`[Step 2/3] Fetching metadata for ${e.length} datapoints`));let p=U(e,l);t.start(e.length,0);let n=0;await w(p,async s=>{try{let{dataPoints:{nodes:o}}=await S(u,B,{first:l,filterBy:{ids:s}});a.push(...o),n+=s.length,t.update(n)}catch(o){throw i.error(f.red(`An error fetching subdatapoints for IDs ${s.join(", ")}`)),o}}),t.stop();let d=new Date().getTime()-c;return i.info(f.green(`Successfully pulled in ${a.length} dataPoints in ${d/1e3} seconds!`)),a}async function Q(u,{dataSiloIds:e=[],pageSize:l=100}){let a=[],c=new Date().getTime(),t=new h.SingleBar({},h.Presets.shades_classic);i.info(f.magenta(`[Step 3/3] Fetching metadata for ${e.length} data silos`));let p=U(e,l);t.start(e.length,0);let n=0;await w(p,async s=>{try{let{dataSilos:{nodes:o}}=await S(u,R,{first:l,filterBy:{ids:s}});a.push(...o),n+=s.length,t.update(n)}catch(o){throw i.error(f.red(`An error fetching data silos for IDs ${s.join(", ")}`)),o}}),t.stop();let d=new Date().getTime()-c;return i.info(f.green(`Successfully pulled in ${a.length} data silos in ${d/1e3} seconds!`)),a}async function H(u,{dataSiloIds:e=[],includeGuessedCategories:l,includeAttributes:a,parentCategories:c=[],subCategories:t=[],pageSize:p=1e3}={}){let n=await q(u,{dataSiloIds:e,includeGuessedCategories:l,includeAttributes:a,parentCategories:c,subCategories:t,pageSize:p}),m=A(n.map(r=>r.dataPointId)),d=await F(u,{dataPointIds:m}),s=O(d,"id"),o=A(n.map(r=>r.dataSiloId)),y=await Q(u,{dataSiloIds:o}),D=O(y,"id");return n.map(r=>({...r,dataPoint:s[r.dataPointId],dataSilo:D[r.dataSiloId]}))}import x from"cli-progress";import v from"colors";import{gql as E}from"graphql-request";import{sortBy as V}from"lodash-es";async function st(u,{dataSiloIds:e=[],status:l,subCategories:a=[],includeEncryptedSnippets:c,pageSize:t=100}={}){let p=[],n=new Date().getTime(),m=new x.SingleBar({},x.Presets.shades_classic),d={...a.length>0?{subCategoryIds:a}:{},...l?{status:l}:{},...e.length>0?{dataSilos:e}:{}},{unstructuredSubDataPointRecommendations:{totalCount:s}}=await S(u,T,{filterBy:d});i.info(v.magenta("[Step 1/3] Pulling in all subdatapoints")),m.start(s,0);let o=0,y=!1,D,r=0;do try{let{unstructuredSubDataPointRecommendations:{nodes:g}}=await S(u,E`
45
+ query TranscendCliUnstructuredSubDataPointRecommendationCsvExport(
46
+ $filterBy: UnstructuredSubDataPointRecommendationsFilterInput
47
+ $first: Int!
48
+ $offset: Int!
49
+ ) {
50
+ unstructuredSubDataPointRecommendations(
51
+ filterBy: $filterBy
52
+ first: $first
53
+ offset: $offset
54
+ useMaster: false
55
+ ) {
56
+ nodes {
57
+ id
58
+ dataSiloId
59
+ scannedObjectPathId
60
+ scannedObjectId
61
+ ${c?"name":""}
62
+ ${c?"contextSnippet":""}
63
+ dataSubCategory {
64
+ name
65
+ category
66
+ }
67
+ status
68
+ confidence
69
+ classificationMethod
70
+ classifierVersion
71
+ }
72
+ }
73
+ }
74
+ `,{first:t,offset:r,filterBy:{...d}});D=g[g.length-1]?.id,p.push(...g),y=g.length===t,o+=g.length,r+=g.length,m.update(o)}catch(g){throw i.error(v.red(`An error fetching subdatapoints for cursor ${D} and offset ${r}`)),g}while(y);m.stop();let I=new Date().getTime()-n,C=V(p,"name");return i.info(v.green(`Successfully pulled in ${C.length} subdatapoints in ${I/1e3} seconds!`)),C}export{H as a,st as b};
75
+ //# sourceMappingURL=chunk-WO5MQBXP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/data-inventory/pullAllDatapoints.ts","../src/lib/data-inventory/pullUnstructuredSubDataPointRecommendations.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport { keyBy, uniq, chunk, sortBy } from 'lodash-es';\nimport {\n type DataCategoryType,\n SubDataPointDataSubCategoryGuessStatus,\n} from '@transcend-io/privacy-types';\nimport cliProgress from 'cli-progress';\nimport { gql } from 'graphql-request';\nimport colors from 'colors';\nimport type { GraphQLClient } from 'graphql-request';\nimport {\n DATAPOINT_EXPORT,\n DATA_SILO_EXPORT,\n type DataSiloAttributeValue,\n SUB_DATA_POINTS_COUNT,\n makeGraphQLRequest,\n} from '../graphql';\nimport { logger } from '../../logger';\nimport type { DataCategoryInput, ProcessingPurposeInput } from '../../codecs';\nimport { mapSeries } from '../bluebird-replace';\n\nexport interface DataSiloCsvPreview {\n /** ID of dataSilo */\n id: string;\n /** Name of dataSilo */\n title: string;\n}\n\nexport interface DataPointCsvPreview {\n /** ID of dataPoint */\n id: string;\n /** The path to this data point */\n path: string[];\n /** Description */\n description: {\n /** Default message */\n defaultMessage: string;\n };\n /** Name */\n name: string;\n}\n\nexport interface SubDataPointCsvPreview {\n /** ID of subDatapoint */\n id: string;\n /** Name (or key) of the subdatapoint */\n name: string;\n /** The description */\n description?: string;\n /** Personal data category */\n categories: DataCategoryInput[];\n /** Data point ID */\n dataPointId: string;\n /** The data silo ID */\n dataSiloId: string;\n /** The processing purpose for this sub datapoint */\n purposes: ProcessingPurposeInput[];\n /** Attribute attached to subdatapoint */\n attributeValues?: DataSiloAttributeValue[];\n /** Data category guesses that are output by the classifier */\n pendingCategoryGuesses?: {\n /** Data category being guessed */\n category: DataCategoryInput;\n /** Status of guess */\n status: SubDataPointDataSubCategoryGuessStatus;\n /** classifier version that produced the guess */\n classifierVersion: number;\n }[];\n}\n\nexport interface DatapointFilterOptions {\n /** IDs of data silos to filter down */\n dataSiloIds?: string[];\n /** Whether to include guessed categories, defaults to only approved categories */\n includeGuessedCategories?: boolean;\n /** Whether or not to include attributes */\n includeAttributes?: boolean;\n /** Parent categories to filter down for */\n parentCategories?: DataCategoryType[];\n /** Sub categories to filter down for */\n subCategories?: string[]; // TODO: https://transcend.height.app/T-40482 - do by name not ID\n}\n\n/**\n * Pull subdatapoint information\n *\n * @param client - Client to use for the request\n * @param options - Options\n * @returns The subdatapoints\n */\nasync function pullSubDatapoints(\n client: GraphQLClient,\n {\n dataSiloIds = [],\n includeGuessedCategories,\n includeAttributes,\n parentCategories = [],\n subCategories = [],\n pageSize = 1000,\n }: DatapointFilterOptions & {\n /** Page size to pull in */\n pageSize?: number;\n } = {},\n): Promise<SubDataPointCsvPreview[]> {\n const subDataPoints: SubDataPointCsvPreview[] = [];\n\n // Time duration\n const t0 = new Date().getTime();\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n\n // Filters\n const filterBy = {\n ...(parentCategories.length > 0 ? { category: parentCategories } : {}),\n ...(subCategories.length > 0 ? { subCategoryIds: subCategories } : {}),\n // if parentCategories or subCategories and not includeGuessedCategories\n ...(parentCategories.length + subCategories.length > 0 &&\n !includeGuessedCategories\n ? // then only show data points with approved data categories\n { status: SubDataPointDataSubCategoryGuessStatus.Approved }\n : {}),\n ...(dataSiloIds.length > 0 ? { dataSilos: dataSiloIds } : {}),\n };\n\n // Build a GraphQL client\n const {\n subDataPoints: { totalCount },\n } = await makeGraphQLRequest<{\n /** Query response */\n subDataPoints: {\n /** Count */\n totalCount: number;\n };\n }>(client, SUB_DATA_POINTS_COUNT, {\n filterBy,\n });\n\n logger.info(colors.magenta('[Step 1/3] Pulling in all subdatapoints'));\n\n progressBar.start(totalCount, 0);\n let total = 0;\n let shouldContinue = false;\n let cursor: string | undefined;\n let offset = 0;\n do {\n try {\n const {\n subDataPoints: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n subDataPoints: {\n /** List of matches */\n nodes: SubDataPointCsvPreview[];\n };\n }>(\n client,\n gql`\n query TranscendCliSubDataPointCsvExport(\n $filterBy: SubDataPointFiltersInput\n $first: Int!\n $offset: Int!\n ) {\n subDataPoints(\n filterBy: $filterBy\n first: $first\n offset: $offset\n useMaster: false\n ) {\n nodes {\n id\n name\n description\n dataPointId\n dataSiloId\n purposes {\n name\n purpose\n }\n categories {\n name\n category\n }\n ${\n includeGuessedCategories\n ? `pendingCategoryGuesses {\n category {\n name\n category\n }\n status\n classifierVersion\n }`\n : ''\n }\n ${\n includeAttributes\n ? `attributeValues {\n attributeKey {\n name\n }\n name\n }`\n : ''\n }\n }\n }\n }\n `,\n {\n first: pageSize,\n offset,\n filterBy: {\n ...filterBy,\n // TODO: https://transcend.height.app/T-40484 - add cursor support\n // ...(cursor ? { cursor: { id: cursor } } : {}),\n },\n },\n );\n\n cursor = nodes[nodes.length - 1]?.id as string;\n subDataPoints.push(...nodes);\n shouldContinue = nodes.length === pageSize;\n total += nodes.length;\n offset += nodes.length;\n progressBar.update(total);\n } catch (err) {\n logger.error(\n colors.red(\n `An error fetching subdatapoints for cursor ${cursor} and offset ${offset}`,\n ),\n );\n throw err;\n }\n } while (shouldContinue);\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n const sorted = sortBy(subDataPoints, 'name');\n\n logger.info(\n colors.green(\n `Successfully pulled in ${sorted.length} subdatapoints in ${\n totalTime / 1000\n } seconds!`,\n ),\n );\n return sorted;\n}\n\n/**\n * Pull datapoint information\n *\n * @param client - Client to use for the request\n * @param options - Options\n * @returns The datapoints\n */\nasync function pullDatapoints(\n client: GraphQLClient,\n {\n dataPointIds = [],\n pageSize = 100,\n }: {\n /** IDs of data points to filter down */\n dataPointIds: string[];\n /** Page size to pull in */\n pageSize?: number;\n },\n): Promise<DataPointCsvPreview[]> {\n const dataPoints: DataPointCsvPreview[] = [];\n\n // Time duration\n const t0 = new Date().getTime();\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n\n logger.info(\n colors.magenta(\n `[Step 2/3] Fetching metadata for ${dataPointIds.length} datapoints`,\n ),\n );\n\n // Group by 100\n const dataPointsGrouped = chunk(dataPointIds, pageSize);\n\n progressBar.start(dataPointIds.length, 0);\n let total = 0;\n await mapSeries(dataPointsGrouped, async (dataPointIdsGroup) => {\n try {\n const {\n dataPoints: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n dataPoints: {\n /** List of matches */\n nodes: DataPointCsvPreview[];\n };\n }>(client, DATAPOINT_EXPORT, {\n first: pageSize,\n filterBy: {\n ids: dataPointIdsGroup,\n },\n });\n\n dataPoints.push(...nodes);\n total += dataPointIdsGroup.length;\n progressBar.update(total);\n } catch (err) {\n logger.error(\n colors.red(\n `An error fetching subdatapoints for IDs ${dataPointIdsGroup.join(\n ', ',\n )}`,\n ),\n );\n throw err;\n }\n });\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully pulled in ${dataPoints.length} dataPoints in ${\n totalTime / 1000\n } seconds!`,\n ),\n );\n return dataPoints;\n}\n\n/**\n * Pull data silo information\n *\n * @param client - Client to use for the request\n * @param options - Options\n * @returns The data silos\n */\nasync function pullDataSilos(\n client: GraphQLClient,\n {\n dataSiloIds = [],\n pageSize = 100,\n }: {\n /** IDs of data silos to filter down */\n dataSiloIds: string[];\n /** Page size to pull in */\n pageSize?: number;\n },\n): Promise<DataSiloCsvPreview[]> {\n const dataSilos: DataSiloCsvPreview[] = [];\n\n // Time duration\n const t0 = new Date().getTime();\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n\n logger.info(\n colors.magenta(\n `[Step 3/3] Fetching metadata for ${dataSiloIds.length} data silos`,\n ),\n );\n\n // Group by 100\n const dataSilosGrouped = chunk(dataSiloIds, pageSize);\n\n progressBar.start(dataSiloIds.length, 0);\n let total = 0;\n await mapSeries(dataSilosGrouped, async (dataSiloIdsGroup) => {\n try {\n const {\n dataSilos: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n dataSilos: {\n /** List of matches */\n nodes: DataSiloCsvPreview[];\n };\n }>(client, DATA_SILO_EXPORT, {\n first: pageSize,\n filterBy: {\n ids: dataSiloIdsGroup,\n },\n });\n\n dataSilos.push(...nodes);\n total += dataSiloIdsGroup.length;\n progressBar.update(total);\n } catch (err) {\n logger.error(\n colors.red(\n `An error fetching data silos for IDs ${dataSiloIdsGroup.join(', ')}`,\n ),\n );\n throw err;\n }\n });\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully pulled in ${dataSilos.length} data silos in ${\n totalTime / 1000\n } seconds!`,\n ),\n );\n return dataSilos;\n}\n\n/**\n * Pull all datapoints from the data inventory.\n *\n * @param client - Client to use for the request\n * @param options - Options\n * @returns The datapoints and data silos\n */\nexport async function pullAllDatapoints(\n client: GraphQLClient,\n {\n dataSiloIds = [],\n includeGuessedCategories,\n includeAttributes,\n parentCategories = [],\n subCategories = [],\n pageSize = 1000,\n }: DatapointFilterOptions & {\n /** Page size to pull in */\n pageSize?: number;\n } = {},\n): Promise<\n (SubDataPointCsvPreview & {\n /** Data point information */\n dataPoint: DataPointCsvPreview;\n /** Data silo information */\n dataSilo: DataSiloCsvPreview;\n })[]\n> {\n // Subdatapoint information\n const subDatapoints = await pullSubDatapoints(client, {\n dataSiloIds,\n includeGuessedCategories,\n includeAttributes,\n parentCategories,\n subCategories,\n pageSize,\n });\n\n // The datapoint ids to grab\n const dataPointIds = uniq(subDatapoints.map((point) => point.dataPointId));\n const dataPoints = await pullDatapoints(client, {\n dataPointIds,\n });\n const dataPointById = keyBy(dataPoints, 'id');\n\n // The data silo IDs to grab\n const allDataSiloIds = uniq(subDatapoints.map((point) => point.dataSiloId));\n const dataSilos = await pullDataSilos(client, {\n dataSiloIds: allDataSiloIds,\n });\n const dataSiloById = keyBy(dataSilos, 'id');\n\n return subDatapoints.map((subDataPoint) => ({\n ...subDataPoint,\n dataPoint: dataPointById[subDataPoint.dataPointId],\n dataSilo: dataSiloById[subDataPoint.dataSiloId],\n }));\n}\n/* eslint-enable max-lines */\n","import type { UnstructuredSubDataPointRecommendationStatus } from '@transcend-io/privacy-types';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\nimport { gql, type GraphQLClient } from 'graphql-request';\nimport { sortBy } from 'lodash-es';\nimport type { DataCategoryInput } from '../../codecs';\nimport { ENTRY_COUNT, makeGraphQLRequest } from '../graphql';\nimport { logger } from '../../logger';\n\ninterface UnstructuredSubDataPointRecommendationCsvPreview {\n /** ID of subDatapoint */\n id: string;\n /** Entry or Named Entity recognized by the classifier */\n name: string;\n /** Context snippet including entry */\n contextSnippet: string;\n /** Scanned object ID */\n scannedObjectId: string;\n /** Scanned object path ID */\n scannedObjectPathId: string;\n /** The data silo ID */\n dataSiloId: string;\n /** Personal data category */\n dataSubCategory: DataCategoryInput;\n /** Classification Status */\n status: UnstructuredSubDataPointRecommendationStatus;\n /** Confidence */\n confidence: number;\n /** Classification method */\n classificationMethod: string;\n /** Classifier version */\n classifierVersion: string;\n}\n\ninterface EntryFilterOptions {\n /** IDs of data silos to filter down */\n dataSiloIds?: string[];\n /** Parent categories to filter down for */\n status?: UnstructuredSubDataPointRecommendationStatus[];\n /** Sub categories to filter down for */\n subCategories?: string[]; // TODO: https://transcend.height.app/T-40482 - do by name not ID\n /** Include entry and snippet */\n includeEncryptedSnippets?: boolean;\n /** Include encryptedSamplesS3Key */\n includeEncryptedSamplesS3Key?: boolean;\n}\n/**\n * Pull unstructured subdatapoint information\n *\n * @param client - Client to use for the request\n * @param options - Options\n * @param options.dataSiloIds - IDs of data silos to filter down\n * @param options.status - Parent categories to filter down for\n * @param options.subCategories - Sub categories to filter down for\n * @param options.includeEncryptedSnippets - Include entry and snippet\n * @param options.includeEncryptedSamplesS3Key - Include encryptedSamplesS3Key\n * @param options.pageSize - Page size to pull in\n * @returns A promise that resolves to an array of unstructured subdatapoint recommendations\n */\nexport async function pullUnstructuredSubDataPointRecommendations(\n client: GraphQLClient,\n {\n dataSiloIds = [],\n status,\n subCategories = [],\n includeEncryptedSnippets,\n pageSize = 100,\n }: EntryFilterOptions & {\n /** Page size to pull in */\n pageSize?: number;\n } = {},\n): Promise<UnstructuredSubDataPointRecommendationCsvPreview[]> {\n const unstructuredSubDataPointRecommendations: UnstructuredSubDataPointRecommendationCsvPreview[] =\n [];\n\n // Time duration\n const t0 = new Date().getTime();\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n\n // Filters\n const filterBy = {\n ...(subCategories.length > 0 ? { subCategoryIds: subCategories } : {}),\n ...(status ? { status } : {}),\n ...(dataSiloIds.length > 0 ? { dataSilos: dataSiloIds } : {}),\n };\n\n // Build a GraphQL client\n const {\n unstructuredSubDataPointRecommendations: { totalCount },\n } = await makeGraphQLRequest<{\n /** Query response */\n unstructuredSubDataPointRecommendations: {\n /** Count */\n totalCount: number;\n };\n }>(client, ENTRY_COUNT, {\n filterBy,\n });\n\n logger.info(colors.magenta('[Step 1/3] Pulling in all subdatapoints'));\n\n progressBar.start(totalCount, 0);\n let total = 0;\n let shouldContinue = false;\n let cursor: string | undefined;\n let offset = 0;\n do {\n try {\n const {\n unstructuredSubDataPointRecommendations: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n unstructuredSubDataPointRecommendations: {\n /** List of matches */\n nodes: UnstructuredSubDataPointRecommendationCsvPreview[];\n };\n }>(\n client,\n gql`\n query TranscendCliUnstructuredSubDataPointRecommendationCsvExport(\n $filterBy: UnstructuredSubDataPointRecommendationsFilterInput\n $first: Int!\n $offset: Int!\n ) {\n unstructuredSubDataPointRecommendations(\n filterBy: $filterBy\n first: $first\n offset: $offset\n useMaster: false\n ) {\n nodes {\n id\n dataSiloId\n scannedObjectPathId\n scannedObjectId\n ${includeEncryptedSnippets ? 'name' : ''}\n ${includeEncryptedSnippets ? 'contextSnippet' : ''}\n dataSubCategory {\n name\n category\n }\n status\n confidence\n classificationMethod\n classifierVersion\n }\n }\n }\n `,\n {\n first: pageSize,\n offset,\n filterBy: {\n ...filterBy,\n },\n },\n );\n\n cursor = nodes[nodes.length - 1]?.id as string;\n unstructuredSubDataPointRecommendations.push(...nodes);\n shouldContinue = nodes.length === pageSize;\n total += nodes.length;\n offset += nodes.length;\n progressBar.update(total);\n } catch (err) {\n logger.error(\n colors.red(\n `An error fetching subdatapoints for cursor ${cursor} and offset ${offset}`,\n ),\n );\n throw err;\n }\n } while (shouldContinue);\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n const sorted = sortBy(unstructuredSubDataPointRecommendations, 'name');\n\n logger.info(\n colors.green(\n `Successfully pulled in ${sorted.length} subdatapoints in ${\n totalTime / 1000\n } seconds!`,\n ),\n );\n return sorted;\n}\n"],"mappings":"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","names":["keyBy","uniq","chunk","sortBy","SubDataPointDataSubCategoryGuessStatus","cliProgress","gql","colors","pullSubDatapoints","client","dataSiloIds","includeGuessedCategories","includeAttributes","parentCategories","subCategories","pageSize","subDataPoints","t0","progressBar","cliProgress","filterBy","SubDataPointDataSubCategoryGuessStatus","totalCount","makeGraphQLRequest","SUB_DATA_POINTS_COUNT","logger","colors","total","shouldContinue","cursor","offset","nodes","gql","err","totalTime","sorted","sortBy","pullDatapoints","dataPointIds","dataPoints","dataPointsGrouped","chunk","mapSeries","dataPointIdsGroup","DATAPOINT_EXPORT","pullDataSilos","dataSilos","dataSilosGrouped","dataSiloIdsGroup","DATA_SILO_EXPORT","pullAllDatapoints","subDatapoints","uniq","point","dataPointById","keyBy","allDataSiloIds","dataSiloById","subDataPoint","cliProgress","colors","gql","sortBy","pullUnstructuredSubDataPointRecommendations","client","dataSiloIds","status","subCategories","includeEncryptedSnippets","pageSize","unstructuredSubDataPointRecommendations","t0","progressBar","cliProgress","filterBy","totalCount","makeGraphQLRequest","ENTRY_COUNT","logger","colors","total","shouldContinue","cursor","offset","nodes","gql","err","totalTime","sorted","sortBy"]}
@@ -0,0 +1,2 @@
1
+ import{V as t}from"./chunk-N6JZHL5U.js";import"./chunk-MK5T6DBK.js";import"./chunk-43JWXG77.js";import"./chunk-L5ULN3IT.js";import"./chunk-EZHASXA5.js";import"./chunk-ARVEJERC.js";async function n({auth:s,dataSiloId:a,status:e,statuses:i,transcendUrl:o}){await t({transcendUrl:o,auth:s,status:e,dataSiloId:a,requestStatuses:i})}export{n as skipRequestDataSilos};
2
+ //# sourceMappingURL=impl-24IS3GIF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/request/system/skip-request-data-silos/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context';\nimport type { RequestStatus } from '@transcend-io/privacy-types';\nimport { skipRequestDataSilos as skipRequestDataSilosHelper } from '../../../../lib/requests';\n\ninterface SkipRequestDataSilosCommandFlags {\n auth: string;\n dataSiloId: string;\n transcendUrl: string;\n statuses: RequestStatus[];\n status: 'SKIPPED' | 'RESOLVED';\n}\n\nexport async function skipRequestDataSilos(\n this: LocalContext,\n {\n auth,\n dataSiloId,\n status,\n statuses,\n transcendUrl,\n }: SkipRequestDataSilosCommandFlags,\n): Promise<void> {\n await skipRequestDataSilosHelper({\n transcendUrl,\n auth,\n status,\n dataSiloId,\n requestStatuses: statuses,\n });\n}\n"],"mappings":"oLAYA,eAAsBA,EAEpB,CACE,KAAAC,EACA,WAAAC,EACA,OAAAC,EACA,SAAAC,EACA,aAAAC,CACF,EACe,CACf,MAAML,EAA2B,CAC/B,aAAAK,EACA,KAAAJ,EACA,OAAAE,EACA,WAAAD,EACA,gBAAiBE,CACnB,CAAC,CACH","names":["skipRequestDataSilos","auth","dataSiloId","status","statuses","transcendUrl"]}
@@ -0,0 +1,2 @@
1
+ import{J as t}from"./chunk-N6JZHL5U.js";import"./chunk-MK5T6DBK.js";import"./chunk-43JWXG77.js";import"./chunk-L5ULN3IT.js";import"./chunk-EZHASXA5.js";import"./chunk-ARVEJERC.js";async function f({auth:e,transcendUrl:i,createdAtBefore:n,createdAtAfter:o,actions:r,daysLeft:a,days:s,requestIds:m,emailTemplate:c,concurrency:d}){await t({transcendUrl:i,requestActions:r,auth:e,emailTemplate:c,days:s,daysLeft:a,requestIds:m,concurrency:d,createdAtBefore:n,createdAtAfter:o})}export{f as notifyAdditionalTime};
2
+ //# sourceMappingURL=impl-3YESYKVQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/request/notify-additional-time/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context';\nimport { notifyPrivacyRequestsAdditionalTime } from '../../../lib/requests';\nimport type { RequestAction } from '@transcend-io/privacy-types';\n\ninterface NotifyAdditionalTimeCommandFlags {\n auth: string;\n createdAtBefore: Date;\n createdAtAfter?: Date;\n actions?: RequestAction[];\n daysLeft: number;\n days: number;\n requestIds?: string[];\n emailTemplate: string;\n transcendUrl: string;\n concurrency: number;\n}\n\nexport async function notifyAdditionalTime(\n this: LocalContext,\n {\n auth,\n transcendUrl,\n createdAtBefore,\n createdAtAfter,\n actions,\n daysLeft,\n days,\n requestIds,\n emailTemplate,\n concurrency,\n }: NotifyAdditionalTimeCommandFlags,\n): Promise<void> {\n await notifyPrivacyRequestsAdditionalTime({\n transcendUrl,\n requestActions: actions,\n auth,\n emailTemplate,\n days,\n daysLeft,\n requestIds,\n concurrency,\n createdAtBefore,\n createdAtAfter,\n });\n}\n"],"mappings":"oLAiBA,eAAsBA,EAEpB,CACE,KAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,eAAAC,EACA,QAAAC,EACA,SAAAC,EACA,KAAAC,EACA,WAAAC,EACA,cAAAC,EACA,YAAAC,CACF,EACe,CACf,MAAMC,EAAoC,CACxC,aAAAT,EACA,eAAgBG,EAChB,KAAAJ,EACA,cAAAQ,EACA,KAAAF,EACA,SAAAD,EACA,WAAAE,EACA,YAAAE,EACA,gBAAAP,EACA,eAAAC,CACF,CAAC,CACH","names":["notifyAdditionalTime","auth","transcendUrl","createdAtBefore","createdAtAfter","actions","daysLeft","days","requestIds","emailTemplate","concurrency","notifyPrivacyRequestsAdditionalTime"]}
@@ -0,0 +1,2 @@
1
+ import{S as r}from"./chunk-N6JZHL5U.js";import"./chunk-MK5T6DBK.js";import"./chunk-43JWXG77.js";import"./chunk-L5ULN3IT.js";import"./chunk-EZHASXA5.js";import"./chunk-ARVEJERC.js";async function m({auth:n,enricherId:s,actions:i,requestEnricherStatuses:a,requestIds:c,createdAtBefore:e,createdAtAfter:t,concurrency:o,transcendUrl:u}){await r({auth:n,enricherId:s,requestActions:i,requestEnricherStatuses:a,requestIds:c,createdAtBefore:e?new Date(e):void 0,createdAtAfter:t?new Date(t):void 0,concurrency:o,transcendUrl:u})}export{m as enricherRestart};
2
+ //# sourceMappingURL=impl-6MGNPY7O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/request/enricher-restart/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../context';\nimport { bulkRetryEnrichers } from '../../../lib/requests';\nimport type {\n RequestAction,\n RequestEnricherStatus,\n} from '@transcend-io/privacy-types';\n\ninterface EnricherRestartCommandFlags {\n auth: string;\n enricherId: string;\n actions?: RequestAction[];\n requestEnricherStatuses?: RequestEnricherStatus[];\n transcendUrl: string;\n concurrency: number;\n requestIds?: string[];\n createdAtBefore?: Date;\n createdAtAfter?: Date;\n}\n\nexport async function enricherRestart(\n this: LocalContext,\n {\n auth,\n enricherId,\n actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore,\n createdAtAfter,\n concurrency,\n transcendUrl,\n }: EnricherRestartCommandFlags,\n): Promise<void> {\n await bulkRetryEnrichers({\n auth,\n enricherId,\n requestActions: actions,\n requestEnricherStatuses,\n requestIds,\n createdAtBefore: createdAtBefore ? new Date(createdAtBefore) : undefined,\n createdAtAfter: createdAtAfter ? new Date(createdAtAfter) : undefined,\n concurrency,\n transcendUrl,\n });\n}\n"],"mappings":"oLAmBA,eAAsBA,EAEpB,CACE,KAAAC,EACA,WAAAC,EACA,QAAAC,EACA,wBAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,eAAAC,EACA,YAAAC,EACA,aAAAC,CACF,EACe,CACf,MAAMC,EAAmB,CACvB,KAAAT,EACA,WAAAC,EACA,eAAgBC,EAChB,wBAAAC,EACA,WAAAC,EACA,gBAAiBC,EAAkB,IAAI,KAAKA,CAAe,EAAI,OAC/D,eAAgBC,EAAiB,IAAI,KAAKA,CAAc,EAAI,OAC5D,YAAAC,EACA,aAAAC,CACF,CAAC,CACH","names":["enricherRestart","auth","enricherId","actions","requestEnricherStatuses","requestIds","createdAtBefore","createdAtAfter","concurrency","transcendUrl","bulkRetryEnrichers"]}
@@ -0,0 +1,2 @@
1
+ import{g as f}from"./chunk-2LCGZ77N.js";import{c as l,d as m}from"./chunk-MA4JWWRO.js";import"./chunk-N6JZHL5U.js";import"./chunk-MK5T6DBK.js";import{a as t}from"./chunk-43JWXG77.js";import"./chunk-L5ULN3IT.js";import"./chunk-EZHASXA5.js";import"./chunk-ARVEJERC.js";import o from"colors";import{uniq as P}from"lodash-es";async function N({file:d,transcendUrl:u,auth:p,sombraAuth:g,dataSiloId:c,actions:v,pageLimit:r,skipRequestCount:n,chunkSize:e}){n&&t.info(o.yellow("Skipping request count as requested. This may help speed up the call.")),(Number.isNaN(e)||e<=0||e%r!==0)&&(t.error(o.red(`Invalid chunk size: "${e}". Must be a positive integer that is a multiple of ${r}.`)),process.exit(1));let{baseName:b,extension:C}=m(d),a=0;await f({transcendUrl:u,apiPageSize:r,savePageSize:e,onSave:i=>{let s=`${b}-${a}${C}`;t.info(o.blue(`Saving ${i.length} identifiers to file "${s}"`));let $=P(i.map(I=>Object.keys(I)).flat());return l(s,i,$),t.info(o.green(`Successfully wrote ${i.length} identifiers to file "${s}"`)),a+=1,Promise.resolve()},actions:v,auth:p,sombraAuth:g,dataSiloId:c,skipRequestCount:n})}export{N as pullIdentifiers};
2
+ //# sourceMappingURL=impl-6SYXV3YI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/request/cron/pull-identifiers/impl.ts"],"sourcesContent":["import type { LocalContext } from '../../../../context';\nimport colors from 'colors';\n\nimport { logger } from '../../../../logger';\nimport { uniq } from 'lodash-es';\nimport {\n CsvFormattedIdentifier,\n parseFilePath,\n pullChunkedCustomSiloOutstandingIdentifiers,\n writeCsv,\n} from '../../../../lib/cron';\nimport { RequestAction } from '@transcend-io/privacy-types';\n\ninterface PullIdentifiersCommandFlags {\n file: string;\n transcendUrl: string;\n auth: string;\n sombraAuth?: string;\n dataSiloId: string;\n actions: RequestAction[];\n pageLimit: number;\n skipRequestCount: boolean;\n chunkSize: number;\n}\n\nexport async function pullIdentifiers(\n this: LocalContext,\n {\n file,\n transcendUrl,\n auth,\n sombraAuth,\n dataSiloId,\n actions,\n pageLimit,\n skipRequestCount,\n chunkSize,\n }: PullIdentifiersCommandFlags,\n): Promise<void> {\n if (skipRequestCount) {\n logger.info(\n colors.yellow(\n 'Skipping request count as requested. This may help speed up the call.',\n ),\n );\n }\n\n if (\n Number.isNaN(chunkSize) ||\n chunkSize <= 0 ||\n chunkSize % pageLimit !== 0\n ) {\n logger.error(\n colors.red(\n `Invalid chunk size: \"${chunkSize}\". Must be a positive integer that is a multiple of ${pageLimit}.`,\n ),\n );\n process.exit(1);\n }\n\n const { baseName, extension } = parseFilePath(file);\n let fileCount = 0;\n\n const onSave = (chunk: CsvFormattedIdentifier[]): Promise<void> => {\n const numberedFileName = `${baseName}-${fileCount}${extension}`;\n logger.info(\n colors.blue(\n `Saving ${chunk.length} identifiers to file \"${numberedFileName}\"`,\n ),\n );\n\n const headers = uniq(chunk.map((d) => Object.keys(d)).flat());\n writeCsv(numberedFileName, chunk, headers);\n logger.info(\n colors.green(\n `Successfully wrote ${chunk.length} identifiers to file \"${numberedFileName}\"`,\n ),\n );\n fileCount += 1;\n return Promise.resolve();\n };\n\n // Pull down outstanding identifiers\n await pullChunkedCustomSiloOutstandingIdentifiers({\n transcendUrl,\n apiPageSize: pageLimit,\n savePageSize: chunkSize,\n onSave,\n actions,\n auth,\n sombraAuth,\n dataSiloId,\n skipRequestCount,\n });\n}\n"],"mappings":"2QACA,OAAOA,MAAY,SAGnB,OAAS,QAAAC,MAAY,YAqBrB,eAAsBC,EAEpB,CACE,KAAAC,EACA,aAAAC,EACA,KAAAC,EACA,WAAAC,EACA,WAAAC,EACA,QAAAC,EACA,UAAAC,EACA,iBAAAC,EACA,UAAAC,CACF,EACe,CACXD,GACFE,EAAO,KACLC,EAAO,OACL,uEACF,CACF,GAIA,OAAO,MAAMF,CAAS,GACtBA,GAAa,GACbA,EAAYF,IAAc,KAE1BG,EAAO,MACLC,EAAO,IACL,wBAAwBF,CAAS,uDAAuDF,CAAS,GACnG,CACF,EACA,QAAQ,KAAK,CAAC,GAGhB,GAAM,CAAE,SAAAK,EAAU,UAAAC,CAAU,EAAIC,EAAcb,CAAI,EAC9Cc,EAAY,EAsBhB,MAAMC,EAA4C,CAChD,aAAAd,EACA,YAAaK,EACb,aAAcE,EACd,OAxBcQ,GAAmD,CACjE,IAAMC,EAAmB,GAAGN,CAAQ,IAAIG,CAAS,GAAGF,CAAS,GAC7DH,EAAO,KACLC,EAAO,KACL,UAAUM,EAAM,MAAM,yBAAyBC,CAAgB,GACjE,CACF,EAEA,IAAMC,EAAUC,EAAKH,EAAM,IAAKI,GAAM,OAAO,KAAKA,CAAC,CAAC,EAAE,KAAK,CAAC,EAC5D,OAAAC,EAASJ,EAAkBD,EAAOE,CAAO,EACzCT,EAAO,KACLC,EAAO,MACL,sBAAsBM,EAAM,MAAM,yBAAyBC,CAAgB,GAC7E,CACF,EACAH,GAAa,EACN,QAAQ,QAAQ,CACzB,EAQE,QAAAT,EACA,KAAAH,EACA,WAAAC,EACA,WAAAC,EACA,iBAAAG,CACF,CAAC,CACH","names":["colors","uniq","pullIdentifiers","file","transcendUrl","auth","sombraAuth","dataSiloId","actions","pageLimit","skipRequestCount","chunkSize","logger","colors","baseName","extension","parseFilePath","fileCount","pullChunkedCustomSiloOutstandingIdentifiers","chunk","numberedFileName","headers","uniq","d","writeCsv"]}
@@ -0,0 +1,4 @@
1
+ import{a as D}from"./chunk-NZZKRVAI.js";import"./chunk-65I2PF73.js";import"./chunk-LAYHULHH.js";import"./chunk-347UQP43.js";import{Od as u,le as S,pe as y}from"./chunk-MK5T6DBK.js";import{a as r}from"./chunk-43JWXG77.js";import{b as h}from"./chunk-L5ULN3IT.js";import"./chunk-EZHASXA5.js";import"./chunk-ARVEJERC.js";import{stringify as C}from"query-string";import w from"colors";import v from"fast-glob";async function m({scanPath:t,fileGlobs:e,ignoreDirs:g,config:p}){let{ignoreDirs:f,supportedFiles:s,scanFunction:a}=p,n=e===""?s:s.concat(e.split(",")),l=[...g.split(","),...f].filter(o=>o.length>0);try{let o=await v(`${t}/**/${n.join("|")}`,{ignore:l.map(i=>`${t}/**/${i}`),unique:!0,onlyFiles:!0});r.info(`Scanning: ${o.length} files`);let $=o.map(i=>a(i)).flat().map(i=>i.softwareDevelopmentKits||[]).flat(),d=[...new Set($.map(i=>i.name))];return r.info(`Found: ${d.length} unique dependencies`),d.map(i=>({name:i,resourceId:`${t}/**/${i}`,useStrictClassifier:!0}))}catch(o){throw new Error(`Error scanning globs ${m} with error: ${o}`)}}async function k({scanPath:t,dataSiloId:e,auth:g,fileGlobs:p,ignoreDirs:f,transcendUrl:s}){let a=y(s,g),n=await u(a,e),l=D[n.dataSilo.type];l||(r.error(w.red(`This plugin "${n.dataSilo.type}" is not supported for offline silo discovery.`)),process.exit(1));let o=await m({scanPath:t,fileGlobs:p,ignoreDirs:f,config:l});await S(a,n.id,o);let c=new URL(h);c.pathname="/data-map/data-inventory/silo-discovery/triage",c.search=C({filters:JSON.stringify({pluginIds:[n.id]})}),r.info(w.green(`Scan found ${o.length} potential data silos at ${t}! View at '${c.href}'
2
+
3
+ NOTE: it may take 2-3 minutes for scan results to appear in the UI.`))}export{k as discoverSilos};
4
+ //# sourceMappingURL=impl-BVOF3W2V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/inventory/discover-silos/impl.ts","../src/lib/code-scanning/findFilesToScan.ts"],"sourcesContent":["import type { LocalContext } from '../../../context';\nimport { stringify } from 'query-string';\nimport { logger } from '../../../logger';\nimport colors from 'colors';\nimport { ADMIN_DASH } from '../../../constants';\nimport {\n fetchActiveSiloDiscoPlugin,\n buildTranscendGraphQLClient,\n uploadSiloDiscoveryResults,\n} from '../../../lib/graphql';\nimport { findFilesToScan } from '../../../lib/code-scanning/findFilesToScan';\nimport { SILO_DISCOVERY_CONFIGS } from '../../../lib/code-scanning';\n\ninterface DiscoverSilosCommandFlags {\n scanPath: string;\n dataSiloId: string;\n auth: string;\n fileGlobs: string;\n ignoreDirs: string;\n transcendUrl: string;\n}\n\nexport async function discoverSilos(\n this: LocalContext,\n {\n scanPath,\n dataSiloId,\n auth,\n fileGlobs,\n ignoreDirs,\n transcendUrl,\n }: DiscoverSilosCommandFlags,\n): Promise<void> {\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const plugin = await fetchActiveSiloDiscoPlugin(client, dataSiloId);\n\n const config = SILO_DISCOVERY_CONFIGS[plugin.dataSilo.type];\n if (!config) {\n logger.error(\n colors.red(\n `This plugin \"${plugin.dataSilo.type}\" is not supported for offline silo discovery.`,\n ),\n );\n process.exit(1);\n }\n\n const results = await findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n });\n\n await uploadSiloDiscoveryResults(client, plugin.id, results);\n\n const newUrl = new URL(ADMIN_DASH);\n newUrl.pathname = '/data-map/data-inventory/silo-discovery/triage';\n newUrl.search = stringify({\n filters: JSON.stringify({ pluginIds: [plugin.id] }),\n });\n\n // Indicate success\n logger.info(\n colors.green(\n `Scan found ${results.length} potential data silos at ${scanPath}! ` +\n `View at '${newUrl.href}' ` +\n '\\n\\n NOTE: it may take 2-3 minutes for scan results to appear in the UI.',\n ),\n );\n}\n","import fastGlob from 'fast-glob';\nimport { logger } from '../../logger';\nimport { CodeScanningConfig } from './types';\n\nexport interface SiloDiscoveryRawResults {\n /** The name of the potential data silo entry */\n name: string;\n /** A unique UUID (represents the same resource across different silo discovery runs) */\n resourceId: string;\n /** Any hosts associated with the entry */\n host?: string;\n /** Type of data silo */\n type?: string | undefined;\n}\n\n/**\n * Helper to scan for data silos in all package.json files that it can find in a directory\n *\n * @deprecated TODO: https://transcend.height.app/T-32325 - use code scanning instead\n * @param options - Options\n * @returns the list of integrations\n */\nexport async function findFilesToScan({\n scanPath,\n fileGlobs,\n ignoreDirs,\n config,\n}: {\n /** Where to look for package.json files */\n scanPath: string;\n /** Globs to look for */\n fileGlobs: string;\n /** The directories to ignore (excludes node_modules and serverless-build) */\n ignoreDirs: string;\n /** Silo Discovery configuration */\n config: CodeScanningConfig;\n}): Promise<SiloDiscoveryRawResults[]> {\n const { ignoreDirs: IGNORE_DIRS, supportedFiles, scanFunction } = config;\n const globsToSupport =\n fileGlobs === ''\n ? supportedFiles\n : supportedFiles.concat(fileGlobs.split(','));\n const dirsToIgnore = [...ignoreDirs.split(','), ...IGNORE_DIRS].filter(\n (dir) => dir.length > 0,\n );\n try {\n const filesToScan: string[] = await fastGlob(\n `${scanPath}/**/${globsToSupport.join('|')}`,\n {\n ignore: dirsToIgnore.map((dir: string) => `${scanPath}/**/${dir}`),\n unique: true,\n onlyFiles: true,\n },\n );\n logger.info(`Scanning: ${filesToScan.length} files`);\n const allPackages = filesToScan\n .map((filePath: string) => scanFunction(filePath))\n .flat();\n const allSdks = allPackages\n .map((appPackage) => appPackage.softwareDevelopmentKits || [])\n .flat();\n const uniqueDeps = new Set(allSdks.map((sdk) => sdk.name));\n const deps = [...uniqueDeps];\n logger.info(`Found: ${deps.length} unique dependencies`);\n return deps.map((dep) => ({\n name: dep,\n resourceId: `${scanPath}/**/${dep}`,\n useStrictClassifier: true,\n }));\n } catch (error) {\n throw new Error(\n `Error scanning globs ${findFilesToScan} with error: ${error}`,\n );\n }\n}\n"],"mappings":"6TACA,OAAS,aAAAA,MAAiB,eAE1B,OAAOC,MAAY,SCHnB,OAAOC,MAAc,YAsBrB,eAAsBC,EAAgB,CACpC,SAAAC,EACA,UAAAC,EACA,WAAAC,EACA,OAAAC,CACF,EASuC,CACrC,GAAM,CAAE,WAAYC,EAAa,eAAAC,EAAgB,aAAAC,CAAa,EAAIH,EAC5DI,EACJN,IAAc,GACVI,EACAA,EAAe,OAAOJ,EAAU,MAAM,GAAG,CAAC,EAC1CO,EAAe,CAAC,GAAGN,EAAW,MAAM,GAAG,EAAG,GAAGE,CAAW,EAAE,OAC7DK,GAAQA,EAAI,OAAS,CACxB,EACA,GAAI,CACF,IAAMC,EAAwB,MAAMC,EAClC,GAAGX,CAAQ,OAAOO,EAAe,KAAK,GAAG,CAAC,GAC1C,CACE,OAAQC,EAAa,IAAKC,GAAgB,GAAGT,CAAQ,OAAOS,CAAG,EAAE,EACjE,OAAQ,GACR,UAAW,EACb,CACF,EACAG,EAAO,KAAK,aAAaF,EAAY,MAAM,QAAQ,EAInD,IAAMG,EAHcH,EACjB,IAAKI,GAAqBR,EAAaQ,CAAQ,CAAC,EAChD,KAAK,EAEL,IAAKC,GAAeA,EAAW,yBAA2B,CAAC,CAAC,EAC5D,KAAK,EAEFC,EAAO,CAAC,GADK,IAAI,IAAIH,EAAQ,IAAKI,GAAQA,EAAI,IAAI,CAAC,CAC9B,EAC3B,OAAAL,EAAO,KAAK,UAAUI,EAAK,MAAM,sBAAsB,EAChDA,EAAK,IAAKE,IAAS,CACxB,KAAMA,EACN,WAAY,GAAGlB,CAAQ,OAAOkB,CAAG,GACjC,oBAAqB,EACvB,EAAE,CACJ,OAASC,EAAO,CACd,MAAM,IAAI,MACR,wBAAwBpB,CAAe,gBAAgBoB,CAAK,EAC9D,CACF,CACF,CDpDA,eAAsBC,EAEpB,CACE,SAAAC,EACA,WAAAC,EACA,KAAAC,EACA,UAAAC,EACA,WAAAC,EACA,aAAAC,CACF,EACe,CAEf,IAAMC,EAASC,EAA4BF,EAAcH,CAAI,EAEvDM,EAAS,MAAMC,EAA2BH,EAAQL,CAAU,EAE5DS,EAASC,EAAuBH,EAAO,SAAS,IAAI,EACrDE,IACHE,EAAO,MACLC,EAAO,IACL,gBAAgBL,EAAO,SAAS,IAAI,gDACtC,CACF,EACA,QAAQ,KAAK,CAAC,GAGhB,IAAMM,EAAU,MAAMC,EAAgB,CACpC,SAAAf,EACA,UAAAG,EACA,WAAAC,EACA,OAAAM,CACF,CAAC,EAED,MAAMM,EAA2BV,EAAQE,EAAO,GAAIM,CAAO,EAE3D,IAAMG,EAAS,IAAI,IAAIC,CAAU,EACjCD,EAAO,SAAW,iDAClBA,EAAO,OAASE,EAAU,CACxB,QAAS,KAAK,UAAU,CAAE,UAAW,CAACX,EAAO,EAAE,CAAE,CAAC,CACpD,CAAC,EAGDI,EAAO,KACLC,EAAO,MACL,cAAcC,EAAQ,MAAM,4BAA4Bd,CAAQ,cAClDiB,EAAO,IAAI;AAAA;AAAA,qEAE3B,CACF,CACF","names":["stringify","colors","fastGlob","findFilesToScan","scanPath","fileGlobs","ignoreDirs","config","IGNORE_DIRS","supportedFiles","scanFunction","globsToSupport","dirsToIgnore","dir","filesToScan","fastGlob","logger","allSdks","filePath","appPackage","deps","sdk","dep","error","discoverSilos","scanPath","dataSiloId","auth","fileGlobs","ignoreDirs","transcendUrl","client","buildTranscendGraphQLClient","plugin","fetchActiveSiloDiscoPlugin","config","SILO_DISCOVERY_CONFIGS","logger","colors","results","findFilesToScan","uploadSiloDiscoveryResults","newUrl","ADMIN_DASH","stringify"]}
@@ -0,0 +1,12 @@
1
+ import{a as Q}from"./chunk-FHZRITAV.js";import"./chunk-4GLITB3Y.js";import{n as F,p as X,q as Z}from"./chunk-N6JZHL5U.js";import"./chunk-347UQP43.js";import{Qc as H,_d as ee,a as A,b as V,pe as te,qe as re}from"./chunk-MK5T6DBK.js";import{a as l}from"./chunk-43JWXG77.js";import{f as oe}from"./chunk-L5ULN3IT.js";import"./chunk-EZHASXA5.js";import"./chunk-ARVEJERC.js";import v from"colors";import k from"colors";import{chunk as Qe}from"lodash-es";import ye from"cli-progress";import{PersistedState as Ge}from"@transcend-io/persisted-state";import{keyBy as De}from"lodash-es";import*as x from"io-ts";import de from"colors";import{PreferenceQueryResponseItem as Ue}from"@transcend-io/privacy-types";import ne from"colors";import se from"cli-progress";import{chunk as ke}from"lodash-es";import{decodeCodec as Re}from"@transcend-io/type-utils";import*as T from"io-ts";var Me=T.intersection([T.type({nodes:T.array(Ue)}),T.partial({cursor:T.string})]),Ve=["ENOTFOUND","ETIMEDOUT","504 Gateway Time-out","Task timed out after"];async function ie(m,{identifiers:n,partitionKey:h,skipLogging:d=!1}){let s=[],u=ke(n,100),i=new Date().getTime(),t=new se.SingleBar({},se.Presets.shades_classic);d||t.start(n.length,0);let c=0;await V(u,async e=>{let a=0,g=3;for(;a<g;)try{let p=await m.post(`v1/preferences/${h}/query`,{json:{filter:{identifiers:e},limit:e.length}}).json(),w=Re(Me,p);s.push(...w.nodes),c+=e.length,t.update(c);break}catch(p){a+=1;let w=p?.response?.body||p?.message||"";if(a>=g||!Ve.some(P=>w.includes(P)))throw new Error(`Received an error from server after ${a} attempts: ${w}`);l.warn(ne.yellow(`[RETRYING FAILED REQUEST - Attempt ${a}] Failed to fetch ${e.length} user preferences from partition ${h}: ${w}`))}},{concurrency:40}),t.stop();let r=new Date().getTime()-i;return d||l.info(ne.green(`Completed download in "${r/1e3}" seconds.`)),s}import{PreferenceTopicType as G}from"@transcend-io/privacy-types";import{apply as Fe}from"@transcend-io/type-utils";function D({row:m,columnToPurposeName:n,purposeSlugs:h,preferenceTopics:d}){let s={};return Object.entries(n).forEach(([u,{purpose:i,preference:t,valueMapping:c}])=>{if(!h.includes(i))throw new Error(`Invalid purpose slug: ${i}, expected: ${h.join(", ")}`);if(t){let f=d.find(g=>g.slug===t&&g.purpose.trackingType===i);if(!f){let g=d.filter(p=>p.purpose.trackingType===i).map(p=>p.slug);throw new Error(`Invalid preference slug: ${t} for purpose: ${i}. Allowed preference slugs for purpose are: ${g.join(",")}`)}s[i]||(s[i]={preferences:[]}),s[i].preferences||(s[i].preferences=[]);let r=m[u],e=c[r],a=typeof e=="string"&&e.trim()||null;switch(f.type){case G.Boolean:if(typeof e!="boolean")throw new Error(`Invalid value for boolean preference: ${t}, expected boolean, got: ${r}`);s[i].preferences.push({topic:t,choice:{booleanValue:e}});break;case G.Select:if(typeof e!="string"&&e!==null)throw new Error(`Invalid value for select preference: ${t}, expected string or null, got: ${r}`);if(a&&!f.preferenceOptionValues.map(({slug:g})=>g).includes(a))throw new Error(`Invalid value for select preference: ${t}, expected one of: ${f.preferenceOptionValues.map(({slug:g})=>g).join(", ")}, got: ${r}`);s[i].preferences.push({topic:t,choice:{selectValue:a}});break;case G.MultiSelect:if(typeof r!="string")throw new Error(`Invalid value for multi select preference: ${t}, expected string, got: ${r}`);s[i].preferences.push({topic:t,choice:{selectValues:F(r).map(g=>{let p=c[g];if(typeof p!="string")throw new Error(`Invalid value for multi select preference: ${t}, expected one of: ${f.preferenceOptionValues.map(({slug:w})=>w).join(", ")}, got: ${g}`);return p}).sort((g,p)=>g.localeCompare(p))}});break;default:throw new Error(`Unknown preference type: ${f.type}`)}}else s[i]?s[i].enabled=c[m[u]]===!0:s[i]={enabled:c[m[u]]===!0}}),Fe(s,(u,i)=>{if(typeof u.enabled!="boolean")throw new Error(`No mapping provided for purpose.enabled=true/false value: ${i}`);return{...u,enabled:u.enabled}})}import{uniq as Se,difference as Ee}from"lodash-es";import ae from"colors";import Ie from"inquirer";var q="[NONE]";async function pe(m,n){let h=Se(m.map(s=>Object.keys(s)).flat()),d=Ee(h,[...n.identifierColumn?[n.identifierColumn]:[],...Object.keys(n.columnToPurposeName)]);if(!n.timestampColum){let{timestampName:s}=await Ie.prompt([{name:"timestampName",message:"Choose the column that will be used as the timestamp of last preference update",type:"list",default:d.find(u=>u.toLowerCase().includes("date"))||d.find(u=>u.toLowerCase().includes("time"))||d[0],choices:[...d,q]}]);n.timestampColum=s}if(l.info(ae.magenta(`Using timestamp column "${n.timestampColum}"`)),n.timestampColum!==q){let s=m.map((u,i)=>u[n.timestampColum]?null:[i]).filter(u=>!!u).flat();if(s.length>0)throw new Error(`The timestamp column "${n.timestampColum}" is missing a value for the following rows: ${s.join(`
2
+ `)}`);l.info(ae.magenta(`The timestamp column "${n.timestampColum}" is present for all row`))}return n}import{uniq as Ne,groupBy as Oe,difference as xe}from"lodash-es";import N from"colors";import je from"inquirer";async function le(m,n){let h=Ne(m.map(t=>Object.keys(t)).flat()),d=xe(h,[...n.identifierColumn?[n.identifierColumn]:[],...Object.keys(n.columnToPurposeName)]);if(!n.identifierColumn){let{identifierName:t}=await je.prompt([{name:"identifierName",message:"Choose the column that will be used as the identifier to upload consent preferences by",type:"list",default:d.find(c=>c.toLowerCase().includes("email"))||d[0],choices:d}]);n.identifierColumn=t}l.info(N.magenta(`Using identifier column "${n.identifierColumn}"`));let s=m.map((t,c)=>t[n.identifierColumn]?null:[c]).filter(t=>!!t).flat();if(s.length>0){let t=`The identifier column "${n.identifierColumn}" is missing a value for the following rows: ${s.join(", ")}`;if(l.warn(N.yellow(t)),!await Q({message:"Would you like to skip rows missing an identifier?"}))throw new Error(t);let f=m.length;m=m.filter(r=>r[n.identifierColumn]),l.info(N.yellow(`Skipped ${f-m.length} rows missing an identifier`))}l.info(N.magenta(`The identifier column "${n.identifierColumn}" is present for all rows`));let u=Oe(m,n.identifierColumn),i=Object.entries(u).filter(([,t])=>t.length>1);if(i.length>0){let t=`The identifier column "${n.identifierColumn}" has duplicate values for the following rows: ${i.slice(0,10).map(([f,r])=>`${f} (${r.length})`).join(`
3
+ `)}`;if(l.warn(N.yellow(t)),!await Q({message:"Would you like to automatically take the latest update?"}))throw new Error(t);m=Object.entries(u).map(([,f])=>f.sort((e,a)=>new Date(a[n.timestampColum]).getTime()-new Date(e[n.timestampColum]).getTime())[0]).filter(f=>f)}return{currentState:n,preferences:m}}import{uniq as ce,difference as Ae}from"lodash-es";import W from"colors";import O from"inquirer";import{PreferenceTopicType as _}from"@transcend-io/privacy-types";async function fe(m,n,{purposeSlugs:h,preferenceTopics:d,forceTriggerWorkflows:s}){let u=ce(m.map(c=>Object.keys(c)).flat()),i=Ae(u,[...n.identifierColumn?[n.identifierColumn]:[],...n.timestampColum?[n.timestampColum]:[]]);if(i.length===0){if(s)return n;throw new Error("No other columns to process")}let t=[...h,...d.map(c=>`${c.purpose.trackingType}->${c.slug}`)];return await A(i,async c=>{let f=ce(m.map(e=>e[c])),r=n.columnToPurposeName[c];if(r)l.info(W.magenta(`Column "${c}" is associated with purpose "${r.purpose}"`));else{let{purposeName:e}=await O.prompt([{name:"purposeName",message:`Choose the purpose that column ${c} is associated with`,type:"list",default:t.find(p=>p.startsWith(h[0])),choices:t}]),[a,g]=e.split("->");r={purpose:a,preference:g||null,valueMapping:{}}}await A(f,async e=>{if(r.valueMapping[e]!==void 0){l.info(W.magenta(`Value "${e}" is associated with purpose value "${r.valueMapping[e]}"`));return}if(r.preference===null){let{purposeValue:a}=await O.prompt([{name:"purposeValue",message:`Choose the purpose value for value "${e}" associated with purpose "${r.purpose}"`,type:"confirm",default:e!=="false"}]);r.valueMapping[e]=a}if(r.preference!==null){let a=d.find(p=>p.slug===r.preference);if(!a){l.error(W.red(`Preference topic "${r.preference}" not found`));return}let g=a.preferenceOptionValues.map(({slug:p})=>p);if(a.type===_.Boolean){let{preferenceValue:p}=await O.prompt([{name:"preferenceValue",message:`Choose the preference value for "${a.slug}" value "${e}" associated with purpose "${r.purpose}"`,type:"confirm",default:e!=="false"}]);r.valueMapping[e]=p;return}if(a.type===_.Select){let{preferenceValue:p}=await O.prompt([{name:"preferenceValue",message:`Choose the preference value for "${a.slug}" value "${e}" associated with purpose "${r.purpose}"`,type:"list",choices:g,default:g.find(w=>w===e)}]);r.valueMapping[e]=p;return}if(a.type===_.MultiSelect){let p=F(e);await A(p,async w=>{if(r.valueMapping[w]!==void 0)return;let{preferenceValue:P}=await O.prompt([{name:"preferenceValue",message:`Choose the preference value for "${a.slug}" value "${w}" associated with purpose "${r.purpose}"`,type:"list",choices:g,default:g.find(y=>y===w)}]);r.valueMapping[w]=P});return}throw new Error(`Unknown preference topic type: ${a.type}`)}}),n.columnToPurposeName[c]=r}),n}import{PreferenceTopicType as K}from"@transcend-io/privacy-types";function me({currentConsentRecord:m,pendingUpdates:n,preferenceTopics:h}){return Object.entries(n).every(([d,{preferences:s=[],enabled:u}])=>{let i=m.purposes.find(c=>c.purpose===d);return!!i&&i.enabled===u?s.every(({topic:c,choice:f})=>i.preferences&&i.preferences.find(r=>{if(r.topic!==c)return!1;let e=h.find(a=>a.slug===c&&a.purpose.trackingType===d);if(!e)throw new Error(`Could not find preference topic for ${c}`);switch(e.type){case K.Boolean:return r.choice.booleanValue===f.booleanValue;case K.Select:return r.choice.selectValue===f.selectValue;case K.MultiSelect:let a=(r.choice.selectValues||[]).sort(),g=(f.selectValues||[]).sort();return a.length===g.length&&a.every((p,w)=>p===g[w]);default:throw new Error(`Unknown preference topic type: ${e.type}`)}})):!1})}import{PreferenceTopicType as Y}from"@transcend-io/privacy-types";function ue({currentConsentRecord:m,pendingUpdates:n,preferenceTopics:h}){return!!Object.entries(n).find(([d,{preferences:s=[],enabled:u}])=>{let i=m.purposes.find(t=>t.purpose===d);return i?i.enabled!==u?!0:!!s.find(({topic:t,choice:c})=>{let f=(i.preferences||[]).find(e=>e.topic===t);if(!f)return!1;let r=h.find(e=>e.slug===t&&e.purpose.trackingType===d);if(!r)throw new Error(`Could not find preference topic for ${t}`);switch(r.type){case Y.Boolean:return f.choice.booleanValue!==c.booleanValue;case Y.Select:return f.choice.selectValue!==c.selectValue;case Y.MultiSelect:let e=(f.choice.selectValues||[]).sort(),a=(c.selectValues||[]).sort();return e.length!==a.length||!e.every((g,p)=>g===a[p]);default:throw new Error(`Unknown preference topic type: ${r.type}`)}}):!1})}async function ge({file:m,sombra:n,purposeSlugs:h,preferenceTopics:d,partitionKey:s,skipExistingRecordCheck:u,forceTriggerWorkflows:i},t){let c=new Date().getTime(),f=t.getValue("fileMetadata");l.info(de.magenta(`Reading in file: "${m}"`));let r=Z(m,x.record(x.string,x.string)),e={columnToPurposeName:{},pendingSafeUpdates:{},pendingConflictUpdates:{},skippedUpdates:{},...f[m]||{},lastFetchedAt:new Date().toISOString()};e=await pe(r,e),f[m]=e,await t.setValue(f,"fileMetadata");let a=await le(r,e);e=a.currentState,r=a.preferences,f[m]=e,await t.setValue(f,"fileMetadata"),e=await fe(r,e,{preferenceTopics:d,purposeSlugs:h,forceTriggerWorkflows:i}),f[m]=e,await t.setValue(f,"fileMetadata");let g=r.map(y=>y[e.identifierColumn]),p=u?[]:await ie(n,{identifiers:g.map(y=>({value:y})),partitionKey:s}),w=De(p,"userId");e.pendingConflictUpdates={},e.pendingSafeUpdates={},e.skippedUpdates={},r.forEach(y=>{let C=y[e.identifierColumn],S=D({row:y,columnToPurposeName:e.columnToPurposeName,preferenceTopics:d,purposeSlugs:h}),U=w[C];if(i&&!U)throw new Error(`No existing consent record found for user with id: ${C}.
4
+ When 'forceTriggerWorkflows' is set all the user identifiers should contain a consent record`);if(U&&me({currentConsentRecord:U,pendingUpdates:S,preferenceTopics:d})&&!i){e.skippedUpdates[C]=y;return}if(U&&ue({currentConsentRecord:U,pendingUpdates:S,preferenceTopics:d})){e.pendingConflictUpdates[C]={row:y,record:U};return}e.pendingSafeUpdates[C]=y}),f[m]=e,await t.setValue(f,"fileMetadata");let P=new Date().getTime();l.info(de.green(`Successfully pre-processed file: "${m}" in ${(P-c)/1e3}s`))}import{PreferenceQueryResponseItem as qe,PreferenceUpdateItem as we}from"@transcend-io/privacy-types";import*as o from"io-ts";var Be=o.type({purpose:o.string,preference:o.union([o.string,o.null]),valueMapping:o.record(o.string,o.union([o.string,o.boolean,o.null]))}),Le=o.intersection([o.type({columnToPurposeName:o.record(o.string,Be),lastFetchedAt:o.string,pendingSafeUpdates:o.record(o.string,o.record(o.string,o.string)),pendingConflictUpdates:o.record(o.string,o.type({record:qe,row:o.record(o.string,o.string)})),skippedUpdates:o.record(o.string,o.record(o.string,o.string))}),o.partial({identifierColumn:o.string,timestampColum:o.string})]),he=o.type({fileMetadata:o.record(o.string,Le),failingUpdates:o.record(o.string,o.type({uploadedAt:o.string,error:o.string,update:we})),pendingUpdates:o.record(o.string,we)});import{apply as We}from"@transcend-io/type-utils";async function Pe({auth:m,sombraAuth:n,receiptFilepath:h,file:d,partition:s,isSilent:u=!0,dryRun:i=!1,skipWorkflowTriggers:t=!1,skipConflictUpdates:c=!1,skipExistingRecordCheck:f=!1,attributes:r=[],transcendUrl:e=oe,forceTriggerWorkflows:a=!1}){let g=X(r),p=new Ge(h,he,{fileMetadata:{},failingUpdates:{},pendingUpdates:{}}),w=p.getValue("failingUpdates"),P=p.getValue("pendingUpdates"),y=p.getValue("fileMetadata");l.info(k.magenta(`Restored cache, there are:
5
+ ${Object.values(w).length} failing requests to be retried
6
+ ${Object.values(P).length} pending requests to be processed
7
+ The following files are stored in cache and will be used:
8
+ ${Object.keys(y).map(b=>b).join(`
9
+ `)}
10
+ The following file will be processed: ${d}
11
+ `));let C=te(e,m),[S,U,J]=await Promise.all([re(e,m,n),a?Promise.resolve([]):H(C),a?Promise.resolve([]):ee(C)]);await ge({file:d,purposeSlugs:U.map(b=>b.trackingType),preferenceTopics:J,sombra:S,partitionKey:s,skipExistingRecordCheck:f,forceTriggerWorkflows:a},p);let E={};y=p.getValue("fileMetadata");let R=y[d];if(l.info(k.magenta(`Found ${Object.entries(R.pendingSafeUpdates).length} safe updates in ${d}`)),l.info(k.magenta(`Found ${Object.entries(R.pendingConflictUpdates).length} conflict updates in ${d}`)),l.info(k.magenta(`Found ${Object.entries(R.skippedUpdates).length} skipped updates in ${d}`)),Object.entries({...R.pendingSafeUpdates,...c?{}:We(R.pendingConflictUpdates,({row:b})=>b)}).forEach(([b,$])=>{let j=R.timestampColum===q?new Date:new Date($[R.timestampColum]),M=D({row:$,columnToPurposeName:R.columnToPurposeName,preferenceTopics:J,purposeSlugs:U.map(I=>I.trackingType)});E[b]={userId:b,partition:s,timestamp:j.toISOString(),purposes:Object.entries(M).map(([I,ve])=>({...ve,purpose:I,workflowSettings:{attributes:g,isSilent:u,skipWorkflowTrigger:t}}))}}),await p.setValue(E,"pendingUpdates"),await p.setValue({},"failingUpdates"),i){l.info(k.green(`Dry run complete, exiting. ${Object.values(E).length} pending updates. Check file: ${h}`));return}l.info(k.magenta(`Uploading ${Object.values(E).length} preferences to partition: ${s}`));let Ce=new Date().getTime(),B=new ye.SingleBar({},ye.Presets.shades_classic),z=0,L=Object.entries(E),$e=Qe(L,t?100:10);B.start(L.length,0),await V($e,async b=>{try{await S.put("v1/preferences",{json:{records:b.map(([,$])=>$),skipWorkflowTriggers:t,forceTriggerWorkflows:a}}).json()}catch($){try{let M=JSON.parse($?.response?.body||"{}");M.error&&l.error(k.red(`Error: ${M.error}`))}catch{}l.error(k.red(`Failed to upload ${b.length} user preferences to partition ${s}: ${$?.response?.body||$?.message}`));let j=p.getValue("failingUpdates");b.forEach(([M,I])=>{j[M]={uploadedAt:new Date().toISOString(),update:I,error:$?.response?.body||$?.message||"Unknown error"}}),await p.setValue(j,"failingUpdates")}z+=b.length,B.update(z)},{concurrency:40}),B.stop();let Te=new Date().getTime()-Ce;l.info(k.green(`Successfully uploaded ${L.length} user preferences to partition ${s} in "${Te/1e3}" seconds!`))}import{readdirSync as _e}from"fs";import{basename as Ke,join as be}from"path";async function Sr({auth:m,partition:n,sombraAuth:h,consentUrl:d,file:s="",directory:u,dryRun:i,skipExistingRecordCheck:t,receiptFileDir:c,skipWorkflowTriggers:f,forceTriggerWorkflows:r,skipConflictUpdates:e,isSilent:a,attributes:g,concurrency:p}){u&&s&&(l.error(v.red("Cannot provide both a directory and a file. Please provide only one.")),process.exit(1)),!s&&!u&&(l.error(v.red("A file or directory must be provided. Please provide one using --file=./preferences.csv or --directory=./preferences")),process.exit(1));let w=[];if(u)try{let y=_e(u).filter(C=>C.endsWith(".csv"));y.length===0&&(l.error(v.red(`No CSV files found in directory: ${u}`)),process.exit(1)),w.push(...y.map(C=>be(u,C)))}catch(P){l.error(v.red(`Failed to read directory: ${u}`)),l.error(v.red(P.message)),process.exit(1)}else try{s.endsWith(".csv")||(l.error(v.red("File must be a CSV file")),process.exit(1)),w.push(s)}catch(P){l.error(v.red(`Failed to access file: ${s}`)),l.error(v.red(P.message)),process.exit(1)}l.info(v.green(`Processing ${w.length} consent preferences files for partition: ${n}`)),l.debug(`Files to process: ${w.join(", ")}`),t&&l.info(v.bgYellow(`Skipping existing record check: ${t}`)),await V(w,async P=>{let y=Ke(P).replace(".csv","");await Pe({receiptFilepath:be(c,`${y}-receipts.json`),auth:m,sombraAuth:h,file:P,partition:n,transcendUrl:d,skipConflictUpdates:e,skipWorkflowTriggers:f,skipExistingRecordCheck:t,isSilent:a,dryRun:i,attributes:F(g),forceTriggerWorkflows:r})},{concurrency:p})}export{Sr as uploadPreferences};
12
+ //# sourceMappingURL=impl-D4AEXEMN.js.map