@transcend-io/cli 8.26.0 → 8.26.2

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 (121) hide show
  1. package/dist/bin/bash-complete.cjs +1 -1
  2. package/dist/bin/cli.cjs +1 -1
  3. package/dist/bin/deprecated-command.cjs +2 -2
  4. package/dist/{chunk-WGCFVEJZ.cjs → chunk-4LSUJDDH.cjs} +2 -2
  5. package/dist/{chunk-WGCFVEJZ.cjs.map → chunk-4LSUJDDH.cjs.map} +1 -1
  6. package/dist/{chunk-L32BTN2M.cjs → chunk-5HNRVLH2.cjs} +4 -4
  7. package/dist/{chunk-L32BTN2M.cjs.map → chunk-5HNRVLH2.cjs.map} +1 -1
  8. package/dist/{chunk-2MHJ5LZ7.cjs → chunk-5QRRUXRI.cjs} +2 -2
  9. package/dist/{chunk-2MHJ5LZ7.cjs.map → chunk-5QRRUXRI.cjs.map} +1 -1
  10. package/dist/{chunk-VEU5LPA6.cjs → chunk-6GWHYOPM.cjs} +2 -2
  11. package/dist/{chunk-VEU5LPA6.cjs.map → chunk-6GWHYOPM.cjs.map} +1 -1
  12. package/dist/{chunk-L5QUUSVB.cjs → chunk-7OG6A4LI.cjs} +4 -4
  13. package/dist/{chunk-L5QUUSVB.cjs.map → chunk-7OG6A4LI.cjs.map} +1 -1
  14. package/dist/{chunk-XN6WUCF4.cjs → chunk-ACHJOO4S.cjs} +2 -2
  15. package/dist/{chunk-XN6WUCF4.cjs.map → chunk-ACHJOO4S.cjs.map} +1 -1
  16. package/dist/{chunk-KOXU6674.cjs → chunk-BLSMEA5C.cjs} +2 -2
  17. package/dist/{chunk-KOXU6674.cjs.map → chunk-BLSMEA5C.cjs.map} +1 -1
  18. package/dist/{chunk-SONNKP33.cjs → chunk-CP42F62X.cjs} +6 -6
  19. package/dist/chunk-CP42F62X.cjs.map +1 -0
  20. package/dist/{chunk-K65NYGJM.cjs → chunk-FE6CECES.cjs} +12 -12
  21. package/dist/{chunk-K65NYGJM.cjs.map → chunk-FE6CECES.cjs.map} +1 -1
  22. package/dist/{chunk-5TKJLZA2.cjs → chunk-JKEVZFNY.cjs} +2 -2
  23. package/dist/{chunk-5TKJLZA2.cjs.map → chunk-JKEVZFNY.cjs.map} +1 -1
  24. package/dist/{chunk-U2XRCT7A.cjs → chunk-M7EKT75X.cjs} +2 -2
  25. package/dist/{chunk-U2XRCT7A.cjs.map → chunk-M7EKT75X.cjs.map} +1 -1
  26. package/dist/{chunk-QAKUAPPO.cjs → chunk-QMXGMC2H.cjs} +2 -2
  27. package/dist/{chunk-QAKUAPPO.cjs.map → chunk-QMXGMC2H.cjs.map} +1 -1
  28. package/dist/{chunk-AZ4GTUNR.cjs → chunk-TQEFJGW6.cjs} +21 -21
  29. package/dist/{chunk-AZ4GTUNR.cjs.map → chunk-TQEFJGW6.cjs.map} +1 -1
  30. package/dist/{chunk-FTXFBDFW.cjs → chunk-UBVZKE7V.cjs} +2 -2
  31. package/dist/{chunk-FTXFBDFW.cjs.map → chunk-UBVZKE7V.cjs.map} +1 -1
  32. package/dist/{impl-MENWC3FS.cjs → impl-24WXRAZH.cjs} +2 -2
  33. package/dist/{impl-MENWC3FS.cjs.map → impl-24WXRAZH.cjs.map} +1 -1
  34. package/dist/{impl-S2UBMTKQ.cjs → impl-2QA5YMX7.cjs} +2 -2
  35. package/dist/{impl-S2UBMTKQ.cjs.map → impl-2QA5YMX7.cjs.map} +1 -1
  36. package/dist/{impl-CCY7BINI.cjs → impl-33BZGWDB.cjs} +2 -2
  37. package/dist/{impl-CCY7BINI.cjs.map → impl-33BZGWDB.cjs.map} +1 -1
  38. package/dist/{impl-JHP4RJZ4.cjs → impl-3NHKBP7U.cjs} +2 -2
  39. package/dist/{impl-JHP4RJZ4.cjs.map → impl-3NHKBP7U.cjs.map} +1 -1
  40. package/dist/{impl-JYAKR5RR.cjs → impl-47P6B22N.cjs} +2 -2
  41. package/dist/{impl-JYAKR5RR.cjs.map → impl-47P6B22N.cjs.map} +1 -1
  42. package/dist/impl-5T356QQ5.cjs +2 -0
  43. package/dist/impl-5T356QQ5.cjs.map +1 -0
  44. package/dist/{impl-PK3DXVLW.cjs → impl-72VUDRUK.cjs} +2 -2
  45. package/dist/{impl-PK3DXVLW.cjs.map → impl-72VUDRUK.cjs.map} +1 -1
  46. package/dist/{impl-SAWOUYGV.cjs → impl-7RRE2GGO.cjs} +2 -2
  47. package/dist/{impl-SAWOUYGV.cjs.map → impl-7RRE2GGO.cjs.map} +1 -1
  48. package/dist/{impl-3BLJB5VJ.cjs → impl-7V22LA5U.cjs} +2 -2
  49. package/dist/{impl-3BLJB5VJ.cjs.map → impl-7V22LA5U.cjs.map} +1 -1
  50. package/dist/{impl-5PPLTGRY.cjs → impl-A7QHIGMS.cjs} +2 -2
  51. package/dist/{impl-5PPLTGRY.cjs.map → impl-A7QHIGMS.cjs.map} +1 -1
  52. package/dist/{impl-KZZC7P5D.cjs → impl-ARSWR7NX.cjs} +2 -2
  53. package/dist/{impl-KZZC7P5D.cjs.map → impl-ARSWR7NX.cjs.map} +1 -1
  54. package/dist/{impl-XJX7GD3G.cjs → impl-BEATRFDE.cjs} +2 -2
  55. package/dist/{impl-XJX7GD3G.cjs.map → impl-BEATRFDE.cjs.map} +1 -1
  56. package/dist/{impl-S6GUFHKS.cjs → impl-BQKRH5GQ.cjs} +2 -2
  57. package/dist/{impl-S6GUFHKS.cjs.map → impl-BQKRH5GQ.cjs.map} +1 -1
  58. package/dist/{impl-YZ6LZ2LI.cjs → impl-CBO3W76N.cjs} +2 -2
  59. package/dist/{impl-YZ6LZ2LI.cjs.map → impl-CBO3W76N.cjs.map} +1 -1
  60. package/dist/{impl-X5JUJPG5.cjs → impl-CSXBLMR7.cjs} +2 -2
  61. package/dist/{impl-X5JUJPG5.cjs.map → impl-CSXBLMR7.cjs.map} +1 -1
  62. package/dist/{impl-HZJIVXWT.cjs → impl-DVDXXRQC.cjs} +2 -2
  63. package/dist/{impl-HZJIVXWT.cjs.map → impl-DVDXXRQC.cjs.map} +1 -1
  64. package/dist/impl-EMD77BVT.cjs +2 -0
  65. package/dist/{impl-3TTJGFRK.cjs.map → impl-EMD77BVT.cjs.map} +1 -1
  66. package/dist/{impl-H3J7N77A.cjs → impl-FHICSIT4.cjs} +2 -2
  67. package/dist/{impl-H3J7N77A.cjs.map → impl-FHICSIT4.cjs.map} +1 -1
  68. package/dist/{impl-2CF2PKFH.cjs → impl-FK7FC2AF.cjs} +2 -2
  69. package/dist/{impl-2CF2PKFH.cjs.map → impl-FK7FC2AF.cjs.map} +1 -1
  70. package/dist/{impl-L74WP6LX.cjs → impl-GCAHKCXJ.cjs} +2 -2
  71. package/dist/{impl-L74WP6LX.cjs.map → impl-GCAHKCXJ.cjs.map} +1 -1
  72. package/dist/{impl-UR7MDG5O.cjs → impl-GOJL7NWE.cjs} +2 -2
  73. package/dist/{impl-UR7MDG5O.cjs.map → impl-GOJL7NWE.cjs.map} +1 -1
  74. package/dist/{impl-DEQW3OGQ.cjs → impl-HRVPP3AF.cjs} +2 -2
  75. package/dist/{impl-DEQW3OGQ.cjs.map → impl-HRVPP3AF.cjs.map} +1 -1
  76. package/dist/{impl-2XEHL54N.cjs → impl-JY5JVCKH.cjs} +2 -2
  77. package/dist/{impl-2XEHL54N.cjs.map → impl-JY5JVCKH.cjs.map} +1 -1
  78. package/dist/{impl-4GZIUG3H.cjs → impl-K7NLXEZN.cjs} +3 -3
  79. package/dist/{impl-4GZIUG3H.cjs.map → impl-K7NLXEZN.cjs.map} +1 -1
  80. package/dist/{impl-IQCQDDW7.cjs → impl-KBXUU7JT.cjs} +2 -2
  81. package/dist/{impl-IQCQDDW7.cjs.map → impl-KBXUU7JT.cjs.map} +1 -1
  82. package/dist/{impl-QVM227RD.cjs → impl-LDYN63H6.cjs} +2 -2
  83. package/dist/{impl-QVM227RD.cjs.map → impl-LDYN63H6.cjs.map} +1 -1
  84. package/dist/{impl-UTJTENWY.cjs → impl-LOR6NAV6.cjs} +2 -2
  85. package/dist/{impl-UTJTENWY.cjs.map → impl-LOR6NAV6.cjs.map} +1 -1
  86. package/dist/{impl-SBIOFGRE.cjs → impl-M4OXXOMC.cjs} +2 -2
  87. package/dist/{impl-SBIOFGRE.cjs.map → impl-M4OXXOMC.cjs.map} +1 -1
  88. package/dist/impl-M6YOD7LA.cjs +2 -0
  89. package/dist/{impl-43MGE5WS.cjs.map → impl-M6YOD7LA.cjs.map} +1 -1
  90. package/dist/{impl-J3FUD3MS.cjs → impl-NILGKSUG.cjs} +5 -5
  91. package/dist/{impl-J3FUD3MS.cjs.map → impl-NILGKSUG.cjs.map} +1 -1
  92. package/dist/{impl-BEVLBZ2F.cjs → impl-NVHVPNKZ.cjs} +2 -2
  93. package/dist/{impl-BEVLBZ2F.cjs.map → impl-NVHVPNKZ.cjs.map} +1 -1
  94. package/dist/{impl-35DXHKNE.cjs → impl-ONAOXMKU.cjs} +2 -2
  95. package/dist/{impl-35DXHKNE.cjs.map → impl-ONAOXMKU.cjs.map} +1 -1
  96. package/dist/{impl-WLYI6G4A.cjs → impl-OU5VJBRQ.cjs} +4 -4
  97. package/dist/{impl-WLYI6G4A.cjs.map → impl-OU5VJBRQ.cjs.map} +1 -1
  98. package/dist/{impl-4VNXB52F.cjs → impl-RHZNZ6CW.cjs} +2 -2
  99. package/dist/{impl-4VNXB52F.cjs.map → impl-RHZNZ6CW.cjs.map} +1 -1
  100. package/dist/{impl-JK3TTCKR.cjs → impl-SXOCIQPX.cjs} +2 -2
  101. package/dist/{impl-JK3TTCKR.cjs.map → impl-SXOCIQPX.cjs.map} +1 -1
  102. package/dist/{impl-7TIKA2O6.cjs → impl-TSZSY33S.cjs} +2 -2
  103. package/dist/{impl-7TIKA2O6.cjs.map → impl-TSZSY33S.cjs.map} +1 -1
  104. package/dist/{impl-UTDGC4UZ.cjs → impl-VSGGPMKM.cjs} +2 -2
  105. package/dist/{impl-UTDGC4UZ.cjs.map → impl-VSGGPMKM.cjs.map} +1 -1
  106. package/dist/{impl-LUKG7ED6.cjs → impl-VUMK2QR4.cjs} +2 -2
  107. package/dist/{impl-LUKG7ED6.cjs.map → impl-VUMK2QR4.cjs.map} +1 -1
  108. package/dist/{impl-VEW5WAK7.cjs → impl-WJZL3F6W.cjs} +3 -3
  109. package/dist/{impl-VEW5WAK7.cjs.map → impl-WJZL3F6W.cjs.map} +1 -1
  110. package/dist/{impl-W33BLTPN.cjs → impl-YEQ5CW47.cjs} +2 -2
  111. package/dist/{impl-W33BLTPN.cjs.map → impl-YEQ5CW47.cjs.map} +1 -1
  112. package/dist/{impl-F2UNSOIO.cjs → impl-ZA3FYBHK.cjs} +2 -2
  113. package/dist/{impl-F2UNSOIO.cjs.map → impl-ZA3FYBHK.cjs.map} +1 -1
  114. package/dist/index.cjs +3 -3
  115. package/dist/index.d.cts +8 -4
  116. package/package.json +1 -1
  117. package/dist/chunk-SONNKP33.cjs.map +0 -1
  118. package/dist/impl-3TTJGFRK.cjs +0 -2
  119. package/dist/impl-43MGE5WS.cjs +0 -2
  120. package/dist/impl-K6MYBWAY.cjs +0 -2
  121. package/dist/impl-K6MYBWAY.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- "use strict"; function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkT462ONFXcjs = require('../chunk-T462ONFX.cjs');var _chunkAZ4GTUNRcjs = require('../chunk-AZ4GTUNR.cjs');require('../chunk-U2XRCT7A.cjs');require('../chunk-FTXFBDFW.cjs');require('../chunk-Q7I37FJV.cjs');var _core = require('@stricli/core');async function e(){let o=process.argv.slice(3);_optionalChain([process, 'access', _ => _.env, 'access', _2 => _2.COMP_LINE, 'optionalAccess', _3 => _3.endsWith, 'call', _4 => _4(" ")])&&o.push(""),await _core.proposeCompletions.call(void 0, _chunkAZ4GTUNRcjs.a,o,_chunkT462ONFXcjs.a.call(void 0, process));try{for(let{completion:r}of await _core.proposeCompletions.call(void 0, _chunkAZ4GTUNRcjs.a,o,_chunkT462ONFXcjs.a.call(void 0, process)))process.stdout.write(`${r}
2
+ "use strict"; function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkT462ONFXcjs = require('../chunk-T462ONFX.cjs');var _chunkTQEFJGW6cjs = require('../chunk-TQEFJGW6.cjs');require('../chunk-M7EKT75X.cjs');require('../chunk-UBVZKE7V.cjs');require('../chunk-Q7I37FJV.cjs');var _core = require('@stricli/core');async function e(){let o=process.argv.slice(3);_optionalChain([process, 'access', _ => _.env, 'access', _2 => _2.COMP_LINE, 'optionalAccess', _3 => _3.endsWith, 'call', _4 => _4(" ")])&&o.push(""),await _core.proposeCompletions.call(void 0, _chunkTQEFJGW6cjs.a,o,_chunkT462ONFXcjs.a.call(void 0, process));try{for(let{completion:r}of await _core.proposeCompletions.call(void 0, _chunkTQEFJGW6cjs.a,o,_chunkT462ONFXcjs.a.call(void 0, process)))process.stdout.write(`${r}
3
3
  `)}catch (e2){}}e();
4
4
  //# sourceMappingURL=bash-complete.cjs.map
package/dist/bin/cli.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var _chunkT462ONFXcjs = require('../chunk-T462ONFX.cjs');var _chunkAZ4GTUNRcjs = require('../chunk-AZ4GTUNR.cjs');require('../chunk-U2XRCT7A.cjs');require('../chunk-FTXFBDFW.cjs');require('../chunk-Q7I37FJV.cjs');var _core = require('@stricli/core');async function n(){await _core.run.call(void 0, _chunkAZ4GTUNRcjs.a,process.argv.slice(2),_chunkT462ONFXcjs.a.call(void 0, process))}n();
2
+ "use strict";var _chunkT462ONFXcjs = require('../chunk-T462ONFX.cjs');var _chunkTQEFJGW6cjs = require('../chunk-TQEFJGW6.cjs');require('../chunk-M7EKT75X.cjs');require('../chunk-UBVZKE7V.cjs');require('../chunk-Q7I37FJV.cjs');var _core = require('@stricli/core');async function n(){await _core.run.call(void 0, _chunkTQEFJGW6cjs.a,process.argv.slice(2),_chunkT462ONFXcjs.a.call(void 0, process))}n();
3
3
  //# sourceMappingURL=cli.cjs.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- "use strict"; function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkAZ4GTUNRcjs = require('../chunk-AZ4GTUNR.cjs');require('../chunk-U2XRCT7A.cjs');var _chunkZUNVPK23cjs = require('../chunk-ZUNVPK23.cjs');require('../chunk-FTXFBDFW.cjs');require('../chunk-Q7I37FJV.cjs');var _core = require('@stricli/core');var o={"tr-build-xdi-sync-endpoint":["consent","build-xdi-sync-endpoint"],"tr-consent-manager-service-json-to-yml":["inventory","consent-manager-service-json-to-yml"],"tr-consent-managers-to-business-entities":["inventory","consent-managers-to-business-entities"],"tr-cron-mark-identifiers-completed":["request","cron","mark-identifiers-completed"],"tr-cron-pull-identifiers":["request","cron","pull-identifiers"],"tr-derive-data-silos-from-data-flows":["inventory","derive-data-silos-from-data-flows"],"tr-derive-data-silos-from-data-flows-cross-instance":["inventory","derive-data-silos-from-data-flows-cross-instance"],"tr-discover-silos":["inventory","discover-silos"],"tr-generate-api-keys":["admin","generate-api-keys"],"tr-manual-enrichment-pull-identifiers":["request","preflight","pull-identifiers"],"tr-manual-enrichment-push-identifiers":["request","preflight","push-identifiers"],"tr-mark-request-data-silos-completed":["request","system","mark-request-data-silos-completed"],"tr-pull":["inventory","pull"],"tr-pull-consent-metrics":["consent","pull-consent-metrics"],"tr-pull-consent-preferences":["consent","pull-consent-preferences"],"tr-pull-datapoints":["inventory","pull-datapoints"],"tr-pull-pull-unstructured-discovery-files":["inventory","pull-unstructured-discovery-files"],"tr-push":["inventory","push"],"tr-request-approve":["request","approve"],"tr-request-cancel":["request","cancel"],"tr-request-download-files":["request","download-files"],"tr-request-enricher-restart":["request","enricher-restart"],"tr-request-export":["request","export"],"tr-request-mark-silent":["request","mark-silent"],"tr-request-notify-additional-time":["request","notify-additional-time"],"tr-request-reject-unverified-identifiers":["request","reject-unverified-identifiers"],"tr-request-restart":["request","restart"],"tr-request-upload":["request","upload"],"tr-retry-request-data-silos":["request","system","retry-request-data-silos"],"tr-scan-packages":["inventory","scan-packages"],"tr-skip-preflight-jobs":["request","skip-preflight-jobs"],"tr-skip-request-data-silos":["request","system","skip-request-data-silos"],"tr-sync-ot":["migration","sync-ot"],"tr-update-consent-manager":["consent","update-consent-manager"],"tr-upload-consent-preferences":["consent","upload-consent-preferences"],"tr-upload-cookies-from-csv":["consent","upload-cookies-from-csv"],"tr-upload-data-flows-from-csv":["consent","upload-data-flows-from-csv"],"tr-upload-preferences":["consent","upload-preferences"]};function p(t){return _optionalChain([_core.generateHelpTextForAllCommands.call(void 0, _chunkAZ4GTUNRcjs.a), 'access', _ => _.find, 'call', _2 => _2(s=>s[0]===`${_chunkAZ4GTUNRcjs.a.config.name} ${t.join(" ")}`), 'optionalAccess', _3 => _3[1]])}function i(t){_chunkZUNVPK23cjs.a.log("[DEPRECATION NOTICE]");let e=o[t];if(!e){let a=Object.entries(o).map(([l,d])=>`\`${l}\` -> \`${_chunkAZ4GTUNRcjs.a.config.name} ${d.join(" ")}\``).join(`
2
+ "use strict"; function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkTQEFJGW6cjs = require('../chunk-TQEFJGW6.cjs');require('../chunk-M7EKT75X.cjs');var _chunkZUNVPK23cjs = require('../chunk-ZUNVPK23.cjs');require('../chunk-UBVZKE7V.cjs');require('../chunk-Q7I37FJV.cjs');var _core = require('@stricli/core');var o={"tr-build-xdi-sync-endpoint":["consent","build-xdi-sync-endpoint"],"tr-consent-manager-service-json-to-yml":["inventory","consent-manager-service-json-to-yml"],"tr-consent-managers-to-business-entities":["inventory","consent-managers-to-business-entities"],"tr-cron-mark-identifiers-completed":["request","cron","mark-identifiers-completed"],"tr-cron-pull-identifiers":["request","cron","pull-identifiers"],"tr-derive-data-silos-from-data-flows":["inventory","derive-data-silos-from-data-flows"],"tr-derive-data-silos-from-data-flows-cross-instance":["inventory","derive-data-silos-from-data-flows-cross-instance"],"tr-discover-silos":["inventory","discover-silos"],"tr-generate-api-keys":["admin","generate-api-keys"],"tr-manual-enrichment-pull-identifiers":["request","preflight","pull-identifiers"],"tr-manual-enrichment-push-identifiers":["request","preflight","push-identifiers"],"tr-mark-request-data-silos-completed":["request","system","mark-request-data-silos-completed"],"tr-pull":["inventory","pull"],"tr-pull-consent-metrics":["consent","pull-consent-metrics"],"tr-pull-consent-preferences":["consent","pull-consent-preferences"],"tr-pull-datapoints":["inventory","pull-datapoints"],"tr-pull-pull-unstructured-discovery-files":["inventory","pull-unstructured-discovery-files"],"tr-push":["inventory","push"],"tr-request-approve":["request","approve"],"tr-request-cancel":["request","cancel"],"tr-request-download-files":["request","download-files"],"tr-request-enricher-restart":["request","enricher-restart"],"tr-request-export":["request","export"],"tr-request-mark-silent":["request","mark-silent"],"tr-request-notify-additional-time":["request","notify-additional-time"],"tr-request-reject-unverified-identifiers":["request","reject-unverified-identifiers"],"tr-request-restart":["request","restart"],"tr-request-upload":["request","upload"],"tr-retry-request-data-silos":["request","system","retry-request-data-silos"],"tr-scan-packages":["inventory","scan-packages"],"tr-skip-preflight-jobs":["request","skip-preflight-jobs"],"tr-skip-request-data-silos":["request","system","skip-request-data-silos"],"tr-sync-ot":["migration","sync-ot"],"tr-update-consent-manager":["consent","update-consent-manager"],"tr-upload-consent-preferences":["consent","upload-consent-preferences"],"tr-upload-cookies-from-csv":["consent","upload-cookies-from-csv"],"tr-upload-data-flows-from-csv":["consent","upload-data-flows-from-csv"],"tr-upload-preferences":["consent","upload-preferences"]};function p(t){return _optionalChain([_core.generateHelpTextForAllCommands.call(void 0, _chunkTQEFJGW6cjs.a), 'access', _ => _.find, 'call', _2 => _2(s=>s[0]===`${_chunkTQEFJGW6cjs.a.config.name} ${t.join(" ")}`), 'optionalAccess', _3 => _3[1]])}function i(t){_chunkZUNVPK23cjs.a.log("[DEPRECATION NOTICE]");let e=o[t];if(!e){let a=Object.entries(o).map(([l,d])=>`\`${l}\` -> \`${_chunkTQEFJGW6cjs.a.config.name} ${d.join(" ")}\``).join(`
3
3
  `);_chunkZUNVPK23cjs.a.log(`This command is deprecated as of v7.0.0. Here is a list of new commands, mapped to their legacy command names:
4
4
  ${a}`);return}_chunkZUNVPK23cjs.a.log(`\`${t}\` is deprecated as of v7.0.0.
5
- Use \`${_chunkAZ4GTUNRcjs.a.config.name} ${e.join(" ")}\` instead.
5
+ Use \`${_chunkTQEFJGW6cjs.a.config.name} ${e.join(" ")}\` instead.
6
6
  `);let s=p(e);if(!s)throw new Error(`Failed to get help text for command: \`${e.join(" ")}\``);_chunkZUNVPK23cjs.a.log(s)}function m(){let e=_optionalChain([process, 'access', _4 => _4.argv, 'access', _5 => _5.at, 'call', _6 => _6(-1), 'optionalAccess', _7 => _7.split, 'call', _8 => _8("/"), 'access', _9 => _9.pop, 'call', _10 => _10(), 'optionalAccess', _11 => _11.trim, 'call', _12 => _12()]);if(e)i(e);else throw new Error("Deprecated command");process.exit(1)}m();
