@transcend-io/cli 10.2.1 → 10.2.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 (128) hide show
  1. package/dist/{app-DLzaZHc8.mjs → app-DcwjuHHn.mjs} +16 -16
  2. package/dist/{app-DLzaZHc8.mjs.map → app-DcwjuHHn.mjs.map} +1 -1
  3. package/dist/{approvePrivacyRequests-BlUcYXpH.mjs → approvePrivacyRequests-vTXeO7hC.mjs} +2 -2
  4. package/dist/{approvePrivacyRequests-BlUcYXpH.mjs.map → approvePrivacyRequests-vTXeO7hC.mjs.map} +1 -1
  5. package/dist/bin/bash-complete.mjs +1 -1
  6. package/dist/bin/cli.mjs +1 -1
  7. package/dist/bin/deprecated-command.mjs +1 -1
  8. package/dist/{buildXdiSyncEndpoint-D5GxPH6o.mjs → buildXdiSyncEndpoint-Bd9SRD1A.mjs} +2 -2
  9. package/dist/{buildXdiSyncEndpoint-D5GxPH6o.mjs.map → buildXdiSyncEndpoint-Bd9SRD1A.mjs.map} +1 -1
  10. package/dist/{bulkRestartRequests-DILDBdc1.mjs → bulkRestartRequests-BvURrcOl.mjs} +2 -2
  11. package/dist/{bulkRestartRequests-DILDBdc1.mjs.map → bulkRestartRequests-BvURrcOl.mjs.map} +1 -1
  12. package/dist/{bulkRetryEnrichers-CjSz1472.mjs → bulkRetryEnrichers-CTbBdTEm.mjs} +2 -2
  13. package/dist/{bulkRetryEnrichers-CjSz1472.mjs.map → bulkRetryEnrichers-CTbBdTEm.mjs.map} +1 -1
  14. package/dist/{cancelPrivacyRequests-BWJZmZVY.mjs → cancelPrivacyRequests-p9OEzUXv.mjs} +2 -2
  15. package/dist/{cancelPrivacyRequests-BWJZmZVY.mjs.map → cancelPrivacyRequests-p9OEzUXv.mjs.map} +1 -1
  16. package/dist/{command-BMa3UWax.mjs → command-CuxgABlk.mjs} +2 -2
  17. package/dist/{command-BMa3UWax.mjs.map → command-CuxgABlk.mjs.map} +1 -1
  18. package/dist/{constants-TpID7AXE.mjs → constants-D22_ckyl.mjs} +2 -2
  19. package/dist/{constants-TpID7AXE.mjs.map → constants-D22_ckyl.mjs.map} +1 -1
  20. package/dist/{createExtraKeyHandler-BO4lu0HO.mjs → createExtraKeyHandler-BkfSV_aF.mjs} +2 -2
  21. package/dist/{createExtraKeyHandler-BO4lu0HO.mjs.map → createExtraKeyHandler-BkfSV_aF.mjs.map} +1 -1
  22. package/dist/{downloadPrivacyRequestFiles-8DtRUNXp.mjs → downloadPrivacyRequestFiles-CqHT6HSU.mjs} +2 -2
  23. package/dist/{downloadPrivacyRequestFiles-8DtRUNXp.mjs.map → downloadPrivacyRequestFiles-CqHT6HSU.mjs.map} +1 -1
  24. package/dist/{generateCrossAccountApiKeys-D6hg9146.mjs → generateCrossAccountApiKeys-Cj3YCdZN.mjs} +2 -2
  25. package/dist/{generateCrossAccountApiKeys-D6hg9146.mjs.map → generateCrossAccountApiKeys-Cj3YCdZN.mjs.map} +1 -1
  26. package/dist/{impl-C71CkarV.mjs → impl-0w7yd5pK.mjs} +2 -2
  27. package/dist/{impl-C71CkarV.mjs.map → impl-0w7yd5pK.mjs.map} +1 -1
  28. package/dist/{impl-DmQAAT-u.mjs → impl-122G24x5.mjs} +2 -2
  29. package/dist/{impl-DmQAAT-u.mjs.map → impl-122G24x5.mjs.map} +1 -1
  30. package/dist/{impl--VlanXjT.mjs → impl-56wfH4jn.mjs} +2 -2
  31. package/dist/{impl--VlanXjT.mjs.map → impl-56wfH4jn.mjs.map} +1 -1
  32. package/dist/{impl-DTaM3UE3.mjs → impl-7rVYG2LQ.mjs} +2 -2
  33. package/dist/{impl-DTaM3UE3.mjs.map → impl-7rVYG2LQ.mjs.map} +1 -1
  34. package/dist/{impl-BaHZqboi.mjs → impl-B1YGN9Iu.mjs} +2 -2
  35. package/dist/{impl-BaHZqboi.mjs.map → impl-B1YGN9Iu.mjs.map} +1 -1
  36. package/dist/{impl-Du8quB1O.mjs → impl-BF0jh34q.mjs} +2 -2
  37. package/dist/{impl-Du8quB1O.mjs.map → impl-BF0jh34q.mjs.map} +1 -1
  38. package/dist/{impl-BECek1in.mjs → impl-BJTCOmGC.mjs} +2 -2
  39. package/dist/{impl-BECek1in.mjs.map → impl-BJTCOmGC.mjs.map} +1 -1
  40. package/dist/{impl-Dik9I7Bz.mjs → impl-BPqs_ltg.mjs} +2 -2
  41. package/dist/{impl-Dik9I7Bz.mjs.map → impl-BPqs_ltg.mjs.map} +1 -1
  42. package/dist/{impl-OxHej0UO.mjs → impl-BdafaDmy.mjs} +2 -2
  43. package/dist/{impl-OxHej0UO.mjs.map → impl-BdafaDmy.mjs.map} +1 -1
  44. package/dist/{impl-BuvbXmXj.mjs → impl-BnRNJ3pm.mjs} +2 -2
  45. package/dist/{impl-BuvbXmXj.mjs.map → impl-BnRNJ3pm.mjs.map} +1 -1
  46. package/dist/{impl-DAu079Yl.mjs → impl-Bu8p8dqt.mjs} +2 -2
  47. package/dist/{impl-DAu079Yl.mjs.map → impl-Bu8p8dqt.mjs.map} +1 -1
  48. package/dist/{impl-BTZOd3VN.mjs → impl-BzWh_Xg7.mjs} +2 -2
  49. package/dist/{impl-BTZOd3VN.mjs.map → impl-BzWh_Xg7.mjs.map} +1 -1
  50. package/dist/{impl-DbGCApR_.mjs → impl-C-1-lvCm.mjs} +2 -2
  51. package/dist/{impl-DbGCApR_.mjs.map → impl-C-1-lvCm.mjs.map} +1 -1
  52. package/dist/{impl-BC17WMY4.mjs → impl-CXBLyoPL.mjs} +2 -2
  53. package/dist/{impl-BC17WMY4.mjs.map → impl-CXBLyoPL.mjs.map} +1 -1
  54. package/dist/{impl-CR6tW9Jz.mjs → impl-CZrCBjBJ.mjs} +2 -2
  55. package/dist/{impl-CR6tW9Jz.mjs.map → impl-CZrCBjBJ.mjs.map} +1 -1
  56. package/dist/{impl-BKvcmB7W.mjs → impl-Cf-R4Ale.mjs} +2 -2
  57. package/dist/{impl-BKvcmB7W.mjs.map → impl-Cf-R4Ale.mjs.map} +1 -1
  58. package/dist/{impl-DWiE5RsV.mjs → impl-Ci8n7Ohd.mjs} +2 -2
  59. package/dist/{impl-DWiE5RsV.mjs.map → impl-Ci8n7Ohd.mjs.map} +1 -1
  60. package/dist/{impl-CYS38cQM.mjs → impl-CruHl43V.mjs} +2 -2
  61. package/dist/{impl-CYS38cQM.mjs.map → impl-CruHl43V.mjs.map} +1 -1
  62. package/dist/{impl-c7VvcNpZ.mjs → impl-Cziyty3N.mjs} +2 -2
  63. package/dist/{impl-c7VvcNpZ.mjs.map → impl-Cziyty3N.mjs.map} +1 -1
  64. package/dist/{impl-CxwEMQhw.mjs → impl-D3XO6Mas.mjs} +2 -2
  65. package/dist/{impl-CxwEMQhw.mjs.map → impl-D3XO6Mas.mjs.map} +1 -1
  66. package/dist/{impl-DpuPyy-w.mjs → impl-D50QXpV8.mjs} +2 -2
  67. package/dist/{impl-DpuPyy-w.mjs.map → impl-D50QXpV8.mjs.map} +1 -1
  68. package/dist/{impl-CIYSnaMG.mjs → impl-DCS69D4u.mjs} +2 -2
  69. package/dist/{impl-CIYSnaMG.mjs.map → impl-DCS69D4u.mjs.map} +1 -1
  70. package/dist/{impl-BtIsgTGn.mjs → impl-DCqgx2-j.mjs} +2 -2
  71. package/dist/{impl-BtIsgTGn.mjs.map → impl-DCqgx2-j.mjs.map} +1 -1
  72. package/dist/{impl-CScy-GrG.mjs → impl-DJFLycxa.mjs} +2 -2
  73. package/dist/{impl-CScy-GrG.mjs.map → impl-DJFLycxa.mjs.map} +1 -1
  74. package/dist/{impl-BNDNzc2I.mjs → impl-Di_93pXw.mjs} +2 -2
  75. package/dist/{impl-BNDNzc2I.mjs.map → impl-Di_93pXw.mjs.map} +1 -1
  76. package/dist/{impl-AEjPyfhu.mjs → impl-FIRoVM7G.mjs} +2 -2
  77. package/dist/{impl-AEjPyfhu.mjs.map → impl-FIRoVM7G.mjs.map} +1 -1
  78. package/dist/{impl-BXb07jBU.mjs → impl-HoctnN3Y.mjs} +2 -2
  79. package/dist/{impl-BXb07jBU.mjs.map → impl-HoctnN3Y.mjs.map} +1 -1
  80. package/dist/{impl-BsecIND0.mjs → impl-NkVnS7sH.mjs} +2 -2
  81. package/dist/{impl-BsecIND0.mjs.map → impl-NkVnS7sH.mjs.map} +1 -1
  82. package/dist/{impl-DZicly6r.mjs → impl-Ozxwpuoj.mjs} +2 -2
  83. package/dist/{impl-DZicly6r.mjs.map → impl-Ozxwpuoj.mjs.map} +1 -1
  84. package/dist/{impl-BhnojAfL.mjs → impl-SEFLf4jX.mjs} +2 -2
  85. package/dist/{impl-BhnojAfL.mjs.map → impl-SEFLf4jX.mjs.map} +1 -1
  86. package/dist/{impl-DgG4lZ9T.mjs → impl-Wbg70K6q.mjs} +2 -2
  87. package/dist/{impl-DgG4lZ9T.mjs.map → impl-Wbg70K6q.mjs.map} +1 -1
  88. package/dist/{impl-DAkBsgQN.mjs → impl-gSRG1ELM.mjs} +2 -2
  89. package/dist/{impl-DAkBsgQN.mjs.map → impl-gSRG1ELM.mjs.map} +1 -1
  90. package/dist/{impl-Djlx-Dqj.mjs → impl-jXl2dlnG.mjs} +2 -2
  91. package/dist/{impl-Djlx-Dqj.mjs.map → impl-jXl2dlnG.mjs.map} +1 -1
  92. package/dist/index.d.mts +62 -62
  93. package/dist/index.mjs +1 -1
  94. package/dist/{markRequestDataSiloIdsCompleted-sDBo1vUD.mjs → markRequestDataSiloIdsCompleted-DTfOjCUB.mjs} +2 -2
  95. package/dist/{markRequestDataSiloIdsCompleted-sDBo1vUD.mjs.map → markRequestDataSiloIdsCompleted-DTfOjCUB.mjs.map} +1 -1
  96. package/dist/{markSilentPrivacyRequests-Cmn1fxHI.mjs → markSilentPrivacyRequests-DWyW4Ndj.mjs} +2 -2
  97. package/dist/{markSilentPrivacyRequests-Cmn1fxHI.mjs.map → markSilentPrivacyRequests-DWyW4Ndj.mjs.map} +1 -1
  98. package/dist/{notifyPrivacyRequestsAdditionalTime-CmhFE4b0.mjs → notifyPrivacyRequestsAdditionalTime-BIr4P7lx.mjs} +2 -2
  99. package/dist/{notifyPrivacyRequestsAdditionalTime-CmhFE4b0.mjs.map → notifyPrivacyRequestsAdditionalTime-BIr4P7lx.mjs.map} +1 -1
  100. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-QRET4M0x.mjs → pullChunkedCustomSiloOutstandingIdentifiers-Cb7HbDD8.mjs} +2 -2
  101. package/dist/{pullChunkedCustomSiloOutstandingIdentifiers-QRET4M0x.mjs.map → pullChunkedCustomSiloOutstandingIdentifiers-Cb7HbDD8.mjs.map} +1 -1
  102. package/dist/{pullManualEnrichmentIdentifiersToCsv-8I6PgBQc.mjs → pullManualEnrichmentIdentifiersToCsv-WvXvuTGM.mjs} +2 -2
  103. package/dist/{pullManualEnrichmentIdentifiersToCsv-8I6PgBQc.mjs.map → pullManualEnrichmentIdentifiersToCsv-WvXvuTGM.mjs.map} +1 -1
  104. package/dist/{pushCronIdentifiersFromCsv-CBb2FvPD.mjs → pushCronIdentifiersFromCsv-DJywyHYU.mjs} +2 -2
  105. package/dist/{pushCronIdentifiersFromCsv-CBb2FvPD.mjs.map → pushCronIdentifiersFromCsv-DJywyHYU.mjs.map} +1 -1
  106. package/dist/{pushManualEnrichmentIdentifiersFromCsv-DYQq7hsN.mjs → pushManualEnrichmentIdentifiersFromCsv-DT4-FUe0.mjs} +2 -2
  107. package/dist/{pushManualEnrichmentIdentifiersFromCsv-DYQq7hsN.mjs.map → pushManualEnrichmentIdentifiersFromCsv-DT4-FUe0.mjs.map} +1 -1
  108. package/dist/{removeUnverifiedRequestIdentifiers-VCbL2BXD.mjs → removeUnverifiedRequestIdentifiers-Dt5hvhtq.mjs} +2 -2
  109. package/dist/{removeUnverifiedRequestIdentifiers-VCbL2BXD.mjs.map → removeUnverifiedRequestIdentifiers-Dt5hvhtq.mjs.map} +1 -1
  110. package/dist/{retryRequestDataSilos-BCe-WGdL.mjs → retryRequestDataSilos-Ds3bF0yd.mjs} +2 -2
  111. package/dist/{retryRequestDataSilos-BCe-WGdL.mjs.map → retryRequestDataSilos-Ds3bF0yd.mjs.map} +1 -1
  112. package/dist/{skipPreflightJobs-Bc0--Bvs.mjs → skipPreflightJobs-h8H7ZEX6.mjs} +2 -2
  113. package/dist/{skipPreflightJobs-Bc0--Bvs.mjs.map → skipPreflightJobs-h8H7ZEX6.mjs.map} +1 -1
  114. package/dist/{skipRequestDataSilos-BHbAQkpb.mjs → skipRequestDataSilos-C8y5PYaZ.mjs} +2 -2
  115. package/dist/{skipRequestDataSilos-BHbAQkpb.mjs.map → skipRequestDataSilos-C8y5PYaZ.mjs.map} +1 -1
  116. package/dist/{streamPrivacyRequestsToCsv-eB3gNhol.mjs → streamPrivacyRequestsToCsv-CipyYYbS.mjs} +2 -2
  117. package/dist/{streamPrivacyRequestsToCsv-eB3gNhol.mjs.map → streamPrivacyRequestsToCsv-CipyYYbS.mjs.map} +1 -1
  118. package/dist/{updateConsentManagerVersionToLatest-D6i1Xh6o.mjs → updateConsentManagerVersionToLatest-F6ywYQg4.mjs} +2 -2
  119. package/dist/{updateConsentManagerVersionToLatest-D6i1Xh6o.mjs.map → updateConsentManagerVersionToLatest-F6ywYQg4.mjs.map} +1 -1
  120. package/dist/{uploadConsents-BTM49EbZ.mjs → uploadConsents-C6gFr33S.mjs} +2 -2
  121. package/dist/{uploadConsents-BTM49EbZ.mjs.map → uploadConsents-C6gFr33S.mjs.map} +1 -1
  122. package/dist/{uploadCookiesFromCsv-DoC9rtEF.mjs → uploadCookiesFromCsv-DydhyjYq.mjs} +2 -2
  123. package/dist/{uploadCookiesFromCsv-DoC9rtEF.mjs.map → uploadCookiesFromCsv-DydhyjYq.mjs.map} +1 -1
  124. package/dist/{uploadDataFlowsFromCsv-DL1-cAit.mjs → uploadDataFlowsFromCsv-BDs2jS3I.mjs} +2 -2
  125. package/dist/{uploadDataFlowsFromCsv-DL1-cAit.mjs.map → uploadDataFlowsFromCsv-BDs2jS3I.mjs.map} +1 -1
  126. package/dist/{uploadPrivacyRequestsFromCsv-wXm4H4FH.mjs → uploadPrivacyRequestsFromCsv-oVE4Am-C.mjs} +2 -2
  127. package/dist/{uploadPrivacyRequestsFromCsv-wXm4H4FH.mjs.map → uploadPrivacyRequestsFromCsv-oVE4Am-C.mjs.map} +1 -1
  128. package/package.json +6 -6
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{o as n}from"./request-DfkRPQFr.mjs";import{r}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestStatus as i}from"@transcend-io/privacy-types";import a from"colors";import{buildTranscendGraphQLClient as o,makeGraphQLRequest as s}from"@transcend-io/sdk";import{map as c}from"@transcend-io/utils";import l from"cli-progress";async function u({requestActions:u,auth:d,requestIds:f,statuses:p=[i.Compiling,i.RequestMade,i.Delayed,i.Approving,i.Secondary,i.Enriching,i.Waiting,i.SecondaryApproving],createdAtAfter:m,createdAtBefore:h,updatedAtBefore:g,updatedAtAfter:_,concurrency:v=100,transcendUrl:y=e}){let b=o(y,d),x=new Date().getTime(),S=new l.SingleBar({},l.Presets.shades_classic),C=await r(b,{actions:u,statuses:p,createdAtBefore:h,createdAtAfter:m,updatedAtBefore:g,updatedAtAfter:_,isSilent:!1,requestIds:f});t.info(a.magenta(`Marking "${C.length}" as silent mode.`));let w=0;S.start(C.length,0),await c(C,async e=>{await s(b,n,{variables:{input:{id:e.id,isSilent:!0}},logger:t}),w+=1,S.update(w)},{concurrency:v}),S.stop();let T=new Date().getTime()-x;return t.info(a.green(`Successfully marked ${w} requests as silent mode in "${T/1e3}" seconds!`)),C.length}export{u as t};
2
- //# sourceMappingURL=markSilentPrivacyRequests-Cmn1fxHI.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{o as n}from"./request-DfkRPQFr.mjs";import{r}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestStatus as i}from"@transcend-io/privacy-types";import a from"colors";import{buildTranscendGraphQLClient as o,makeGraphQLRequest as s}from"@transcend-io/sdk";import{map as c}from"@transcend-io/utils";import l from"cli-progress";async function u({requestActions:u,auth:d,requestIds:f,statuses:p=[i.Compiling,i.RequestMade,i.Delayed,i.Approving,i.Secondary,i.Enriching,i.Waiting,i.SecondaryApproving],createdAtAfter:m,createdAtBefore:h,updatedAtBefore:g,updatedAtAfter:_,concurrency:v=100,transcendUrl:y=e}){let b=o(y,d),x=new Date().getTime(),S=new l.SingleBar({},l.Presets.shades_classic),C=await r(b,{actions:u,statuses:p,createdAtBefore:h,createdAtAfter:m,updatedAtBefore:g,updatedAtAfter:_,isSilent:!1,requestIds:f});t.info(a.magenta(`Marking "${C.length}" as silent mode.`));let w=0;S.start(C.length,0),await c(C,async e=>{await s(b,n,{variables:{input:{id:e.id,isSilent:!0}},logger:t}),w+=1,S.update(w)},{concurrency:v}),S.stop();let T=new Date().getTime()-x;return t.info(a.green(`Successfully marked ${w} requests as silent mode in "${T/1e3}" seconds!`)),C.length}export{u as t};
2
+ //# sourceMappingURL=markSilentPrivacyRequests-DWyW4Ndj.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"markSilentPrivacyRequests-Cmn1fxHI.mjs","names":[],"sources":["../src/lib/requests/markSilentPrivacyRequests.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, makeGraphQLRequest } from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { UPDATE_PRIVACY_REQUEST, fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Mark a set of privacy requests to be in silent mode\n *\n * @param options - Options\n * @returns The number of requests marked silent\n */\nexport async function markSilentPrivacyRequests({\n requestActions,\n auth,\n requestIds,\n statuses = [\n RequestStatus.Compiling,\n RequestStatus.RequestMade,\n RequestStatus.Delayed,\n RequestStatus.Approving,\n RequestStatus.Secondary,\n RequestStatus.Enriching,\n RequestStatus.Waiting,\n RequestStatus.SecondaryApproving,\n ],\n createdAtAfter,\n createdAtBefore,\n updatedAtBefore,\n updatedAtAfter,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** Concurrency limit for approving */\n concurrency?: number;\n /** The request statuses to mark silent */\n statuses?: RequestStatus[];\n /** The set of privacy requests to mark silent */\n requestIds?: string[];\n /** Filter for requests created before this date */\n createdAtBefore?: Date;\n /** Filter for requests created after this date */\n createdAtAfter?: Date;\n /** Filter for requests updated before this date */\n updatedAtBefore?: Date;\n /** Filter for requests updated after this date */\n updatedAtAfter?: Date;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isSilent: false,\n requestIds,\n });\n\n // Notify Transcend\n logger.info(colors.magenta(`Marking \"${allRequests.length}\" as silent mode.`));\n\n let total = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToMarkSilent) => {\n await makeGraphQLRequest(client, UPDATE_PRIVACY_REQUEST, {\n variables: {\n input: {\n id: requestToMarkSilent.id,\n isSilent: true,\n },\n },\n logger,\n });\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 marked ${total} requests as silent mode in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"4ZAgBA,eAAsB,EAA0B,CAC9C,iBACA,OACA,aACA,WAAW,CACT,EAAc,UACd,EAAc,YACd,EAAc,QACd,EAAc,UACd,EAAc,UACd,EAAc,UACd,EAAc,QACd,EAAc,mBACf,CACD,iBACA,kBACA,kBACA,iBACA,cAAc,IACd,eAAe,GAsBG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,WACA,kBACA,iBACA,kBACA,iBACA,SAAU,GACV,aACD,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAY,OAAO,mBAAmB,CAAC,CAE9E,IAAI,EAAQ,EACZ,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAwB,CAC7B,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,GAAI,EAAoB,GACxB,SAAU,GACX,CACF,CACD,SACD,CAAC,CAEF,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAM,+BAA+B,EAAY,IAAK,YAC9E,CACF,CACM,EAAY"}
1
+ {"version":3,"file":"markSilentPrivacyRequests-DWyW4Ndj.mjs","names":[],"sources":["../src/lib/requests/markSilentPrivacyRequests.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, makeGraphQLRequest } from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { UPDATE_PRIVACY_REQUEST, fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Mark a set of privacy requests to be in silent mode\n *\n * @param options - Options\n * @returns The number of requests marked silent\n */\nexport async function markSilentPrivacyRequests({\n requestActions,\n auth,\n requestIds,\n statuses = [\n RequestStatus.Compiling,\n RequestStatus.RequestMade,\n RequestStatus.Delayed,\n RequestStatus.Approving,\n RequestStatus.Secondary,\n RequestStatus.Enriching,\n RequestStatus.Waiting,\n RequestStatus.SecondaryApproving,\n ],\n createdAtAfter,\n createdAtBefore,\n updatedAtBefore,\n updatedAtAfter,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** Concurrency limit for approving */\n concurrency?: number;\n /** The request statuses to mark silent */\n statuses?: RequestStatus[];\n /** The set of privacy requests to mark silent */\n requestIds?: string[];\n /** Filter for requests created before this date */\n createdAtBefore?: Date;\n /** Filter for requests created after this date */\n createdAtAfter?: Date;\n /** Filter for requests updated before this date */\n updatedAtBefore?: Date;\n /** Filter for requests updated after this date */\n updatedAtAfter?: Date;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isSilent: false,\n requestIds,\n });\n\n // Notify Transcend\n logger.info(colors.magenta(`Marking \"${allRequests.length}\" as silent mode.`));\n\n let total = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToMarkSilent) => {\n await makeGraphQLRequest(client, UPDATE_PRIVACY_REQUEST, {\n variables: {\n input: {\n id: requestToMarkSilent.id,\n isSilent: true,\n },\n },\n logger,\n });\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 marked ${total} requests as silent mode in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"4ZAgBA,eAAsB,EAA0B,CAC9C,iBACA,OACA,aACA,WAAW,CACT,EAAc,UACd,EAAc,YACd,EAAc,QACd,EAAc,UACd,EAAc,UACd,EAAc,UACd,EAAc,QACd,EAAc,mBACf,CACD,iBACA,kBACA,kBACA,iBACA,cAAc,IACd,eAAe,GAsBG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,WACA,kBACA,iBACA,kBACA,iBACA,SAAU,GACV,aACD,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAY,OAAO,mBAAmB,CAAC,CAE9E,IAAI,EAAQ,EACZ,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAwB,CAC7B,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,GAAI,EAAoB,GACxB,SAAU,GACX,CACF,CACD,SACD,CAAC,CAEF,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAM,+BAA+B,EAAY,IAAK,YAC9E,CACF,CACM,EAAY"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./request-DfkRPQFr.mjs";import{r}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestAction as i}from"@transcend-io/privacy-types";import a from"colors";import{buildTranscendGraphQLClient as o,fetchAllTemplates as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d=Object.values(i),auth:f,requestIds:p,createdAtBefore:m,days:h=45,daysLeft:g=10,createdAtAfter:_,updatedAtBefore:v,updatedAtAfter:y,emailTemplate:b=`Additional Time Needed`,concurrency:x=100,transcendUrl:S=e}){let C=o(S,f),w=new Date().getTime(),T=new u.SingleBar({},u.Presets.shades_classic),E=(await s(C,{logger:t,filterBy:{title:b}})).find(e=>e.title===b);if(!E)throw Error(`Failed to find a template with title: "${b}"`);let D=await r(C,{actions:d,createdAtBefore:m,createdAtAfter:_,updatedAtBefore:v,updatedAtAfter:y,isSilent:!1,isClosed:!1,requestIds:p});D=D.filter(e=>typeof e.daysRemaining==`number`&&e.daysRemaining<g),t.info(a.magenta(`Notifying "${D.length}" that more time is needed.`));let O=0;T.start(D.length,0),await l(D,async e=>{await c(C,n,{variables:{input:{requestId:e.id,template:E.template.defaultMessage,subject:E.subject.defaultMessage,additionalTime:h}},logger:t}),O+=1,T.update(O)},{concurrency:x}),T.stop();let k=new Date().getTime()-w;return t.info(a.green(`Successfully marked ${O} requests as silent mode in "${k/1e3}" seconds!`)),D.length}export{d as t};
2
- //# sourceMappingURL=notifyPrivacyRequestsAdditionalTime-CmhFE4b0.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./request-DfkRPQFr.mjs";import{r}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestAction as i}from"@transcend-io/privacy-types";import a from"colors";import{buildTranscendGraphQLClient as o,fetchAllTemplates as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d=Object.values(i),auth:f,requestIds:p,createdAtBefore:m,days:h=45,daysLeft:g=10,createdAtAfter:_,updatedAtBefore:v,updatedAtAfter:y,emailTemplate:b=`Additional Time Needed`,concurrency:x=100,transcendUrl:S=e}){let C=o(S,f),w=new Date().getTime(),T=new u.SingleBar({},u.Presets.shades_classic),E=(await s(C,{logger:t,filterBy:{title:b}})).find(e=>e.title===b);if(!E)throw Error(`Failed to find a template with title: "${b}"`);let D=await r(C,{actions:d,createdAtBefore:m,createdAtAfter:_,updatedAtBefore:v,updatedAtAfter:y,isSilent:!1,isClosed:!1,requestIds:p});D=D.filter(e=>typeof e.daysRemaining==`number`&&e.daysRemaining<g),t.info(a.magenta(`Notifying "${D.length}" that more time is needed.`));let O=0;T.start(D.length,0),await l(D,async e=>{await c(C,n,{variables:{input:{requestId:e.id,template:E.template.defaultMessage,subject:E.subject.defaultMessage,additionalTime:h}},logger:t}),O+=1,T.update(O)},{concurrency:x}),T.stop();let k=new Date().getTime()-w;return t.info(a.green(`Successfully marked ${O} requests as silent mode in "${k/1e3}" seconds!`)),D.length}export{d as t};
2
+ //# sourceMappingURL=notifyPrivacyRequestsAdditionalTime-BIr4P7lx.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifyPrivacyRequestsAdditionalTime-CmhFE4b0.mjs","names":[],"sources":["../src/lib/requests/notifyPrivacyRequestsAdditionalTime.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllTemplates,\n makeGraphQLRequest,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { NOTIFY_ADDITIONAL_TIME, fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Mark a set of privacy requests to be in silent mode.\n * Note requests in silent mode are ignored\n *\n * @param options - Options\n * @returns The number of requests marked silent\n */\nexport async function notifyPrivacyRequestsAdditionalTime({\n requestActions = Object.values(RequestAction),\n auth,\n requestIds,\n createdAtBefore,\n days = 45,\n daysLeft = 10,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n emailTemplate = 'Additional Time Needed',\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions?: RequestAction[];\n /** Filter for requests created before this date */\n createdAtBefore: Date;\n /** Filter for requests created after this date */\n createdAtAfter?: Date;\n /** Filter for requests updated before this date */\n updatedAtBefore?: Date;\n /** Filter for requests updated after this date */\n updatedAtAfter?: Date;\n /** Email template */\n emailTemplate?: string;\n /** Transcend API key authentication */\n auth: string;\n /** Number of days to extend request by */\n days?: number;\n /**\n * Only notify requests that have less than this number of days until they are considered expired.\n * This allows for re-running the command without notifying the same users multiple times\n */\n daysLeft?: number;\n /** Concurrency limit for approving */\n concurrency?: number;\n /** The set of privacy requests to notify */\n requestIds?: string[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Grab the template with that title\n const matchingTemplates = await fetchAllTemplates(client, {\n logger,\n filterBy: { title: emailTemplate },\n });\n const exactTemplateMatch = matchingTemplates.find((template) => template.title === emailTemplate);\n if (!exactTemplateMatch) {\n throw new Error(`Failed to find a template with title: \"${emailTemplate}\"`);\n }\n\n // Pull in the requests\n let allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isSilent: false,\n isClosed: false,\n requestIds,\n });\n\n // Filter requests by daysLeft\n allRequests = allRequests.filter(\n (request) => typeof request.daysRemaining === 'number' && request.daysRemaining < daysLeft,\n );\n\n // Notify Transcend\n logger.info(colors.magenta(`Notifying \"${allRequests.length}\" that more time is needed.`));\n\n let total = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToNotify) => {\n await makeGraphQLRequest(client, NOTIFY_ADDITIONAL_TIME, {\n variables: {\n input: {\n requestId: requestToNotify.id,\n template: exactTemplateMatch.template.defaultMessage,\n subject: exactTemplateMatch.subject.defaultMessage,\n additionalTime: days,\n },\n },\n logger,\n });\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 marked ${total} requests as silent mode in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"mbAqBA,eAAsB,EAAoC,CACxD,iBAAiB,OAAO,OAAO,EAAc,CAC7C,OACA,aACA,kBACA,OAAO,GACP,WAAW,GACX,iBACA,kBACA,iBACA,gBAAgB,yBAChB,cAAc,IACd,eAAe,GA6BG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAO/E,GAJoB,MAAM,EAAkB,EAAQ,CACxD,SACA,SAAU,CAAE,MAAO,EAAe,CACnC,CAAC,EAC2C,KAAM,GAAa,EAAS,QAAU,EAAc,CACjG,GAAI,CAAC,EACH,MAAU,MAAM,0CAA0C,EAAc,GAAG,CAI7E,IAAI,EAAc,MAAM,EAAiB,EAAQ,CAC/C,QAAS,EACT,kBACA,iBACA,kBACA,iBACA,SAAU,GACV,SAAU,GACV,aACD,CAAC,CAGF,EAAc,EAAY,OACvB,GAAY,OAAO,EAAQ,eAAkB,UAAY,EAAQ,cAAgB,EACnF,CAGD,EAAO,KAAK,EAAO,QAAQ,cAAc,EAAY,OAAO,6BAA6B,CAAC,CAE1F,IAAI,EAAQ,EACZ,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAoB,CACzB,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,UAAW,EAAgB,GAC3B,SAAU,EAAmB,SAAS,eACtC,QAAS,EAAmB,QAAQ,eACpC,eAAgB,EACjB,CACF,CACD,SACD,CAAC,CAEF,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAM,+BAA+B,EAAY,IAAK,YAC9E,CACF,CACM,EAAY"}
1
+ {"version":3,"file":"notifyPrivacyRequestsAdditionalTime-BIr4P7lx.mjs","names":[],"sources":["../src/lib/requests/notifyPrivacyRequestsAdditionalTime.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllTemplates,\n makeGraphQLRequest,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { NOTIFY_ADDITIONAL_TIME, fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Mark a set of privacy requests to be in silent mode.\n * Note requests in silent mode are ignored\n *\n * @param options - Options\n * @returns The number of requests marked silent\n */\nexport async function notifyPrivacyRequestsAdditionalTime({\n requestActions = Object.values(RequestAction),\n auth,\n requestIds,\n createdAtBefore,\n days = 45,\n daysLeft = 10,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n emailTemplate = 'Additional Time Needed',\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions?: RequestAction[];\n /** Filter for requests created before this date */\n createdAtBefore: Date;\n /** Filter for requests created after this date */\n createdAtAfter?: Date;\n /** Filter for requests updated before this date */\n updatedAtBefore?: Date;\n /** Filter for requests updated after this date */\n updatedAtAfter?: Date;\n /** Email template */\n emailTemplate?: string;\n /** Transcend API key authentication */\n auth: string;\n /** Number of days to extend request by */\n days?: number;\n /**\n * Only notify requests that have less than this number of days until they are considered expired.\n * This allows for re-running the command without notifying the same users multiple times\n */\n daysLeft?: number;\n /** Concurrency limit for approving */\n concurrency?: number;\n /** The set of privacy requests to notify */\n requestIds?: string[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Grab the template with that title\n const matchingTemplates = await fetchAllTemplates(client, {\n logger,\n filterBy: { title: emailTemplate },\n });\n const exactTemplateMatch = matchingTemplates.find((template) => template.title === emailTemplate);\n if (!exactTemplateMatch) {\n throw new Error(`Failed to find a template with title: \"${emailTemplate}\"`);\n }\n\n // Pull in the requests\n let allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isSilent: false,\n isClosed: false,\n requestIds,\n });\n\n // Filter requests by daysLeft\n allRequests = allRequests.filter(\n (request) => typeof request.daysRemaining === 'number' && request.daysRemaining < daysLeft,\n );\n\n // Notify Transcend\n logger.info(colors.magenta(`Notifying \"${allRequests.length}\" that more time is needed.`));\n\n let total = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToNotify) => {\n await makeGraphQLRequest(client, NOTIFY_ADDITIONAL_TIME, {\n variables: {\n input: {\n requestId: requestToNotify.id,\n template: exactTemplateMatch.template.defaultMessage,\n subject: exactTemplateMatch.subject.defaultMessage,\n additionalTime: days,\n },\n },\n logger,\n });\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 marked ${total} requests as silent mode in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"mbAqBA,eAAsB,EAAoC,CACxD,iBAAiB,OAAO,OAAO,EAAc,CAC7C,OACA,aACA,kBACA,OAAO,GACP,WAAW,GACX,iBACA,kBACA,iBACA,gBAAgB,yBAChB,cAAc,IACd,eAAe,GA6BG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAO/E,GAJoB,MAAM,EAAkB,EAAQ,CACxD,SACA,SAAU,CAAE,MAAO,EAAe,CACnC,CAAC,EAC2C,KAAM,GAAa,EAAS,QAAU,EAAc,CACjG,GAAI,CAAC,EACH,MAAU,MAAM,0CAA0C,EAAc,GAAG,CAI7E,IAAI,EAAc,MAAM,EAAiB,EAAQ,CAC/C,QAAS,EACT,kBACA,iBACA,kBACA,iBACA,SAAU,GACV,SAAU,GACV,aACD,CAAC,CAGF,EAAc,EAAY,OACvB,GAAY,OAAO,EAAQ,eAAkB,UAAY,EAAQ,cAAgB,EACnF,CAGD,EAAO,KAAK,EAAO,QAAQ,cAAc,EAAY,OAAO,6BAA6B,CAAC,CAE1F,IAAI,EAAQ,EACZ,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAoB,CACzB,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,UAAW,EAAgB,GAC3B,SAAU,EAAmB,SAAS,eACtC,QAAS,EAAmB,QAAQ,eACpC,eAAgB,EACjB,CACF,CACD,SACD,CAAC,CAEF,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAM,+BAA+B,EAAY,IAAK,YAC9E,CACF,CACM,EAAY"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{decodeCodec as n}from"@transcend-io/type-utils";import r from"colors";import*as i from"io-ts";import{REDUCED_REQUESTS_FOR_DATA_SILO_COUNT as a,buildTranscendGraphQLClient as o,createSombraGotInstance as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{mapSeries as l}from"@transcend-io/utils";import u from"cli-progress";async function d(e,{dataSiloId:n}){let{listReducedRequestsForDataSilo:{totalCount:r}}=await c(e,a,{variables:{input:{dataSiloId:n,isResolved:!1}},logger:t});return r}const f=i.type({identifier:i.string,type:i.string,coreIdentifier:i.string,dataSiloId:i.string,requestId:i.string,nonce:i.string,requestCreatedAt:i.string,daysUntilOverdue:i.number,attributes:i.array(i.type({key:i.string,values:i.array(i.string)}))});async function p(e,{dataSiloId:t,limit:r=100,offset:a=0,requestType:o}){try{let s=await e.get(`v1/data-silo/${t}/pending-requests/${o}`,{searchParams:{offset:a,limit:r}}).json(),{items:c}=n(i.type({items:i.array(f)}),s);return c}catch(e){throw Error(`Received an error from server: ${e?.response?.body||e?.message}`)}}async function m({dataSiloId:n,auth:i,sombraAuth:a,actions:c,apiPageSize:f=100,savePageSize:m=1e3,onSave:h,transcendUrl:g=e,skipRequestCount:_=!1}){if(m%f!==0)throw Error(`savePageSize must be a multiple of apiPageSize. savePageSize: ${m}, apiPageSize: ${f}`);let v=await s(g,i,{logger:t,sombraApiKey:a,sombraUrl:process.env.SOMBRA_URL}),y=o(g,i),b=0;_||(b=await d(y,{dataSiloId:n})),t.info(r.magenta(`Pulling ${_?`all`:b} outstanding request identifiers for data silo: "${n}" for requests of types "${c.join(`", "`)}"`));let x=new Date().getTime(),S=new u.SingleBar({},u.Presets.shades_classic),C=new Set,w=[],T=[];_||S.start(b,0),await l(c,async e=>{let i=0,a=!0;for(;a;){let o=await p(v,{dataSiloId:n,limit:f,offset:i,requestType:e}),s=o.map(t=>(C.add(t.requestId),{...t,action:e})),c=s.map(({attributes:e,...t})=>({...t,...e.reduce((e,t)=>Object.assign(e,{[t.key]:t.values.join(`,`)}),{})}));w.push(...s),T.push(...c),T.length>=m&&(await h(T),T=[]),a=o.length===f,i+=f,_?t.info(r.magenta(`Pulled ${o.length} outstanding identifiers for ${C.size} requests`)):S.update(C.size)}}),T.length>0&&await h(T),_||S.stop();let E=new Date().getTime()-x;return t.info(r.green(`Successfully pulled ${w.length} outstanding identifiers from ${C.size} requests in "${E/1e3}" seconds!`)),{identifiers:w}}export{d as i,f as n,p as r,m as t};
2
- //# sourceMappingURL=pullChunkedCustomSiloOutstandingIdentifiers-QRET4M0x.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{decodeCodec as n}from"@transcend-io/type-utils";import r from"colors";import*as i from"io-ts";import{REDUCED_REQUESTS_FOR_DATA_SILO_COUNT as a,buildTranscendGraphQLClient as o,createSombraGotInstance as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{mapSeries as l}from"@transcend-io/utils";import u from"cli-progress";async function d(e,{dataSiloId:n}){let{listReducedRequestsForDataSilo:{totalCount:r}}=await c(e,a,{variables:{input:{dataSiloId:n,isResolved:!1}},logger:t});return r}const f=i.type({identifier:i.string,type:i.string,coreIdentifier:i.string,dataSiloId:i.string,requestId:i.string,nonce:i.string,requestCreatedAt:i.string,daysUntilOverdue:i.number,attributes:i.array(i.type({key:i.string,values:i.array(i.string)}))});async function p(e,{dataSiloId:t,limit:r=100,offset:a=0,requestType:o}){try{let s=await e.get(`v1/data-silo/${t}/pending-requests/${o}`,{searchParams:{offset:a,limit:r}}).json(),{items:c}=n(i.type({items:i.array(f)}),s);return c}catch(e){throw Error(`Received an error from server: ${e?.response?.body||e?.message}`)}}async function m({dataSiloId:n,auth:i,sombraAuth:a,actions:c,apiPageSize:f=100,savePageSize:m=1e3,onSave:h,transcendUrl:g=e,skipRequestCount:_=!1}){if(m%f!==0)throw Error(`savePageSize must be a multiple of apiPageSize. savePageSize: ${m}, apiPageSize: ${f}`);let v=await s(g,i,{logger:t,sombraApiKey:a,sombraUrl:process.env.SOMBRA_URL}),y=o(g,i),b=0;_||(b=await d(y,{dataSiloId:n})),t.info(r.magenta(`Pulling ${_?`all`:b} outstanding request identifiers for data silo: "${n}" for requests of types "${c.join(`", "`)}"`));let x=new Date().getTime(),S=new u.SingleBar({},u.Presets.shades_classic),C=new Set,w=[],T=[];_||S.start(b,0),await l(c,async e=>{let i=0,a=!0;for(;a;){let o=await p(v,{dataSiloId:n,limit:f,offset:i,requestType:e}),s=o.map(t=>(C.add(t.requestId),{...t,action:e})),c=s.map(({attributes:e,...t})=>({...t,...e.reduce((e,t)=>Object.assign(e,{[t.key]:t.values.join(`,`)}),{})}));w.push(...s),T.push(...c),T.length>=m&&(await h(T),T=[]),a=o.length===f,i+=f,_?t.info(r.magenta(`Pulled ${o.length} outstanding identifiers for ${C.size} requests`)):S.update(C.size)}}),T.length>0&&await h(T),_||S.stop();let E=new Date().getTime()-x;return t.info(r.green(`Successfully pulled ${w.length} outstanding identifiers from ${C.size} requests in "${E/1e3}" seconds!`)),{identifiers:w}}export{d as i,f as n,p as r,m as t};
2
+ //# sourceMappingURL=pullChunkedCustomSiloOutstandingIdentifiers-Cb7HbDD8.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pullChunkedCustomSiloOutstandingIdentifiers-QRET4M0x.mjs","names":[],"sources":["../src/lib/graphql/fetchRequestDataSiloActiveCount.ts","../src/lib/cron/pullCronPageOfIdentifiers.ts","../src/lib/cron/pullChunkedCustomSiloOutstandingIdentifiers.ts"],"sourcesContent":["import { makeGraphQLRequest, REDUCED_REQUESTS_FOR_DATA_SILO_COUNT } from '@transcend-io/sdk';\nimport { GraphQLClient } from 'graphql-request';\n\nimport { logger } from '../../logger.js';\n\n/**\n * Get number of open requests for a data silo\n *\n * @param client - GraphQL client\n * @param options - Filter options\n * @returns List of request identifiers\n */\nexport async function fetchRequestDataSiloActiveCount(\n client: GraphQLClient,\n {\n dataSiloId,\n }: {\n /** Data silo ID */\n dataSiloId: string;\n },\n): Promise<number> {\n const {\n listReducedRequestsForDataSilo: { totalCount },\n } = await makeGraphQLRequest<{\n /** Requests */\n listReducedRequestsForDataSilo: {\n /** Total count */\n totalCount: number;\n };\n }>(client, REDUCED_REQUESTS_FOR_DATA_SILO_COUNT, {\n variables: {\n input: {\n dataSiloId,\n isResolved: false,\n },\n },\n logger,\n });\n\n return totalCount;\n}\n","import { RequestAction } from '@transcend-io/privacy-types';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport type { Got } from 'got';\nimport * as t from 'io-ts';\n\nexport const CronIdentifier = t.type({\n /** The identifier value */\n identifier: t.string,\n /** The type of identifier */\n type: t.string,\n /** The core identifier of the request */\n coreIdentifier: t.string,\n /** The ID of the underlying data silo */\n dataSiloId: t.string,\n /** The ID of the underlying request */\n requestId: t.string,\n /** The request nonce */\n nonce: t.string,\n /** The time the request was created */\n requestCreatedAt: t.string,\n /** The number of days until the request is overdue */\n daysUntilOverdue: t.number,\n /** Request attributes */\n attributes: t.array(\n t.type({\n key: t.string,\n values: t.array(t.string),\n }),\n ),\n});\n\n/** Type override */\nexport type CronIdentifier = t.TypeOf<typeof CronIdentifier>;\n\n/**\n * Pull a offset of identifiers for a cron job\n *\n * @see https://docs.transcend.io/docs/api-reference/GET/v1/data-silo/(id)/pending-requests/(type)\n * @param sombra - Sombra instance configured to make requests\n * @param options - Additional options\n * @returns Successfully submitted request\n */\nexport async function pullCronPageOfIdentifiers(\n sombra: Got,\n {\n dataSiloId,\n limit = 100,\n offset = 0,\n requestType,\n }: {\n /** Data Silo ID */\n dataSiloId: string;\n /** Type of request */\n requestType: RequestAction;\n /** Number of identifiers to pull in */\n limit?: number;\n /** Page to pull in */\n offset?: number;\n },\n): Promise<CronIdentifier[]> {\n try {\n // Make the GraphQL request\n const response = await sombra\n .get(`v1/data-silo/${dataSiloId}/pending-requests/${requestType}`, {\n searchParams: {\n offset,\n limit,\n },\n })\n .json();\n\n const { items } = decodeCodec(\n t.type({\n items: t.array(CronIdentifier),\n }),\n response,\n );\n return items;\n } catch (err) {\n throw new Error(`Received an error from server: ${err?.response?.body || err?.message}`);\n }\n}\n","import { RequestAction } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, createSombraGotInstance } from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchRequestDataSiloActiveCount } from '../graphql/index.js';\nimport { pullCronPageOfIdentifiers, CronIdentifier } from './pullCronPageOfIdentifiers.js';\n\n/**\n * A CSV formatted identifier\n */\nexport type CsvFormattedIdentifier = {\n [k in string]: string | null | boolean | number;\n};\n\nexport interface CronIdentifierWithAction extends CronIdentifier {\n /** The request action that the identifier relates to */\n action: RequestAction;\n}\n\n/**\n * Pull the set of identifiers outstanding for a cron or AVC integration\n *\n * This function is designed to be used in a loop, and will call the onSave callback\n * with a chunk of identifiers when the savePageSize is reached.\n *\n * @param options - Options\n * @returns The identifiers and identifiers formatted for CSV\n */\nexport async function pullChunkedCustomSiloOutstandingIdentifiers({\n dataSiloId,\n auth,\n sombraAuth,\n actions,\n apiPageSize = 100,\n savePageSize = 1000,\n onSave,\n transcendUrl = DEFAULT_TRANSCEND_API,\n skipRequestCount = false,\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** The request actions to fetch */\n actions: RequestAction[];\n /** How many identifiers to pull in a single call to the backend */\n apiPageSize: number;\n /** How many identifiers to save at a time (usually to a CSV file, should be a multiple of apiPageSize) */\n savePageSize: number;\n /** Callback function called when a chunk of identifiers is ready to be saved */\n onSave: (chunk: CsvFormattedIdentifier[]) => Promise<void>;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Skip request count */\n skipRequestCount?: boolean;\n}): Promise<{\n /** Raw Identifiers */\n identifiers: CronIdentifierWithAction[];\n}> {\n // Validate savePageSize\n if (savePageSize % apiPageSize !== 0) {\n throw new Error(\n `savePageSize must be a multiple of apiPageSize. savePageSize: ${savePageSize}, apiPageSize: ${apiPageSize}`,\n );\n }\n\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n\n // Create GraphQL client to connect to Transcend backend\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n let totalRequestCount = 0;\n if (!skipRequestCount) {\n totalRequestCount = await fetchRequestDataSiloActiveCount(client, {\n dataSiloId,\n });\n }\n\n logger.info(\n colors.magenta(\n `Pulling ${skipRequestCount ? 'all' : totalRequestCount} outstanding request identifiers ` +\n `for data silo: \"${dataSiloId}\" for requests of types \"${actions.join('\", \"')}\"`,\n ),\n );\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n const foundRequestIds = new Set<string>();\n\n // identifiers found in total\n const identifiers: CronIdentifierWithAction[] = [];\n // current chunk of identifiers to be saved\n let currentChunk: CsvFormattedIdentifier[] = [];\n\n // map over each action\n if (!skipRequestCount) {\n progressBar.start(totalRequestCount, 0);\n }\n await mapSeries(actions, async (action) => {\n let offset = 0;\n let shouldContinue = true;\n\n // Fetch a page of identifiers\n while (shouldContinue) {\n const pageIdentifiers = await pullCronPageOfIdentifiers(sombra, {\n dataSiloId,\n limit: apiPageSize,\n offset,\n requestType: action,\n });\n\n const identifiersWithAction: CronIdentifierWithAction[] = pageIdentifiers.map(\n (identifier) => {\n foundRequestIds.add(identifier.requestId);\n return {\n ...identifier,\n action,\n };\n },\n );\n\n const csvFormattedIdentifiers = identifiersWithAction.map(\n ({ attributes, ...identifier }) => ({\n ...identifier,\n ...attributes.reduce(\n (acc, val) =>\n Object.assign(acc, {\n [val.key]: val.values.join(','),\n }),\n {},\n ),\n }),\n );\n\n identifiers.push(...identifiersWithAction);\n currentChunk.push(...csvFormattedIdentifiers);\n\n // Check if we've reached the savePageSize and call the onSave callback\n if (currentChunk.length >= savePageSize) {\n await onSave(currentChunk);\n currentChunk = [];\n }\n\n shouldContinue = pageIdentifiers.length === apiPageSize;\n offset += apiPageSize;\n if (!skipRequestCount) {\n progressBar.update(foundRequestIds.size);\n } else {\n logger.info(\n colors.magenta(\n `Pulled ${pageIdentifiers.length} outstanding identifiers for ${foundRequestIds.size} requests`,\n ),\n );\n }\n }\n });\n\n // Save any remaining identifiers in the current chunk\n if (currentChunk.length > 0) {\n await onSave(currentChunk);\n }\n\n if (!skipRequestCount) {\n progressBar.stop();\n }\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully pulled ${identifiers.length} outstanding identifiers from ${\n foundRequestIds.size\n } requests in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n\n return { identifiers };\n}\n"],"mappings":"kaAYA,eAAsB,EACpB,EACA,CACE,cAKe,CACjB,GAAM,CACJ,+BAAgC,CAAE,eAChC,MAAM,EAMP,EAAQ,EAAsC,CAC/C,UAAW,CACT,MAAO,CACL,aACA,WAAY,GACb,CACF,CACD,SACD,CAAC,CAEF,OAAO,EClCT,MAAa,EAAiB,EAAE,KAAK,CAEnC,WAAY,EAAE,OAEd,KAAM,EAAE,OAER,eAAgB,EAAE,OAElB,WAAY,EAAE,OAEd,UAAW,EAAE,OAEb,MAAO,EAAE,OAET,iBAAkB,EAAE,OAEpB,iBAAkB,EAAE,OAEpB,WAAY,EAAE,MACZ,EAAE,KAAK,CACL,IAAK,EAAE,OACP,OAAQ,EAAE,MAAM,EAAE,OAAO,CAC1B,CAAC,CACH,CACF,CAAC,CAaF,eAAsB,EACpB,EACA,CACE,aACA,QAAQ,IACR,SAAS,EACT,eAWyB,CAC3B,GAAI,CAEF,IAAM,EAAW,MAAM,EACpB,IAAI,gBAAgB,EAAW,oBAAoB,IAAe,CACjE,aAAc,CACZ,SACA,QACD,CACF,CAAC,CACD,MAAM,CAEH,CAAE,SAAU,EAChB,EAAE,KAAK,CACL,MAAO,EAAE,MAAM,EAAe,CAC/B,CAAC,CACF,EACD,CACD,OAAO,QACA,EAAK,CACZ,MAAU,MAAM,kCAAkC,GAAK,UAAU,MAAQ,GAAK,UAAU,EC/C5F,eAAsB,EAA4C,CAChE,aACA,OACA,aACA,UACA,cAAc,IACd,eAAe,IACf,SACA,eAAe,EACf,mBAAmB,IAuBlB,CAED,GAAI,EAAe,IAAgB,EACjC,MAAU,MACR,iEAAiE,EAAa,iBAAiB,IAChG,CAIH,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAGI,EAAS,EAA4B,EAAc,EAAK,CAE1D,EAAoB,EACnB,IACH,EAAoB,MAAM,EAAgC,EAAQ,CAChE,aACD,CAAC,EAGJ,EAAO,KACL,EAAO,QACL,WAAW,EAAmB,MAAQ,EAAkB,mDACnC,EAAW,2BAA2B,EAAQ,KAAK,OAAO,CAAC,GACjF,CACF,CAGD,IAAM,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAC/E,EAAkB,IAAI,IAGtB,EAA0C,EAAE,CAE9C,EAAyC,EAAE,CAG1C,GACH,EAAY,MAAM,EAAmB,EAAE,CAEzC,MAAM,EAAU,EAAS,KAAO,IAAW,CACzC,IAAI,EAAS,EACT,EAAiB,GAGrB,KAAO,GAAgB,CACrB,IAAM,EAAkB,MAAM,EAA0B,EAAQ,CAC9D,aACA,MAAO,EACP,SACA,YAAa,EACd,CAAC,CAEI,EAAoD,EAAgB,IACvE,IACC,EAAgB,IAAI,EAAW,UAAU,CAClC,CACL,GAAG,EACH,SACD,EAEJ,CAEK,EAA0B,EAAsB,KACnD,CAAE,aAAY,GAAG,MAAkB,CAClC,GAAG,EACH,GAAG,EAAW,QACX,EAAK,IACJ,OAAO,OAAO,EAAK,EAChB,EAAI,KAAM,EAAI,OAAO,KAAK,IAAI,CAChC,CAAC,CACJ,EAAE,CACH,CACF,EACF,CAED,EAAY,KAAK,GAAG,EAAsB,CAC1C,EAAa,KAAK,GAAG,EAAwB,CAGzC,EAAa,QAAU,IACzB,MAAM,EAAO,EAAa,CAC1B,EAAe,EAAE,EAGnB,EAAiB,EAAgB,SAAW,EAC5C,GAAU,EACL,EAGH,EAAO,KACL,EAAO,QACL,UAAU,EAAgB,OAAO,+BAA+B,EAAgB,KAAK,WACtF,CACF,CAND,EAAY,OAAO,EAAgB,KAAK,GAS5C,CAGE,EAAa,OAAS,GACxB,MAAM,EAAO,EAAa,CAGvB,GACH,EAAY,MAAM,CAGpB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAUvB,OARA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAY,OAAO,gCACxC,EAAgB,KACjB,gBAAgB,EAAY,IAAK,YACnC,CACF,CAEM,CAAE,cAAa"}
1
+ {"version":3,"file":"pullChunkedCustomSiloOutstandingIdentifiers-Cb7HbDD8.mjs","names":[],"sources":["../src/lib/graphql/fetchRequestDataSiloActiveCount.ts","../src/lib/cron/pullCronPageOfIdentifiers.ts","../src/lib/cron/pullChunkedCustomSiloOutstandingIdentifiers.ts"],"sourcesContent":["import { makeGraphQLRequest, REDUCED_REQUESTS_FOR_DATA_SILO_COUNT } from '@transcend-io/sdk';\nimport { GraphQLClient } from 'graphql-request';\n\nimport { logger } from '../../logger.js';\n\n/**\n * Get number of open requests for a data silo\n *\n * @param client - GraphQL client\n * @param options - Filter options\n * @returns List of request identifiers\n */\nexport async function fetchRequestDataSiloActiveCount(\n client: GraphQLClient,\n {\n dataSiloId,\n }: {\n /** Data silo ID */\n dataSiloId: string;\n },\n): Promise<number> {\n const {\n listReducedRequestsForDataSilo: { totalCount },\n } = await makeGraphQLRequest<{\n /** Requests */\n listReducedRequestsForDataSilo: {\n /** Total count */\n totalCount: number;\n };\n }>(client, REDUCED_REQUESTS_FOR_DATA_SILO_COUNT, {\n variables: {\n input: {\n dataSiloId,\n isResolved: false,\n },\n },\n logger,\n });\n\n return totalCount;\n}\n","import { RequestAction } from '@transcend-io/privacy-types';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport type { Got } from 'got';\nimport * as t from 'io-ts';\n\nexport const CronIdentifier = t.type({\n /** The identifier value */\n identifier: t.string,\n /** The type of identifier */\n type: t.string,\n /** The core identifier of the request */\n coreIdentifier: t.string,\n /** The ID of the underlying data silo */\n dataSiloId: t.string,\n /** The ID of the underlying request */\n requestId: t.string,\n /** The request nonce */\n nonce: t.string,\n /** The time the request was created */\n requestCreatedAt: t.string,\n /** The number of days until the request is overdue */\n daysUntilOverdue: t.number,\n /** Request attributes */\n attributes: t.array(\n t.type({\n key: t.string,\n values: t.array(t.string),\n }),\n ),\n});\n\n/** Type override */\nexport type CronIdentifier = t.TypeOf<typeof CronIdentifier>;\n\n/**\n * Pull a offset of identifiers for a cron job\n *\n * @see https://docs.transcend.io/docs/api-reference/GET/v1/data-silo/(id)/pending-requests/(type)\n * @param sombra - Sombra instance configured to make requests\n * @param options - Additional options\n * @returns Successfully submitted request\n */\nexport async function pullCronPageOfIdentifiers(\n sombra: Got,\n {\n dataSiloId,\n limit = 100,\n offset = 0,\n requestType,\n }: {\n /** Data Silo ID */\n dataSiloId: string;\n /** Type of request */\n requestType: RequestAction;\n /** Number of identifiers to pull in */\n limit?: number;\n /** Page to pull in */\n offset?: number;\n },\n): Promise<CronIdentifier[]> {\n try {\n // Make the GraphQL request\n const response = await sombra\n .get(`v1/data-silo/${dataSiloId}/pending-requests/${requestType}`, {\n searchParams: {\n offset,\n limit,\n },\n })\n .json();\n\n const { items } = decodeCodec(\n t.type({\n items: t.array(CronIdentifier),\n }),\n response,\n );\n return items;\n } catch (err) {\n throw new Error(`Received an error from server: ${err?.response?.body || err?.message}`);\n }\n}\n","import { RequestAction } from '@transcend-io/privacy-types';\nimport { buildTranscendGraphQLClient, createSombraGotInstance } from '@transcend-io/sdk';\nimport { mapSeries } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchRequestDataSiloActiveCount } from '../graphql/index.js';\nimport { pullCronPageOfIdentifiers, CronIdentifier } from './pullCronPageOfIdentifiers.js';\n\n/**\n * A CSV formatted identifier\n */\nexport type CsvFormattedIdentifier = {\n [k in string]: string | null | boolean | number;\n};\n\nexport interface CronIdentifierWithAction extends CronIdentifier {\n /** The request action that the identifier relates to */\n action: RequestAction;\n}\n\n/**\n * Pull the set of identifiers outstanding for a cron or AVC integration\n *\n * This function is designed to be used in a loop, and will call the onSave callback\n * with a chunk of identifiers when the savePageSize is reached.\n *\n * @param options - Options\n * @returns The identifiers and identifiers formatted for CSV\n */\nexport async function pullChunkedCustomSiloOutstandingIdentifiers({\n dataSiloId,\n auth,\n sombraAuth,\n actions,\n apiPageSize = 100,\n savePageSize = 1000,\n onSave,\n transcendUrl = DEFAULT_TRANSCEND_API,\n skipRequestCount = false,\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** The request actions to fetch */\n actions: RequestAction[];\n /** How many identifiers to pull in a single call to the backend */\n apiPageSize: number;\n /** How many identifiers to save at a time (usually to a CSV file, should be a multiple of apiPageSize) */\n savePageSize: number;\n /** Callback function called when a chunk of identifiers is ready to be saved */\n onSave: (chunk: CsvFormattedIdentifier[]) => Promise<void>;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Skip request count */\n skipRequestCount?: boolean;\n}): Promise<{\n /** Raw Identifiers */\n identifiers: CronIdentifierWithAction[];\n}> {\n // Validate savePageSize\n if (savePageSize % apiPageSize !== 0) {\n throw new Error(\n `savePageSize must be a multiple of apiPageSize. savePageSize: ${savePageSize}, apiPageSize: ${apiPageSize}`,\n );\n }\n\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n\n // Create GraphQL client to connect to Transcend backend\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n let totalRequestCount = 0;\n if (!skipRequestCount) {\n totalRequestCount = await fetchRequestDataSiloActiveCount(client, {\n dataSiloId,\n });\n }\n\n logger.info(\n colors.magenta(\n `Pulling ${skipRequestCount ? 'all' : totalRequestCount} outstanding request identifiers ` +\n `for data silo: \"${dataSiloId}\" for requests of types \"${actions.join('\", \"')}\"`,\n ),\n );\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n const foundRequestIds = new Set<string>();\n\n // identifiers found in total\n const identifiers: CronIdentifierWithAction[] = [];\n // current chunk of identifiers to be saved\n let currentChunk: CsvFormattedIdentifier[] = [];\n\n // map over each action\n if (!skipRequestCount) {\n progressBar.start(totalRequestCount, 0);\n }\n await mapSeries(actions, async (action) => {\n let offset = 0;\n let shouldContinue = true;\n\n // Fetch a page of identifiers\n while (shouldContinue) {\n const pageIdentifiers = await pullCronPageOfIdentifiers(sombra, {\n dataSiloId,\n limit: apiPageSize,\n offset,\n requestType: action,\n });\n\n const identifiersWithAction: CronIdentifierWithAction[] = pageIdentifiers.map(\n (identifier) => {\n foundRequestIds.add(identifier.requestId);\n return {\n ...identifier,\n action,\n };\n },\n );\n\n const csvFormattedIdentifiers = identifiersWithAction.map(\n ({ attributes, ...identifier }) => ({\n ...identifier,\n ...attributes.reduce(\n (acc, val) =>\n Object.assign(acc, {\n [val.key]: val.values.join(','),\n }),\n {},\n ),\n }),\n );\n\n identifiers.push(...identifiersWithAction);\n currentChunk.push(...csvFormattedIdentifiers);\n\n // Check if we've reached the savePageSize and call the onSave callback\n if (currentChunk.length >= savePageSize) {\n await onSave(currentChunk);\n currentChunk = [];\n }\n\n shouldContinue = pageIdentifiers.length === apiPageSize;\n offset += apiPageSize;\n if (!skipRequestCount) {\n progressBar.update(foundRequestIds.size);\n } else {\n logger.info(\n colors.magenta(\n `Pulled ${pageIdentifiers.length} outstanding identifiers for ${foundRequestIds.size} requests`,\n ),\n );\n }\n }\n });\n\n // Save any remaining identifiers in the current chunk\n if (currentChunk.length > 0) {\n await onSave(currentChunk);\n }\n\n if (!skipRequestCount) {\n progressBar.stop();\n }\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully pulled ${identifiers.length} outstanding identifiers from ${\n foundRequestIds.size\n } requests in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n\n return { identifiers };\n}\n"],"mappings":"kaAYA,eAAsB,EACpB,EACA,CACE,cAKe,CACjB,GAAM,CACJ,+BAAgC,CAAE,eAChC,MAAM,EAMP,EAAQ,EAAsC,CAC/C,UAAW,CACT,MAAO,CACL,aACA,WAAY,GACb,CACF,CACD,SACD,CAAC,CAEF,OAAO,EClCT,MAAa,EAAiB,EAAE,KAAK,CAEnC,WAAY,EAAE,OAEd,KAAM,EAAE,OAER,eAAgB,EAAE,OAElB,WAAY,EAAE,OAEd,UAAW,EAAE,OAEb,MAAO,EAAE,OAET,iBAAkB,EAAE,OAEpB,iBAAkB,EAAE,OAEpB,WAAY,EAAE,MACZ,EAAE,KAAK,CACL,IAAK,EAAE,OACP,OAAQ,EAAE,MAAM,EAAE,OAAO,CAC1B,CAAC,CACH,CACF,CAAC,CAaF,eAAsB,EACpB,EACA,CACE,aACA,QAAQ,IACR,SAAS,EACT,eAWyB,CAC3B,GAAI,CAEF,IAAM,EAAW,MAAM,EACpB,IAAI,gBAAgB,EAAW,oBAAoB,IAAe,CACjE,aAAc,CACZ,SACA,QACD,CACF,CAAC,CACD,MAAM,CAEH,CAAE,SAAU,EAChB,EAAE,KAAK,CACL,MAAO,EAAE,MAAM,EAAe,CAC/B,CAAC,CACF,EACD,CACD,OAAO,QACA,EAAK,CACZ,MAAU,MAAM,kCAAkC,GAAK,UAAU,MAAQ,GAAK,UAAU,EC/C5F,eAAsB,EAA4C,CAChE,aACA,OACA,aACA,UACA,cAAc,IACd,eAAe,IACf,SACA,eAAe,EACf,mBAAmB,IAuBlB,CAED,GAAI,EAAe,IAAgB,EACjC,MAAU,MACR,iEAAiE,EAAa,iBAAiB,IAChG,CAIH,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAGI,EAAS,EAA4B,EAAc,EAAK,CAE1D,EAAoB,EACnB,IACH,EAAoB,MAAM,EAAgC,EAAQ,CAChE,aACD,CAAC,EAGJ,EAAO,KACL,EAAO,QACL,WAAW,EAAmB,MAAQ,EAAkB,mDACnC,EAAW,2BAA2B,EAAQ,KAAK,OAAO,CAAC,GACjF,CACF,CAGD,IAAM,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAC/E,EAAkB,IAAI,IAGtB,EAA0C,EAAE,CAE9C,EAAyC,EAAE,CAG1C,GACH,EAAY,MAAM,EAAmB,EAAE,CAEzC,MAAM,EAAU,EAAS,KAAO,IAAW,CACzC,IAAI,EAAS,EACT,EAAiB,GAGrB,KAAO,GAAgB,CACrB,IAAM,EAAkB,MAAM,EAA0B,EAAQ,CAC9D,aACA,MAAO,EACP,SACA,YAAa,EACd,CAAC,CAEI,EAAoD,EAAgB,IACvE,IACC,EAAgB,IAAI,EAAW,UAAU,CAClC,CACL,GAAG,EACH,SACD,EAEJ,CAEK,EAA0B,EAAsB,KACnD,CAAE,aAAY,GAAG,MAAkB,CAClC,GAAG,EACH,GAAG,EAAW,QACX,EAAK,IACJ,OAAO,OAAO,EAAK,EAChB,EAAI,KAAM,EAAI,OAAO,KAAK,IAAI,CAChC,CAAC,CACJ,EAAE,CACH,CACF,EACF,CAED,EAAY,KAAK,GAAG,EAAsB,CAC1C,EAAa,KAAK,GAAG,EAAwB,CAGzC,EAAa,QAAU,IACzB,MAAM,EAAO,EAAa,CAC1B,EAAe,EAAE,EAGnB,EAAiB,EAAgB,SAAW,EAC5C,GAAU,EACL,EAGH,EAAO,KACL,EAAO,QACL,UAAU,EAAgB,OAAO,+BAA+B,EAAgB,KAAK,WACtF,CACF,CAND,EAAY,OAAO,EAAgB,KAAK,GAS5C,CAGE,EAAa,OAAS,GACxB,MAAM,EAAO,EAAa,CAGvB,GACH,EAAY,MAAM,CAGpB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAUvB,OARA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAY,OAAO,gCACxC,EAAgB,KACjB,gBAAgB,EAAY,IAAK,YACnC,CACF,CAEM,CAAE,cAAa"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{a as r}from"./writeCsv-C4pjXGsD.mjs";import{RequestStatus as i}from"@transcend-io/privacy-types";import{groupBy as a,uniq as o}from"lodash-es";import s from"colors";import{buildTranscendGraphQLClient as c,createSombraGotInstance as l,fetchAllRequestEnrichers as u,fetchAllRequestIdentifiers as d,validateSombraVersion as f}from"@transcend-io/sdk";import{map as p}from"@transcend-io/utils";async function m({file:m,auth:h,sombraAuth:g,requestActions:_=[],concurrency:v=100,transcendUrl:y=e}){let b=c(y,h),x=await l(y,h,{logger:t,sombraApiKey:g,sombraUrl:process.env.SOMBRA_URL});t.info(s.magenta(`Pulling manual enrichment requests, filtered for actions: ${_.join(`,`)}`));let S=await n(b,{actions:_,statuses:[i.Enriching]});await f(b,{logger:t});let C=[];await p(S,async e=>{let n=await u(b,{filterBy:{requestId:e.id},logger:t});if(n.filter(({status:e})=>e===`ACTION_REQUIRED`)){let r=await d(b,x,{filterBy:{requestId:e.id},skipSombraCheck:!0,logger:t});C.push({...e,requestIdentifiers:r,requestEnrichers:n})}},{concurrency:v});let w=C.map(({attributeValues:e,requestIdentifiers:t,requestEnrichers:n,...r})=>({...r,...Object.entries(a(t,`name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({value:e})=>e).join(`,`)}),{}),...Object.entries(a(e,`attributeKey.name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({name:e})=>e).join(`,`)}),{})}));return await r(m,w,o(w.map(e=>Object.keys(e)).flat())),t.info(s.green(`Successfully wrote ${C.length} requests to file "${m}"`)),C}export{m as t};
2
- //# sourceMappingURL=pullManualEnrichmentIdentifiersToCsv-8I6PgBQc.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{a as r}from"./writeCsv-C4pjXGsD.mjs";import{RequestStatus as i}from"@transcend-io/privacy-types";import{groupBy as a,uniq as o}from"lodash-es";import s from"colors";import{buildTranscendGraphQLClient as c,createSombraGotInstance as l,fetchAllRequestEnrichers as u,fetchAllRequestIdentifiers as d,validateSombraVersion as f}from"@transcend-io/sdk";import{map as p}from"@transcend-io/utils";async function m({file:m,auth:h,sombraAuth:g,requestActions:_=[],concurrency:v=100,transcendUrl:y=e}){let b=c(y,h),x=await l(y,h,{logger:t,sombraApiKey:g,sombraUrl:process.env.SOMBRA_URL});t.info(s.magenta(`Pulling manual enrichment requests, filtered for actions: ${_.join(`,`)}`));let S=await n(b,{actions:_,statuses:[i.Enriching]});await f(b,{logger:t});let C=[];await p(S,async e=>{let n=await u(b,{filterBy:{requestId:e.id},logger:t});if(n.filter(({status:e})=>e===`ACTION_REQUIRED`)){let r=await d(b,x,{filterBy:{requestId:e.id},skipSombraCheck:!0,logger:t});C.push({...e,requestIdentifiers:r,requestEnrichers:n})}},{concurrency:v});let w=C.map(({attributeValues:e,requestIdentifiers:t,requestEnrichers:n,...r})=>({...r,...Object.entries(a(t,`name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({value:e})=>e).join(`,`)}),{}),...Object.entries(a(e,`attributeKey.name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({name:e})=>e).join(`,`)}),{})}));return await r(m,w,o(w.map(e=>Object.keys(e)).flat())),t.info(s.green(`Successfully wrote ${C.length} requests to file "${m}"`)),C}export{m as t};
2
+ //# sourceMappingURL=pullManualEnrichmentIdentifiersToCsv-WvXvuTGM.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pullManualEnrichmentIdentifiersToCsv-8I6PgBQc.mjs","names":[],"sources":["../src/lib/manual-enrichment/pullManualEnrichmentIdentifiersToCsv.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n fetchAllRequestEnrichers,\n fetchAllRequestIdentifiers,\n validateSombraVersion,\n type RequestEnricher,\n type RequestIdentifier,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport { groupBy, uniq } from 'lodash-es';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { type PrivacyRequest, fetchAllRequests } from '../graphql/index.js';\nimport { writeCsv } from '../helpers/writeCsv.js';\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, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n\n logger.info(\n colors.magenta(\n `Pulling manual enrichment requests, filtered for actions: ${requestActions.join(',')}`,\n ),\n );\n\n // Pull all privacy requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n await validateSombraVersion(client, { logger });\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 filterBy: { requestId: request.id },\n logger,\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(client, sombra, {\n filterBy: { requestId: request.id },\n skipSombraCheck: true,\n logger,\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(`Successfully wrote ${savedRequests.length} requests to file \"${file}\"`),\n );\n\n return savedRequests;\n}\n"],"mappings":"khBAgCA,eAAsB,EAAqC,CACzD,OACA,OACA,aACA,iBAAiB,EAAE,CACnB,cAAc,IACd,eAAe,GAc4B,CAE3C,IAAM,EAAS,EAA4B,EAAc,EAAK,CACxD,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAEF,EAAO,KACL,EAAO,QACL,6DAA6D,EAAe,KAAK,IAAI,GACtF,CACF,CAGD,IAAM,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAEF,MAAM,EAAsB,EAAQ,CAAE,SAAQ,CAAC,CAG/C,IAAM,EAAiD,EAAE,CAGzD,MAAM,EACJ,EACA,KAAO,IAAY,CAEjB,IAAM,EAAmB,MAAM,EAAyB,EAAQ,CAC9D,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,SACD,CAAC,CAQF,GAL4B,EAAiB,QAC1C,CAAE,YAAa,IAAW,kBAC5B,CAGwB,CACvB,IAAM,EAAqB,MAAM,EAA2B,EAAQ,EAAQ,CAC1E,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,gBAAiB,GACjB,SACD,CAAC,CACF,EAAc,KAAK,CACjB,GAAG,EACH,qBACA,mBACD,CAAC,GAGN,CACE,cACD,CACF,CAED,IAAM,EAAO,EAAc,KACxB,CACC,kBACA,qBACA,mBACA,GAAG,MACE,CACL,GAAG,EAEH,GAAG,OAAO,QAAQ,EAAQ,EAAoB,OAAO,CAAC,CAAC,QACpD,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,GAAM,EAAO,KAAK,CAAE,WAAY,EAAM,CAAC,KAAK,IAAI,CAClD,CAAC,CACJ,EAAE,CACH,CAED,GAAG,OAAO,QAAQ,EAAQ,EAAiB,oBAAoB,CAAC,CAAC,QAC9D,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,GAAM,EAAO,KAAK,CAAE,UAAW,EAAK,CAAC,KAAK,IAAI,CAChD,CAAC,CACJ,EAAE,CACH,CACF,EACF,CAUD,OANA,MAAM,EAAS,EAAM,EADL,EAAK,EAAK,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CACzB,CAEnC,EAAO,KACL,EAAO,MAAM,sBAAsB,EAAc,OAAO,qBAAqB,EAAK,GAAG,CACtF,CAEM"}
1
+ {"version":3,"file":"pullManualEnrichmentIdentifiersToCsv-WvXvuTGM.mjs","names":[],"sources":["../src/lib/manual-enrichment/pullManualEnrichmentIdentifiersToCsv.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n fetchAllRequestEnrichers,\n fetchAllRequestIdentifiers,\n validateSombraVersion,\n type RequestEnricher,\n type RequestIdentifier,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\nimport { groupBy, uniq } from 'lodash-es';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { type PrivacyRequest, fetchAllRequests } from '../graphql/index.js';\nimport { writeCsv } from '../helpers/writeCsv.js';\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, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n\n logger.info(\n colors.magenta(\n `Pulling manual enrichment requests, filtered for actions: ${requestActions.join(',')}`,\n ),\n );\n\n // Pull all privacy requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n await validateSombraVersion(client, { logger });\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 filterBy: { requestId: request.id },\n logger,\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(client, sombra, {\n filterBy: { requestId: request.id },\n skipSombraCheck: true,\n logger,\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(`Successfully wrote ${savedRequests.length} requests to file \"${file}\"`),\n );\n\n return savedRequests;\n}\n"],"mappings":"khBAgCA,eAAsB,EAAqC,CACzD,OACA,OACA,aACA,iBAAiB,EAAE,CACnB,cAAc,IACd,eAAe,GAc4B,CAE3C,IAAM,EAAS,EAA4B,EAAc,EAAK,CACxD,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAEF,EAAO,KACL,EAAO,QACL,6DAA6D,EAAe,KAAK,IAAI,GACtF,CACF,CAGD,IAAM,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAEF,MAAM,EAAsB,EAAQ,CAAE,SAAQ,CAAC,CAG/C,IAAM,EAAiD,EAAE,CAGzD,MAAM,EACJ,EACA,KAAO,IAAY,CAEjB,IAAM,EAAmB,MAAM,EAAyB,EAAQ,CAC9D,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,SACD,CAAC,CAQF,GAL4B,EAAiB,QAC1C,CAAE,YAAa,IAAW,kBAC5B,CAGwB,CACvB,IAAM,EAAqB,MAAM,EAA2B,EAAQ,EAAQ,CAC1E,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,gBAAiB,GACjB,SACD,CAAC,CACF,EAAc,KAAK,CACjB,GAAG,EACH,qBACA,mBACD,CAAC,GAGN,CACE,cACD,CACF,CAED,IAAM,EAAO,EAAc,KACxB,CACC,kBACA,qBACA,mBACA,GAAG,MACE,CACL,GAAG,EAEH,GAAG,OAAO,QAAQ,EAAQ,EAAoB,OAAO,CAAC,CAAC,QACpD,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,GAAM,EAAO,KAAK,CAAE,WAAY,EAAM,CAAC,KAAK,IAAI,CAClD,CAAC,CACJ,EAAE,CACH,CAED,GAAG,OAAO,QAAQ,EAAQ,EAAiB,oBAAoB,CAAC,CAAC,QAC9D,EAAK,CAAC,EAAK,KACV,OAAO,OAAO,EAAK,EAChB,GAAM,EAAO,KAAK,CAAE,UAAW,EAAK,CAAC,KAAK,IAAI,CAChD,CAAC,CACJ,EAAE,CACH,CACF,EACF,CAUD,OANA,MAAM,EAAS,EAAM,EADL,EAAK,EAAK,IAAK,GAAM,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CACzB,CAEnC,EAAO,KACL,EAAO,MAAM,sBAAsB,EAAc,OAAO,qBAAqB,EAAK,GAAG,CACtF,CAEM"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{t as n}from"./readCsv-C4TyEs-r.mjs";import{chunk as r}from"lodash-es";import i from"colors";import*as a from"io-ts";import{createSombraGotInstance as o}from"@transcend-io/sdk";import{map as s,mapSeries as c}from"@transcend-io/utils";import l from"cli-progress";const u=a.type({nonce:a.string,identifier:a.string});async function d(e,{nonce:t,identifier:n}){try{return await e.put(`v1/data-silo`,{headers:{"x-transcend-nonce":t},json:{profiles:[{profileId:n}]}}),!0}catch(e){if(e.response?.statusCode===409)return!1;throw Error(`Received an error from server: ${e?.response?.body||e?.message}`)}}async function f({file:a,dataSiloId:f,auth:p,sombraAuth:m,concurrency:h=100,transcendUrl:g=e,sleepSeconds:_=10}){let v=await o(g,p,{logger:t,sombraApiKey:m,sombraUrl:process.env.SOMBRA_URL});t.info(i.magenta(`Reading "${a}" from disk`));let y=n(a,u);t.info(i.magenta(`Notifying Transcend for data silo "${f}" marking "${y.length}" identifiers as completed.`));let b=new Date().getTime(),x=new l.SingleBar({},l.Presets.shades_classic),S=0,C=0,w=0;x.start(y.length,0);let T=r(y,h),E=T.length;await c(T,async(e,n)=>{t.info(i.blue(`Processing chunk ${n+1}/${E} (${r.length} items)`)),await s(e,async e=>{try{await d(v,e)?S+=1:C+=1}catch(n){t.error(i.red(`Error notifying Transcend for identifier "${e.identifier}" - ${n?.message}`)),w+=1}x.update(S+C)}),_>0&&n<E-1&&(t.info(i.yellow(`Sleeping for ${_}s before next chunk...`)),await new Promise(e=>{setTimeout(e,_*1e3)}))}),x.stop();let D=new Date().getTime()-b;if(t.info(i.green(`Successfully notified Transcend for ${S} identifiers in "${D/1e3}" seconds!`)),C&&t.info(i.magenta(`There were ${C} identifiers that were not in a state to be updated.They likely have already been resolved.`)),w)throw t.error(i.red(`There were ${w} identifiers that failed to be updated. Please review the logs for more information.`)),Error(`Failed to update all identifiers`);return y.length}export{u as n,d as r,f as t};
2
- //# sourceMappingURL=pushCronIdentifiersFromCsv-CBb2FvPD.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{t as n}from"./readCsv-C4TyEs-r.mjs";import{chunk as r}from"lodash-es";import i from"colors";import*as a from"io-ts";import{createSombraGotInstance as o}from"@transcend-io/sdk";import{map as s,mapSeries as c}from"@transcend-io/utils";import l from"cli-progress";const u=a.type({nonce:a.string,identifier:a.string});async function d(e,{nonce:t,identifier:n}){try{return await e.put(`v1/data-silo`,{headers:{"x-transcend-nonce":t},json:{profiles:[{profileId:n}]}}),!0}catch(e){if(e.response?.statusCode===409)return!1;throw Error(`Received an error from server: ${e?.response?.body||e?.message}`)}}async function f({file:a,dataSiloId:f,auth:p,sombraAuth:m,concurrency:h=100,transcendUrl:g=e,sleepSeconds:_=10}){let v=await o(g,p,{logger:t,sombraApiKey:m,sombraUrl:process.env.SOMBRA_URL});t.info(i.magenta(`Reading "${a}" from disk`));let y=n(a,u);t.info(i.magenta(`Notifying Transcend for data silo "${f}" marking "${y.length}" identifiers as completed.`));let b=new Date().getTime(),x=new l.SingleBar({},l.Presets.shades_classic),S=0,C=0,w=0;x.start(y.length,0);let T=r(y,h),E=T.length;await c(T,async(e,n)=>{t.info(i.blue(`Processing chunk ${n+1}/${E} (${r.length} items)`)),await s(e,async e=>{try{await d(v,e)?S+=1:C+=1}catch(n){t.error(i.red(`Error notifying Transcend for identifier "${e.identifier}" - ${n?.message}`)),w+=1}x.update(S+C)}),_>0&&n<E-1&&(t.info(i.yellow(`Sleeping for ${_}s before next chunk...`)),await new Promise(e=>{setTimeout(e,_*1e3)}))}),x.stop();let D=new Date().getTime()-b;if(t.info(i.green(`Successfully notified Transcend for ${S} identifiers in "${D/1e3}" seconds!`)),C&&t.info(i.magenta(`There were ${C} identifiers that were not in a state to be updated.They likely have already been resolved.`)),w)throw t.error(i.red(`There were ${w} identifiers that failed to be updated. Please review the logs for more information.`)),Error(`Failed to update all identifiers`);return y.length}export{u as n,d as r,f as t};
2
+ //# sourceMappingURL=pushCronIdentifiersFromCsv-DJywyHYU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pushCronIdentifiersFromCsv-CBb2FvPD.mjs","names":[],"sources":["../src/lib/cron/markCronIdentifierCompleted.ts","../src/lib/cron/pushCronIdentifiersFromCsv.ts"],"sourcesContent":["import type { Got } from 'got';\nimport * as t from 'io-ts';\n\n/**\n * Minimal set required to mark as completed\n */\nexport const CronIdentifierPush = t.type({\n nonce: t.string,\n identifier: t.string,\n});\n\n/** Type override */\nexport type CronIdentifierPush = t.TypeOf<typeof CronIdentifierPush>;\n\n/**\n * Mark an identifier output by the cron job as completed.\n *\n * @see https://docs.transcend.io/docs/api-reference/PUT/v1/data-silo\n * @param sombra - Sombra instance configured to make requests\n * @param options - Additional options\n * @returns Successfully submitted request, false if not in a state to update\n */\nexport async function markCronIdentifierCompleted(\n sombra: Got,\n { nonce, identifier }: CronIdentifierPush,\n): Promise<boolean> {\n try {\n // Make the GraphQL request\n await sombra.put('v1/data-silo', {\n headers: {\n 'x-transcend-nonce': nonce,\n },\n json: {\n profiles: [\n {\n profileId: identifier,\n },\n ],\n },\n });\n return true;\n } catch (err) {\n // handle gracefully\n if (err.response?.statusCode === 409) {\n return false;\n }\n throw new Error(`Received an error from server: ${err?.response?.body || err?.message}`);\n }\n}\n","import { createSombraGotInstance } from '@transcend-io/sdk';\nimport { map, mapSeries } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\nimport { chunk } from 'lodash-es';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { readCsv } from '../requests/index.js';\nimport { markCronIdentifierCompleted, CronIdentifierPush } from './markCronIdentifierCompleted.js';\n\n/**\n * Given a CSV of cron job outputs, mark all requests as completed in Transcend\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function pushCronIdentifiersFromCsv({\n file,\n dataSiloId,\n auth,\n sombraAuth,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n sleepSeconds = 10,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Upload concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Sleep time in seconds between chunks of concurrent calls */\n sleepSeconds?: number;\n}): Promise<number> {\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n\n // Read from CSV\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, CronIdentifierPush);\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Notifying Transcend for data silo \"${dataSiloId}\" marking \"${activeResults.length}\" identifiers as completed.`,\n ),\n );\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n let successCount = 0;\n let failureCount = 0;\n let errorCount = 0;\n progressBar.start(activeResults.length, 0);\n\n // Process in chunks with sleep intervals\n const chunks = chunk(activeResults, concurrency);\n const totalChunks = chunks.length;\n const processChunk = async (items: CronIdentifierPush[], chunkIndex: number): Promise<void> => {\n logger.info(\n colors.blue(`Processing chunk ${chunkIndex + 1}/${totalChunks} (${chunk.length} items)`),\n );\n\n // Process the items of the chunk concurrently\n await map(items, async (identifier) => {\n try {\n const success = await markCronIdentifierCompleted(sombra, identifier);\n if (success) {\n successCount += 1;\n } else {\n failureCount += 1;\n }\n } catch (e) {\n logger.error(\n colors.red(\n `Error notifying Transcend for identifier \"${identifier.identifier}\" - ${e?.message}`,\n ),\n );\n errorCount += 1;\n }\n progressBar.update(successCount + failureCount);\n });\n\n // Sleep between chunks (except for the last chunk)\n if (sleepSeconds > 0 && chunkIndex < totalChunks - 1) {\n logger.info(colors.yellow(`Sleeping for ${sleepSeconds}s before next chunk...`));\n\n await new Promise((resolve) => {\n setTimeout(resolve, sleepSeconds * 1000);\n });\n }\n };\n\n // Process all chunks sequentially\n await mapSeries(chunks, processChunk);\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully notified Transcend for ${successCount} identifiers in \"${\n totalTime / 1000\n }\" seconds!`,\n ),\n );\n if (failureCount) {\n logger.info(\n colors.magenta(\n `There were ${failureCount} identifiers that were not in a state to be updated.` +\n 'They likely have already been resolved.',\n ),\n );\n }\n if (errorCount) {\n logger.error(\n colors.red(\n `There were ${errorCount} identifiers that failed to be updated. Please review the logs for more information.`,\n ),\n );\n throw new Error('Failed to update all identifiers');\n }\n return activeResults.length;\n}\n"],"mappings":"8VAMA,MAAa,EAAqB,EAAE,KAAK,CACvC,MAAO,EAAE,OACT,WAAY,EAAE,OACf,CAAC,CAaF,eAAsB,EACpB,EACA,CAAE,QAAO,cACS,CAClB,GAAI,CAcF,OAZA,MAAM,EAAO,IAAI,eAAgB,CAC/B,QAAS,CACP,oBAAqB,EACtB,CACD,KAAM,CACJ,SAAU,CACR,CACE,UAAW,EACZ,CACF,CACF,CACF,CAAC,CACK,SACA,EAAK,CAEZ,GAAI,EAAI,UAAU,aAAe,IAC/B,MAAO,GAET,MAAU,MAAM,kCAAkC,GAAK,UAAU,MAAQ,GAAK,UAAU,EC7B5F,eAAsB,EAA2B,CAC/C,OACA,aACA,OACA,aACA,cAAc,IACd,eAAe,EACf,eAAe,IAgBG,CAElB,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAC1D,IAAM,EAAgB,EAAQ,EAAM,EAAmB,CAGvD,EAAO,KACL,EAAO,QACL,sCAAsC,EAAW,aAAa,EAAc,OAAO,6BACpF,CACF,CAGD,IAAM,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAe,EACf,EAAe,EACf,EAAa,EACjB,EAAY,MAAM,EAAc,OAAQ,EAAE,CAG1C,IAAM,EAAS,EAAM,EAAe,EAAY,CAC1C,EAAc,EAAO,OAqC3B,MAAM,EAAU,EApCK,MAAO,EAA6B,IAAsC,CAC7F,EAAO,KACL,EAAO,KAAK,oBAAoB,EAAa,EAAE,GAAG,EAAY,IAAI,EAAM,OAAO,SAAS,CACzF,CAGD,MAAM,EAAI,EAAO,KAAO,IAAe,CACrC,GAAI,CACc,MAAM,EAA4B,EAAQ,EAAW,CAEnE,GAAgB,EAEhB,GAAgB,QAEX,EAAG,CACV,EAAO,MACL,EAAO,IACL,6CAA6C,EAAW,WAAW,MAAM,GAAG,UAC7E,CACF,CACD,GAAc,EAEhB,EAAY,OAAO,EAAe,EAAa,EAC/C,CAGE,EAAe,GAAK,EAAa,EAAc,IACjD,EAAO,KAAK,EAAO,OAAO,gBAAgB,EAAa,wBAAwB,CAAC,CAEhF,MAAM,IAAI,QAAS,GAAY,CAC7B,WAAW,EAAS,EAAe,IAAK,EACxC,GAK+B,CAErC,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAiBvB,GAfA,EAAO,KACL,EAAO,MACL,uCAAuC,EAAa,mBAClD,EAAY,IACb,YACF,CACF,CACG,GACF,EAAO,KACL,EAAO,QACL,cAAc,EAAa,6FAE5B,CACF,CAEC,EAMF,MALA,EAAO,MACL,EAAO,IACL,cAAc,EAAW,sFAC1B,CACF,CACS,MAAM,mCAAmC,CAErD,OAAO,EAAc"}
1
+ {"version":3,"file":"pushCronIdentifiersFromCsv-DJywyHYU.mjs","names":[],"sources":["../src/lib/cron/markCronIdentifierCompleted.ts","../src/lib/cron/pushCronIdentifiersFromCsv.ts"],"sourcesContent":["import type { Got } from 'got';\nimport * as t from 'io-ts';\n\n/**\n * Minimal set required to mark as completed\n */\nexport const CronIdentifierPush = t.type({\n nonce: t.string,\n identifier: t.string,\n});\n\n/** Type override */\nexport type CronIdentifierPush = t.TypeOf<typeof CronIdentifierPush>;\n\n/**\n * Mark an identifier output by the cron job as completed.\n *\n * @see https://docs.transcend.io/docs/api-reference/PUT/v1/data-silo\n * @param sombra - Sombra instance configured to make requests\n * @param options - Additional options\n * @returns Successfully submitted request, false if not in a state to update\n */\nexport async function markCronIdentifierCompleted(\n sombra: Got,\n { nonce, identifier }: CronIdentifierPush,\n): Promise<boolean> {\n try {\n // Make the GraphQL request\n await sombra.put('v1/data-silo', {\n headers: {\n 'x-transcend-nonce': nonce,\n },\n json: {\n profiles: [\n {\n profileId: identifier,\n },\n ],\n },\n });\n return true;\n } catch (err) {\n // handle gracefully\n if (err.response?.statusCode === 409) {\n return false;\n }\n throw new Error(`Received an error from server: ${err?.response?.body || err?.message}`);\n }\n}\n","import { createSombraGotInstance } from '@transcend-io/sdk';\nimport { map, mapSeries } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\nimport { chunk } from 'lodash-es';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { readCsv } from '../requests/index.js';\nimport { markCronIdentifierCompleted, CronIdentifierPush } from './markCronIdentifierCompleted.js';\n\n/**\n * Given a CSV of cron job outputs, mark all requests as completed in Transcend\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function pushCronIdentifiersFromCsv({\n file,\n dataSiloId,\n auth,\n sombraAuth,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n sleepSeconds = 10,\n}: {\n /** CSV file path */\n file: string;\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Upload concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Sleep time in seconds between chunks of concurrent calls */\n sleepSeconds?: number;\n}): Promise<number> {\n // Create sombra instance to communicate with\n const sombra = await createSombraGotInstance(transcendUrl, auth, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\n\n // Read from CSV\n logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n const activeResults = readCsv(file, CronIdentifierPush);\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Notifying Transcend for data silo \"${dataSiloId}\" marking \"${activeResults.length}\" identifiers as completed.`,\n ),\n );\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n let successCount = 0;\n let failureCount = 0;\n let errorCount = 0;\n progressBar.start(activeResults.length, 0);\n\n // Process in chunks with sleep intervals\n const chunks = chunk(activeResults, concurrency);\n const totalChunks = chunks.length;\n const processChunk = async (items: CronIdentifierPush[], chunkIndex: number): Promise<void> => {\n logger.info(\n colors.blue(`Processing chunk ${chunkIndex + 1}/${totalChunks} (${chunk.length} items)`),\n );\n\n // Process the items of the chunk concurrently\n await map(items, async (identifier) => {\n try {\n const success = await markCronIdentifierCompleted(sombra, identifier);\n if (success) {\n successCount += 1;\n } else {\n failureCount += 1;\n }\n } catch (e) {\n logger.error(\n colors.red(\n `Error notifying Transcend for identifier \"${identifier.identifier}\" - ${e?.message}`,\n ),\n );\n errorCount += 1;\n }\n progressBar.update(successCount + failureCount);\n });\n\n // Sleep between chunks (except for the last chunk)\n if (sleepSeconds > 0 && chunkIndex < totalChunks - 1) {\n logger.info(colors.yellow(`Sleeping for ${sleepSeconds}s before next chunk...`));\n\n await new Promise((resolve) => {\n setTimeout(resolve, sleepSeconds * 1000);\n });\n }\n };\n\n // Process all chunks sequentially\n await mapSeries(chunks, processChunk);\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully notified Transcend for ${successCount} identifiers in \"${\n totalTime / 1000\n }\" seconds!`,\n ),\n );\n if (failureCount) {\n logger.info(\n colors.magenta(\n `There were ${failureCount} identifiers that were not in a state to be updated.` +\n 'They likely have already been resolved.',\n ),\n );\n }\n if (errorCount) {\n logger.error(\n colors.red(\n `There were ${errorCount} identifiers that failed to be updated. Please review the logs for more information.`,\n ),\n );\n throw new Error('Failed to update all identifiers');\n }\n return activeResults.length;\n}\n"],"mappings":"8VAMA,MAAa,EAAqB,EAAE,KAAK,CACvC,MAAO,EAAE,OACT,WAAY,EAAE,OACf,CAAC,CAaF,eAAsB,EACpB,EACA,CAAE,QAAO,cACS,CAClB,GAAI,CAcF,OAZA,MAAM,EAAO,IAAI,eAAgB,CAC/B,QAAS,CACP,oBAAqB,EACtB,CACD,KAAM,CACJ,SAAU,CACR,CACE,UAAW,EACZ,CACF,CACF,CACF,CAAC,CACK,SACA,EAAK,CAEZ,GAAI,EAAI,UAAU,aAAe,IAC/B,MAAO,GAET,MAAU,MAAM,kCAAkC,GAAK,UAAU,MAAQ,GAAK,UAAU,EC7B5F,eAAsB,EAA2B,CAC/C,OACA,aACA,OACA,aACA,cAAc,IACd,eAAe,EACf,eAAe,IAgBG,CAElB,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAC1D,IAAM,EAAgB,EAAQ,EAAM,EAAmB,CAGvD,EAAO,KACL,EAAO,QACL,sCAAsC,EAAW,aAAa,EAAc,OAAO,6BACpF,CACF,CAGD,IAAM,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAe,EACf,EAAe,EACf,EAAa,EACjB,EAAY,MAAM,EAAc,OAAQ,EAAE,CAG1C,IAAM,EAAS,EAAM,EAAe,EAAY,CAC1C,EAAc,EAAO,OAqC3B,MAAM,EAAU,EApCK,MAAO,EAA6B,IAAsC,CAC7F,EAAO,KACL,EAAO,KAAK,oBAAoB,EAAa,EAAE,GAAG,EAAY,IAAI,EAAM,OAAO,SAAS,CACzF,CAGD,MAAM,EAAI,EAAO,KAAO,IAAe,CACrC,GAAI,CACc,MAAM,EAA4B,EAAQ,EAAW,CAEnE,GAAgB,EAEhB,GAAgB,QAEX,EAAG,CACV,EAAO,MACL,EAAO,IACL,6CAA6C,EAAW,WAAW,MAAM,GAAG,UAC7E,CACF,CACD,GAAc,EAEhB,EAAY,OAAO,EAAe,EAAa,EAC/C,CAGE,EAAe,GAAK,EAAa,EAAc,IACjD,EAAO,KAAK,EAAO,OAAO,gBAAgB,EAAa,wBAAwB,CAAC,CAEhF,MAAM,IAAI,QAAS,GAAY,CAC7B,WAAW,EAAS,EAAe,IAAK,EACxC,GAK+B,CAErC,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAiBvB,GAfA,EAAO,KACL,EAAO,MACL,uCAAuC,EAAa,mBAClD,EAAY,IACb,YACF,CACF,CACG,GACF,EAAO,KACL,EAAO,QACL,cAAc,EAAa,6FAE5B,CACF,CAEC,EAMF,MALA,EAAO,MACL,EAAO,IACL,cAAc,EAAW,sFAC1B,CACF,CACS,MAAM,mCAAmC,CAErD,OAAO,EAAc"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{t as n}from"./readCsv-C4TyEs-r.mjs";import{o as r}from"./request-DfkRPQFr.mjs";import{uniq as i}from"lodash-es";import a from"colors";import*as o from"io-ts";import{buildTranscendGraphQLClient as s,createSombraGotInstance as c,makeGraphQLRequest as l}from"@transcend-io/sdk";import{map as u,splitCsvToList as d}from"@transcend-io/utils";const f=`https://app.transcend.io/privacy-requests/incoming-requests/`,p=o.record(o.string,o.string);async function m(e,{id:n,...r},o,s){if(!n){let e=`Request ID must be provided to enricher request.${s?` Found error in row: ${s}`:``}`;throw t.error(a.red(e)),Error(e)}let c=n.toLowerCase(),l=Object.entries(r).reduce((e,[t,n])=>i(d(n)).length===0?e:Object.assign(e,{[t]:i(d(n)).map(e=>({value:t===`email`?e.toLowerCase():e}))}),{});try{return await e.post(`v1/enrich-identifiers`,{headers:{"x-transcend-request-id":c,"x-transcend-enricher-id":o},json:{enrichedIdentifiers:l}}).json(),t.error(a.green(`Successfully enriched request: ${f}${c}`)),!0}catch(e){if(typeof e.response.body==`string`&&e.response.body.includes(`Cannot update a resolved RequestEnricher`))return t.warn(a.magenta(`Skipped enrichment for request: ${f}${c}, request is no longer in the enriching phase.`)),!1;throw t.error(a.red(`Failed to enricher identifiers for request with id: ${f}${c} - ${e.message} - ${e.response.body}`)),e}}async function h({file:i,auth:o,sombraAuth:d,enricherId:f,markSilent:h,concurrency:g=100,transcendUrl:_=e}){let v=await c(_,o,{logger:t,sombraApiKey:d,sombraUrl:process.env.SOMBRA_URL}),y=s(_,o);t.info(a.magenta(`Reading "${i}" from disk`));let b=n(i,p);t.info(a.magenta(`Enriching "${b.length}" privacy requests.`));let x=0,S=0,C=0;if(await u(b,async(e,n)=>{try{h&&(await l(y,r,{variables:{input:{id:e.id,isSilent:!0}},logger:t}),t.info(a.magenta(`Mark request as silent mode - ${e.id}`))),await m(v,e,f,n)?x+=1:S+=1}catch{C+=1}},{concurrency:g}),t.info(a.green(`Successfully notified Transcend! \n Success count: ${x}.`)),S>0&&t.info(a.magenta(`Skipped count: ${S}.`)),C>0)throw t.info(a.red(`Error Count: ${C}.`)),Error(`Failed to enrich: ${C} requests.`);return b.length}export{p as n,m as r,h as t};
2
- //# sourceMappingURL=pushManualEnrichmentIdentifiersFromCsv-DYQq7hsN.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{t as n}from"./readCsv-C4TyEs-r.mjs";import{o as r}from"./request-DfkRPQFr.mjs";import{uniq as i}from"lodash-es";import a from"colors";import*as o from"io-ts";import{buildTranscendGraphQLClient as s,createSombraGotInstance as c,makeGraphQLRequest as l}from"@transcend-io/sdk";import{map as u,splitCsvToList as d}from"@transcend-io/utils";const f=`https://app.transcend.io/privacy-requests/incoming-requests/`,p=o.record(o.string,o.string);async function m(e,{id:n,...r},o,s){if(!n){let e=`Request ID must be provided to enricher request.${s?` Found error in row: ${s}`:``}`;throw t.error(a.red(e)),Error(e)}let c=n.toLowerCase(),l=Object.entries(r).reduce((e,[t,n])=>i(d(n)).length===0?e:Object.assign(e,{[t]:i(d(n)).map(e=>({value:t===`email`?e.toLowerCase():e}))}),{});try{return await e.post(`v1/enrich-identifiers`,{headers:{"x-transcend-request-id":c,"x-transcend-enricher-id":o},json:{enrichedIdentifiers:l}}).json(),t.error(a.green(`Successfully enriched request: ${f}${c}`)),!0}catch(e){if(typeof e.response.body==`string`&&e.response.body.includes(`Cannot update a resolved RequestEnricher`))return t.warn(a.magenta(`Skipped enrichment for request: ${f}${c}, request is no longer in the enriching phase.`)),!1;throw t.error(a.red(`Failed to enricher identifiers for request with id: ${f}${c} - ${e.message} - ${e.response.body}`)),e}}async function h({file:i,auth:o,sombraAuth:d,enricherId:f,markSilent:h,concurrency:g=100,transcendUrl:_=e}){let v=await c(_,o,{logger:t,sombraApiKey:d,sombraUrl:process.env.SOMBRA_URL}),y=s(_,o);t.info(a.magenta(`Reading "${i}" from disk`));let b=n(i,p);t.info(a.magenta(`Enriching "${b.length}" privacy requests.`));let x=0,S=0,C=0;if(await u(b,async(e,n)=>{try{h&&(await l(y,r,{variables:{input:{id:e.id,isSilent:!0}},logger:t}),t.info(a.magenta(`Mark request as silent mode - ${e.id}`))),await m(v,e,f,n)?x+=1:S+=1}catch{C+=1}},{concurrency:g}),t.info(a.green(`Successfully notified Transcend! \n Success count: ${x}.`)),S>0&&t.info(a.magenta(`Skipped count: ${S}.`)),C>0)throw t.info(a.red(`Error Count: ${C}.`)),Error(`Failed to enrich: ${C} requests.`);return b.length}export{p as n,m as r,h as t};
2
+ //# sourceMappingURL=pushManualEnrichmentIdentifiersFromCsv-DT4-FUe0.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pushManualEnrichmentIdentifiersFromCsv-DYQq7hsN.mjs","names":[],"sources":["../src/lib/manual-enrichment/enrichPrivacyRequest.ts","../src/lib/manual-enrichment/pushManualEnrichmentIdentifiersFromCsv.ts"],"sourcesContent":["import { splitCsvToList } from '@transcend-io/utils';\nimport colors from 'colors';\nimport type { Got } from 'got';\nimport * as t from 'io-ts';\nimport { uniq } from 'lodash-es';\n\nimport { logger } from '../../logger.js';\n\nconst ADMIN_URL = 'https://app.transcend.io/privacy-requests/incoming-requests/';\n/**\n * Minimal set required to mark as completed\n */\nexport const EnrichPrivacyRequest = t.record(t.string, t.string);\n\n/** Type override */\nexport type EnrichPrivacyRequest = t.TypeOf<typeof EnrichPrivacyRequest>;\n\n/**\n * Upload identifiers to a privacy request or mark request as\n *\n * @param sombra - Sombra instance configured to make requests\n * @param request - Request to enricher\n * @param enricherId - The ID of the enricher being uploaded to\n * @param index - Index of request ID\n * @returns True if enriched successfully, false if skipped, throws error if failed\n */\nexport async function enrichPrivacyRequest(\n sombra: Got,\n { id: rawId, ...rest }: EnrichPrivacyRequest,\n enricherId: string,\n index?: number,\n): Promise<boolean> {\n if (!rawId) {\n // error\n const msg = `Request ID must be provided to enricher request.${\n index ? ` Found error in row: ${index}` : ''\n }`;\n logger.error(colors.red(msg));\n throw new Error(msg);\n }\n\n const id = rawId.toLowerCase();\n\n // Pull out the identifiers\n const enrichedIdentifiers = Object.entries(rest).reduce(\n (acc, [key, value]) => {\n const values = uniq(splitCsvToList(value));\n return values.length === 0\n ? acc\n : Object.assign(acc, {\n [key]: uniq(splitCsvToList(value)).map((val) => ({\n value: key === 'email' ? val.toLowerCase() : val,\n })),\n });\n },\n {} as Record<string, string[]>,\n );\n\n // Make the GraphQL request\n try {\n await sombra\n .post('v1/enrich-identifiers', {\n headers: {\n 'x-transcend-request-id': id,\n 'x-transcend-enricher-id': enricherId,\n },\n json: {\n enrichedIdentifiers,\n },\n })\n .json();\n\n logger.error(colors.green(`Successfully enriched request: ${ADMIN_URL}${id}`));\n return true;\n } catch (err) {\n // skip if already enriched\n if (\n typeof err.response.body === 'string' &&\n err.response.body.includes('Cannot update a resolved RequestEnricher')\n ) {\n logger.warn(\n colors.magenta(\n `Skipped enrichment for request: ${ADMIN_URL}${id}, request is no longer in the enriching phase.`,\n ),\n );\n return false;\n }\n\n // error\n logger.error(\n colors.red(\n `Failed to enricher identifiers for request with id: ${ADMIN_URL}${id} - ${err.message} - ${err.response.body}`,\n ),\n );\n throw err;\n }\n}\n","import {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n makeGraphQLRequest,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { UPDATE_PRIVACY_REQUEST } from '../graphql/index.js';\nimport { readCsv } from '../requests/index.js';\nimport { enrichPrivacyRequest, EnrichPrivacyRequest } from './enrichPrivacyRequest.js';\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, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\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(colors.magenta(`Enriching \"${activeResults.length}\" privacy requests.`));\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 variables: {\n input: {\n id: request.id,\n isSilent: true,\n },\n },\n logger,\n });\n\n logger.info(colors.magenta(`Mark request as silent mode - ${request.id}`));\n }\n\n const result = await enrichPrivacyRequest(sombra, request, enricherId, index);\n if (result) {\n successCount += 1;\n } else {\n skippedCount += 1;\n }\n } catch {\n errorCount += 1;\n }\n },\n { concurrency },\n );\n\n logger.info(colors.green(`Successfully notified Transcend! \\n Success count: ${successCount}.`));\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"],"mappings":"0aAQA,MAAM,EAAY,+DAIL,EAAuB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAchE,eAAsB,EACpB,EACA,CAAE,GAAI,EAAO,GAAG,GAChB,EACA,EACkB,CAClB,GAAI,CAAC,EAAO,CAEV,IAAM,EAAM,mDACV,EAAQ,wBAAwB,IAAU,KAG5C,MADA,EAAO,MAAM,EAAO,IAAI,EAAI,CAAC,CACnB,MAAM,EAAI,CAGtB,IAAM,EAAK,EAAM,aAAa,CAGxB,EAAsB,OAAO,QAAQ,EAAK,CAAC,QAC9C,EAAK,CAAC,EAAK,KACK,EAAK,EAAe,EAAM,CAAC,CAC5B,SAAW,EACrB,EACA,OAAO,OAAO,EAAK,EAChB,GAAM,EAAK,EAAe,EAAM,CAAC,CAAC,IAAK,IAAS,CAC/C,MAAO,IAAQ,QAAU,EAAI,aAAa,CAAG,EAC9C,EAAE,CACJ,CAAC,CAER,EAAE,CACH,CAGD,GAAI,CAcF,OAbA,MAAM,EACH,KAAK,wBAAyB,CAC7B,QAAS,CACP,yBAA0B,EAC1B,0BAA2B,EAC5B,CACD,KAAM,CACJ,sBACD,CACF,CAAC,CACD,MAAM,CAET,EAAO,MAAM,EAAO,MAAM,kCAAkC,IAAY,IAAK,CAAC,CACvE,SACA,EAAK,CAEZ,GACE,OAAO,EAAI,SAAS,MAAS,UAC7B,EAAI,SAAS,KAAK,SAAS,2CAA2C,CAOtE,OALA,EAAO,KACL,EAAO,QACL,mCAAmC,IAAY,EAAG,gDACnD,CACF,CACM,GAST,MALA,EAAO,MACL,EAAO,IACL,uDAAuD,IAAY,EAAG,KAAK,EAAI,QAAQ,KAAK,EAAI,SAAS,OAC1G,CACF,CACK,GC1EV,eAAsB,EAAuC,CAC3D,OACA,OACA,aACA,aACA,aACA,cAAc,IACd,eAAe,GAgBG,CAElB,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CACI,EAAS,EAA4B,EAAc,EAAK,CAG9D,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAC1D,IAAM,EAAgB,EAAQ,EAAM,EAAqB,CAGzD,EAAO,KAAK,EAAO,QAAQ,cAAc,EAAc,OAAO,qBAAqB,CAAC,CAEpF,IAAI,EAAe,EACf,EAAe,EACf,EAAa,EAwCjB,GAtCA,MAAM,EACJ,EACA,MAAO,EAAS,IAAU,CACxB,GAAI,CAEE,IACF,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,GAAI,EAAQ,GACZ,SAAU,GACX,CACF,CACD,SACD,CAAC,CAEF,EAAO,KAAK,EAAO,QAAQ,iCAAiC,EAAQ,KAAK,CAAC,EAG7D,MAAM,EAAqB,EAAQ,EAAS,EAAY,EAAM,CAE3E,GAAgB,EAEhB,GAAgB,OAEZ,CACN,GAAc,IAGlB,CAAE,cAAa,CAChB,CAED,EAAO,KAAK,EAAO,MAAM,sDAAsD,EAAa,GAAG,CAAC,CAE5F,EAAe,GACjB,EAAO,KAAK,EAAO,QAAQ,kBAAkB,EAAa,GAAG,CAAC,CAG5D,EAAa,EAEf,MADA,EAAO,KAAK,EAAO,IAAI,gBAAgB,EAAW,GAAG,CAAC,CAC5C,MAAM,qBAAqB,EAAW,YAAY,CAG9D,OAAO,EAAc"}
1
+ {"version":3,"file":"pushManualEnrichmentIdentifiersFromCsv-DT4-FUe0.mjs","names":[],"sources":["../src/lib/manual-enrichment/enrichPrivacyRequest.ts","../src/lib/manual-enrichment/pushManualEnrichmentIdentifiersFromCsv.ts"],"sourcesContent":["import { splitCsvToList } from '@transcend-io/utils';\nimport colors from 'colors';\nimport type { Got } from 'got';\nimport * as t from 'io-ts';\nimport { uniq } from 'lodash-es';\n\nimport { logger } from '../../logger.js';\n\nconst ADMIN_URL = 'https://app.transcend.io/privacy-requests/incoming-requests/';\n/**\n * Minimal set required to mark as completed\n */\nexport const EnrichPrivacyRequest = t.record(t.string, t.string);\n\n/** Type override */\nexport type EnrichPrivacyRequest = t.TypeOf<typeof EnrichPrivacyRequest>;\n\n/**\n * Upload identifiers to a privacy request or mark request as\n *\n * @param sombra - Sombra instance configured to make requests\n * @param request - Request to enricher\n * @param enricherId - The ID of the enricher being uploaded to\n * @param index - Index of request ID\n * @returns True if enriched successfully, false if skipped, throws error if failed\n */\nexport async function enrichPrivacyRequest(\n sombra: Got,\n { id: rawId, ...rest }: EnrichPrivacyRequest,\n enricherId: string,\n index?: number,\n): Promise<boolean> {\n if (!rawId) {\n // error\n const msg = `Request ID must be provided to enricher request.${\n index ? ` Found error in row: ${index}` : ''\n }`;\n logger.error(colors.red(msg));\n throw new Error(msg);\n }\n\n const id = rawId.toLowerCase();\n\n // Pull out the identifiers\n const enrichedIdentifiers = Object.entries(rest).reduce(\n (acc, [key, value]) => {\n const values = uniq(splitCsvToList(value));\n return values.length === 0\n ? acc\n : Object.assign(acc, {\n [key]: uniq(splitCsvToList(value)).map((val) => ({\n value: key === 'email' ? val.toLowerCase() : val,\n })),\n });\n },\n {} as Record<string, string[]>,\n );\n\n // Make the GraphQL request\n try {\n await sombra\n .post('v1/enrich-identifiers', {\n headers: {\n 'x-transcend-request-id': id,\n 'x-transcend-enricher-id': enricherId,\n },\n json: {\n enrichedIdentifiers,\n },\n })\n .json();\n\n logger.error(colors.green(`Successfully enriched request: ${ADMIN_URL}${id}`));\n return true;\n } catch (err) {\n // skip if already enriched\n if (\n typeof err.response.body === 'string' &&\n err.response.body.includes('Cannot update a resolved RequestEnricher')\n ) {\n logger.warn(\n colors.magenta(\n `Skipped enrichment for request: ${ADMIN_URL}${id}, request is no longer in the enriching phase.`,\n ),\n );\n return false;\n }\n\n // error\n logger.error(\n colors.red(\n `Failed to enricher identifiers for request with id: ${ADMIN_URL}${id} - ${err.message} - ${err.response.body}`,\n ),\n );\n throw err;\n }\n}\n","import {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n makeGraphQLRequest,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { UPDATE_PRIVACY_REQUEST } from '../graphql/index.js';\nimport { readCsv } from '../requests/index.js';\nimport { enrichPrivacyRequest, EnrichPrivacyRequest } from './enrichPrivacyRequest.js';\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, {\n logger,\n sombraApiKey: sombraAuth,\n sombraUrl: process.env.SOMBRA_URL,\n });\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(colors.magenta(`Enriching \"${activeResults.length}\" privacy requests.`));\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 variables: {\n input: {\n id: request.id,\n isSilent: true,\n },\n },\n logger,\n });\n\n logger.info(colors.magenta(`Mark request as silent mode - ${request.id}`));\n }\n\n const result = await enrichPrivacyRequest(sombra, request, enricherId, index);\n if (result) {\n successCount += 1;\n } else {\n skippedCount += 1;\n }\n } catch {\n errorCount += 1;\n }\n },\n { concurrency },\n );\n\n logger.info(colors.green(`Successfully notified Transcend! \\n Success count: ${successCount}.`));\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"],"mappings":"0aAQA,MAAM,EAAY,+DAIL,EAAuB,EAAE,OAAO,EAAE,OAAQ,EAAE,OAAO,CAchE,eAAsB,EACpB,EACA,CAAE,GAAI,EAAO,GAAG,GAChB,EACA,EACkB,CAClB,GAAI,CAAC,EAAO,CAEV,IAAM,EAAM,mDACV,EAAQ,wBAAwB,IAAU,KAG5C,MADA,EAAO,MAAM,EAAO,IAAI,EAAI,CAAC,CACnB,MAAM,EAAI,CAGtB,IAAM,EAAK,EAAM,aAAa,CAGxB,EAAsB,OAAO,QAAQ,EAAK,CAAC,QAC9C,EAAK,CAAC,EAAK,KACK,EAAK,EAAe,EAAM,CAAC,CAC5B,SAAW,EACrB,EACA,OAAO,OAAO,EAAK,EAChB,GAAM,EAAK,EAAe,EAAM,CAAC,CAAC,IAAK,IAAS,CAC/C,MAAO,IAAQ,QAAU,EAAI,aAAa,CAAG,EAC9C,EAAE,CACJ,CAAC,CAER,EAAE,CACH,CAGD,GAAI,CAcF,OAbA,MAAM,EACH,KAAK,wBAAyB,CAC7B,QAAS,CACP,yBAA0B,EAC1B,0BAA2B,EAC5B,CACD,KAAM,CACJ,sBACD,CACF,CAAC,CACD,MAAM,CAET,EAAO,MAAM,EAAO,MAAM,kCAAkC,IAAY,IAAK,CAAC,CACvE,SACA,EAAK,CAEZ,GACE,OAAO,EAAI,SAAS,MAAS,UAC7B,EAAI,SAAS,KAAK,SAAS,2CAA2C,CAOtE,OALA,EAAO,KACL,EAAO,QACL,mCAAmC,IAAY,EAAG,gDACnD,CACF,CACM,GAST,MALA,EAAO,MACL,EAAO,IACL,uDAAuD,IAAY,EAAG,KAAK,EAAI,QAAQ,KAAK,EAAI,SAAS,OAC1G,CACF,CACK,GC1EV,eAAsB,EAAuC,CAC3D,OACA,OACA,aACA,aACA,aACA,cAAc,IACd,eAAe,GAgBG,CAElB,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CACI,EAAS,EAA4B,EAAc,EAAK,CAG9D,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAC1D,IAAM,EAAgB,EAAQ,EAAM,EAAqB,CAGzD,EAAO,KAAK,EAAO,QAAQ,cAAc,EAAc,OAAO,qBAAqB,CAAC,CAEpF,IAAI,EAAe,EACf,EAAe,EACf,EAAa,EAwCjB,GAtCA,MAAM,EACJ,EACA,MAAO,EAAS,IAAU,CACxB,GAAI,CAEE,IACF,MAAM,EAAmB,EAAQ,EAAwB,CACvD,UAAW,CACT,MAAO,CACL,GAAI,EAAQ,GACZ,SAAU,GACX,CACF,CACD,SACD,CAAC,CAEF,EAAO,KAAK,EAAO,QAAQ,iCAAiC,EAAQ,KAAK,CAAC,EAG7D,MAAM,EAAqB,EAAQ,EAAS,EAAY,EAAM,CAE3E,GAAgB,EAEhB,GAAgB,OAEZ,CACN,GAAc,IAGlB,CAAE,cAAa,CAChB,CAED,EAAO,KAAK,EAAO,MAAM,sDAAsD,EAAa,GAAG,CAAC,CAE5F,EAAe,GACjB,EAAO,KAAK,EAAO,QAAQ,kBAAkB,EAAa,GAAG,CAAC,CAG5D,EAAa,EAEf,MADA,EAAO,KAAK,EAAO,IAAI,gBAAgB,EAAW,GAAG,CAAC,CAC5C,MAAM,qBAAqB,EAAW,YAAY,CAG9D,OAAO,EAAc"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestStatus as r}from"@transcend-io/privacy-types";import i from"colors";import{REMOVE_REQUEST_IDENTIFIERS as a,buildTranscendGraphQLClient as o,fetchAllRequestIdentifierMetadata as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d,identifierNames:f,auth:p,concurrency:m=20,transcendUrl:h=e}){let g=o(h,p),_=new Date().getTime(),v=new u.SingleBar({},u.Presets.shades_classic),y=await n(g,{actions:d,statuses:[r.Enriching]});t.info(i.magenta(`Fetched requests in preflight/enriching state.`));let b=0,x=0;v.start(y.length,0),await l(y,async e=>{let n=(await s(g,{filterBy:{requestId:e.id},logger:t})).filter(({isVerifiedAtLeastOnce:e,name:t})=>e===!1&&f.includes(t)).map(({id:e})=>e);n.length>0&&(await c(g,a,{variables:{input:{requestId:e.id,requestIdentifierIds:n}},logger:t}),x+=n.length),b+=1,v.update(b)},{concurrency:m}),v.stop();let S=new Date().getTime()-_;return t.info(i.green(`Successfully cleared out unverified identifiers "${S/1e3}" seconds for ${b} requests, ${x} identifiers were cleared out!`)),y.length}export{d as t};
2
- //# sourceMappingURL=removeUnverifiedRequestIdentifiers-VCbL2BXD.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestStatus as r}from"@transcend-io/privacy-types";import i from"colors";import{REMOVE_REQUEST_IDENTIFIERS as a,buildTranscendGraphQLClient as o,fetchAllRequestIdentifierMetadata as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d,identifierNames:f,auth:p,concurrency:m=20,transcendUrl:h=e}){let g=o(h,p),_=new Date().getTime(),v=new u.SingleBar({},u.Presets.shades_classic),y=await n(g,{actions:d,statuses:[r.Enriching]});t.info(i.magenta(`Fetched requests in preflight/enriching state.`));let b=0,x=0;v.start(y.length,0),await l(y,async e=>{let n=(await s(g,{filterBy:{requestId:e.id},logger:t})).filter(({isVerifiedAtLeastOnce:e,name:t})=>e===!1&&f.includes(t)).map(({id:e})=>e);n.length>0&&(await c(g,a,{variables:{input:{requestId:e.id,requestIdentifierIds:n}},logger:t}),x+=n.length),b+=1,v.update(b)},{concurrency:m}),v.stop();let S=new Date().getTime()-_;return t.info(i.green(`Successfully cleared out unverified identifiers "${S/1e3}" seconds for ${b} requests, ${x} identifiers were cleared out!`)),y.length}export{d as t};
2
+ //# sourceMappingURL=removeUnverifiedRequestIdentifiers-Dt5hvhtq.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"removeUnverifiedRequestIdentifiers-VCbL2BXD.mjs","names":[],"sources":["../src/lib/requests/removeUnverifiedRequestIdentifiers.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllRequestIdentifierMetadata,\n makeGraphQLRequest,\n REMOVE_REQUEST_IDENTIFIERS,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Remove a set of unverified request identifier\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function removeUnverifiedRequestIdentifiers({\n requestActions,\n identifierNames,\n auth,\n concurrency = 20,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** The set of identifier names to remove */\n identifierNames: string[];\n /** Concurrency to upload requests in parallel */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n // Notify Transcend\n logger.info(colors.magenta('Fetched requests in preflight/enriching state.'));\n\n let total = 0;\n let processed = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToRestart) => {\n const requestIdentifiers = await fetchAllRequestIdentifierMetadata(client, {\n filterBy: { requestId: requestToRestart.id },\n logger,\n });\n const clearOut = requestIdentifiers\n .filter(\n ({ isVerifiedAtLeastOnce, name }) =>\n isVerifiedAtLeastOnce === false && identifierNames.includes(name),\n )\n .map(({ id }) => id);\n\n if (clearOut.length > 0) {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, REMOVE_REQUEST_IDENTIFIERS, {\n variables: {\n input: {\n requestId: requestToRestart.id,\n requestIdentifierIds: clearOut,\n },\n },\n logger,\n });\n processed += clearOut.length;\n }\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 cleared out unverified identifiers \"${\n totalTime / 1000\n }\" seconds for ${total} requests, ${processed} identifiers were cleared out!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"6bAqBA,eAAsB,EAAmC,CACvD,iBACA,kBACA,OACA,cAAc,GACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,iDAAiD,CAAC,CAE7E,IAAI,EAAQ,EACR,EAAY,EAChB,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAqB,CAK1B,IAAM,GAJqB,MAAM,EAAkC,EAAQ,CACzE,SAAU,CAAE,UAAW,EAAiB,GAAI,CAC5C,SACD,CAAC,EAEC,QACE,CAAE,wBAAuB,UACxB,IAA0B,IAAS,EAAgB,SAAS,EAAK,CACpE,CACA,KAAK,CAAE,QAAS,EAAG,CAElB,EAAS,OAAS,IACpB,MAAM,EAGH,EAAQ,EAA4B,CACrC,UAAW,CACT,MAAO,CACL,UAAW,EAAiB,GAC5B,qBAAsB,EACvB,CACF,CACD,SACD,CAAC,CACF,GAAa,EAAS,QAGxB,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EASvB,OAPA,EAAO,KACL,EAAO,MACL,oDACE,EAAY,IACb,gBAAgB,EAAM,aAAa,EAAU,gCAC/C,CACF,CACM,EAAY"}
1
+ {"version":3,"file":"removeUnverifiedRequestIdentifiers-Dt5hvhtq.mjs","names":[],"sources":["../src/lib/requests/removeUnverifiedRequestIdentifiers.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllRequestIdentifierMetadata,\n makeGraphQLRequest,\n REMOVE_REQUEST_IDENTIFIERS,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Remove a set of unverified request identifier\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function removeUnverifiedRequestIdentifiers({\n requestActions,\n identifierNames,\n auth,\n concurrency = 20,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** The set of identifier names to remove */\n identifierNames: string[];\n /** Concurrency to upload requests in parallel */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Enriching],\n });\n\n // Notify Transcend\n logger.info(colors.magenta('Fetched requests in preflight/enriching state.'));\n\n let total = 0;\n let processed = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToRestart) => {\n const requestIdentifiers = await fetchAllRequestIdentifierMetadata(client, {\n filterBy: { requestId: requestToRestart.id },\n logger,\n });\n const clearOut = requestIdentifiers\n .filter(\n ({ isVerifiedAtLeastOnce, name }) =>\n isVerifiedAtLeastOnce === false && identifierNames.includes(name),\n )\n .map(({ id }) => id);\n\n if (clearOut.length > 0) {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, REMOVE_REQUEST_IDENTIFIERS, {\n variables: {\n input: {\n requestId: requestToRestart.id,\n requestIdentifierIds: clearOut,\n },\n },\n logger,\n });\n processed += clearOut.length;\n }\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 cleared out unverified identifiers \"${\n totalTime / 1000\n }\" seconds for ${total} requests, ${processed} identifiers were cleared out!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"6bAqBA,eAAsB,EAAmC,CACvD,iBACA,kBACA,OACA,cAAc,GACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,iDAAiD,CAAC,CAE7E,IAAI,EAAQ,EACR,EAAY,EAChB,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAqB,CAK1B,IAAM,GAJqB,MAAM,EAAkC,EAAQ,CACzE,SAAU,CAAE,UAAW,EAAiB,GAAI,CAC5C,SACD,CAAC,EAEC,QACE,CAAE,wBAAuB,UACxB,IAA0B,IAAS,EAAgB,SAAS,EAAK,CACpE,CACA,KAAK,CAAE,QAAS,EAAG,CAElB,EAAS,OAAS,IACpB,MAAM,EAGH,EAAQ,EAA4B,CACrC,UAAW,CACT,MAAO,CACL,UAAW,EAAiB,GAC5B,qBAAsB,EACvB,CACF,CACD,SACD,CAAC,CACF,GAAa,EAAS,QAGxB,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EASvB,OAPA,EAAO,KACL,EAAO,MACL,oDACE,EAAY,IACb,gBAAgB,EAAM,aAAa,EAAU,gCAC/C,CACF,CACM,EAAY"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestStatus as r}from"@transcend-io/privacy-types";import i from"colors";import{RETRY_REQUEST_DATA_SILO as a,buildTranscendGraphQLClient as o,fetchRequestDataSilo as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d,dataSiloId:f,auth:p,concurrency:m=20,transcendUrl:h=e}){let g=o(h,p),_=new Date().getTime(),v=new u.SingleBar({},u.Presets.shades_classic),y=await n(g,{actions:d,statuses:[r.Compiling,r.Approving]});t.info(i.magenta(`Retrying requests for Data Silo: "${f}", restarting "${y.length}" requests.`));let b=0,x=0;v.start(y.length,0),await l(y,async e=>{try{await c(g,a,{variables:{requestDataSiloId:(await s(g,{logger:t,filterBy:{requestId:e.id,dataSiloId:f}})).id},logger:t})}catch(e){if(!e.message.includes(`Failed to find RequestDataSilo`))throw e;x+=1}b+=1,v.update(b)},{concurrency:m}),v.stop();let S=new Date().getTime()-_;return t.info(i.green(`Successfully notified Transcend in "${S/1e3}" seconds for ${b} requests, ${x} requests were skipped because data silo was not attached to the request!`)),y.length}export{d as t};
2
- //# sourceMappingURL=retryRequestDataSilos-BCe-WGdL.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestStatus as r}from"@transcend-io/privacy-types";import i from"colors";import{RETRY_REQUEST_DATA_SILO as a,buildTranscendGraphQLClient as o,fetchRequestDataSilo as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({requestActions:d,dataSiloId:f,auth:p,concurrency:m=20,transcendUrl:h=e}){let g=o(h,p),_=new Date().getTime(),v=new u.SingleBar({},u.Presets.shades_classic),y=await n(g,{actions:d,statuses:[r.Compiling,r.Approving]});t.info(i.magenta(`Retrying requests for Data Silo: "${f}", restarting "${y.length}" requests.`));let b=0,x=0;v.start(y.length,0),await l(y,async e=>{try{await c(g,a,{variables:{requestDataSiloId:(await s(g,{logger:t,filterBy:{requestId:e.id,dataSiloId:f}})).id},logger:t})}catch(e){if(!e.message.includes(`Failed to find RequestDataSilo`))throw e;x+=1}b+=1,v.update(b)},{concurrency:m}),v.stop();let S=new Date().getTime()-_;return t.info(i.green(`Successfully notified Transcend in "${S/1e3}" seconds for ${b} requests, ${x} requests were skipped because data silo was not attached to the request!`)),y.length}export{d as t};
2
+ //# sourceMappingURL=retryRequestDataSilos-Ds3bF0yd.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"retryRequestDataSilos-BCe-WGdL.mjs","names":[],"sources":["../src/lib/requests/retryRequestDataSilos.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n makeGraphQLRequest,\n RETRY_REQUEST_DATA_SILO,\n fetchRequestDataSilo,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Retry a set of RequestDataSilos\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function retryRequestDataSilos({\n requestActions,\n dataSiloId,\n auth,\n concurrency = 20,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Concurrency to upload requests in parallel */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Compiling, RequestStatus.Approving],\n });\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Retrying requests for Data Silo: \"${dataSiloId}\", restarting \"${allRequests.length}\" requests.`,\n ),\n );\n\n let total = 0;\n let skipped = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToRestart) => {\n try {\n const requestDataSilo = await fetchRequestDataSilo(client, {\n logger,\n filterBy: { requestId: requestToRestart.id, dataSiloId },\n });\n\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, RETRY_REQUEST_DATA_SILO, {\n variables: { requestDataSiloId: requestDataSilo.id },\n logger,\n });\n } catch (err) {\n // some requests may not have this data silo connected\n if (!err.message.includes('Failed to find RequestDataSilo')) {\n throw err;\n }\n skipped += 1;\n }\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 notified Transcend in \"${\n totalTime / 1000\n }\" seconds for ${total} requests, ${skipped} requests were skipped because data silo was not attached to the request!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"6aAqBA,eAAsB,EAAsB,CAC1C,iBACA,aACA,OACA,cAAc,GACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAW,EAAc,UAAU,CAC7D,CAAC,CAGF,EAAO,KACL,EAAO,QACL,qCAAqC,EAAW,iBAAiB,EAAY,OAAO,aACrF,CACF,CAED,IAAI,EAAQ,EACR,EAAU,EACd,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAqB,CAC1B,GAAI,CAMF,MAAM,EAGH,EAAQ,EAAyB,CAClC,UAAW,CAAE,mBATS,MAAM,EAAqB,EAAQ,CACzD,SACA,SAAU,CAAE,UAAW,EAAiB,GAAI,aAAY,CACzD,CAAC,EAMgD,GAAI,CACpD,SACD,CAAC,OACK,EAAK,CAEZ,GAAI,CAAC,EAAI,QAAQ,SAAS,iCAAiC,CACzD,MAAM,EAER,GAAW,EAGb,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EASvB,OAPA,EAAO,KACL,EAAO,MACL,uCACE,EAAY,IACb,gBAAgB,EAAM,aAAa,EAAQ,2EAC7C,CACF,CACM,EAAY"}
1
+ {"version":3,"file":"retryRequestDataSilos-Ds3bF0yd.mjs","names":[],"sources":["../src/lib/requests/retryRequestDataSilos.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n makeGraphQLRequest,\n RETRY_REQUEST_DATA_SILO,\n fetchRequestDataSilo,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Retry a set of RequestDataSilos\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function retryRequestDataSilos({\n requestActions,\n dataSiloId,\n auth,\n concurrency = 20,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions: RequestAction[];\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Concurrency to upload requests in parallel */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Pull in the requests\n const allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n statuses: [RequestStatus.Compiling, RequestStatus.Approving],\n });\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Retrying requests for Data Silo: \"${dataSiloId}\", restarting \"${allRequests.length}\" requests.`,\n ),\n );\n\n let total = 0;\n let skipped = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToRestart) => {\n try {\n const requestDataSilo = await fetchRequestDataSilo(client, {\n logger,\n filterBy: { requestId: requestToRestart.id, dataSiloId },\n });\n\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, RETRY_REQUEST_DATA_SILO, {\n variables: { requestDataSiloId: requestDataSilo.id },\n logger,\n });\n } catch (err) {\n // some requests may not have this data silo connected\n if (!err.message.includes('Failed to find RequestDataSilo')) {\n throw err;\n }\n skipped += 1;\n }\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 notified Transcend in \"${\n totalTime / 1000\n }\" seconds for ${total} requests, ${skipped} requests were skipped because data silo was not attached to the request!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"6aAqBA,eAAsB,EAAsB,CAC1C,iBACA,aACA,OACA,cAAc,GACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAG/E,EAAc,MAAM,EAAiB,EAAQ,CACjD,QAAS,EACT,SAAU,CAAC,EAAc,UAAW,EAAc,UAAU,CAC7D,CAAC,CAGF,EAAO,KACL,EAAO,QACL,qCAAqC,EAAW,iBAAiB,EAAY,OAAO,aACrF,CACF,CAED,IAAI,EAAQ,EACR,EAAU,EACd,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAqB,CAC1B,GAAI,CAMF,MAAM,EAGH,EAAQ,EAAyB,CAClC,UAAW,CAAE,mBATS,MAAM,EAAqB,EAAQ,CACzD,SACA,SAAU,CAAE,UAAW,EAAiB,GAAI,aAAY,CACzD,CAAC,EAMgD,GAAI,CACpD,SACD,CAAC,OACK,EAAK,CAEZ,GAAI,CAAC,EAAI,QAAQ,SAAS,iCAAiC,CACzD,MAAM,EAER,GAAW,EAGb,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EASvB,OAPA,EAAO,KACL,EAAO,MACL,uCACE,EAAY,IACb,gBAAgB,EAAM,aAAa,EAAQ,2EAC7C,CACF,CACM,EAAY"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestEnricherStatus as r,RequestStatus as i}from"@transcend-io/privacy-types";import a from"colors";import{SKIP_REQUEST_ENRICHER as o,buildTranscendGraphQLClient as s,fetchAllRequestEnrichers as c,makeGraphQLRequest as l}from"@transcend-io/sdk";import{map as u,mapSeries as d}from"@transcend-io/utils";import f from"cli-progress";async function p({enricherIds:p,auth:m,concurrency:h=100,transcendUrl:g=e}){let _=s(g,m),v=new Date().getTime(),y=await n(_,{statuses:[i.Enriching]});t.info(a.magenta(`Processing enricher: "${p.join(`,`)}" fetched "${y.length}" in enriching status.`));let b=new f.SingleBar({},f.Presets.shades_classic),x=0;b.start(y.length,0);let S=0;await u(y,async e=>{let n=(await c(_,{filterBy:{requestId:e.id},logger:t})).filter(e=>p.includes(e.enricher.id)&&![r.Resolved,r.Skipped].includes(e.status));n.length>0&&await d(n,async e=>{try{await l(_,o,{variables:{requestEnricherId:e.id},logger:t}),S+=1}catch(e){if(!e.message.includes(`Client error: Cannot skip Request enricher because it has already completed`))throw e}}),x+=1,b.update(x)},{concurrency:h}),b.stop();let C=new Date().getTime()-v;return t.info(a.green(`Successfully skipped "${S}" for "${y.length}" requests in "${C/1e3}" seconds!`)),y.length}export{p as t};
2
- //# sourceMappingURL=skipPreflightJobs-Bc0--Bvs.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{r as n}from"./fetchAllRequests-CHHdyb4Q.mjs";import{RequestEnricherStatus as r,RequestStatus as i}from"@transcend-io/privacy-types";import a from"colors";import{SKIP_REQUEST_ENRICHER as o,buildTranscendGraphQLClient as s,fetchAllRequestEnrichers as c,makeGraphQLRequest as l}from"@transcend-io/sdk";import{map as u,mapSeries as d}from"@transcend-io/utils";import f from"cli-progress";async function p({enricherIds:p,auth:m,concurrency:h=100,transcendUrl:g=e}){let _=s(g,m),v=new Date().getTime(),y=await n(_,{statuses:[i.Enriching]});t.info(a.magenta(`Processing enricher: "${p.join(`,`)}" fetched "${y.length}" in enriching status.`));let b=new f.SingleBar({},f.Presets.shades_classic),x=0;b.start(y.length,0);let S=0;await u(y,async e=>{let n=(await c(_,{filterBy:{requestId:e.id},logger:t})).filter(e=>p.includes(e.enricher.id)&&![r.Resolved,r.Skipped].includes(e.status));n.length>0&&await d(n,async e=>{try{await l(_,o,{variables:{requestEnricherId:e.id},logger:t}),S+=1}catch(e){if(!e.message.includes(`Client error: Cannot skip Request enricher because it has already completed`))throw e}}),x+=1,b.update(x)},{concurrency:h}),b.stop();let C=new Date().getTime()-v;return t.info(a.green(`Successfully skipped "${S}" for "${y.length}" requests in "${C/1e3}" seconds!`)),y.length}export{p as t};
2
+ //# sourceMappingURL=skipPreflightJobs-h8H7ZEX6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"skipPreflightJobs-Bc0--Bvs.mjs","names":[],"sources":["../src/lib/requests/skipPreflightJobs.ts"],"sourcesContent":["import { RequestEnricherStatus, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllRequestEnrichers,\n makeGraphQLRequest,\n SKIP_REQUEST_ENRICHER,\n} from '@transcend-io/sdk';\nimport { mapSeries, map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Given an enricher ID, mark all open request enrichers as skipped\n *\n * @param options - Options\n * @returns Number of items skipped\n */\nexport async function skipPreflightJobs({\n enricherIds,\n auth,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** Enricher IDs to pull down jobs for */\n enricherIds: string[];\n /** Upload concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Request statuses to mark as completed */\n requestStatuses?: RequestStatus[];\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n\n // fetch all RequestDataSilos that are open\n const requests = await fetchAllRequests(client, {\n statuses: [RequestStatus.Enriching],\n });\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Processing enricher: \"${enricherIds.join(',')}\" fetched \"${\n requests.length\n }\" in enriching status.`,\n ),\n );\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n let total = 0;\n progressBar.start(requests.length, 0);\n let totalSkipped = 0;\n await map(\n requests,\n async (request) => {\n // TODO dont pull all in\n const requestEnrichers = await fetchAllRequestEnrichers(client, {\n filterBy: { requestId: request.id },\n logger,\n });\n const requestEnrichersFiltered = requestEnrichers.filter(\n (enricher) =>\n enricherIds.includes(enricher.enricher.id) &&\n ![\n RequestEnricherStatus.Resolved,\n RequestEnricherStatus.Skipped,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ].includes(enricher.status as any),\n );\n\n // TODO\n if (requestEnrichersFiltered.length > 0) {\n await mapSeries(requestEnrichersFiltered, async (requestEnricher) => {\n try {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, SKIP_REQUEST_ENRICHER, {\n variables: { requestEnricherId: requestEnricher.id },\n logger,\n });\n totalSkipped += 1;\n } catch (err) {\n if (\n !err.message.includes(\n 'Client error: Cannot skip Request enricher because it has already completed',\n )\n ) {\n throw err;\n }\n }\n });\n }\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 skipped \"${totalSkipped}\" for \"${\n requests.length\n }\" requests in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return requests.length;\n}\n"],"mappings":"ydAqBA,eAAsB,EAAkB,CACtC,cACA,OACA,cAAc,IACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAGzB,EAAW,MAAM,EAAiB,EAAQ,CAC9C,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAGF,EAAO,KACL,EAAO,QACL,yBAAyB,EAAY,KAAK,IAAI,CAAC,aAC7C,EAAS,OACV,wBACF,CACF,CAGD,IAAM,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAQ,EACZ,EAAY,MAAM,EAAS,OAAQ,EAAE,CACrC,IAAI,EAAe,EACnB,MAAM,EACJ,EACA,KAAO,IAAY,CAMjB,IAAM,GAJmB,MAAM,EAAyB,EAAQ,CAC9D,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,SACD,CAAC,EACgD,OAC/C,GACC,EAAY,SAAS,EAAS,SAAS,GAAG,EAC1C,CAAC,CACC,EAAsB,SACtB,EAAsB,QAEvB,CAAC,SAAS,EAAS,OAAc,CACrC,CAGG,EAAyB,OAAS,GACpC,MAAM,EAAU,EAA0B,KAAO,IAAoB,CACnE,GAAI,CACF,MAAM,EAGH,EAAQ,EAAuB,CAChC,UAAW,CAAE,kBAAmB,EAAgB,GAAI,CACpD,SACD,CAAC,CACF,GAAgB,QACT,EAAK,CACZ,GACE,CAAC,EAAI,QAAQ,SACX,8EACD,CAED,MAAM,IAGV,CAEJ,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EASvB,OAPA,EAAO,KACL,EAAO,MACL,yBAAyB,EAAa,UACpC,EAAS,OACV,iBAAiB,EAAY,IAAK,YACpC,CACF,CACM,EAAS"}
1
+ {"version":3,"file":"skipPreflightJobs-h8H7ZEX6.mjs","names":[],"sources":["../src/lib/requests/skipPreflightJobs.ts"],"sourcesContent":["import { RequestEnricherStatus, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n fetchAllRequestEnrichers,\n makeGraphQLRequest,\n SKIP_REQUEST_ENRICHER,\n} from '@transcend-io/sdk';\nimport { mapSeries, map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { fetchAllRequests } from '../graphql/index.js';\n\n/**\n * Given an enricher ID, mark all open request enrichers as skipped\n *\n * @param options - Options\n * @returns Number of items skipped\n */\nexport async function skipPreflightJobs({\n enricherIds,\n auth,\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** Enricher IDs to pull down jobs for */\n enricherIds: string[];\n /** Upload concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Request statuses to mark as completed */\n requestStatuses?: RequestStatus[];\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n\n // fetch all RequestDataSilos that are open\n const requests = await fetchAllRequests(client, {\n statuses: [RequestStatus.Enriching],\n });\n\n // Notify Transcend\n logger.info(\n colors.magenta(\n `Processing enricher: \"${enricherIds.join(',')}\" fetched \"${\n requests.length\n }\" in enriching status.`,\n ),\n );\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n let total = 0;\n progressBar.start(requests.length, 0);\n let totalSkipped = 0;\n await map(\n requests,\n async (request) => {\n // TODO dont pull all in\n const requestEnrichers = await fetchAllRequestEnrichers(client, {\n filterBy: { requestId: request.id },\n logger,\n });\n const requestEnrichersFiltered = requestEnrichers.filter(\n (enricher) =>\n enricherIds.includes(enricher.enricher.id) &&\n ![\n RequestEnricherStatus.Resolved,\n RequestEnricherStatus.Skipped,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ].includes(enricher.status as any),\n );\n\n // TODO\n if (requestEnrichersFiltered.length > 0) {\n await mapSeries(requestEnrichersFiltered, async (requestEnricher) => {\n try {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, SKIP_REQUEST_ENRICHER, {\n variables: { requestEnricherId: requestEnricher.id },\n logger,\n });\n totalSkipped += 1;\n } catch (err) {\n if (\n !err.message.includes(\n 'Client error: Cannot skip Request enricher because it has already completed',\n )\n ) {\n throw err;\n }\n }\n });\n }\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\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 skipped \"${totalSkipped}\" for \"${\n requests.length\n }\" requests in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return requests.length;\n}\n"],"mappings":"ydAqBA,eAAsB,EAAkB,CACtC,cACA,OACA,cAAc,IACd,eAAe,GAYG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAGzB,EAAW,MAAM,EAAiB,EAAQ,CAC9C,SAAU,CAAC,EAAc,UAAU,CACpC,CAAC,CAGF,EAAO,KACL,EAAO,QACL,yBAAyB,EAAY,KAAK,IAAI,CAAC,aAC7C,EAAS,OACV,wBACF,CACF,CAGD,IAAM,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAQ,EACZ,EAAY,MAAM,EAAS,OAAQ,EAAE,CACrC,IAAI,EAAe,EACnB,MAAM,EACJ,EACA,KAAO,IAAY,CAMjB,IAAM,GAJmB,MAAM,EAAyB,EAAQ,CAC9D,SAAU,CAAE,UAAW,EAAQ,GAAI,CACnC,SACD,CAAC,EACgD,OAC/C,GACC,EAAY,SAAS,EAAS,SAAS,GAAG,EAC1C,CAAC,CACC,EAAsB,SACtB,EAAsB,QAEvB,CAAC,SAAS,EAAS,OAAc,CACrC,CAGG,EAAyB,OAAS,GACpC,MAAM,EAAU,EAA0B,KAAO,IAAoB,CACnE,GAAI,CACF,MAAM,EAGH,EAAQ,EAAuB,CAChC,UAAW,CAAE,kBAAmB,EAAgB,GAAI,CACpD,SACD,CAAC,CACF,GAAgB,QACT,EAAK,CACZ,GACE,CAAC,EAAI,QAAQ,SACX,8EACD,CAED,MAAM,IAGV,CAEJ,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EASvB,OAPA,EAAO,KACL,EAAO,MACL,yBAAyB,EAAa,UACpC,EAAS,OACV,iBAAiB,EAAY,IAAK,YACpC,CACF,CACM,EAAS"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{RequestStatus as n}from"@transcend-io/privacy-types";import r from"colors";import{CHANGE_REQUEST_DATA_SILO_STATUS as i,buildTranscendGraphQLClient as a,fetchRequestDataSilos as o,fetchRequestDataSilosCount as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({dataSiloId:d,auth:f,concurrency:p=50,status:m=`SKIPPED`,transcendUrl:h=e,requestStatuses:g=[n.Compiling,n.Secondary],actionTypes:_=[]}){let v=a(h,f),y=new Date().getTime(),b=await s(v,{logger:t,filterBy:{dataSiloId:d,requestStatuses:g}});t.info(r.magenta(`Marking ${b} request data silos as completed${_.length>0?` for action types: ${_.join(`,`)}`:``}`));let x=new u.SingleBar({},u.Presets.shades_classic),S=0;x.start(b,0),await l(await o(v,{logger:t,filterBy:{dataSiloId:d,requestStatuses:g},onProgress:e=>{S+=e/2,x.update(S)}}),async e=>{if(_.length===0||_.includes(e.request.type))try{await c(v,i,{variables:{requestDataSiloId:e.id,status:m},logger:t})}catch(e){if(!e.message.includes(`Client error: Request must be active:`))throw e}S+=.5,x.update(S)},{concurrency:p}),x.stop();let C=new Date().getTime()-y;return t.info(r.green(`Successfully skipped "${b}" requests in "${C/1e3}" seconds!`)),b}export{d as t};
2
- //# sourceMappingURL=skipRequestDataSilos-BHbAQkpb.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{RequestStatus as n}from"@transcend-io/privacy-types";import r from"colors";import{CHANGE_REQUEST_DATA_SILO_STATUS as i,buildTranscendGraphQLClient as a,fetchRequestDataSilos as o,fetchRequestDataSilosCount as s,makeGraphQLRequest as c}from"@transcend-io/sdk";import{map as l}from"@transcend-io/utils";import u from"cli-progress";async function d({dataSiloId:d,auth:f,concurrency:p=50,status:m=`SKIPPED`,transcendUrl:h=e,requestStatuses:g=[n.Compiling,n.Secondary],actionTypes:_=[]}){let v=a(h,f),y=new Date().getTime(),b=await s(v,{logger:t,filterBy:{dataSiloId:d,requestStatuses:g}});t.info(r.magenta(`Marking ${b} request data silos as completed${_.length>0?` for action types: ${_.join(`,`)}`:``}`));let x=new u.SingleBar({},u.Presets.shades_classic),S=0;x.start(b,0),await l(await o(v,{logger:t,filterBy:{dataSiloId:d,requestStatuses:g},onProgress:e=>{S+=e/2,x.update(S)}}),async e=>{if(_.length===0||_.includes(e.request.type))try{await c(v,i,{variables:{requestDataSiloId:e.id,status:m},logger:t})}catch(e){if(!e.message.includes(`Client error: Request must be active:`))throw e}S+=.5,x.update(S)},{concurrency:p}),x.stop();let C=new Date().getTime()-y;return t.info(r.green(`Successfully skipped "${b}" requests in "${C/1e3}" seconds!`)),b}export{d as t};
2
+ //# sourceMappingURL=skipRequestDataSilos-C8y5PYaZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"skipRequestDataSilos-BHbAQkpb.mjs","names":[],"sources":["../src/lib/requests/skipRequestDataSilos.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n makeGraphQLRequest,\n CHANGE_REQUEST_DATA_SILO_STATUS,\n fetchRequestDataSilos,\n fetchRequestDataSilosCount,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\n\n/**\n * Given a data silo ID, mark all open request data silos as skipped\n *\n * @param options - Options\n * @returns Number of items skipped\n */\nexport async function skipRequestDataSilos({\n dataSiloId,\n auth,\n concurrency = 50,\n status = 'SKIPPED',\n transcendUrl = DEFAULT_TRANSCEND_API,\n requestStatuses = [RequestStatus.Compiling, RequestStatus.Secondary],\n actionTypes = [],\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Status to set */\n status?: 'SKIPPED' | 'RESOLVED';\n /** Upload concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Request statuses to mark as completed */\n requestStatuses?: RequestStatus[];\n /** Request action types to filter on */\n actionTypes?: RequestAction[];\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n\n // Determine total number of request data silos\n const requestDataSiloCount = await fetchRequestDataSilosCount(client, {\n logger,\n filterBy: { dataSiloId, requestStatuses },\n });\n logger.info(\n colors.magenta(\n `Marking ${requestDataSiloCount} request data silos as completed${actionTypes.length > 0 ? ` for action types: ${actionTypes.join(',')}` : ''}`,\n ),\n );\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n let total = 0;\n progressBar.start(requestDataSiloCount, 0);\n\n // Fetch all matching request data silos, updating progress as pages are fetched\n const requestDataSilos = await fetchRequestDataSilos(client, {\n logger,\n filterBy: { dataSiloId, requestStatuses },\n onProgress: (numFetched) => {\n total += numFetched / 2;\n progressBar.update(total);\n },\n });\n\n await map(\n requestDataSilos,\n async (requestDataSilo) => {\n if (actionTypes.length === 0 || actionTypes.includes(requestDataSilo.request.type)) {\n try {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, CHANGE_REQUEST_DATA_SILO_STATUS, {\n variables: { requestDataSiloId: requestDataSilo.id, status },\n logger,\n });\n } catch (err) {\n if (!err.message.includes('Client error: Request must be active:')) {\n throw err;\n }\n }\n }\n\n total += 0.5;\n progressBar.update(total);\n },\n { concurrency },\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 skipped \"${requestDataSiloCount}\" requests in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return requestDataSiloCount;\n}\n"],"mappings":"kaAqBA,eAAsB,EAAqB,CACzC,aACA,OACA,cAAc,GACd,SAAS,UACT,eAAe,EACf,kBAAkB,CAAC,EAAc,UAAW,EAAc,UAAU,CACpE,cAAc,EAAE,EAgBE,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAGzB,EAAuB,MAAM,EAA2B,EAAQ,CACpE,SACA,SAAU,CAAE,aAAY,kBAAiB,CAC1C,CAAC,CACF,EAAO,KACL,EAAO,QACL,WAAW,EAAqB,kCAAkC,EAAY,OAAS,EAAI,sBAAsB,EAAY,KAAK,IAAI,GAAK,KAC5I,CACF,CAGD,IAAM,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAQ,EACZ,EAAY,MAAM,EAAsB,EAAE,CAY1C,MAAM,EATmB,MAAM,EAAsB,EAAQ,CAC3D,SACA,SAAU,CAAE,aAAY,kBAAiB,CACzC,WAAa,GAAe,CAC1B,GAAS,EAAa,EACtB,EAAY,OAAO,EAAM,EAE5B,CAAC,CAIA,KAAO,IAAoB,CACzB,GAAI,EAAY,SAAW,GAAK,EAAY,SAAS,EAAgB,QAAQ,KAAK,CAChF,GAAI,CACF,MAAM,EAGH,EAAQ,EAAiC,CAC1C,UAAW,CAAE,kBAAmB,EAAgB,GAAI,SAAQ,CAC5D,SACD,CAAC,OACK,EAAK,CACZ,GAAI,CAAC,EAAI,QAAQ,SAAS,wCAAwC,CAChE,MAAM,EAKZ,GAAS,GACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,yBAAyB,EAAqB,iBAAiB,EAAY,IAAK,YACjF,CACF,CACM"}
1
+ {"version":3,"file":"skipRequestDataSilos-C8y5PYaZ.mjs","names":[],"sources":["../src/lib/requests/skipRequestDataSilos.ts"],"sourcesContent":["import { RequestAction, RequestStatus } from '@transcend-io/privacy-types';\nimport {\n buildTranscendGraphQLClient,\n makeGraphQLRequest,\n CHANGE_REQUEST_DATA_SILO_STATUS,\n fetchRequestDataSilos,\n fetchRequestDataSilosCount,\n} from '@transcend-io/sdk';\nimport { map } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\n\n/**\n * Given a data silo ID, mark all open request data silos as skipped\n *\n * @param options - Options\n * @returns Number of items skipped\n */\nexport async function skipRequestDataSilos({\n dataSiloId,\n auth,\n concurrency = 50,\n status = 'SKIPPED',\n transcendUrl = DEFAULT_TRANSCEND_API,\n requestStatuses = [RequestStatus.Compiling, RequestStatus.Secondary],\n actionTypes = [],\n}: {\n /** Transcend API key authentication */\n auth: string;\n /** Data Silo ID to pull down jobs for */\n dataSiloId: string;\n /** Status to set */\n status?: 'SKIPPED' | 'RESOLVED';\n /** Upload concurrency */\n concurrency?: number;\n /** API URL for Transcend backend */\n transcendUrl?: string;\n /** Request statuses to mark as completed */\n requestStatuses?: RequestStatus[];\n /** Request action types to filter on */\n actionTypes?: RequestAction[];\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n\n // Determine total number of request data silos\n const requestDataSiloCount = await fetchRequestDataSilosCount(client, {\n logger,\n filterBy: { dataSiloId, requestStatuses },\n });\n logger.info(\n colors.magenta(\n `Marking ${requestDataSiloCount} request data silos as completed${actionTypes.length > 0 ? ` for action types: ${actionTypes.join(',')}` : ''}`,\n ),\n );\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n let total = 0;\n progressBar.start(requestDataSiloCount, 0);\n\n // Fetch all matching request data silos, updating progress as pages are fetched\n const requestDataSilos = await fetchRequestDataSilos(client, {\n logger,\n filterBy: { dataSiloId, requestStatuses },\n onProgress: (numFetched) => {\n total += numFetched / 2;\n progressBar.update(total);\n },\n });\n\n await map(\n requestDataSilos,\n async (requestDataSilo) => {\n if (actionTypes.length === 0 || actionTypes.includes(requestDataSilo.request.type)) {\n try {\n await makeGraphQLRequest<{\n /** Whether we successfully uploaded the results */\n success: boolean;\n }>(client, CHANGE_REQUEST_DATA_SILO_STATUS, {\n variables: { requestDataSiloId: requestDataSilo.id, status },\n logger,\n });\n } catch (err) {\n if (!err.message.includes('Client error: Request must be active:')) {\n throw err;\n }\n }\n }\n\n total += 0.5;\n progressBar.update(total);\n },\n { concurrency },\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 skipped \"${requestDataSiloCount}\" requests in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return requestDataSiloCount;\n}\n"],"mappings":"kaAqBA,eAAsB,EAAqB,CACzC,aACA,OACA,cAAc,GACd,SAAS,UACT,eAAe,EACf,kBAAkB,CAAC,EAAc,UAAW,EAAc,UAAU,CACpE,cAAc,EAAE,EAgBE,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAGzB,EAAuB,MAAM,EAA2B,EAAQ,CACpE,SACA,SAAU,CAAE,aAAY,kBAAiB,CAC1C,CAAC,CACF,EAAO,KACL,EAAO,QACL,WAAW,EAAqB,kCAAkC,EAAY,OAAS,EAAI,sBAAsB,EAAY,KAAK,IAAI,GAAK,KAC5I,CACF,CAGD,IAAM,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAQ,EACZ,EAAY,MAAM,EAAsB,EAAE,CAY1C,MAAM,EATmB,MAAM,EAAsB,EAAQ,CAC3D,SACA,SAAU,CAAE,aAAY,kBAAiB,CACzC,WAAa,GAAe,CAC1B,GAAS,EAAa,EACtB,EAAY,OAAO,EAAM,EAE5B,CAAC,CAIA,KAAO,IAAoB,CACzB,GAAI,EAAY,SAAW,GAAK,EAAY,SAAS,EAAgB,QAAQ,KAAK,CAChF,GAAI,CACF,MAAM,EAGH,EAAQ,EAAiC,CAC1C,UAAW,CAAE,kBAAmB,EAAgB,GAAI,SAAQ,CAC5D,SACD,CAAC,OACK,EAAK,CACZ,GAAI,CAAC,EAAI,QAAQ,SAAS,wCAAwC,CAChE,MAAM,EAKZ,GAAS,GACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,yBAAyB,EAAqB,iBAAiB,EAAY,IAAK,YACjF,CACF,CACM"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./constants-TpID7AXE.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{i as n,r}from"./fetchAllRequests-CHHdyb4Q.mjs";import{i,r as a,t as o}from"./writeCsv-C4pjXGsD.mjs";import{groupBy as s,uniq as c}from"lodash-es";import l from"colors";import{buildTranscendGraphQLClient as u,createSombraGotInstance as d,fetchAllRequestIdentifiers as f,validateSombraVersion as p}from"@transcend-io/sdk";import{map as m}from"@transcend-io/utils";import h from"cli-progress";function g({attributeValues:e,requestIdentifiers:t,id:n,email:r,type:i,status:a,subjectType:o,details:c,createdAt:l,successfullyCompletedAt:u,country:d,locale:f,origin:p,countrySubDivision:m,isSilent:h,isTest:g,coreIdentifier:_,purpose:v,...y}){return{"Request ID":n,"Created At":l,"Successfully Completed At":u||``,Email:r,"Core Identifier":_,"Request Type":i,"Data Subject Type":o,Status:a,Country:d,"Country Sub Division":m,Details:c,Origin:p,"Silent Mode":h,"Is Test Request":g,Language:f,"Purpose Trigger Name":v?.title||v?.name||``,"Purpose Trigger Value":v?.consent?.toString()||``,...(v?.enrichedPreferences||[]).reduce((e,t)=>{let n=t.preferenceTopic?.title.defaultMessage||t.name;return n?{...e,[n]:t.selectValues?t.selectValues.map(e=>e.name).join(`;`):t.selectValue?.name||t.booleanValue}:e},{}),...y,...Object.entries(s(e,`attributeKey.name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({name:e})=>e).join(`,`)}),{}),...Object.entries(s(t,`name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({value:e})=>e).join(`,`)}),{})}}function _(e,t,n){let r=e.getTime(),i=t.getTime(),a=(i-r)/n;return Array.from({length:n},(e,t)=>({createdAtAfter:new Date(r+a*t),createdAtBefore:new Date(t===n-1?i:r+a*(t+1))}))}async function v({auth:s,sombraAuth:v,actions:y=[],statuses:b=[],identifierSearch:x,concurrency:S=1,pageLimit:C=100,transcendUrl:w=e,createdAtBefore:T,createdAtAfter:E,updatedAtBefore:D,updatedAtAfter:O,isTest:k,skipRequestIdentifiers:A=!1,file:j}){let M=u(w,s),N=A?void 0:await d(w,s,{logger:t,sombraApiKey:v,sombraUrl:process.env.SOMBRA_URL}),P=``;T&&(P+=` before ${T.toISOString()}`),E&&(P+=`${P?`, and`:``} after ${E.toISOString()}`),t.info(l.magenta(`${y.length>0?`Pulling requests of type "${y.join(`" , "`)}"`:`Pulling all requests`}${P}`));let F=S>1&&E&&T,I=F?_(E,T,S):[{createdAtAfter:E,createdAtBefore:T}];F&&t.info(l.magenta(`Splitting date range into ${S} parallel chunks`));let L={type:y.length>0?y:void 0,status:b.length>0?b:void 0,isTest:k,createdAtBefore:T?T.toISOString():void 0,createdAtAfter:E?E.toISOString():void 0,updatedAtBefore:D?D.toISOString():void 0,updatedAtAfter:O?O.toISOString():void 0},R=Date.now();A||await p(M,{logger:t});let z=await n(M,L);t.info(l.magenta(`Fetching ${z} requests`));let B=new h.SingleBar({},h.Presets.shades_classic);B.start(z,0);let V=0,{baseName:H,extension:U}=i(j),W=I.map((e,t)=>I.length===1?j:`${H}-${t}${U}`),G=[],K=await m(I,async(e,n)=>{let i=W[n],s,u=0;try{await r(M,{actions:y,text:x,statuses:b,createdAtBefore:e.createdAtBefore,createdAtAfter:e.createdAtAfter,updatedAtBefore:D,updatedAtAfter:O,isTest:k,onPage:async e=>{if(e.length===0)return;let n=(A?e.map(e=>({...e,requestIdentifiers:[]})):await m(e,async e=>({...e,requestIdentifiers:await f(M,N,{filterBy:{requestId:e.id},skipSombraCheck:!0,logger:t})}),{concurrency:C})).map(g);s||(s=c(n.map(e=>Object.keys(e)).flat()),a(i,s)),o(i,n,s),u+=n.length,V+=n.length,B.update(V)}})}catch(r){let i=r instanceof Error?r.message:String(r);t.error(l.red(`Chunk ${n} failed (${e.createdAtAfter?.toISOString()??`start`} → ${e.createdAtBefore?.toISOString()??`end`}): ${i}`)),G.push({index:n,createdAtAfter:e.createdAtAfter,createdAtBefore:e.createdAtBefore,error:i})}return s||a(i,[]),u},{concurrency:F?S:1});B.stop();let q=K.reduce((e,t)=>e+t,0),J=(Date.now()-R)/1e3;if(G.length>0){t.error(l.red(`\n${G.length} chunk(s) failed. Re-run with these date ranges to fill the gaps:`));for(let e of G)t.error(l.red(` Chunk ${e.index}: --createdAtAfter=${e.createdAtAfter?.toISOString()??``} --createdAtBefore=${e.createdAtBefore?.toISOString()??``}`))}return t.info(l.green(`Streamed ${q} requests to ${W.length} file(s) in ${J}s`)),{filePaths:W,totalCount:q}}export{g as n,v as t};
2
- //# sourceMappingURL=streamPrivacyRequestsToCsv-eB3gNhol.mjs.map
1
+ import{a as e}from"./constants-D22_ckyl.mjs";import{t}from"./logger-Bj782ZYD.mjs";import{i as n,r}from"./fetchAllRequests-CHHdyb4Q.mjs";import{i,r as a,t as o}from"./writeCsv-C4pjXGsD.mjs";import{groupBy as s,uniq as c}from"lodash-es";import l from"colors";import{buildTranscendGraphQLClient as u,createSombraGotInstance as d,fetchAllRequestIdentifiers as f,validateSombraVersion as p}from"@transcend-io/sdk";import{map as m}from"@transcend-io/utils";import h from"cli-progress";function g({attributeValues:e,requestIdentifiers:t,id:n,email:r,type:i,status:a,subjectType:o,details:c,createdAt:l,successfullyCompletedAt:u,country:d,locale:f,origin:p,countrySubDivision:m,isSilent:h,isTest:g,coreIdentifier:_,purpose:v,...y}){return{"Request ID":n,"Created At":l,"Successfully Completed At":u||``,Email:r,"Core Identifier":_,"Request Type":i,"Data Subject Type":o,Status:a,Country:d,"Country Sub Division":m,Details:c,Origin:p,"Silent Mode":h,"Is Test Request":g,Language:f,"Purpose Trigger Name":v?.title||v?.name||``,"Purpose Trigger Value":v?.consent?.toString()||``,...(v?.enrichedPreferences||[]).reduce((e,t)=>{let n=t.preferenceTopic?.title.defaultMessage||t.name;return n?{...e,[n]:t.selectValues?t.selectValues.map(e=>e.name).join(`;`):t.selectValue?.name||t.booleanValue}:e},{}),...y,...Object.entries(s(e,`attributeKey.name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({name:e})=>e).join(`,`)}),{}),...Object.entries(s(t,`name`)).reduce((e,[t,n])=>Object.assign(e,{[t]:n.map(({value:e})=>e).join(`,`)}),{})}}function _(e,t,n){let r=e.getTime(),i=t.getTime(),a=(i-r)/n;return Array.from({length:n},(e,t)=>({createdAtAfter:new Date(r+a*t),createdAtBefore:new Date(t===n-1?i:r+a*(t+1))}))}async function v({auth:s,sombraAuth:v,actions:y=[],statuses:b=[],identifierSearch:x,concurrency:S=1,pageLimit:C=100,transcendUrl:w=e,createdAtBefore:T,createdAtAfter:E,updatedAtBefore:D,updatedAtAfter:O,isTest:k,skipRequestIdentifiers:A=!1,file:j}){let M=u(w,s),N=A?void 0:await d(w,s,{logger:t,sombraApiKey:v,sombraUrl:process.env.SOMBRA_URL}),P=``;T&&(P+=` before ${T.toISOString()}`),E&&(P+=`${P?`, and`:``} after ${E.toISOString()}`),t.info(l.magenta(`${y.length>0?`Pulling requests of type "${y.join(`" , "`)}"`:`Pulling all requests`}${P}`));let F=S>1&&E&&T,I=F?_(E,T,S):[{createdAtAfter:E,createdAtBefore:T}];F&&t.info(l.magenta(`Splitting date range into ${S} parallel chunks`));let L={type:y.length>0?y:void 0,status:b.length>0?b:void 0,isTest:k,createdAtBefore:T?T.toISOString():void 0,createdAtAfter:E?E.toISOString():void 0,updatedAtBefore:D?D.toISOString():void 0,updatedAtAfter:O?O.toISOString():void 0},R=Date.now();A||await p(M,{logger:t});let z=await n(M,L);t.info(l.magenta(`Fetching ${z} requests`));let B=new h.SingleBar({},h.Presets.shades_classic);B.start(z,0);let V=0,{baseName:H,extension:U}=i(j),W=I.map((e,t)=>I.length===1?j:`${H}-${t}${U}`),G=[],K=await m(I,async(e,n)=>{let i=W[n],s,u=0;try{await r(M,{actions:y,text:x,statuses:b,createdAtBefore:e.createdAtBefore,createdAtAfter:e.createdAtAfter,updatedAtBefore:D,updatedAtAfter:O,isTest:k,onPage:async e=>{if(e.length===0)return;let n=(A?e.map(e=>({...e,requestIdentifiers:[]})):await m(e,async e=>({...e,requestIdentifiers:await f(M,N,{filterBy:{requestId:e.id},skipSombraCheck:!0,logger:t})}),{concurrency:C})).map(g);s||(s=c(n.map(e=>Object.keys(e)).flat()),a(i,s)),o(i,n,s),u+=n.length,V+=n.length,B.update(V)}})}catch(r){let i=r instanceof Error?r.message:String(r);t.error(l.red(`Chunk ${n} failed (${e.createdAtAfter?.toISOString()??`start`} → ${e.createdAtBefore?.toISOString()??`end`}): ${i}`)),G.push({index:n,createdAtAfter:e.createdAtAfter,createdAtBefore:e.createdAtBefore,error:i})}return s||a(i,[]),u},{concurrency:F?S:1});B.stop();let q=K.reduce((e,t)=>e+t,0),J=(Date.now()-R)/1e3;if(G.length>0){t.error(l.red(`\n${G.length} chunk(s) failed. Re-run with these date ranges to fill the gaps:`));for(let e of G)t.error(l.red(` Chunk ${e.index}: --createdAtAfter=${e.createdAtAfter?.toISOString()??``} --createdAtBefore=${e.createdAtBefore?.toISOString()??``}`))}return t.info(l.green(`Streamed ${q} requests to ${W.length} file(s) in ${J}s`)),{filePaths:W,totalCount:q}}export{g as n,v as t};
2
+ //# sourceMappingURL=streamPrivacyRequestsToCsv-CipyYYbS.mjs.map