7
7
  //# sourceMappingURL=deprecated-command.cjs.map
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunk5UBGZNDCcjs = require('./chunk-5UBGZNDC.cjs');var _chunkK65NYGJMcjs = require('./chunk-K65NYGJM.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');var _chunkFTXFBDFWcjs = require('./chunk-FTXFBDFW.cjs');var _privacytypes = require('@transcend-io/privacy-types');var _bluebird = require('bluebird');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);async function nt({auth:e,deploy:s=!1,transcendUrl:o=_chunkFTXFBDFWcjs.r,bundleTypes:t=Object.values(_privacytypes.ConsentBundleType)}){let a=_chunkK65NYGJMcjs.wc.call(void 0, o,e),n=await _chunkK65NYGJMcjs.Qc.call(void 0, a);await _bluebird.mapSeries.call(void 0, t,async i=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Update Consent Manager bundle with ID "${n}" and type "${i}" to latest version...`)),await _chunkK65NYGJMcjs.Ac.call(void 0, a,{id:n,bundleType:i}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Updated Consent Manager bundle with ID "${n}" and type "${i}" to latest version!`))}),s&&await _bluebird.mapSeries.call(void 0, t,async i=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Deploying Consent Manager bundle with ID "${n}" and type "${i}"...`)),await _chunkK65NYGJMcjs.zc.call(void 0, a,{id:n,bundleType:i}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Deployed Consent Manager bundle with ID "${n}" and type "${i}"!`))})}var F=["ID","Activity","Encounters","Last Seen At","Has Native Do Not Sell/Share Support","IAB USP API Support","Service Description","Website URL","Categories of Recipients"];async function ft({auth:e,trackerStatus:s,file:o,classifyService:t=!1,transcendUrl:a=_chunkFTXFBDFWcjs.r}){let n=_chunkK65NYGJMcjs.wc.call(void 0, a,e);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading "${o}" from disk`));let l=_chunkK65NYGJMcjs.rc.call(void 0, o,_chunk5UBGZNDCcjs.ia).map(({Type:S,Notes:p,Service:m,Purpose:C,Status:f,Owners:E,Teams:T,"Connections Made To":A,...I})=>({value:A,type:S,description:p,trackingPurposes:_chunkK65NYGJMcjs.oc.call(void 0, C),status:f||s,owners:E?_chunkK65NYGJMcjs.oc.call(void 0, E):void 0,teams:T?_chunkK65NYGJMcjs.oc.call(void 0, T):void 0,attributes:Object.entries(I).filter(([y])=>!F.includes(y)).map(([y,$])=>({key:y,values:_chunkK65NYGJMcjs.oc.call(void 0, $)}))}));await _chunkK65NYGJMcjs.We.call(void 0, n,l,t)||(_chunkZUNVPK23cjs.a.error(_colors2.default.red("Encountered error(s) syncing data flows from CSV, see logs above for more info. ")),process.exit(1))}var H=["ID","Activity","Encounters","Last Seen At","Has Native Do Not Sell/Share Support","IAB USP API Support","Service Description","Website URL","Categories of Recipients"];async function Mt({auth:e,trackerStatus:s,file:o,transcendUrl:t=_chunkFTXFBDFWcjs.r}){let a=_chunkK65NYGJMcjs.wc.call(void 0, t,e);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading "${o}" from disk`));let i=_chunkK65NYGJMcjs.rc.call(void 0, o,_chunk5UBGZNDCcjs.ja).map(({"Is Regex?":c,Notes:S,Service:p,Purpose:m,Status:C,Owners:f,Teams:E,Name:T,...A})=>({...typeof c=="string"?{isRegex:c.toLowerCase()==="true"}:{},name:T,description:S,trackingPurposes:_chunkK65NYGJMcjs.oc.call(void 0, m),status:C||s,owners:f?_chunkK65NYGJMcjs.oc.call(void 0, f):void 0,teams:E?_chunkK65NYGJMcjs.oc.call(void 0, E):void 0,attributes:Object.entries(A).filter(([I])=>!H.includes(I)).map(([I,y])=>({key:I,values:_chunkK65NYGJMcjs.oc.call(void 0, y)}))}));await _chunkK65NYGJMcjs.Qe.call(void 0, a,i)||(_chunkZUNVPK23cjs.a.error(_colors2.default.red("Encountered error(s) syncing cookies from CSV, see logs above for more info. ")),process.exit(1))}var Y=1e3,j=60*Y,Q=60*j,V=24*Q,X=7*V;async function Rt(e,{bin:s,start:o,end:t=new Date}){let a=await _chunkK65NYGJMcjs.Qc.call(void 0, e),n=Math.floor(o.getTime()/1e3),i=Math.floor(t.getTime()/1e3);if(n>i)throw new Error('Received "end" date that happened before "start" date');if(s==="1h"&&t.getTime()-o.getTime()>X*2)throw new Error("When using bin=1h, start and end time can be no more than 2 weeks apart");let l=o.toISOString(),c=t.toISOString(),[S,p,m]=await Promise.all([_chunkK65NYGJMcjs.Tc.call(void 0, e,{dataSource:"PRIVACY_SIGNAL_TIMESERIES",startDate:l,endDate:c,forceRefetch:!0,airgapBundleId:a,binInterval:s,smoothTimeseries:!1}),_chunkK65NYGJMcjs.Tc.call(void 0, e,{dataSource:"CONSENT_CHANGES_TIMESERIES",startDate:l,endDate:c,forceRefetch:!0,airgapBundleId:a,binInterval:s,smoothTimeseries:!1}),_chunkK65NYGJMcjs.Tc.call(void 0, e,{dataSource:"CONSENT_SESSIONS_BY_REGIME",startDate:l,endDate:c,forceRefetch:!0,airgapBundleId:a,binInterval:s,smoothTimeseries:!1})]);return{PRIVACY_SIGNAL_TIMESERIES:S,CONSENT_CHANGES_TIMESERIES:p,CONSENT_SESSIONS_BY_REGIME:m}}var G=e=>new URL(`https://${e}`).hostname.split(".").slice(-2).join(".");var W=/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;async function Gt(e,{xdiLocation:s,transcendUrl:o=_chunkFTXFBDFWcjs.r,removeIpAddresses:t=!0,domainBlockList:a=["localhost"],xdiAllowedCommands:n="ConsentManager:Sync"}){let i=Array.isArray(e)?e:[{apiKey:e,organizationId:"",organizationName:""}],l=await _bluebird.map.call(void 0, i,async p=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Pulling consent metadata for organization - ${p.organizationName}`));let m=_chunkK65NYGJMcjs.wc.call(void 0, o,p.apiKey);return await _chunkK65NYGJMcjs.Pc.call(void 0, m)},{concurrency:5}),c={};return l.forEach(p=>{let m=_optionalChain([p, 'access', _2 => _2.partition, 'optionalAccess', _3 => _3.partition])||p.bundleURL.split("/").reverse()[1];c[m]||(c[m]=[]);let C=_chunkFTXFBDFWcjs.c.call(void 0, p.configuration.domains.filter(f=>!t||!W.test(f)).map(f=>G(f)),a);c[m]=[...new Set([...c[m]||[],...C])]}),{html:`
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunk5UBGZNDCcjs = require('./chunk-5UBGZNDC.cjs');var _chunkFE6CECEScjs = require('./chunk-FE6CECES.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');var _chunkUBVZKE7Vcjs = require('./chunk-UBVZKE7V.cjs');var _privacytypes = require('@transcend-io/privacy-types');var _bluebird = require('bluebird');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);async function nt({auth:e,deploy:s=!1,transcendUrl:o=_chunkUBVZKE7Vcjs.r,bundleTypes:t=Object.values(_privacytypes.ConsentBundleType)}){let a=_chunkFE6CECEScjs.wc.call(void 0, o,e),n=await _chunkFE6CECEScjs.Qc.call(void 0, a);await _bluebird.mapSeries.call(void 0, t,async i=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Update Consent Manager bundle with ID "${n}" and type "${i}" to latest version...`)),await _chunkFE6CECEScjs.Ac.call(void 0, a,{id:n,bundleType:i}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Updated Consent Manager bundle with ID "${n}" and type "${i}" to latest version!`))}),s&&await _bluebird.mapSeries.call(void 0, t,async i=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Deploying Consent Manager bundle with ID "${n}" and type "${i}"...`)),await _chunkFE6CECEScjs.zc.call(void 0, a,{id:n,bundleType:i}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Deployed Consent Manager bundle with ID "${n}" and type "${i}"!`))})}var F=["ID","Activity","Encounters","Last Seen At","Has Native Do Not Sell/Share Support","IAB USP API Support","Service Description","Website URL","Categories of Recipients"];async function ft({auth:e,trackerStatus:s,file:o,classifyService:t=!1,transcendUrl:a=_chunkUBVZKE7Vcjs.r}){let n=_chunkFE6CECEScjs.wc.call(void 0, a,e);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading "${o}" from disk`));let l=_chunkFE6CECEScjs.rc.call(void 0, o,_chunk5UBGZNDCcjs.ia).map(({Type:S,Notes:p,Service:m,Purpose:C,Status:f,Owners:E,Teams:T,"Connections Made To":A,...I})=>({value:A,type:S,description:p,trackingPurposes:_chunkFE6CECEScjs.oc.call(void 0, C),status:f||s,owners:E?_chunkFE6CECEScjs.oc.call(void 0, E):void 0,teams:T?_chunkFE6CECEScjs.oc.call(void 0, T):void 0,attributes:Object.entries(I).filter(([y])=>!F.includes(y)).map(([y,$])=>({key:y,values:_chunkFE6CECEScjs.oc.call(void 0, $)}))}));await _chunkFE6CECEScjs.We.call(void 0, n,l,t)||(_chunkZUNVPK23cjs.a.error(_colors2.default.red("Encountered error(s) syncing data flows from CSV, see logs above for more info. ")),process.exit(1))}var H=["ID","Activity","Encounters","Last Seen At","Has Native Do Not Sell/Share Support","IAB USP API Support","Service Description","Website URL","Categories of Recipients"];async function Mt({auth:e,trackerStatus:s,file:o,transcendUrl:t=_chunkUBVZKE7Vcjs.r}){let a=_chunkFE6CECEScjs.wc.call(void 0, t,e);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading "${o}" from disk`));let i=_chunkFE6CECEScjs.rc.call(void 0, o,_chunk5UBGZNDCcjs.ja).map(({"Is Regex?":c,Notes:S,Service:p,Purpose:m,Status:C,Owners:f,Teams:E,Name:T,...A})=>({...typeof c=="string"?{isRegex:c.toLowerCase()==="true"}:{},name:T,description:S,trackingPurposes:_chunkFE6CECEScjs.oc.call(void 0, m),status:C||s,owners:f?_chunkFE6CECEScjs.oc.call(void 0, f):void 0,teams:E?_chunkFE6CECEScjs.oc.call(void 0, E):void 0,attributes:Object.entries(A).filter(([I])=>!H.includes(I)).map(([I,y])=>({key:I,values:_chunkFE6CECEScjs.oc.call(void 0, y)}))}));await _chunkFE6CECEScjs.Qe.call(void 0, a,i)||(_chunkZUNVPK23cjs.a.error(_colors2.default.red("Encountered error(s) syncing cookies from CSV, see logs above for more info. ")),process.exit(1))}var Y=1e3,j=60*Y,Q=60*j,V=24*Q,X=7*V;async function Rt(e,{bin:s,start:o,end:t=new Date}){let a=await _chunkFE6CECEScjs.Qc.call(void 0, e),n=Math.floor(o.getTime()/1e3),i=Math.floor(t.getTime()/1e3);if(n>i)throw new Error('Received "end" date that happened before "start" date');if(s==="1h"&&t.getTime()-o.getTime()>X*2)throw new Error("When using bin=1h, start and end time can be no more than 2 weeks apart");let l=o.toISOString(),c=t.toISOString(),[S,p,m]=await Promise.all([_chunkFE6CECEScjs.Tc.call(void 0, e,{dataSource:"PRIVACY_SIGNAL_TIMESERIES",startDate:l,endDate:c,forceRefetch:!0,airgapBundleId:a,binInterval:s,smoothTimeseries:!1}),_chunkFE6CECEScjs.Tc.call(void 0, e,{dataSource:"CONSENT_CHANGES_TIMESERIES",startDate:l,endDate:c,forceRefetch:!0,airgapBundleId:a,binInterval:s,smoothTimeseries:!1}),_chunkFE6CECEScjs.Tc.call(void 0, e,{dataSource:"CONSENT_SESSIONS_BY_REGIME",startDate:l,endDate:c,forceRefetch:!0,airgapBundleId:a,binInterval:s,smoothTimeseries:!1})]);return{PRIVACY_SIGNAL_TIMESERIES:S,CONSENT_CHANGES_TIMESERIES:p,CONSENT_SESSIONS_BY_REGIME:m}}var G=e=>new URL(`https://${e}`).hostname.split(".").slice(-2).join(".");var W=/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;async function Gt(e,{xdiLocation:s,transcendUrl:o=_chunkUBVZKE7Vcjs.r,removeIpAddresses:t=!0,domainBlockList:a=["localhost"],xdiAllowedCommands:n="ConsentManager:Sync"}){let i=Array.isArray(e)?e:[{apiKey:e,organizationId:"",organizationName:""}],l=await _bluebird.map.call(void 0, i,async p=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Pulling consent metadata for organization - ${p.organizationName}`));let m=_chunkFE6CECEScjs.wc.call(void 0, o,p.apiKey);return await _chunkFE6CECEScjs.Pc.call(void 0, m)},{concurrency:5}),c={};return l.forEach(p=>{let m=_optionalChain([p, 'access', _2 => _2.partition, 'optionalAccess', _3 => _3.partition])||p.bundleURL.split("/").reverse()[1];c[m]||(c[m]=[]);let C=_chunkUBVZKE7Vcjs.c.call(void 0, p.configuration.domains.filter(f=>!t||!W.test(f)).map(f=>G(f)),a);c[m]=[...new Set([...c[m]||[],...C])]}),{html:`
2
2
  <!DOCTYPE html>
3
3
  <script
4
4
  src="${s}"
@@ -9,4 +9,4 @@ data-xdi-commands="${n}"
9
9
 
10
10
  ~~~~~~~~~~~
11
11
  Airgap scripts to host:`),s.forEach(({attributes:o,title:t},a)=>{_optionalChain([o, 'optionalAccess', _7 => _7.find, 'call', _8 => _8(n=>n.key==="Airgap Production URL"), 'optionalAccess', _9 => _9.values, 'optionalAccess', _10 => _10.forEach, 'call', _11 => _11(n=>{_chunkZUNVPK23cjs.a.info(`${a}) ${t} - ${n}`)})])}),s}exports.a = nt; exports.b = ft; exports.c = Mt; exports.d = Rt; exports.e = G; exports.f = W; exports.g = Gt; exports.h = Ft;
12
- //# sourceMappingURL=chunk-WGCFVEJZ.cjs.map
12
+ //# sourceMappingURL=chunk-4LSUJDDH.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-WGCFVEJZ.cjs","../src/lib/consent-manager/updateConsentManagerVersionToLatest.ts","../src/lib/consent-manager/uploadDataFlowsFromCsv.ts","../src/lib/consent-manager/uploadCookiesFromCsv.ts","../src/lib/consent-manager/pullConsentManagerMetrics.ts","../src/lib/consent-manager/domainToHost.ts","../src/lib/consent-manager/buildXdiSyncEndpoint.ts","../src/lib/consent-manager/consentManagersToBusinessEntities.ts"],"names":["updateConsentManagerVersionToLatest","auth","deploy","transcendUrl","DEFAULT_TRANSCEND_API","bundleTypes","ConsentBundleType","client","buildTranscendGraphQLClient","consentManagerId","fetchConsentManagerId","mapSeries","bundleType","logger","colors","updateConsentManagerToLatest","deployConsentManager","OMIT_COLUMNS","uploadDataFlowsFromCsv","trackerStatus","file","classifyService","validatedDataFlowInputs","readCsv","DataFlowCsvInput","Type","Notes","Service","Purpose","Status","Owners","Teams","value","rest","splitCsvToList","key","syncDataFlows","uploadCookiesFromCsv","validatedCookieInputs","CookieCsvInput","isRegex","Name","syncCookies","ONE_SECOND","ONE_MINUTE","ONE_HOUR","ONE_DAY","ONE_WEEK","pullConsentManagerMetrics","bin","start","end","airgapBundleId","startTime","endTime","startDate","endDate","privacySignalData","consentChangesData","consentSessionsByRegimeData","fetchConsentManagerAnalyticsData","domainToHost","domain"],"mappings":"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","file":"/home/runner/work/cli/cli/dist/chunk-WGCFVEJZ.cjs","sourcesContent":[null,"import { ConsentBundleType } from '@transcend-io/privacy-types';\nimport { mapSeries } from 'bluebird';\nimport {\n updateConsentManagerToLatest,\n buildTranscendGraphQLClient,\n fetchConsentManagerId,\n deployConsentManager,\n} from '../graphql';\nimport colors from 'colors';\n\nimport { logger } from '../../logger';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\n/**\n * Update the consent manager to latest version\n *\n * @param options - Options\n */\nexport async function updateConsentManagerVersionToLatest({\n auth,\n deploy = false,\n transcendUrl = DEFAULT_TRANSCEND_API,\n bundleTypes = Object.values(ConsentBundleType),\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Deploy consent manager with this update */\n deploy?: boolean;\n /** The bundle types to update and deploy */\n bundleTypes?: ConsentBundleType[];\n}): Promise<void> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Grab Consent Manager ID\n const consentManagerId = await fetchConsentManagerId(client);\n\n // Update each bundle type to latest version\n await mapSeries(bundleTypes, async (bundleType) => {\n logger.info(\n colors.magenta(\n `Update Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\" to latest version...`,\n ),\n );\n await updateConsentManagerToLatest(client, {\n id: consentManagerId,\n bundleType,\n });\n logger.info(\n colors.green(\n `Updated Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\" to latest version!`,\n ),\n );\n });\n\n // deploy Consent Managers\n if (deploy) {\n // Update each bundle type to latest version\n await mapSeries(bundleTypes, async (bundleType) => {\n logger.info(\n colors.magenta(\n `Deploying Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\"...`,\n ),\n );\n await deployConsentManager(client, {\n id: consentManagerId,\n bundleType,\n });\n logger.info(\n colors.green(\n `Deployed Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\"!`,\n ),\n );\n });\n }\n}\n","import colors from 'colors';\nimport { logger } from '../../logger';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, syncDataFlows } from '../graphql';\nimport { readCsv } from '../requests/readCsv';\nimport { DataFlowInput, DataFlowCsvInput } from '../../codecs';\nimport { splitCsvToList } from '../requests';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\nconst OMIT_COLUMNS = [\n 'ID',\n 'Activity',\n 'Encounters',\n 'Last Seen At',\n 'Has Native Do Not Sell/Share Support',\n 'IAB USP API Support',\n 'Service Description',\n 'Website URL',\n 'Categories of Recipients',\n];\n\n/**\n * Upload a set of data flows from CSV\n *\n * @param options - Options\n */\nexport async function uploadDataFlowsFromCsv({\n auth,\n trackerStatus,\n file,\n classifyService = false,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Sombra API key authentication */\n trackerStatus: ConsentTrackerStatus;\n /** classify data flow service if missing */\n classifyService?: boolean;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<void> {\n // Build a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV the set of data flow inputs\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const dataFlowInputs = readCsv(file, DataFlowCsvInput);\n\n // Convert these data flow inputs into a format that the other function can use\n const validatedDataFlowInputs = dataFlowInputs.map(\n ({\n Type,\n Notes,\n // TODO: https://transcend.height.app/T-26391 - export in CSV\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Service,\n Purpose,\n Status,\n Owners,\n Teams,\n 'Connections Made To': value,\n ...rest\n }): DataFlowInput => ({\n value,\n type: Type,\n description: Notes,\n trackingPurposes: splitCsvToList(Purpose),\n // TODO: https://transcend.height.app/T-26391\n // service: Service,\n // Apply the trackerStatus to all values in the CSV -> allows for customer to define tracker status\n // on a row by row basis if needed\n status: Status || trackerStatus,\n owners: Owners ? splitCsvToList(Owners) : undefined,\n teams: Teams ? splitCsvToList(Teams) : undefined,\n // all remaining options are attribute\n attributes: Object.entries(rest)\n // filter out native columns that are exported from the admin dashboard\n // but not custom attributes\n .filter(([key]) => !OMIT_COLUMNS.includes(key))\n .map(([key, value]) => ({\n key,\n values: splitCsvToList(value),\n })),\n }),\n );\n\n // Upload the data flows into Transcend dashboard\n const syncedDataFlows = await syncDataFlows(\n client,\n validatedDataFlowInputs,\n classifyService,\n );\n\n // Log errors\n if (!syncedDataFlows) {\n logger.error(\n colors.red(\n 'Encountered error(s) syncing data flows from CSV, see logs above for more info. ',\n ),\n );\n process.exit(1);\n }\n}\n","import colors from 'colors';\nimport { logger } from '../../logger';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, syncCookies } from '../graphql';\nimport { readCsv } from '../requests/readCsv';\nimport { CookieInput, CookieCsvInput } from '../../codecs';\nimport { splitCsvToList } from '../requests';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\nconst OMIT_COLUMNS = [\n 'ID',\n 'Activity',\n 'Encounters',\n 'Last Seen At',\n 'Has Native Do Not Sell/Share Support',\n 'IAB USP API Support',\n 'Service Description',\n 'Website URL',\n 'Categories of Recipients',\n];\n\n/**\n * Upload a set of cookies from CSV\n *\n * @param options - Options\n */\nexport async function uploadCookiesFromCsv({\n auth,\n trackerStatus,\n file,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Sombra API key authentication */\n trackerStatus: ConsentTrackerStatus;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<void> {\n // Build a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV the set of cookie inputs\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const cookieInputs = readCsv(file, CookieCsvInput);\n\n // Convert these inputs into a format that the other function can use\n const validatedCookieInputs = cookieInputs.map(\n ({\n 'Is Regex?': isRegex,\n Notes,\n // TODO: https://transcend.height.app/T-26391 - export in CSV\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Service,\n Purpose,\n Status,\n Owners,\n Teams,\n Name,\n ...rest\n }): CookieInput => ({\n ...(typeof isRegex === 'string'\n ? { isRegex: isRegex.toLowerCase() === 'true' }\n : {}),\n name: Name,\n description: Notes,\n trackingPurposes: splitCsvToList(Purpose),\n // TODO: https://transcend.height.app/T-26391\n // service: Service,\n // Apply the trackerStatus to all values in the CSV -> allows for customer to define tracker status\n // on a row by row basis if needed\n status: Status || trackerStatus,\n owners: Owners ? splitCsvToList(Owners) : undefined,\n teams: Teams ? splitCsvToList(Teams) : undefined,\n // all remaining options are attribute\n attributes: Object.entries(rest)\n // filter out native columns that are exported from the admin dashboard\n // but not custom attributes\n .filter(([key]) => !OMIT_COLUMNS.includes(key))\n .map(([key, value]) => ({\n key,\n values: splitCsvToList(value),\n })),\n }),\n );\n\n // Upload the cookies into Transcend dashboard\n const syncedCookies = await syncCookies(client, validatedCookieInputs);\n\n // Log errors\n if (!syncedCookies) {\n logger.error(\n colors.red(\n 'Encountered error(s) syncing cookies from CSV, see logs above for more info. ',\n ),\n );\n process.exit(1);\n }\n}\n","import type { GraphQLClient } from 'graphql-request';\nimport {\n ConsentManagerMetric,\n ConsentManagerMetricBin,\n fetchConsentManagerAnalyticsData,\n fetchConsentManagerId,\n} from '../graphql';\n\n/**\n * One second of time in ms\n */\nconst ONE_SECOND = 1000;\nconst ONE_MINUTE = 60 * ONE_SECOND;\nconst ONE_HOUR = 60 * ONE_MINUTE;\nconst ONE_DAY = 24 * ONE_HOUR;\nconst ONE_WEEK = 7 * ONE_DAY;\n\n/**\n * Pull consent manager metrics in an organization\n *\n * @param client - GraphQL client\n * @param options - Options\n * @returns The consent manager metrics\n */\nexport async function pullConsentManagerMetrics(\n client: GraphQLClient,\n {\n bin,\n start,\n end = new Date(),\n }: {\n /** Start date to pull metrics from */\n start: Date;\n /** End date to pull metrics from (assumes now) */\n end?: Date;\n /** Bin size to pull metrics */\n bin: ConsentManagerMetricBin;\n },\n): Promise<{\n /** Privacy signal data */\n PRIVACY_SIGNAL_TIMESERIES: ConsentManagerMetric[];\n /** Consent changes data */\n CONSENT_CHANGES_TIMESERIES: ConsentManagerMetric[];\n /** Consent sessions by regime */\n CONSENT_SESSIONS_BY_REGIME: ConsentManagerMetric[];\n}> {\n // Grab the bundleId associated with this API key\n const airgapBundleId = await fetchConsentManagerId(client);\n\n // convert start and end to times\n const startTime = Math.floor(start.getTime() / 1000);\n const endTime = Math.floor(end.getTime() / 1000);\n if (startTime > endTime) {\n throw new Error('Received \"end\" date that happened before \"start\" date');\n }\n\n // do not allow hourly bins greater than 2 weeks\n if (bin === '1h' && end.getTime() - start.getTime() > ONE_WEEK * 2) {\n throw new Error(\n 'When using bin=1h, start and end time can be no more than 2 weeks apart',\n );\n }\n\n // Pull in the metrics\n const startDate = start.toISOString();\n const endDate = end.toISOString();\n const [privacySignalData, consentChangesData, consentSessionsByRegimeData] =\n await Promise.all([\n fetchConsentManagerAnalyticsData(client, {\n dataSource: 'PRIVACY_SIGNAL_TIMESERIES',\n startDate,\n endDate,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n }),\n fetchConsentManagerAnalyticsData(client, {\n dataSource: 'CONSENT_CHANGES_TIMESERIES',\n startDate,\n endDate,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n }),\n fetchConsentManagerAnalyticsData(client, {\n dataSource: 'CONSENT_SESSIONS_BY_REGIME',\n startDate,\n endDate,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n }),\n ]);\n\n return {\n PRIVACY_SIGNAL_TIMESERIES: privacySignalData,\n CONSENT_CHANGES_TIMESERIES: consentChangesData,\n CONSENT_SESSIONS_BY_REGIME: consentSessionsByRegimeData,\n };\n}\n","/**\n * Convert a domain to host\n *\n * @param domain - e.g. test.acme.com\n * @returns Host acme.com\n */\nexport const domainToHost = (domain: string): string =>\n new URL(`https://${domain}`).hostname.split('.').slice(-2).join('.');\n","import colors from 'colors';\n\nimport { buildTranscendGraphQLClient, fetchConsentManager } from '../graphql';\nimport { difference } from 'lodash-es';\nimport { map } from 'bluebird';\nimport { StoredApiKey } from '../../codecs';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\nimport { logger } from '../../logger';\nimport { domainToHost } from './domainToHost';\n\n/**\n * Sync group configuration mapping\n * e.g.\n * {\n * \"abdb5e78-0d69-4554-a3bd-84b72ca3b3d9\": [\n * \"test.com\"\n * ],\n * \"f6b3ba87-c9df-444f-b420-6fac49e35910\": [\n * \"blue.com\"\n * ]\n * }\n */\nexport type XdiSyncGroups = { [k in string]: string[] };\n\n/** Regular expression for IP addresses - remove these from sync endpoint */\nexport const IP_ADDRESS_REGEX =\n // eslint-disable-next-line max-len\n /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n\n/**\n * Build the sync endpoint definition for a set of Transcend accounts\n *\n * @param apiKeys - The API keys that will be used to pull down configurations for\n * @param options - Options\n * @returns The XDI configuration\n */\nexport async function buildXdiSyncEndpoint(\n apiKeys: string | StoredApiKey[],\n {\n xdiLocation,\n transcendUrl = DEFAULT_TRANSCEND_API,\n removeIpAddresses = true,\n domainBlockList = ['localhost'],\n xdiAllowedCommands = 'ConsentManager:Sync',\n }: {\n /** The file location where the XDI file is hosted */\n xdiLocation: string;\n /** URL of Transcend API */\n transcendUrl?: string;\n /** When true, remove IP addresses (defaults to true) */\n removeIpAddresses?: boolean;\n /** Block list of domains to omit from sync endpoint - includes `localhost` by default */\n domainBlockList?: string[];\n /** Allows XDI commands */\n xdiAllowedCommands?: string;\n },\n): Promise<{\n /** Sync group configurations */\n syncGroups: XdiSyncGroups;\n /** The HTML string */\n html: string;\n}> {\n // Convert API keys to list\n const apiKeysAsList = Array.isArray(apiKeys)\n ? apiKeys\n : [{ apiKey: apiKeys, organizationId: '', organizationName: '' }];\n\n // Fetch configuration for each account\n const consentManagers = await map(\n apiKeysAsList,\n async (apiKey) => {\n logger.info(\n colors.magenta(\n `Pulling consent metadata for organization - ${apiKey.organizationName}`,\n ),\n );\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, apiKey.apiKey);\n\n // Grab consent manager\n const consentManager = await fetchConsentManager(client);\n return consentManager;\n },\n { concurrency: 5 },\n );\n\n // construct the sync groups\n const syncGroups: XdiSyncGroups = {};\n consentManagers.forEach((consentManager) => {\n // grab the partition key\n const partitionKey =\n // take explicit key first\n consentManager.partition?.partition ||\n // fallback to bundle ID\n consentManager.bundleURL.split('/').reverse()[1];\n\n // Ensure that partition exists in the sync groups\n if (!syncGroups[partitionKey]) {\n syncGroups[partitionKey] = [];\n }\n\n // Map domain list to a host list\n const hosts = difference(\n consentManager.configuration.domains\n .filter(\n // ignore IP addresses\n (domain) => !removeIpAddresses || !IP_ADDRESS_REGEX.test(domain),\n )\n .map((domain) => domainToHost(domain)),\n // ignore block list\n domainBlockList,\n );\n // merge existing sync group with hosts for this consent manager\n syncGroups[partitionKey] = [\n ...new Set([...(syncGroups[partitionKey] || []), ...hosts]),\n ];\n });\n\n // Construct the HTML\n const syncEndpointHtml = `\n<!DOCTYPE html>\n<script\nsrc=\"${xdiLocation}\"\ndata-sync-groups='${JSON.stringify(syncGroups, null, 2)}'\ndata-xdi-commands=\"${xdiAllowedCommands}\"\n></script>\n`;\n\n return {\n html: syncEndpointHtml,\n syncGroups,\n };\n}\n","import { BusinessEntityInput, ConsentManagerInput } from '../../codecs';\nimport { logger } from '../../logger';\n\n/**\n * Combine multiple consent manager configurations into a list of business entity configurations\n *\n * @param inputs - Consent manager configurations to combine\n * @returns Business entity configuration input\n */\nexport function consentManagersToBusinessEntities(\n inputs: {\n /** Name of business entity */\n name: string;\n /** Consent manager input */\n input?: ConsentManagerInput;\n }[],\n): BusinessEntityInput[] {\n // Construct the business entities YAML definition\n const businessEntities = inputs.map(\n ({ name, input }): BusinessEntityInput => ({\n // Title of Transcend Instance\n title: name.replace('.yml', ''),\n attributes: [\n // Sync domain list\n ...(input?.domains\n ? [\n {\n key: 'Transcend Domain List',\n values: [...new Set(input.domains)],\n },\n ]\n : []),\n // Sync bundle URLs\n ...(input?.bundleUrls\n ? [\n {\n key: 'Airgap Production URL',\n values: [input.bundleUrls.PRODUCTION],\n },\n {\n key: 'Airgap Test URL',\n values: [input.bundleUrls.TEST],\n },\n {\n key: 'Airgap XDI URL',\n values: [\n input.bundleUrls.PRODUCTION.replace('airgap.js', 'xdi.js'),\n ],\n },\n ]\n : []),\n // Sync partition keys\n ...(input?.partition\n ? [\n {\n key: 'Consent Partition Key',\n values: [input.partition],\n },\n ]\n : []),\n ],\n }),\n );\n\n // Log out info on airgap scripts to host\n logger.info('\\n\\n~~~~~~~~~~~\\nAirgap scripts to host:');\n businessEntities.forEach(({ attributes, title }, ind) => {\n attributes\n ?.find((attr) => attr.key === 'Airgap Production URL')\n ?.values?.forEach((url) => {\n logger.info(`${ind}) ${title} - ${url}`);\n });\n });\n\n return businessEntities;\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-4LSUJDDH.cjs","../src/lib/consent-manager/updateConsentManagerVersionToLatest.ts","../src/lib/consent-manager/uploadDataFlowsFromCsv.ts","../src/lib/consent-manager/uploadCookiesFromCsv.ts","../src/lib/consent-manager/pullConsentManagerMetrics.ts","../src/lib/consent-manager/domainToHost.ts","../src/lib/consent-manager/buildXdiSyncEndpoint.ts","../src/lib/consent-manager/consentManagersToBusinessEntities.ts"],"names":["updateConsentManagerVersionToLatest","auth","deploy","transcendUrl","DEFAULT_TRANSCEND_API","bundleTypes","ConsentBundleType","client","buildTranscendGraphQLClient","consentManagerId","fetchConsentManagerId","mapSeries","bundleType","logger","colors","updateConsentManagerToLatest","deployConsentManager","OMIT_COLUMNS","uploadDataFlowsFromCsv","trackerStatus","file","classifyService","validatedDataFlowInputs","readCsv","DataFlowCsvInput","Type","Notes","Service","Purpose","Status","Owners","Teams","value","rest","splitCsvToList","key","syncDataFlows","uploadCookiesFromCsv","validatedCookieInputs","CookieCsvInput","isRegex","Name","syncCookies","ONE_SECOND","ONE_MINUTE","ONE_HOUR","ONE_DAY","ONE_WEEK","pullConsentManagerMetrics","bin","start","end","airgapBundleId","startTime","endTime","startDate","endDate","privacySignalData","consentChangesData","consentSessionsByRegimeData","fetchConsentManagerAnalyticsData","domainToHost","domain"],"mappings":"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","file":"/home/runner/work/cli/cli/dist/chunk-4LSUJDDH.cjs","sourcesContent":[null,"import { ConsentBundleType } from '@transcend-io/privacy-types';\nimport { mapSeries } from 'bluebird';\nimport {\n updateConsentManagerToLatest,\n buildTranscendGraphQLClient,\n fetchConsentManagerId,\n deployConsentManager,\n} from '../graphql';\nimport colors from 'colors';\n\nimport { logger } from '../../logger';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\n/**\n * Update the consent manager to latest version\n *\n * @param options - Options\n */\nexport async function updateConsentManagerVersionToLatest({\n auth,\n deploy = false,\n transcendUrl = DEFAULT_TRANSCEND_API,\n bundleTypes = Object.values(ConsentBundleType),\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Deploy consent manager with this update */\n deploy?: boolean;\n /** The bundle types to update and deploy */\n bundleTypes?: ConsentBundleType[];\n}): Promise<void> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Grab Consent Manager ID\n const consentManagerId = await fetchConsentManagerId(client);\n\n // Update each bundle type to latest version\n await mapSeries(bundleTypes, async (bundleType) => {\n logger.info(\n colors.magenta(\n `Update Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\" to latest version...`,\n ),\n );\n await updateConsentManagerToLatest(client, {\n id: consentManagerId,\n bundleType,\n });\n logger.info(\n colors.green(\n `Updated Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\" to latest version!`,\n ),\n );\n });\n\n // deploy Consent Managers\n if (deploy) {\n // Update each bundle type to latest version\n await mapSeries(bundleTypes, async (bundleType) => {\n logger.info(\n colors.magenta(\n `Deploying Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\"...`,\n ),\n );\n await deployConsentManager(client, {\n id: consentManagerId,\n bundleType,\n });\n logger.info(\n colors.green(\n `Deployed Consent Manager bundle with ID \"${consentManagerId}\" and type \"${bundleType}\"!`,\n ),\n );\n });\n }\n}\n","import colors from 'colors';\nimport { logger } from '../../logger';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, syncDataFlows } from '../graphql';\nimport { readCsv } from '../requests/readCsv';\nimport { DataFlowInput, DataFlowCsvInput } from '../../codecs';\nimport { splitCsvToList } from '../requests';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\nconst OMIT_COLUMNS = [\n 'ID',\n 'Activity',\n 'Encounters',\n 'Last Seen At',\n 'Has Native Do Not Sell/Share Support',\n 'IAB USP API Support',\n 'Service Description',\n 'Website URL',\n 'Categories of Recipients',\n];\n\n/**\n * Upload a set of data flows from CSV\n *\n * @param options - Options\n */\nexport async function uploadDataFlowsFromCsv({\n auth,\n trackerStatus,\n file,\n classifyService = false,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Sombra API key authentication */\n trackerStatus: ConsentTrackerStatus;\n /** classify data flow service if missing */\n classifyService?: boolean;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<void> {\n // Build a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV the set of data flow inputs\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const dataFlowInputs = readCsv(file, DataFlowCsvInput);\n\n // Convert these data flow inputs into a format that the other function can use\n const validatedDataFlowInputs = dataFlowInputs.map(\n ({\n Type,\n Notes,\n // TODO: https://transcend.height.app/T-26391 - export in CSV\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Service,\n Purpose,\n Status,\n Owners,\n Teams,\n 'Connections Made To': value,\n ...rest\n }): DataFlowInput => ({\n value,\n type: Type,\n description: Notes,\n trackingPurposes: splitCsvToList(Purpose),\n // TODO: https://transcend.height.app/T-26391\n // service: Service,\n // Apply the trackerStatus to all values in the CSV -> allows for customer to define tracker status\n // on a row by row basis if needed\n status: Status || trackerStatus,\n owners: Owners ? splitCsvToList(Owners) : undefined,\n teams: Teams ? splitCsvToList(Teams) : undefined,\n // all remaining options are attribute\n attributes: Object.entries(rest)\n // filter out native columns that are exported from the admin dashboard\n // but not custom attributes\n .filter(([key]) => !OMIT_COLUMNS.includes(key))\n .map(([key, value]) => ({\n key,\n values: splitCsvToList(value),\n })),\n }),\n );\n\n // Upload the data flows into Transcend dashboard\n const syncedDataFlows = await syncDataFlows(\n client,\n validatedDataFlowInputs,\n classifyService,\n );\n\n // Log errors\n if (!syncedDataFlows) {\n logger.error(\n colors.red(\n 'Encountered error(s) syncing data flows from CSV, see logs above for more info. ',\n ),\n );\n process.exit(1);\n }\n}\n","import colors from 'colors';\nimport { logger } from '../../logger';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, syncCookies } from '../graphql';\nimport { readCsv } from '../requests/readCsv';\nimport { CookieInput, CookieCsvInput } from '../../codecs';\nimport { splitCsvToList } from '../requests';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\nconst OMIT_COLUMNS = [\n 'ID',\n 'Activity',\n 'Encounters',\n 'Last Seen At',\n 'Has Native Do Not Sell/Share Support',\n 'IAB USP API Support',\n 'Service Description',\n 'Website URL',\n 'Categories of Recipients',\n];\n\n/**\n * Upload a set of cookies from CSV\n *\n * @param options - Options\n */\nexport async function uploadCookiesFromCsv({\n auth,\n trackerStatus,\n file,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Sombra API key authentication */\n trackerStatus: ConsentTrackerStatus;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<void> {\n // Build a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV the set of cookie inputs\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const cookieInputs = readCsv(file, CookieCsvInput);\n\n // Convert these inputs into a format that the other function can use\n const validatedCookieInputs = cookieInputs.map(\n ({\n 'Is Regex?': isRegex,\n Notes,\n // TODO: https://transcend.height.app/T-26391 - export in CSV\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Service,\n Purpose,\n Status,\n Owners,\n Teams,\n Name,\n ...rest\n }): CookieInput => ({\n ...(typeof isRegex === 'string'\n ? { isRegex: isRegex.toLowerCase() === 'true' }\n : {}),\n name: Name,\n description: Notes,\n trackingPurposes: splitCsvToList(Purpose),\n // TODO: https://transcend.height.app/T-26391\n // service: Service,\n // Apply the trackerStatus to all values in the CSV -> allows for customer to define tracker status\n // on a row by row basis if needed\n status: Status || trackerStatus,\n owners: Owners ? splitCsvToList(Owners) : undefined,\n teams: Teams ? splitCsvToList(Teams) : undefined,\n // all remaining options are attribute\n attributes: Object.entries(rest)\n // filter out native columns that are exported from the admin dashboard\n // but not custom attributes\n .filter(([key]) => !OMIT_COLUMNS.includes(key))\n .map(([key, value]) => ({\n key,\n values: splitCsvToList(value),\n })),\n }),\n );\n\n // Upload the cookies into Transcend dashboard\n const syncedCookies = await syncCookies(client, validatedCookieInputs);\n\n // Log errors\n if (!syncedCookies) {\n logger.error(\n colors.red(\n 'Encountered error(s) syncing cookies from CSV, see logs above for more info. ',\n ),\n );\n process.exit(1);\n }\n}\n","import type { GraphQLClient } from 'graphql-request';\nimport {\n ConsentManagerMetric,\n ConsentManagerMetricBin,\n fetchConsentManagerAnalyticsData,\n fetchConsentManagerId,\n} from '../graphql';\n\n/**\n * One second of time in ms\n */\nconst ONE_SECOND = 1000;\nconst ONE_MINUTE = 60 * ONE_SECOND;\nconst ONE_HOUR = 60 * ONE_MINUTE;\nconst ONE_DAY = 24 * ONE_HOUR;\nconst ONE_WEEK = 7 * ONE_DAY;\n\n/**\n * Pull consent manager metrics in an organization\n *\n * @param client - GraphQL client\n * @param options - Options\n * @returns The consent manager metrics\n */\nexport async function pullConsentManagerMetrics(\n client: GraphQLClient,\n {\n bin,\n start,\n end = new Date(),\n }: {\n /** Start date to pull metrics from */\n start: Date;\n /** End date to pull metrics from (assumes now) */\n end?: Date;\n /** Bin size to pull metrics */\n bin: ConsentManagerMetricBin;\n },\n): Promise<{\n /** Privacy signal data */\n PRIVACY_SIGNAL_TIMESERIES: ConsentManagerMetric[];\n /** Consent changes data */\n CONSENT_CHANGES_TIMESERIES: ConsentManagerMetric[];\n /** Consent sessions by regime */\n CONSENT_SESSIONS_BY_REGIME: ConsentManagerMetric[];\n}> {\n // Grab the bundleId associated with this API key\n const airgapBundleId = await fetchConsentManagerId(client);\n\n // convert start and end to times\n const startTime = Math.floor(start.getTime() / 1000);\n const endTime = Math.floor(end.getTime() / 1000);\n if (startTime > endTime) {\n throw new Error('Received \"end\" date that happened before \"start\" date');\n }\n\n // do not allow hourly bins greater than 2 weeks\n if (bin === '1h' && end.getTime() - start.getTime() > ONE_WEEK * 2) {\n throw new Error(\n 'When using bin=1h, start and end time can be no more than 2 weeks apart',\n );\n }\n\n // Pull in the metrics\n const startDate = start.toISOString();\n const endDate = end.toISOString();\n const [privacySignalData, consentChangesData, consentSessionsByRegimeData] =\n await Promise.all([\n fetchConsentManagerAnalyticsData(client, {\n dataSource: 'PRIVACY_SIGNAL_TIMESERIES',\n startDate,\n endDate,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n }),\n fetchConsentManagerAnalyticsData(client, {\n dataSource: 'CONSENT_CHANGES_TIMESERIES',\n startDate,\n endDate,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n }),\n fetchConsentManagerAnalyticsData(client, {\n dataSource: 'CONSENT_SESSIONS_BY_REGIME',\n startDate,\n endDate,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n }),\n ]);\n\n return {\n PRIVACY_SIGNAL_TIMESERIES: privacySignalData,\n CONSENT_CHANGES_TIMESERIES: consentChangesData,\n CONSENT_SESSIONS_BY_REGIME: consentSessionsByRegimeData,\n };\n}\n","/**\n * Convert a domain to host\n *\n * @param domain - e.g. test.acme.com\n * @returns Host acme.com\n */\nexport const domainToHost = (domain: string): string =>\n new URL(`https://${domain}`).hostname.split('.').slice(-2).join('.');\n","import colors from 'colors';\n\nimport { buildTranscendGraphQLClient, fetchConsentManager } from '../graphql';\nimport { difference } from 'lodash-es';\nimport { map } from 'bluebird';\nimport { StoredApiKey } from '../../codecs';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\nimport { logger } from '../../logger';\nimport { domainToHost } from './domainToHost';\n\n/**\n * Sync group configuration mapping\n * e.g.\n * {\n * \"abdb5e78-0d69-4554-a3bd-84b72ca3b3d9\": [\n * \"test.com\"\n * ],\n * \"f6b3ba87-c9df-444f-b420-6fac49e35910\": [\n * \"blue.com\"\n * ]\n * }\n */\nexport type XdiSyncGroups = { [k in string]: string[] };\n\n/** Regular expression for IP addresses - remove these from sync endpoint */\nexport const IP_ADDRESS_REGEX =\n // eslint-disable-next-line max-len\n /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n\n/**\n * Build the sync endpoint definition for a set of Transcend accounts\n *\n * @param apiKeys - The API keys that will be used to pull down configurations for\n * @param options - Options\n * @returns The XDI configuration\n */\nexport async function buildXdiSyncEndpoint(\n apiKeys: string | StoredApiKey[],\n {\n xdiLocation,\n transcendUrl = DEFAULT_TRANSCEND_API,\n removeIpAddresses = true,\n domainBlockList = ['localhost'],\n xdiAllowedCommands = 'ConsentManager:Sync',\n }: {\n /** The file location where the XDI file is hosted */\n xdiLocation: string;\n /** URL of Transcend API */\n transcendUrl?: string;\n /** When true, remove IP addresses (defaults to true) */\n removeIpAddresses?: boolean;\n /** Block list of domains to omit from sync endpoint - includes `localhost` by default */\n domainBlockList?: string[];\n /** Allows XDI commands */\n xdiAllowedCommands?: string;\n },\n): Promise<{\n /** Sync group configurations */\n syncGroups: XdiSyncGroups;\n /** The HTML string */\n html: string;\n}> {\n // Convert API keys to list\n const apiKeysAsList = Array.isArray(apiKeys)\n ? apiKeys\n : [{ apiKey: apiKeys, organizationId: '', organizationName: '' }];\n\n // Fetch configuration for each account\n const consentManagers = await map(\n apiKeysAsList,\n async (apiKey) => {\n logger.info(\n colors.magenta(\n `Pulling consent metadata for organization - ${apiKey.organizationName}`,\n ),\n );\n\n // Create a GraphQL client\n const client = buildTranscendGraphQLClient(transcendUrl, apiKey.apiKey);\n\n // Grab consent manager\n const consentManager = await fetchConsentManager(client);\n return consentManager;\n },\n { concurrency: 5 },\n );\n\n // construct the sync groups\n const syncGroups: XdiSyncGroups = {};\n consentManagers.forEach((consentManager) => {\n // grab the partition key\n const partitionKey =\n // take explicit key first\n consentManager.partition?.partition ||\n // fallback to bundle ID\n consentManager.bundleURL.split('/').reverse()[1];\n\n // Ensure that partition exists in the sync groups\n if (!syncGroups[partitionKey]) {\n syncGroups[partitionKey] = [];\n }\n\n // Map domain list to a host list\n const hosts = difference(\n consentManager.configuration.domains\n .filter(\n // ignore IP addresses\n (domain) => !removeIpAddresses || !IP_ADDRESS_REGEX.test(domain),\n )\n .map((domain) => domainToHost(domain)),\n // ignore block list\n domainBlockList,\n );\n // merge existing sync group with hosts for this consent manager\n syncGroups[partitionKey] = [\n ...new Set([...(syncGroups[partitionKey] || []), ...hosts]),\n ];\n });\n\n // Construct the HTML\n const syncEndpointHtml = `\n<!DOCTYPE html>\n<script\nsrc=\"${xdiLocation}\"\ndata-sync-groups='${JSON.stringify(syncGroups, null, 2)}'\ndata-xdi-commands=\"${xdiAllowedCommands}\"\n></script>\n`;\n\n return {\n html: syncEndpointHtml,\n syncGroups,\n };\n}\n","import { BusinessEntityInput, ConsentManagerInput } from '../../codecs';\nimport { logger } from '../../logger';\n\n/**\n * Combine multiple consent manager configurations into a list of business entity configurations\n *\n * @param inputs - Consent manager configurations to combine\n * @returns Business entity configuration input\n */\nexport function consentManagersToBusinessEntities(\n inputs: {\n /** Name of business entity */\n name: string;\n /** Consent manager input */\n input?: ConsentManagerInput;\n }[],\n): BusinessEntityInput[] {\n // Construct the business entities YAML definition\n const businessEntities = inputs.map(\n ({ name, input }): BusinessEntityInput => ({\n // Title of Transcend Instance\n title: name.replace('.yml', ''),\n attributes: [\n // Sync domain list\n ...(input?.domains\n ? [\n {\n key: 'Transcend Domain List',\n values: [...new Set(input.domains)],\n },\n ]\n : []),\n // Sync bundle URLs\n ...(input?.bundleUrls\n ? [\n {\n key: 'Airgap Production URL',\n values: [input.bundleUrls.PRODUCTION],\n },\n {\n key: 'Airgap Test URL',\n values: [input.bundleUrls.TEST],\n },\n {\n key: 'Airgap XDI URL',\n values: [\n input.bundleUrls.PRODUCTION.replace('airgap.js', 'xdi.js'),\n ],\n },\n ]\n : []),\n // Sync partition keys\n ...(input?.partition\n ? [\n {\n key: 'Consent Partition Key',\n values: [input.partition],\n },\n ]\n : []),\n ],\n }),\n );\n\n // Log out info on airgap scripts to host\n logger.info('\\n\\n~~~~~~~~~~~\\nAirgap scripts to host:');\n businessEntities.forEach(({ attributes, title }, ind) => {\n attributes\n ?.find((attr) => attr.key === 'Airgap Production URL')\n ?.values?.forEach((url) => {\n logger.info(`${ind}) ${title} - ${url}`);\n });\n });\n\n return businessEntities;\n}\n"]}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkK65NYGJMcjs = require('./chunk-K65NYGJM.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');var _chunkFTXFBDFWcjs = require('./chunk-FTXFBDFW.cjs');var _privacytypes = require('@transcend-io/privacy-types');var _cliprogress = require('cli-progress'); var _cliprogress2 = _interopRequireDefault(_cliprogress);var _graphqlrequest = require('graphql-request');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);var _bluebird = require('bluebird');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 _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic),s={...c.length>0?{category:c}:{},...t.length>0?{subCategoryIds:t}:{},...c.length+t.length>0&&!l?{status:_privacytypes.SubDataPointDataSubCategoryGuessStatus.Approved}:{},...e.length>0?{dataSilos:e}:{}},{subDataPoints:{totalCount:o}}=await _chunkK65NYGJMcjs.rg.call(void 0, u,_chunkK65NYGJMcjs.d,{filterBy:s});_chunkZUNVPK23cjs.a.info(_colors2.default.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 _chunkK65NYGJMcjs.rg.call(void 0, u,_graphqlrequest.gql`
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkFE6CECEScjs = require('./chunk-FE6CECES.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');var _chunkUBVZKE7Vcjs = require('./chunk-UBVZKE7V.cjs');var _privacytypes = require('@transcend-io/privacy-types');var _cliprogress = require('cli-progress'); var _cliprogress2 = _interopRequireDefault(_cliprogress);var _graphqlrequest = require('graphql-request');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);var _bluebird = require('bluebird');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 _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic),s={...c.length>0?{category:c}:{},...t.length>0?{subCategoryIds:t}:{},...c.length+t.length>0&&!l?{status:_privacytypes.SubDataPointDataSubCategoryGuessStatus.Approved}:{},...e.length>0?{dataSilos:e}:{}},{subDataPoints:{totalCount:o}}=await _chunkFE6CECEScjs.rg.call(void 0, u,_chunkFE6CECEScjs.d,{filterBy:s});_chunkZUNVPK23cjs.a.info(_colors2.default.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 _chunkFE6CECEScjs.rg.call(void 0, u,_graphqlrequest.gql`
2
2
  query TranscendCliSubDataPointCsvExport(
3
3
  $filterBy: SubDataPointFiltersInput
4
4
  $first: Int!
@@ -41,7 +41,7 @@
41
41
  }
42
42
  }
43
43
  }
44
- `,{first:p,offset:b,filterBy:{...s}});r=_optionalChain([P, 'access', _2 => _2[P.length-1], 'optionalAccess', _3 => _3.id]),n.push(...P),D=P.length===p,y+=P.length,b+=P.length,d.update(y)}catch(P){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching subdatapoints for cursor ${r} and offset ${b}`)),P}while(D);d.stop();let C=new Date().getTime()-m,g=_chunkFTXFBDFWcjs.g.call(void 0, n,"name");return _chunkZUNVPK23cjs.a.info(_colors2.default.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 _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`[Step 2/3] Fetching metadata for ${e.length} datapoints`));let p=_chunkFTXFBDFWcjs.b.call(void 0, e,l);t.start(e.length,0);let n=0;await _bluebird.mapSeries.call(void 0, p,async s=>{try{let{dataPoints:{nodes:o}}=await _chunkK65NYGJMcjs.rg.call(void 0, u,_chunkK65NYGJMcjs.g,{first:l,filterBy:{ids:s}});a.push(...o),n+=s.length,t.update(n)}catch(o){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching subdatapoints for IDs ${s.join(", ")}`)),o}}),t.stop();let d=new Date().getTime()-c;return _chunkZUNVPK23cjs.a.info(_colors2.default.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 _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`[Step 3/3] Fetching metadata for ${e.length} data silos`));let p=_chunkFTXFBDFWcjs.b.call(void 0, e,l);t.start(e.length,0);let n=0;await _bluebird.mapSeries.call(void 0, p,async s=>{try{let{dataSilos:{nodes:o}}=await _chunkK65NYGJMcjs.rg.call(void 0, u,_chunkK65NYGJMcjs.j,{first:l,filterBy:{ids:s}});a.push(...o),n+=s.length,t.update(n)}catch(o){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching data silos for IDs ${s.join(", ")}`)),o}}),t.stop();let d=new Date().getTime()-c;return _chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully pulled in ${a.length} data silos in ${d/1e3} seconds!`)),a}async function Y(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=_chunkFTXFBDFWcjs.j.call(void 0, n.map(r=>r.dataPointId)),d=await F(u,{dataPointIds:m}),s=_chunkFTXFBDFWcjs.e.call(void 0, d,"id"),o=_chunkFTXFBDFWcjs.j.call(void 0, n.map(r=>r.dataSiloId)),y=await Q(u,{dataSiloIds:o}),D=_chunkFTXFBDFWcjs.e.call(void 0, y,"id");return n.map(r=>({...r,dataPoint:s[r.dataPointId],dataSilo:D[r.dataSiloId]}))}async function nt(u,{dataSiloIds:e=[],status:l,subCategories:a=[],includeEncryptedSnippets:c,pageSize:t=100}={}){let p=[],n=new Date().getTime(),m=new _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic),d={...a.length>0?{subCategoryIds:a}:{},...l?{status:l}:{},...e.length>0?{dataSilos:e}:{}},{unstructuredSubDataPointRecommendations:{totalCount:s}}=await _chunkK65NYGJMcjs.rg.call(void 0, u,_chunkK65NYGJMcjs.h,{filterBy:d});_chunkZUNVPK23cjs.a.info(_colors2.default.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 _chunkK65NYGJMcjs.rg.call(void 0, u,_graphqlrequest.gql`
44
+ `,{first:p,offset:b,filterBy:{...s}});r=_optionalChain([P, 'access', _2 => _2[P.length-1], 'optionalAccess', _3 => _3.id]),n.push(...P),D=P.length===p,y+=P.length,b+=P.length,d.update(y)}catch(P){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching subdatapoints for cursor ${r} and offset ${b}`)),P}while(D);d.stop();let C=new Date().getTime()-m,g=_chunkUBVZKE7Vcjs.g.call(void 0, n,"name");return _chunkZUNVPK23cjs.a.info(_colors2.default.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 _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`[Step 2/3] Fetching metadata for ${e.length} datapoints`));let p=_chunkUBVZKE7Vcjs.b.call(void 0, e,l);t.start(e.length,0);let n=0;await _bluebird.mapSeries.call(void 0, p,async s=>{try{let{dataPoints:{nodes:o}}=await _chunkFE6CECEScjs.rg.call(void 0, u,_chunkFE6CECEScjs.g,{first:l,filterBy:{ids:s}});a.push(...o),n+=s.length,t.update(n)}catch(o){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching subdatapoints for IDs ${s.join(", ")}`)),o}}),t.stop();let d=new Date().getTime()-c;return _chunkZUNVPK23cjs.a.info(_colors2.default.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 _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`[Step 3/3] Fetching metadata for ${e.length} data silos`));let p=_chunkUBVZKE7Vcjs.b.call(void 0, e,l);t.start(e.length,0);let n=0;await _bluebird.mapSeries.call(void 0, p,async s=>{try{let{dataSilos:{nodes:o}}=await _chunkFE6CECEScjs.rg.call(void 0, u,_chunkFE6CECEScjs.j,{first:l,filterBy:{ids:s}});a.push(...o),n+=s.length,t.update(n)}catch(o){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching data silos for IDs ${s.join(", ")}`)),o}}),t.stop();let d=new Date().getTime()-c;return _chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully pulled in ${a.length} data silos in ${d/1e3} seconds!`)),a}async function Y(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=_chunkUBVZKE7Vcjs.j.call(void 0, n.map(r=>r.dataPointId)),d=await F(u,{dataPointIds:m}),s=_chunkUBVZKE7Vcjs.e.call(void 0, d,"id"),o=_chunkUBVZKE7Vcjs.j.call(void 0, n.map(r=>r.dataSiloId)),y=await Q(u,{dataSiloIds:o}),D=_chunkUBVZKE7Vcjs.e.call(void 0, y,"id");return n.map(r=>({...r,dataPoint:s[r.dataPointId],dataSilo:D[r.dataSiloId]}))}async function nt(u,{dataSiloIds:e=[],status:l,subCategories:a=[],includeEncryptedSnippets:c,pageSize:t=100}={}){let p=[],n=new Date().getTime(),m=new _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic),d={...a.length>0?{subCategoryIds:a}:{},...l?{status:l}:{},...e.length>0?{dataSilos:e}:{}},{unstructuredSubDataPointRecommendations:{totalCount:s}}=await _chunkFE6CECEScjs.rg.call(void 0, u,_chunkFE6CECEScjs.h,{filterBy:d});_chunkZUNVPK23cjs.a.info(_colors2.default.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 _chunkFE6CECEScjs.rg.call(void 0, u,_graphqlrequest.gql`
45
45
  query TranscendCliUnstructuredSubDataPointRecommendationCsvExport(
46
46
  $filterBy: UnstructuredSubDataPointRecommendationsFilterInput
47
47
  $first: Int!
@@ -71,5 +71,5 @@
71
71
  }
72
72
  }
73
73
  }
74
- `,{first:t,offset:r,filterBy:{...d}});D=_optionalChain([g, 'access', _4 => _4[g.length-1], 'optionalAccess', _5 => _5.id]),p.push(...g),y=g.length===t,o+=g.length,r+=g.length,m.update(o)}catch(g){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching subdatapoints for cursor ${D} and offset ${r}`)),g}while(y);m.stop();let T=new Date().getTime()-n,C=_chunkFTXFBDFWcjs.g.call(void 0, p,"name");return _chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully pulled in ${C.length} subdatapoints in ${T/1e3} seconds!`)),C}exports.a = Y; exports.b = nt;
75
- //# sourceMappingURL=chunk-L32BTN2M.cjs.map
74
+ `,{first:t,offset:r,filterBy:{...d}});D=_optionalChain([g, 'access', _4 => _4[g.length-1], 'optionalAccess', _5 => _5.id]),p.push(...g),y=g.length===t,o+=g.length,r+=g.length,m.update(o)}catch(g){throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`An error fetching subdatapoints for cursor ${D} and offset ${r}`)),g}while(y);m.stop();let T=new Date().getTime()-n,C=_chunkUBVZKE7Vcjs.g.call(void 0, p,"name");return _chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully pulled in ${C.length} subdatapoints in ${T/1e3} seconds!`)),C}exports.a = Y; exports.b = nt;
75
+ //# sourceMappingURL=chunk-5HNRVLH2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-L32BTN2M.cjs","../src/lib/data-inventory/pullAllDatapoints.ts","../src/lib/data-inventory/pullUnstructuredSubDataPointRecommendations.ts"],"names":["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"],"mappings":"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","file":"/home/runner/work/cli/cli/dist/chunk-L32BTN2M.cjs","sourcesContent":[null,"/* 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';\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"]}
1
+ {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-5HNRVLH2.cjs","../src/lib/data-inventory/pullAllDatapoints.ts","../src/lib/data-inventory/pullUnstructuredSubDataPointRecommendations.ts"],"names":["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"],"mappings":"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","file":"/home/runner/work/cli/cli/dist/chunk-5HNRVLH2.cjs","sourcesContent":[null,"/* 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';\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"]}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkFTXFBDFWcjs = require('./chunk-FTXFBDFW.cjs');function f(p,{adTechPurposes:m=["SaleOfInfo"],serviceToTitle:s,serviceToSupportedIntegration:r}){let e=[],i=[],n={};p.forEach(t=>{let{service:a,attributes:c=[]}=t;if(!a||a==="internalService")return;let u=c.find(o=>o.key==="Found on Domain");u&&(n[a]||(n[a]=[]),n[a].push(...u.values.map(o=>o.replace("https://","").replace("http://",""))),n[a]=[...new Set(n[a])]),_chunkFTXFBDFWcjs.i.call(void 0, t.trackingPurposes,m).length>0?(i.push(a),e.includes(a)&&(e=e.filter(o=>o!==a))):i.includes(a)||e.push(a)});let h=[...new Set(i)].map(t=>({title:s[t],...r[t]?{integrationName:t}:{integrationName:"promptAPerson","outer-type":t},attributes:[{key:"Tech Type",values:["Ad Tech"]},{key:"Found On Domain",values:n[t]||[]}]}));return{siteTechDataSilos:[...new Set(e)].map(t=>({title:s[t],...r[t]?{integrationName:t}:{integrationName:"promptAPerson",outerType:t},attributes:[{key:"Tech Type",values:["Site Tech"]},{key:"Found On Domain",values:n[t]||[]}]})),adTechDataSilos:h}}exports.a = f;
2
- //# sourceMappingURL=chunk-2MHJ5LZ7.cjs.map
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkUBVZKE7Vcjs = require('./chunk-UBVZKE7V.cjs');function f(p,{adTechPurposes:m=["SaleOfInfo"],serviceToTitle:s,serviceToSupportedIntegration:r}){let e=[],i=[],n={};p.forEach(t=>{let{service:a,attributes:c=[]}=t;if(!a||a==="internalService")return;let u=c.find(o=>o.key==="Found on Domain");u&&(n[a]||(n[a]=[]),n[a].push(...u.values.map(o=>o.replace("https://","").replace("http://",""))),n[a]=[...new Set(n[a])]),_chunkUBVZKE7Vcjs.i.call(void 0, t.trackingPurposes,m).length>0?(i.push(a),e.includes(a)&&(e=e.filter(o=>o!==a))):i.includes(a)||e.push(a)});let h=[...new Set(i)].map(t=>({title:s[t],...r[t]?{integrationName:t}:{integrationName:"promptAPerson","outer-type":t},attributes:[{key:"Tech Type",values:["Ad Tech"]},{key:"Found On Domain",values:n[t]||[]}]}));return{siteTechDataSilos:[...new Set(e)].map(t=>({title:s[t],...r[t]?{integrationName:t}:{integrationName:"promptAPerson",outerType:t},attributes:[{key:"Tech Type",values:["Site Tech"]},{key:"Found On Domain",values:n[t]||[]}]})),adTechDataSilos:h}}exports.a = f;
2
+ //# sourceMappingURL=chunk-5QRRUXRI.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-2MHJ5LZ7.cjs","../src/lib/consent-manager/dataFlowsToDataSilos.ts"],"names":["dataFlowsToDataSilos","inputs","adTechPurposes","serviceToTitle","serviceToSupportedIntegration","siteTechIntegrations","adTechIntegrations","serviceToFoundOnDomain","flow","service","attributes","foundOnDomain","attr","v","union_default","s","adTechDataSilos"],"mappings":"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","file":"/home/runner/work/cli/cli/dist/chunk-2MHJ5LZ7.cjs","sourcesContent":[null,"import { DataFlowInput, DataSiloInput } from '../../codecs';\nimport { union } from 'lodash-es';\nimport { IndexedCatalogs } from '../graphql';\n\n/**\n * Convert data flow configurations into a set of data silo configurations\n *\n * @param inputs - Data flow input to convert to data silos\n * @param options - Additional options\n * @returns Business entity configuration input\n */\nexport function dataFlowsToDataSilos(\n inputs: DataFlowInput[],\n {\n adTechPurposes = ['SaleOfInfo'],\n serviceToTitle,\n serviceToSupportedIntegration,\n }: IndexedCatalogs & {\n /** List of purposes that are considered \"Ad Tech\" */\n adTechPurposes?: string[];\n },\n): {\n /** List of data silo configurations for site-tech services */\n siteTechDataSilos: DataSiloInput[];\n /** List of data silo configurations for ad-tech services */\n adTechDataSilos: DataSiloInput[];\n} {\n // List of site tech integrations\n let siteTechIntegrations: string[] = [];\n\n // List of ad tech integrations\n const adTechIntegrations: string[] = [];\n\n // Mapping from service name to list of\n const serviceToFoundOnDomain: { [k in string]: string[] } = {};\n\n // iterate over each flow\n inputs.forEach((flow) => {\n // process data flows with services\n const { service, attributes = [] } = flow;\n if (!service || service === 'internalService') {\n return;\n }\n\n // create mapping to found on domain\n const foundOnDomain = attributes.find(\n (attr) => attr.key === 'Found on Domain',\n );\n\n // Create a list of all domains where the data flow was found\n if (foundOnDomain) {\n if (!serviceToFoundOnDomain[service]) {\n serviceToFoundOnDomain[service] = [];\n }\n serviceToFoundOnDomain[service]!.push(\n ...foundOnDomain.values.map((v) =>\n v.replace('https://', '').replace('http://', ''),\n ),\n );\n serviceToFoundOnDomain[service] = [\n ...new Set(serviceToFoundOnDomain[service]),\n ];\n }\n\n // Keep track of ad tech\n if (union(flow.trackingPurposes, adTechPurposes).length > 0) {\n // add service to ad tech list\n adTechIntegrations.push(service);\n\n // remove from site tech list\n if (siteTechIntegrations.includes(service)) {\n siteTechIntegrations = siteTechIntegrations.filter(\n (s) => s !== service,\n );\n }\n } else if (!adTechIntegrations.includes(service)) {\n // add to site tech list\n siteTechIntegrations.push(service);\n }\n });\n\n // create the list of ad tech integrations\n const adTechDataSilos = [...new Set(adTechIntegrations)].map((service) => ({\n title: serviceToTitle[service],\n ...(serviceToSupportedIntegration[service]\n ? { integrationName: service }\n : { integrationName: 'promptAPerson', 'outer-type': service }),\n attributes: [\n {\n key: 'Tech Type',\n values: ['Ad Tech'],\n },\n {\n key: 'Found On Domain',\n values: serviceToFoundOnDomain[service] || [],\n },\n ],\n }));\n\n // create the list of site tech integrations\n const siteTechDataSilos = [...new Set(siteTechIntegrations)].map(\n (service) => ({\n title: serviceToTitle[service],\n ...(serviceToSupportedIntegration[service]\n ? { integrationName: service }\n : { integrationName: 'promptAPerson', outerType: service }),\n attributes: [\n {\n key: 'Tech Type',\n values: ['Site Tech'],\n },\n {\n key: 'Found On Domain',\n values: serviceToFoundOnDomain[service] || [],\n },\n ],\n }),\n );\n\n return {\n siteTechDataSilos,\n adTechDataSilos,\n };\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-5QRRUXRI.cjs","../src/lib/consent-manager/dataFlowsToDataSilos.ts"],"names":["dataFlowsToDataSilos","inputs","adTechPurposes","serviceToTitle","serviceToSupportedIntegration","siteTechIntegrations","adTechIntegrations","serviceToFoundOnDomain","flow","service","attributes","foundOnDomain","attr","v","union_default","s","adTechDataSilos"],"mappings":"AAAA,iIAAwC,SCWxBA,CAAAA,CACdC,CAAAA,CACA,CACE,cAAA,CAAAC,CAAAA,CAAiB,CAAC,YAAY,CAAA,CAC9B,cAAA,CAAAC,CAAAA,CACA,6BAAA,CAAAC,CACF,CAAA,CASA,CAEA,IAAIC,CAAAA,CAAiC,CAAC,CAAA,CAGhCC,CAAAA,CAA+B,CAAC,CAAA,CAGhCC,CAAAA,CAAsD,CAAC,CAAA,CAG7DN,CAAAA,CAAO,OAAA,CAASO,CAAAA,EAAS,CAEvB,GAAM,CAAE,OAAA,CAAAC,CAAAA,CAAS,UAAA,CAAAC,CAAAA,CAAa,CAAC,CAAE,CAAA,CAAIF,CAAAA,CACrC,EAAA,CAAI,CAACC,CAAAA,EAAWA,CAAAA,GAAY,iBAAA,CAC1B,MAAA,CAIF,IAAME,CAAAA,CAAgBD,CAAAA,CAAW,IAAA,CAC9BE,CAAAA,EAASA,CAAAA,CAAK,GAAA,GAAQ,iBACzB,CAAA,CAGID,CAAAA,EAAAA,CACGJ,CAAAA,CAAuBE,CAAO,CAAA,EAAA,CACjCF,CAAAA,CAAuBE,CAAO,CAAA,CAAI,CAAC,CAAA,CAAA,CAErCF,CAAAA,CAAuBE,CAAO,CAAA,CAAG,IAAA,CAC/B,GAAGE,CAAAA,CAAc,MAAA,CAAO,GAAA,CAAKE,CAAAA,EAC3BA,CAAAA,CAAE,OAAA,CAAQ,UAAA,CAAY,EAAE,CAAA,CAAE,OAAA,CAAQ,SAAA,CAAW,EAAE,CACjD,CACF,CAAA,CACAN,CAAAA,CAAuBE,CAAO,CAAA,CAAI,CAChC,GAAG,IAAI,GAAA,CAAIF,CAAAA,CAAuBE,CAAO,CAAC,CAC5C,CAAA,CAAA,CAIEK,iCAAAA,CAAMN,CAAK,gBAAA,CAAkBN,CAAc,CAAA,CAAE,MAAA,CAAS,CAAA,CAAA,CAExDI,CAAAA,CAAmB,IAAA,CAAKG,CAAO,CAAA,CAG3BJ,CAAAA,CAAqB,QAAA,CAASI,CAAO,CAAA,EAAA,CACvCJ,CAAAA,CAAuBA,CAAAA,CAAqB,MAAA,CACzCU,CAAAA,EAAMA,CAAAA,GAAMN,CACf,CAAA,CAAA,CAAA,CAEQH,CAAAA,CAAmB,QAAA,CAASG,CAAO,CAAA,EAE7CJ,CAAAA,CAAqB,IAAA,CAAKI,CAAO,CAErC,CAAC,CAAA,CAGD,IAAMO,CAAAA,CAAkB,CAAC,GAAG,IAAI,GAAA,CAAIV,CAAkB,CAAC,CAAA,CAAE,GAAA,CAAKG,CAAAA,EAAAA,CAAa,CACzE,KAAA,CAAON,CAAAA,CAAeM,CAAO,CAAA,CAC7B,GAAIL,CAAAA,CAA8BK,CAAO,CAAA,CACrC,CAAE,eAAA,CAAiBA,CAAQ,CAAA,CAC3B,CAAE,eAAA,CAAiB,eAAA,CAAiB,YAAA,CAAcA,CAAQ,CAAA,CAC9D,UAAA,CAAY,CACV,CACE,GAAA,CAAK,WAAA,CACL,MAAA,CAAQ,CAAC,SAAS,CACpB,CAAA,CACA,CACE,GAAA,CAAK,iBAAA,CACL,MAAA,CAAQF,CAAAA,CAAuBE,CAAO,CAAA,EAAK,CAAC,CAC9C,CACF,CACF,CAAA,CAAE,CAAA,CAsBF,MAAO,CACL,iBAAA,CApBwB,CAAC,GAAG,IAAI,GAAA,CAAIJ,CAAoB,CAAC,CAAA,CAAE,GAAA,CAC1DI,CAAAA,EAAAA,CAAa,CACZ,KAAA,CAAON,CAAAA,CAAeM,CAAO,CAAA,CAC7B,GAAIL,CAAAA,CAA8BK,CAAO,CAAA,CACrC,CAAE,eAAA,CAAiBA,CAAQ,CAAA,CAC3B,CAAE,eAAA,CAAiB,eAAA,CAAiB,SAAA,CAAWA,CAAQ,CAAA,CAC3D,UAAA,CAAY,CACV,CACE,GAAA,CAAK,WAAA,CACL,MAAA,CAAQ,CAAC,WAAW,CACtB,CAAA,CACA,CACE,GAAA,CAAK,iBAAA,CACL,MAAA,CAAQF,CAAAA,CAAuBE,CAAO,CAAA,EAAK,CAAC,CAC9C,CACF,CACF,CAAA,CACF,CAAA,CAIE,eAAA,CAAAO,CACF,CACF,CAAA,cAAA","file":"/home/runner/work/cli/cli/dist/chunk-5QRRUXRI.cjs","sourcesContent":[null,"import { DataFlowInput, DataSiloInput } from '../../codecs';\nimport { union } from 'lodash-es';\nimport { IndexedCatalogs } from '../graphql';\n\n/**\n * Convert data flow configurations into a set of data silo configurations\n *\n * @param inputs - Data flow input to convert to data silos\n * @param options - Additional options\n * @returns Business entity configuration input\n */\nexport function dataFlowsToDataSilos(\n inputs: DataFlowInput[],\n {\n adTechPurposes = ['SaleOfInfo'],\n serviceToTitle,\n serviceToSupportedIntegration,\n }: IndexedCatalogs & {\n /** List of purposes that are considered \"Ad Tech\" */\n adTechPurposes?: string[];\n },\n): {\n /** List of data silo configurations for site-tech services */\n siteTechDataSilos: DataSiloInput[];\n /** List of data silo configurations for ad-tech services */\n adTechDataSilos: DataSiloInput[];\n} {\n // List of site tech integrations\n let siteTechIntegrations: string[] = [];\n\n // List of ad tech integrations\n const adTechIntegrations: string[] = [];\n\n // Mapping from service name to list of\n const serviceToFoundOnDomain: { [k in string]: string[] } = {};\n\n // iterate over each flow\n inputs.forEach((flow) => {\n // process data flows with services\n const { service, attributes = [] } = flow;\n if (!service || service === 'internalService') {\n return;\n }\n\n // create mapping to found on domain\n const foundOnDomain = attributes.find(\n (attr) => attr.key === 'Found on Domain',\n );\n\n // Create a list of all domains where the data flow was found\n if (foundOnDomain) {\n if (!serviceToFoundOnDomain[service]) {\n serviceToFoundOnDomain[service] = [];\n }\n serviceToFoundOnDomain[service]!.push(\n ...foundOnDomain.values.map((v) =>\n v.replace('https://', '').replace('http://', ''),\n ),\n );\n serviceToFoundOnDomain[service] = [\n ...new Set(serviceToFoundOnDomain[service]),\n ];\n }\n\n // Keep track of ad tech\n if (union(flow.trackingPurposes, adTechPurposes).length > 0) {\n // add service to ad tech list\n adTechIntegrations.push(service);\n\n // remove from site tech list\n if (siteTechIntegrations.includes(service)) {\n siteTechIntegrations = siteTechIntegrations.filter(\n (s) => s !== service,\n );\n }\n } else if (!adTechIntegrations.includes(service)) {\n // add to site tech list\n siteTechIntegrations.push(service);\n }\n });\n\n // create the list of ad tech integrations\n const adTechDataSilos = [...new Set(adTechIntegrations)].map((service) => ({\n title: serviceToTitle[service],\n ...(serviceToSupportedIntegration[service]\n ? { integrationName: service }\n : { integrationName: 'promptAPerson', 'outer-type': service }),\n attributes: [\n {\n key: 'Tech Type',\n values: ['Ad Tech'],\n },\n {\n key: 'Found On Domain',\n values: serviceToFoundOnDomain[service] || [],\n },\n ],\n }));\n\n // create the list of site tech integrations\n const siteTechDataSilos = [...new Set(siteTechIntegrations)].map(\n (service) => ({\n title: serviceToTitle[service],\n ...(serviceToSupportedIntegration[service]\n ? { integrationName: service }\n : { integrationName: 'promptAPerson', outerType: service }),\n attributes: [\n {\n key: 'Tech Type',\n values: ['Site Tech'],\n },\n {\n key: 'Found On Domain',\n values: serviceToFoundOnDomain[service] || [],\n },\n ],\n }),\n );\n\n return {\n siteTechDataSilos,\n adTechDataSilos,\n };\n}\n"]}
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _chunkK65NYGJMcjs = require('./chunk-K65NYGJM.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');var _chunkFTXFBDFWcjs = require('./chunk-FTXFBDFW.cjs');var _privacytypes = require('@transcend-io/privacy-types');var _bluebird = require('bluebird');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);async function te({file:u,auth:s,sombraAuth:g,requestActions:f=[],concurrency:p=100,transcendUrl:n=_chunkFTXFBDFWcjs.r}){let o=_chunkK65NYGJMcjs.wc.call(void 0, n,s),e=await _chunkK65NYGJMcjs.xc.call(void 0, n,s,g);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Pulling manual enrichment requests, filtered for actions: ${f.join(",")}`));let d=await _chunkK65NYGJMcjs.nd.call(void 0, o,{actions:f,statuses:[_privacytypes.RequestStatus.Enriching]}),i=[];await _bluebird.map.call(void 0, d,async t=>{let c=await _chunkK65NYGJMcjs.hd.call(void 0, o,{requestId:t.id});if(c.filter(({status:m})=>m==="ACTION_REQUIRED")){let m=await _chunkK65NYGJMcjs.kd.call(void 0, o,e,{requestId:t.id});i.push({...t,requestIdentifiers:m,requestEnrichers:c})}},{concurrency:p});let l=i.map(({attributeValues:t,requestIdentifiers:c,requestEnrichers:w,...m})=>({...m,...Object.entries(_chunkFTXFBDFWcjs.d.call(void 0, c,"name")).reduce((I,[P,$])=>Object.assign(I,{[P]:$.map(({value:C})=>C).join(",")}),{}),...Object.entries(_chunkFTXFBDFWcjs.d.call(void 0, t,"attributeKey.name")).reduce((I,[P,$])=>Object.assign(I,{[P]:$.map(({name:C})=>C).join(",")}),{})})),a=_chunkFTXFBDFWcjs.j.call(void 0, l.map(t=>Object.keys(t)).flat());return await _chunkK65NYGJMcjs.og.call(void 0, u,l,a),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully wrote ${i.length} requests to file "${u}"`)),i}var _iots = require('io-ts'); var R = _interopRequireWildcard(_iots);var T="https://app.transcend.io/privacy-requests/incoming-requests/",F= exports.b =R.record(R.string,R.string);async function M(u,{id:s,...g},f,p){if(!s){let e=`Request ID must be provided to enricher request.${p?` Found error in row: ${p}`:""}`;throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(e)),new Error(e)}let n=s.toLowerCase(),o=Object.entries(g).reduce((e,[d,i])=>_chunkFTXFBDFWcjs.j.call(void 0, _chunkK65NYGJMcjs.oc.call(void 0, i)).length===0?e:Object.assign(e,{[d]:_chunkFTXFBDFWcjs.j.call(void 0, _chunkK65NYGJMcjs.oc.call(void 0, i)).map(a=>({value:d==="email"?a.toLowerCase():a}))}),{});try{return await u.post("v1/enrich-identifiers",{headers:{"x-transcend-request-id":n,"x-transcend-enricher-id":f},json:{enrichedIdentifiers:o}}).json(),_chunkZUNVPK23cjs.a.error(_colors2.default.green(`Successfully enriched request: ${T}${n}`)),!0}catch(e){if(typeof e.response.body=="string"&&e.response.body.includes("Cannot update a resolved RequestEnricher"))return _chunkZUNVPK23cjs.a.warn(_colors2.default.magenta(`Skipped enrichment for request: ${T}${n}, request is no longer in the enriching phase.`)),!1;throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`Failed to enricher identifiers for request with id: ${T}${n} - ${e.message} - ${e.response.body}`)),e}}async function ge({file:u,auth:s,sombraAuth:g,enricherId:f,markSilent:p,concurrency:n=100,transcendUrl:o=_chunkFTXFBDFWcjs.r}){let e=await _chunkK65NYGJMcjs.xc.call(void 0, o,s,g),d=_chunkK65NYGJMcjs.wc.call(void 0, o,s);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading "${u}" from disk`));let i=_chunkK65NYGJMcjs.rc.call(void 0, u,F);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Enriching "${i.length}" privacy requests.`));let l=0,a=0,t=0;if(await _bluebird.map.call(void 0, i,async(c,w)=>{try{p&&(await _chunkK65NYGJMcjs.rg.call(void 0, d,_chunkK65NYGJMcjs.Z,{input:{id:c.id,isSilent:!0}}),_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Mark request as silent mode - ${c.id}`))),await M(e,c,f,w)?l+=1:a+=1}catch (e2){t+=1}},{concurrency:n}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully notified Transcend!
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _chunkFE6CECEScjs = require('./chunk-FE6CECES.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');var _chunkUBVZKE7Vcjs = require('./chunk-UBVZKE7V.cjs');var _privacytypes = require('@transcend-io/privacy-types');var _bluebird = require('bluebird');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);async function te({file:u,auth:s,sombraAuth:g,requestActions:f=[],concurrency:p=100,transcendUrl:n=_chunkUBVZKE7Vcjs.r}){let o=_chunkFE6CECEScjs.wc.call(void 0, n,s),e=await _chunkFE6CECEScjs.xc.call(void 0, n,s,g);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Pulling manual enrichment requests, filtered for actions: ${f.join(",")}`));let d=await _chunkFE6CECEScjs.nd.call(void 0, o,{actions:f,statuses:[_privacytypes.RequestStatus.Enriching]}),i=[];await _bluebird.map.call(void 0, d,async t=>{let c=await _chunkFE6CECEScjs.hd.call(void 0, o,{requestId:t.id});if(c.filter(({status:m})=>m==="ACTION_REQUIRED")){let m=await _chunkFE6CECEScjs.kd.call(void 0, o,e,{requestId:t.id});i.push({...t,requestIdentifiers:m,requestEnrichers:c})}},{concurrency:p});let l=i.map(({attributeValues:t,requestIdentifiers:c,requestEnrichers:w,...m})=>({...m,...Object.entries(_chunkUBVZKE7Vcjs.d.call(void 0, c,"name")).reduce((I,[P,$])=>Object.assign(I,{[P]:$.map(({value:C})=>C).join(",")}),{}),...Object.entries(_chunkUBVZKE7Vcjs.d.call(void 0, t,"attributeKey.name")).reduce((I,[P,$])=>Object.assign(I,{[P]:$.map(({name:C})=>C).join(",")}),{})})),a=_chunkUBVZKE7Vcjs.j.call(void 0, l.map(t=>Object.keys(t)).flat());return await _chunkFE6CECEScjs.og.call(void 0, u,l,a),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully wrote ${i.length} requests to file "${u}"`)),i}var _iots = require('io-ts'); var R = _interopRequireWildcard(_iots);var T="https://app.transcend.io/privacy-requests/incoming-requests/",F= exports.b =R.record(R.string,R.string);async function M(u,{id:s,...g},f,p){if(!s){let e=`Request ID must be provided to enricher request.${p?` Found error in row: ${p}`:""}`;throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(e)),new Error(e)}let n=s.toLowerCase(),o=Object.entries(g).reduce((e,[d,i])=>_chunkUBVZKE7Vcjs.j.call(void 0, _chunkFE6CECEScjs.oc.call(void 0, i)).length===0?e:Object.assign(e,{[d]:_chunkUBVZKE7Vcjs.j.call(void 0, _chunkFE6CECEScjs.oc.call(void 0, i)).map(a=>({value:d==="email"?a.toLowerCase():a}))}),{});try{return await u.post("v1/enrich-identifiers",{headers:{"x-transcend-request-id":n,"x-transcend-enricher-id":f},json:{enrichedIdentifiers:o}}).json(),_chunkZUNVPK23cjs.a.error(_colors2.default.green(`Successfully enriched request: ${T}${n}`)),!0}catch(e){if(typeof e.response.body=="string"&&e.response.body.includes("Cannot update a resolved RequestEnricher"))return _chunkZUNVPK23cjs.a.warn(_colors2.default.magenta(`Skipped enrichment for request: ${T}${n}, request is no longer in the enriching phase.`)),!1;throw _chunkZUNVPK23cjs.a.error(_colors2.default.red(`Failed to enricher identifiers for request with id: ${T}${n} - ${e.message} - ${e.response.body}`)),e}}async function ge({file:u,auth:s,sombraAuth:g,enricherId:f,markSilent:p,concurrency:n=100,transcendUrl:o=_chunkUBVZKE7Vcjs.r}){let e=await _chunkFE6CECEScjs.xc.call(void 0, o,s,g),d=_chunkFE6CECEScjs.wc.call(void 0, o,s);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading "${u}" from disk`));let i=_chunkFE6CECEScjs.rc.call(void 0, u,F);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Enriching "${i.length}" privacy requests.`));let l=0,a=0,t=0;if(await _bluebird.map.call(void 0, i,async(c,w)=>{try{p&&(await _chunkFE6CECEScjs.rg.call(void 0, d,_chunkFE6CECEScjs.Z,{input:{id:c.id,isSilent:!0}}),_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Mark request as silent mode - ${c.id}`))),await M(e,c,f,w)?l+=1:a+=1}catch (e2){t+=1}},{concurrency:n}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully notified Transcend!
2
2
  Success count: ${l}.`)),a>0&&_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Skipped count: ${a}.`)),t>0)throw _chunkZUNVPK23cjs.a.info(_colors2.default.red(`Error Count: ${t}.`)),new Error(`Failed to enrich: ${t} requests.`);return i.length}exports.a = te; exports.b = F; exports.c = M; exports.d = ge;
3
- //# sourceMappingURL=chunk-VEU5LPA6.cjs.map
3
+ //# sourceMappingURL=chunk-6GWHYOPM.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-VEU5LPA6.cjs","../src/lib/manual-enrichment/pullManualEnrichmentIdentifiersToCsv.ts","../src/lib/manual-enrichment/pushManualEnrichmentIdentifiersFromCsv.ts"],"names":["pullManualEnrichmentIdentifiersToCsv","file","auth","sombraAuth","requestActions","concurrency","transcendUrl","DEFAULT_TRANSCEND_API","client","buildTranscendGraphQLClient","sombra","createSombraGotInstance","logger","colors"],"mappings":"AAAA,mfAAgH,wDAAyC,wDAAuD,2DCAnK,oCACzB,gFACD,MA6BnB,SAAsBA,EAAAA,CAAqC,CACzD,IAAA,CAAAC,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CAAiB,CAAC,CAAA,CAClB,WAAA,CAAAC,CAAAA,CAAc,GAAA,CACd,YAAA,CAAAC,CAAAA,CAAeC,mBACjB,CAAA,CAa6C,CAE3C,IAAMC,CAAAA,CAASC,kCAAAA,CAA4BH,CAAcJ,CAAI,CAAA,CACvDQ,CAAAA,CAAS,MAAMC,kCAAAA,CAAwBL,CAAcJ,CAAAA,CAAMC,CAAU,CAAA,CAE3ES,mBAAAA,CAAO,IAAA,CACLC,gBAAAA,CAAO,OAAA,CACL,CAAA,0DAAA,EAA6DT,CAAAA,CAAe,IAAA,CAC1E,GACF,CAAC,CAAA,CAAA;ACuDP,gBAAA","file":"/home/runner/work/cli/cli/dist/chunk-VEU5LPA6.cjs","sourcesContent":[null,"import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport { map } from 'bluebird';\nimport colors from 'colors';\nimport { groupBy, uniq } from 'lodash-es';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\nimport { writeCsv } from '../helpers/writeCsv';\nimport {\n PrivacyRequest,\n RequestEnricher,\n RequestIdentifier,\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n fetchAllRequestEnrichers,\n fetchAllRequestIdentifiers,\n fetchAllRequests,\n} from '../graphql';\nimport { logger } from '../../logger';\n\nexport interface PrivacyRequestWithIdentifiers extends PrivacyRequest {\n /** Request Enrichers */\n requestEnrichers: RequestEnricher[];\n /** Request Identifiers */\n requestIdentifiers: RequestIdentifier[];\n}\n\n/**\n * Pull the set of manual enrichment jobs to CSV\n *\n * @param options - Options\n * @returns List of requests with identifiers\n */\nexport async function pullManualEnrichmentIdentifiersToCsv({\n file,\n auth,\n sombraAuth,\n requestActions = [],\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Sombra API key */\n sombraAuth?: string;\n /** Concurrency */\n concurrency?: number;\n /** The request actions to fetch */\n requestActions?: RequestAction[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<PrivacyRequestWithIdentifiers[]> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n const sombra = await createSombraGotInstance(transcendUrl, auth, sombraAuth);\n\n logger.info(\n colors.magenta(\n `Pulling manual enrichment requests, filtered for actions: ${requestActions.join(\n ',',\n )}`,\n ),\n );\n\n // Pull all privacy requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n // Requests to save\n const savedRequests: PrivacyRequestWithIdentifiers[] = [];\n\n // Filter down requests to what is needed\n await map(\n allRequests,\n async (request) => {\n // Fetch enrichers\n const requestEnrichers = await fetchAllRequestEnrichers(client, {\n requestId: request.id,\n });\n\n // Check if manual enrichment exists for that request\n const hasManualEnrichment = requestEnrichers.filter(\n ({ status }) => status === 'ACTION_REQUIRED',\n );\n\n // Save request to queue\n if (hasManualEnrichment) {\n const requestIdentifiers = await fetchAllRequestIdentifiers(\n client,\n sombra,\n {\n requestId: request.id,\n },\n );\n savedRequests.push({\n ...request,\n requestIdentifiers,\n requestEnrichers,\n });\n }\n },\n {\n concurrency,\n },\n );\n\n const data = savedRequests.map(\n ({\n attributeValues,\n requestIdentifiers,\n requestEnrichers, // eslint-disable-line @typescript-eslint/no-unused-vars\n ...request\n }) => ({\n ...request,\n // flatten identifiers\n ...Object.entries(groupBy(requestIdentifiers, 'name')).reduce(\n (acc, [key, values]) =>\n Object.assign(acc, {\n [key]: values.map(({ value }) => value).join(','),\n }),\n {},\n ),\n // flatten attributes\n ...Object.entries(groupBy(attributeValues, 'attributeKey.name')).reduce(\n (acc, [key, values]) =>\n Object.assign(acc, {\n [key]: values.map(({ name }) => name).join(','),\n }),\n {},\n ),\n }),\n );\n\n // Write out to CSV\n const headers = uniq(data.map((d) => Object.keys(d)).flat());\n await writeCsv(file, data, headers);\n\n logger.info(\n colors.green(\n `Successfully wrote ${savedRequests.length} requests to file \"${file}\"`,\n ),\n );\n\n return savedRequests;\n}\n","import colors from 'colors';\nimport { map } from 'bluebird';\nimport { logger } from '../../logger';\nimport {\n UPDATE_PRIVACY_REQUEST,\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n makeGraphQLRequest,\n} from '../graphql';\nimport {\n enrichPrivacyRequest,\n EnrichPrivacyRequest,\n} from './enrichPrivacyRequest';\nimport { readCsv } from '../requests';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\n/**\n * Push a CSV of enriched requests back into Transcend\n *\n * @param options - Options\n * @returns Number of items processed\n */\nexport async function pushManualEnrichmentIdentifiersFromCsv({\n file,\n auth,\n sombraAuth,\n enricherId,\n markSilent,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** ID of enricher being uploaded to */\n enricherId: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Mark requests in silent mode before enriching */\n markSilent?: boolean;\n}): Promise<number> {\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, sombraAuth);\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, EnrichPrivacyRequest);\n\n // Notify Transcend\n logger.info(\n colors.magenta(`Enriching \"${activeResults.length}\" privacy requests.`),\n );\n\n let successCount = 0;\n let skippedCount = 0;\n let errorCount = 0;\n\n await map(\n activeResults,\n async (request, index) => {\n try {\n // Mark requests in silent mode before a certain date\n if (markSilent) {\n await makeGraphQLRequest(client, UPDATE_PRIVACY_REQUEST, {\n input: {\n id: request.id,\n isSilent: true,\n },\n });\n\n logger.info(\n colors.magenta(`Mark request as silent mode - ${request.id}`),\n );\n }\n\n const result = await enrichPrivacyRequest(\n sombra,\n request,\n enricherId,\n index,\n );\n if (result) {\n successCount += 1;\n } else {\n skippedCount += 1;\n }\n } catch (err) {\n errorCount += 1;\n }\n },\n { concurrency },\n );\n\n logger.info(\n colors.green(\n `Successfully notified Transcend! \\n Success count: ${successCount}.`,\n ),\n );\n\n if (skippedCount > 0) {\n logger.info(colors.magenta(`Skipped count: ${skippedCount}.`));\n }\n\n if (errorCount > 0) {\n logger.info(colors.red(`Error Count: ${errorCount}.`));\n throw new Error(`Failed to enrich: ${errorCount} requests.`);\n }\n\n return activeResults.length;\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-6GWHYOPM.cjs","../src/lib/manual-enrichment/pullManualEnrichmentIdentifiersToCsv.ts","../src/lib/manual-enrichment/pushManualEnrichmentIdentifiersFromCsv.ts"],"names":["pullManualEnrichmentIdentifiersToCsv","file","auth","sombraAuth","requestActions","concurrency","transcendUrl","DEFAULT_TRANSCEND_API","client","buildTranscendGraphQLClient","sombra","createSombraGotInstance","logger","colors"],"mappings":"AAAA,mfAAgH,wDAAyC,wDAAuD,2DCAnK,oCACzB,gFACD,MA6BnB,SAAsBA,EAAAA,CAAqC,CACzD,IAAA,CAAAC,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CAAiB,CAAC,CAAA,CAClB,WAAA,CAAAC,CAAAA,CAAc,GAAA,CACd,YAAA,CAAAC,CAAAA,CAAeC,mBACjB,CAAA,CAa6C,CAE3C,IAAMC,CAAAA,CAASC,kCAAAA,CAA4BH,CAAcJ,CAAI,CAAA,CACvDQ,CAAAA,CAAS,MAAMC,kCAAAA,CAAwBL,CAAcJ,CAAAA,CAAMC,CAAU,CAAA,CAE3ES,mBAAAA,CAAO,IAAA,CACLC,gBAAAA,CAAO,OAAA,CACL,CAAA,0DAAA,EAA6DT,CAAAA,CAAe,IAAA,CAC1E,GACF,CAAC,CAAA,CAAA;ACuDP,gBAAA","file":"/home/runner/work/cli/cli/dist/chunk-6GWHYOPM.cjs","sourcesContent":[null,"import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport { map } from 'bluebird';\nimport colors from 'colors';\nimport { groupBy, uniq } from 'lodash-es';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\nimport { writeCsv } from '../helpers/writeCsv';\nimport {\n PrivacyRequest,\n RequestEnricher,\n RequestIdentifier,\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n fetchAllRequestEnrichers,\n fetchAllRequestIdentifiers,\n fetchAllRequests,\n} from '../graphql';\nimport { logger } from '../../logger';\n\nexport interface PrivacyRequestWithIdentifiers extends PrivacyRequest {\n /** Request Enrichers */\n requestEnrichers: RequestEnricher[];\n /** Request Identifiers */\n requestIdentifiers: RequestIdentifier[];\n}\n\n/**\n * Pull the set of manual enrichment jobs to CSV\n *\n * @param options - Options\n * @returns List of requests with identifiers\n */\nexport async function pullManualEnrichmentIdentifiersToCsv({\n file,\n auth,\n sombraAuth,\n requestActions = [],\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Sombra API key */\n sombraAuth?: string;\n /** Concurrency */\n concurrency?: number;\n /** The request actions to fetch */\n requestActions?: RequestAction[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<PrivacyRequestWithIdentifiers[]> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n const sombra = await createSombraGotInstance(transcendUrl, auth, sombraAuth);\n\n logger.info(\n colors.magenta(\n `Pulling manual enrichment requests, filtered for actions: ${requestActions.join(\n ',',\n )}`,\n ),\n );\n\n // Pull all privacy requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n // Requests to save\n const savedRequests: PrivacyRequestWithIdentifiers[] = [];\n\n // Filter down requests to what is needed\n await map(\n allRequests,\n async (request) => {\n // Fetch enrichers\n const requestEnrichers = await fetchAllRequestEnrichers(client, {\n requestId: request.id,\n });\n\n // Check if manual enrichment exists for that request\n const hasManualEnrichment = requestEnrichers.filter(\n ({ status }) => status === 'ACTION_REQUIRED',\n );\n\n // Save request to queue\n if (hasManualEnrichment) {\n const requestIdentifiers = await fetchAllRequestIdentifiers(\n client,\n sombra,\n {\n requestId: request.id,\n },\n );\n savedRequests.push({\n ...request,\n requestIdentifiers,\n requestEnrichers,\n });\n }\n },\n {\n concurrency,\n },\n );\n\n const data = savedRequests.map(\n ({\n attributeValues,\n requestIdentifiers,\n requestEnrichers, // eslint-disable-line @typescript-eslint/no-unused-vars\n ...request\n }) => ({\n ...request,\n // flatten identifiers\n ...Object.entries(groupBy(requestIdentifiers, 'name')).reduce(\n (acc, [key, values]) =>\n Object.assign(acc, {\n [key]: values.map(({ value }) => value).join(','),\n }),\n {},\n ),\n // flatten attributes\n ...Object.entries(groupBy(attributeValues, 'attributeKey.name')).reduce(\n (acc, [key, values]) =>\n Object.assign(acc, {\n [key]: values.map(({ name }) => name).join(','),\n }),\n {},\n ),\n }),\n );\n\n // Write out to CSV\n const headers = uniq(data.map((d) => Object.keys(d)).flat());\n await writeCsv(file, data, headers);\n\n logger.info(\n colors.green(\n `Successfully wrote ${savedRequests.length} requests to file \"${file}\"`,\n ),\n );\n\n return savedRequests;\n}\n","import colors from 'colors';\nimport { map } from 'bluebird';\nimport { logger } from '../../logger';\nimport {\n UPDATE_PRIVACY_REQUEST,\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n makeGraphQLRequest,\n} from '../graphql';\nimport {\n enrichPrivacyRequest,\n EnrichPrivacyRequest,\n} from './enrichPrivacyRequest';\nimport { readCsv } from '../requests';\nimport { DEFAULT_TRANSCEND_API } from '../../constants';\n\n/**\n * Push a CSV of enriched requests back into Transcend\n *\n * @param options - Options\n * @returns Number of items processed\n */\nexport async function pushManualEnrichmentIdentifiersFromCsv({\n file,\n auth,\n sombraAuth,\n enricherId,\n markSilent,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** ID of enricher being uploaded to */\n enricherId: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Mark requests in silent mode before enriching */\n markSilent?: boolean;\n}): Promise<number> {\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, sombraAuth);\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Read from CSV\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, EnrichPrivacyRequest);\n\n // Notify Transcend\n logger.info(\n colors.magenta(`Enriching \"${activeResults.length}\" privacy requests.`),\n );\n\n let successCount = 0;\n let skippedCount = 0;\n let errorCount = 0;\n\n await map(\n activeResults,\n async (request, index) => {\n try {\n // Mark requests in silent mode before a certain date\n if (markSilent) {\n await makeGraphQLRequest(client, UPDATE_PRIVACY_REQUEST, {\n input: {\n id: request.id,\n isSilent: true,\n },\n });\n\n logger.info(\n colors.magenta(`Mark request as silent mode - ${request.id}`),\n );\n }\n\n const result = await enrichPrivacyRequest(\n sombra,\n request,\n enricherId,\n index,\n );\n if (result) {\n successCount += 1;\n } else {\n skippedCount += 1;\n }\n } catch (err) {\n errorCount += 1;\n }\n },\n { concurrency },\n );\n\n logger.info(\n colors.green(\n `Successfully notified Transcend! \\n Success count: ${successCount}.`,\n ),\n );\n\n if (skippedCount > 0) {\n logger.info(colors.magenta(`Skipped count: ${skippedCount}.`));\n }\n\n if (errorCount > 0) {\n logger.info(colors.red(`Error Count: ${errorCount}.`));\n throw new Error(`Failed to enrich: ${errorCount} requests.`);\n }\n\n return activeResults.length;\n}\n"]}