@transcend-io/cli 8.0.1 → 8.0.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 (143) hide show
  1. package/dist/bin/bash-complete.cjs +1 -1
  2. package/dist/bin/cli.cjs +1 -1
  3. package/dist/bin/deprecated-command.cjs +2 -2
  4. package/dist/{chunk-WRJVOXRS.cjs → chunk-3PX3HVEO.cjs} +2 -2
  5. package/dist/{chunk-WRJVOXRS.cjs.map → chunk-3PX3HVEO.cjs.map} +1 -1
  6. package/dist/{chunk-DBYKJZEA.cjs → chunk-44J2TVZU.cjs} +2 -2
  7. package/dist/{chunk-DBYKJZEA.cjs.map → chunk-44J2TVZU.cjs.map} +1 -1
  8. package/dist/chunk-7UL54E7X.cjs +2 -0
  9. package/dist/{chunk-MBB6OD4E.cjs.map → chunk-7UL54E7X.cjs.map} +1 -1
  10. package/dist/chunk-A4OQQVQT.cjs +3 -0
  11. package/dist/chunk-A4OQQVQT.cjs.map +1 -0
  12. package/dist/chunk-BPX6MSMC.cjs +2 -0
  13. package/dist/chunk-BPX6MSMC.cjs.map +1 -0
  14. package/dist/{chunk-7NYZMFPT.cjs → chunk-FNBADTTI.cjs} +19 -19
  15. package/dist/{chunk-7NYZMFPT.cjs.map → chunk-FNBADTTI.cjs.map} +1 -1
  16. package/dist/{chunk-56TB3NTQ.cjs → chunk-N7QF44VW.cjs} +2 -2
  17. package/dist/{chunk-56TB3NTQ.cjs.map → chunk-N7QF44VW.cjs.map} +1 -1
  18. package/dist/chunk-PQTI6C4Q.cjs +12 -0
  19. package/dist/chunk-PQTI6C4Q.cjs.map +1 -0
  20. package/dist/chunk-UONUI4AB.cjs +2920 -0
  21. package/dist/chunk-UONUI4AB.cjs.map +1 -0
  22. package/dist/chunk-W3S3ULXN.cjs +2 -0
  23. package/dist/chunk-W3S3ULXN.cjs.map +1 -0
  24. package/dist/{chunk-KS2REJYA.cjs → chunk-XARKMCNP.cjs} +4 -4
  25. package/dist/chunk-XARKMCNP.cjs.map +1 -0
  26. package/dist/{chunk-6IHSPKMP.cjs → chunk-XPKFB4IL.cjs} +2 -2
  27. package/dist/{chunk-6IHSPKMP.cjs.map → chunk-XPKFB4IL.cjs.map} +1 -1
  28. package/dist/{chunk-WLUTU3MY.cjs → chunk-YKZKPWDF.cjs} +2 -2
  29. package/dist/{chunk-WLUTU3MY.cjs.map → chunk-YKZKPWDF.cjs.map} +1 -1
  30. package/dist/chunk-YMXQXAUZ.cjs +2 -0
  31. package/dist/{chunk-PSRKLYGK.cjs.map → chunk-YMXQXAUZ.cjs.map} +1 -1
  32. package/dist/{chunk-PNSZQIYV.cjs → chunk-YP2PMUM5.cjs} +2 -2
  33. package/dist/{chunk-PNSZQIYV.cjs.map → chunk-YP2PMUM5.cjs.map} +1 -1
  34. package/dist/{impl-57LDSC2M.cjs → impl-2BXBJZII.cjs} +2 -2
  35. package/dist/{impl-57LDSC2M.cjs.map → impl-2BXBJZII.cjs.map} +1 -1
  36. package/dist/{impl-RGYCC7MP.cjs → impl-2SHN3CZX.cjs} +2 -2
  37. package/dist/{impl-RGYCC7MP.cjs.map → impl-2SHN3CZX.cjs.map} +1 -1
  38. package/dist/{impl-5KEI5AJG.cjs → impl-334G4VTL.cjs} +2 -2
  39. package/dist/{impl-5KEI5AJG.cjs.map → impl-334G4VTL.cjs.map} +1 -1
  40. package/dist/{impl-RXVSZRCO.cjs → impl-37NGCBEQ.cjs} +2 -2
  41. package/dist/{impl-RXVSZRCO.cjs.map → impl-37NGCBEQ.cjs.map} +1 -1
  42. package/dist/{impl-AHLMRZNM.cjs → impl-5IS3UVQQ.cjs} +2 -2
  43. package/dist/{impl-AHLMRZNM.cjs.map → impl-5IS3UVQQ.cjs.map} +1 -1
  44. package/dist/{impl-UMRC5P5T.cjs → impl-5IZQDLG7.cjs} +2 -2
  45. package/dist/{impl-UMRC5P5T.cjs.map → impl-5IZQDLG7.cjs.map} +1 -1
  46. package/dist/impl-7MIPQI3E.cjs +2 -0
  47. package/dist/impl-7MIPQI3E.cjs.map +1 -0
  48. package/dist/impl-AJMAFFJG.cjs +2 -0
  49. package/dist/{impl-FP3D5M5B.cjs.map → impl-AJMAFFJG.cjs.map} +1 -1
  50. package/dist/{impl-XW7JECCZ.cjs → impl-BL64FHKY.cjs} +2 -2
  51. package/dist/{impl-XW7JECCZ.cjs.map → impl-BL64FHKY.cjs.map} +1 -1
  52. package/dist/{impl-QJJNBKJR.cjs → impl-BXNGIHN2.cjs} +2 -2
  53. package/dist/{impl-QJJNBKJR.cjs.map → impl-BXNGIHN2.cjs.map} +1 -1
  54. package/dist/impl-DDHHIRXW.cjs +12 -0
  55. package/dist/impl-DDHHIRXW.cjs.map +1 -0
  56. package/dist/impl-DFDEITPV.cjs +7 -0
  57. package/dist/impl-DFDEITPV.cjs.map +1 -0
  58. package/dist/{impl-TJP4ZLHS.cjs → impl-DZSW2V2J.cjs} +2 -2
  59. package/dist/{impl-TJP4ZLHS.cjs.map → impl-DZSW2V2J.cjs.map} +1 -1
  60. package/dist/impl-FC7ICRDM.cjs +2 -0
  61. package/dist/{impl-YUYWOPRG.cjs.map → impl-FC7ICRDM.cjs.map} +1 -1
  62. package/dist/{impl-T4BXYX2K.cjs → impl-G2MAA4QD.cjs} +2 -2
  63. package/dist/{impl-T4BXYX2K.cjs.map → impl-G2MAA4QD.cjs.map} +1 -1
  64. package/dist/{impl-GP2DMI4O.cjs → impl-GIZXIRD5.cjs} +2 -2
  65. package/dist/{impl-GP2DMI4O.cjs.map → impl-GIZXIRD5.cjs.map} +1 -1
  66. package/dist/{impl-UG3FWG22.cjs → impl-H3RZXUMP.cjs} +2 -2
  67. package/dist/{impl-UG3FWG22.cjs.map → impl-H3RZXUMP.cjs.map} +1 -1
  68. package/dist/impl-HG3PK5DG.cjs +2 -0
  69. package/dist/{impl-HVKSG236.cjs.map → impl-HG3PK5DG.cjs.map} +1 -1
  70. package/dist/impl-IAZCCRHG.cjs +2 -0
  71. package/dist/{impl-GPTJLZHD.cjs.map → impl-IAZCCRHG.cjs.map} +1 -1
  72. package/dist/{impl-LZUXHWDU.cjs → impl-K3VBUCUB.cjs} +2 -2
  73. package/dist/{impl-LZUXHWDU.cjs.map → impl-K3VBUCUB.cjs.map} +1 -1
  74. package/dist/impl-KMLDAWB5.cjs +6 -0
  75. package/dist/impl-KMLDAWB5.cjs.map +1 -0
  76. package/dist/impl-LDJGDZNJ.cjs +2 -0
  77. package/dist/impl-LDJGDZNJ.cjs.map +1 -0
  78. package/dist/impl-LLCE3XUF.cjs +6 -0
  79. package/dist/impl-LLCE3XUF.cjs.map +1 -0
  80. package/dist/{impl-G24XCV65.cjs → impl-MVGWE3OY.cjs} +2 -2
  81. package/dist/{impl-G24XCV65.cjs.map → impl-MVGWE3OY.cjs.map} +1 -1
  82. package/dist/{impl-PAXESZFC.cjs → impl-N56GZUUE.cjs} +2 -2
  83. package/dist/{impl-PAXESZFC.cjs.map → impl-N56GZUUE.cjs.map} +1 -1
  84. package/dist/{impl-HQLA253Z.cjs → impl-NRVKZ6QP.cjs} +2 -2
  85. package/dist/{impl-HQLA253Z.cjs.map → impl-NRVKZ6QP.cjs.map} +1 -1
  86. package/dist/{impl-L2XUXKHL.cjs → impl-O7M62JQO.cjs} +2 -2
  87. package/dist/{impl-L2XUXKHL.cjs.map → impl-O7M62JQO.cjs.map} +1 -1
  88. package/dist/{impl-SW44TCHM.cjs → impl-OXCKKL3L.cjs} +2 -2
  89. package/dist/{impl-SW44TCHM.cjs.map → impl-OXCKKL3L.cjs.map} +1 -1
  90. package/dist/{impl-JUUYZHGL.cjs → impl-OYQLTGBY.cjs} +2 -2
  91. package/dist/{impl-JUUYZHGL.cjs.map → impl-OYQLTGBY.cjs.map} +1 -1
  92. package/dist/{impl-TLDBJN7P.cjs → impl-PNDNQD25.cjs} +2 -2
  93. package/dist/{impl-TLDBJN7P.cjs.map → impl-PNDNQD25.cjs.map} +1 -1
  94. package/dist/{impl-4VCIYJCG.cjs → impl-Q2JAFPV5.cjs} +2 -2
  95. package/dist/{impl-4VCIYJCG.cjs.map → impl-Q2JAFPV5.cjs.map} +1 -1
  96. package/dist/{impl-W6OLYSNF.cjs → impl-Q6LOHZB6.cjs} +2 -2
  97. package/dist/{impl-W6OLYSNF.cjs.map → impl-Q6LOHZB6.cjs.map} +1 -1
  98. package/dist/{impl-AHNQLAH5.cjs → impl-QS77O4PW.cjs} +2 -2
  99. package/dist/{impl-AHNQLAH5.cjs.map → impl-QS77O4PW.cjs.map} +1 -1
  100. package/dist/{impl-MLEPL5MZ.cjs → impl-TC6DE6BU.cjs} +5 -5
  101. package/dist/impl-TC6DE6BU.cjs.map +1 -0
  102. package/dist/{impl-RPRRJOI3.cjs → impl-W6WGF5YD.cjs} +2 -2
  103. package/dist/{impl-RPRRJOI3.cjs.map → impl-W6WGF5YD.cjs.map} +1 -1
  104. package/dist/{impl-C53IQ5HC.cjs → impl-WHZWURMO.cjs} +2 -2
  105. package/dist/{impl-C53IQ5HC.cjs.map → impl-WHZWURMO.cjs.map} +1 -1
  106. package/dist/{impl-WSRMGN2H.cjs → impl-WWQBCKZV.cjs} +2 -2
  107. package/dist/{impl-WSRMGN2H.cjs.map → impl-WWQBCKZV.cjs.map} +1 -1
  108. package/dist/{impl-IKTY3PZ3.cjs → impl-XWRII7ET.cjs} +2 -2
  109. package/dist/{impl-IKTY3PZ3.cjs.map → impl-XWRII7ET.cjs.map} +1 -1
  110. package/dist/index.cjs +3 -3
  111. package/dist/index.cjs.map +1 -1
  112. package/dist/index.d.cts +1 -1
  113. package/package.json +4 -2
  114. package/dist/chunk-7G4SCKPN.cjs +0 -2
  115. package/dist/chunk-7G4SCKPN.cjs.map +0 -1
  116. package/dist/chunk-AMO6I4AO.cjs +0 -2
  117. package/dist/chunk-AMO6I4AO.cjs.map +0 -1
  118. package/dist/chunk-JMBVOY56.cjs +0 -3
  119. package/dist/chunk-JMBVOY56.cjs.map +0 -1
  120. package/dist/chunk-KS2REJYA.cjs.map +0 -1
  121. package/dist/chunk-MBB6OD4E.cjs +0 -2
  122. package/dist/chunk-PSRKLYGK.cjs +0 -2
  123. package/dist/chunk-PTQHBKJU.cjs +0 -12
  124. package/dist/chunk-PTQHBKJU.cjs.map +0 -1
  125. package/dist/chunk-UPUHHIXZ.cjs +0 -2920
  126. package/dist/chunk-UPUHHIXZ.cjs.map +0 -1
  127. package/dist/impl-5BNP4JYG.cjs +0 -2
  128. package/dist/impl-5BNP4JYG.cjs.map +0 -1
  129. package/dist/impl-5MGEJPTO.cjs +0 -12
  130. package/dist/impl-5MGEJPTO.cjs.map +0 -1
  131. package/dist/impl-DSRH7IN2.cjs +0 -2
  132. package/dist/impl-DSRH7IN2.cjs.map +0 -1
  133. package/dist/impl-FP3D5M5B.cjs +0 -2
  134. package/dist/impl-GPTJLZHD.cjs +0 -2
  135. package/dist/impl-HVKSG236.cjs +0 -2
  136. package/dist/impl-IVDJEVS4.cjs +0 -6
  137. package/dist/impl-IVDJEVS4.cjs.map +0 -1
  138. package/dist/impl-MLEPL5MZ.cjs.map +0 -1
  139. package/dist/impl-QW6NAOEK.cjs +0 -7
  140. package/dist/impl-QW6NAOEK.cjs.map +0 -1
  141. package/dist/impl-VF3LT3IJ.cjs +0 -6
  142. package/dist/impl-VF3LT3IJ.cjs.map +0 -1
  143. package/dist/impl-YUYWOPRG.cjs +0 -2
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/chunk-UPUHHIXZ.cjs","../src/lib/bluebird-replace.ts","../src/lib/graphql/gqls/dataPoint.ts","../src/lib/graphql/gqls/entry.ts","../src/lib/graphql/gqls/dataSilo.ts","../src/lib/graphql/gqls/enricher.ts","../src/lib/graphql/gqls/catalog.ts","../src/lib/graphql/gqls/identifier.ts","../src/lib/graphql/gqls/dataSubject.ts","../src/lib/graphql/gqls/repository.ts","../src/lib/graphql/gqls/apiKey.ts","../src/lib/graphql/gqls/siloDiscovery.ts","../src/lib/graphql/gqls/template.ts","../src/lib/graphql/gqls/organization.ts","../src/lib/graphql/gqls/attributeKey.ts","../src/lib/graphql/gqls/softwareDevelopmentKit.ts","../src/lib/graphql/gqls/codePackage.ts","../src/lib/graphql/gqls/promptThread.ts","../src/lib/graphql/gqls/policy.ts","../src/lib/graphql/gqls/request.ts","../src/lib/graphql/gqls/message.ts","../src/lib/graphql/gqls/RequestEnricher.ts","../src/lib/graphql/gqls/assessment.ts","../src/lib/graphql/gqls/purpose.ts","../src/lib/graphql/gqls/preferenceTopic.ts","../src/lib/graphql/gqls/assessmentTemplate.ts","../src/lib/graphql/gqls/prompt.ts","../src/lib/graphql/gqls/RequestDataSilo.ts","../src/lib/graphql/gqls/team.ts","../src/lib/graphql/gqls/RequestIdentifier.ts","../src/lib/graphql/gqls/user.ts","../src/lib/graphql/gqls/requestFile.ts","../src/lib/graphql/gqls/promptRun.ts","../src/lib/graphql/gqls/actionItemCollection.ts","../src/lib/graphql/gqls/attribute.ts","../src/lib/graphql/gqls/consentManager.ts","../src/lib/graphql/gqls/consentManagerMetrics.ts","../src/lib/graphql/gqls/businessEntity.ts","../src/lib/graphql/gqls/action.ts","../src/lib/graphql/gqls/actionItem.ts","../src/lib/graphql/gqls/privacyCenter.ts","../src/lib/graphql/gqls/auth.ts","../src/lib/graphql/gqls/largeLanguageModel.ts","../src/lib/graphql/gqls/agent.ts","../src/lib/graphql/gqls/agentFile.ts","../src/lib/graphql/gqls/agentFunction.ts","../src/lib/graphql/gqls/vendor.ts","../src/lib/graphql/gqls/dataCategory.ts","../src/lib/graphql/gqls/processingPurpose.ts","../src/lib/graphql/gqls/processingActivity.ts","../src/lib/graphql/gqls/sombraVersion.ts","../src/lib/graphql/makeGraphQLRequest.ts","../src/lib/graphql/fetchIdentifiers.ts","../src/lib/graphql/syncIdentifier.ts","../src/lib/graphql/syncEnrichers.ts","../src/lib/graphql/syncDataSilos.ts","../src/lib/graphql/fetchApiKeys.ts"],"names":["mapSeries","array","iterator","results","i","map","options","concurrency","executing","nextIndex","executeNext","currentIndex","promise","result","index","initialBatch","initialPromises","DATA_POINTS","gql","DATA_POINT_COUNT","SUB_DATA_POINTS","SUB_DATA_POINTS_COUNT","SUB_DATA_POINTS_WITH_GUESSES","UPDATE_OR_CREATE_DATA_POINT","DATAPOINT_EXPORT","ENTRY_COUNT","DATA_SILOS","DATA_SILO_EXPORT","DATA_SILOS_ENRICHED","UPDATE_DATA_SILOS","CREATE_DATA_SILOS","ENRICHERS","INITIALIZER","CREATE_ENRICHER","UPDATE_ENRICHER","CATALOGS","IDENTIFIERS","NEW_IDENTIFIER_TYPES","CREATE_IDENTIFIER","UPDATE_IDENTIFIER","DATA_SUBJECTS","CREATE_DATA_SUBJECT","UPDATE_DATA_SUBJECT","TOGGLE_DATA_SUBJECT","REPOSITORIES","UPDATE_REPOSITORIES","CREATE_REPOSITORY","API_KEYS","CREATE_API_KEY","DELETE_API_KEY","ADD_SILO_DISCOVERY_RESULTS","ENABLED_PLUGINS","TEMPLATES","CREATE_TEMPLATE","ORGANIZATION","ATTRIBUTE_KEYS_REQUESTS","SOFTWARE_DEVELOPMENT_KITS","UPDATE_SOFTWARE_DEVELOPMENT_KITS","CREATE_SOFTWARE_DEVELOPMENT_KIT","CODE_PACKAGES","UPDATE_CODE_PACKAGES","CREATE_CODE_PACKAGE","PROMPT_THREADS","POLICIES","UPDATE_POLICIES","REQUESTS","APPROVE_PRIVACY_REQUEST","CANCEL_PRIVACY_REQUEST","UPDATE_PRIVACY_REQUEST","NOTIFY_ADDITIONAL_TIME","MESSAGES","UPDATE_INTL_MESSAGES","REQUEST_ENRICHERS","RETRY_REQUEST_ENRICHER","SKIP_REQUEST_ENRICHER","ASSESSMENT_SECTION_FIELDS","ASSESSMENTS","IMPORT_ONE_TRUST_ASSESSMENT_FORMS","PURPOSES","PREFERENCE_TOPICS","ASSESSMENT_TEMPLATES","PROMPTS","PROMPT_PARTIALS","PROMPT_GROUPS","PROMPTS_WITH_VARIABLES","UPDATE_PROMPTS","CREATE_PROMPT","UPDATE_PROMPT_PARTIALS","CREATE_PROMPT_PARTIAL","UPDATE_PROMPT_GROUPS","CREATE_PROMPT_GROUP","REQUEST_DATA_SILOS","CHANGE_REQUEST_DATA_SILO_STATUS","RETRY_REQUEST_DATA_SILO","REDUCED_REQUESTS_FOR_DATA_SILO_COUNT","TEAMS","CREATE_TEAM","UPDATE_TEAM","REMOVE_REQUEST_IDENTIFIERS","REQUEST_IDENTIFIERS","USERS","REQUEST_FILES","BULK_REQUEST_FILES","REPORT_PROMPT_RUN","ADD_MESSAGES_TO_PROMPT_RUN","GLOBAL_ACTION_ITEM_COLLECTIONS","CREATE_ACTION_ITEM_COLLECTION","UPDATE_ACTION_ITEM_COLLECTION","ATTRIBUTES","CREATE_ATTRIBUTE_VALUES","UPDATE_ATTRIBUTE_VALUES","DELETE_ATTRIBUTE_VALUE","ATTRIBUTE_VALUES","CREATE_ATTRIBUTE","UPDATE_ATTRIBUTE","SET_RESOURCE_ATTRIBUTES","EXPERIENCES","CONSENT_PARTITIONS","CREATE_DATA_FLOWS","UPDATE_DATA_FLOWS","UPDATE_OR_CREATE_COOKIES","DATA_FLOWS","COOKIES","FETCH_CONSENT_MANAGER_ID","FETCH_CONSENT_MANAGER","FETCH_CONSENT_MANAGER_THEME","CREATE_CONSENT_MANAGER","UPDATE_CONSENT_MANAGER_VERSION","UPDATE_CONSENT_MANAGER_TO_LATEST","DEPLOY_CONSENT_MANAGER","UPDATE_CONSENT_MANAGER_DOMAINS","UPDATE_CONSENT_MANAGER_PARTITION","UPDATE_LOAD_OPTIONS","TOGGLE_UNKNOWN_REQUEST_POLICY","TOGGLE_UNKNOWN_COOKIE_POLICY","TOGGLE_TELEMETRY_PARTITION_STRATEGY","TOGGLE_CONSENT_PRECEDENCE","UPDATE_CONSENT_MANAGER_THEME","UPDATE_CONSENT_EXPERIENCE","CREATE_CONSENT_EXPERIENCE","CREATE_CONSENT_PARTITION","CONSENT_MANAGER_ANALYTICS_DATA","BUSINESS_ENTITIES","CREATE_BUSINESS_ENTITY","UPDATE_BUSINESS_ENTITIES","ACTIONS","UPDATE_ACTION","GLOBAL_ACTION_ITEMS","UPDATE_ACTION_ITEMS","CREATE_ACTION_ITEMS","FETCH_PRIVACY_CENTER_ID","DEPLOYED_PRIVACY_CENTER_URL","PRIVACY_CENTER","UPDATE_PRIVACY_CENTER","DETERMINE_LOGIN_METHOD","LOGIN","ASSUME_ROLE","LARGE_LANGUAGE_MODELS","AGENTS","CREATE_AGENT","UPDATE_AGENTS","AGENT_FILES","CREATE_AGENT_FILE","UPDATE_AGENT_FILES","AGENT_FUNCTIONS","CREATE_AGENT_FUNCTION","UPDATE_AGENT_FUNCTIONS","VENDORS","CREATE_VENDOR","UPDATE_VENDORS","DATA_SUB_CATEGORIES","CREATE_DATA_SUB_CATEGORY","UPDATE_DATA_SUB_CATEGORIES","PROCESSING_PURPOSE_SUB_CATEGORIES","CREATE_PROCESSING_PURPOSE_SUB_CATEGORY","UPDATE_PROCESSING_PURPOSE_SUB_CATEGORIES","PROCESSING_ACTIVITIES","CREATE_PROCESSING_ACTIVITY","UPDATE_PROCESSING_ACTIVITIES","SOMBRA_VERSION","MAX_RETRIES","sleepPromise","sleepTime","resolve","KNOWN_ERRORS","makeGraphQLRequest","client","document","variables","requestHeaders","maxRequests","retryCount","err","logger","colors","msg","rateLimitResetAt","PAGE_SIZE","fetchAllIdentifiers","identifiers","offset","shouldContinue","nodes","a","b","fetchIdentifiersAndCreateMissing","enrichers","dataSilos","skipPublish","allIdentifiers","identifiersByName","keyBy_default","expectedIdentifiers","uniq_default","flatten_default","enricher","dataSilo","name","x","missingIdentifiers","difference_default","newIdentifierTypes","nativeTypesRemaining","identifier","createIdentifier","syncIdentifier","dataSubjectsByName","identifierId","type","fetchAllEnrichers","title","syncEnricher","identifierByName","existingEnricher","dataSubjectIds","subject","existing"],"mappings":"AAAA,2lCAAmC,wDAAgH,MCOnJ,SAAsBA,CAAAA,CACpBC,CAAAA,CACAC,CAAAA,CACc,CACd,IAAMC,CAAAA,CAAU,CAAC,CAAA,CACjB,GAAA,CAAA,IAASC,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIH,CAAAA,CAAM,MAAA,CAAQG,CAAAA,EAAK,CAAA,CACrCD,CAAAA,CAAQ,IAAA,CAAK,MAAMD,CAAAA,CAASD,CAAAA,CAAMG,CAAC,CAAA,CAAGA,CAAAA,CAAGH,CAAAA,CAAM,MAAM,CAAC,CAAA,CAExD,OAAOE,CACT,CAUA,MAAA,SAAsBE,CAAAA,CACpBJ,CAAAA,CACAC,CAAAA,CACAI,CAAAA,CAGI,CAAC,CAAA,CACS,CACd,GAAM,CAAE,WAAA,CAAAC,CAAAA,CAAc,CAAA,CAAA,CAAS,CAAA,CAAID,CAAAA,CAC7BH,CAAAA,CAAe,IAAI,KAAA,CAAMF,CAAAA,CAAM,MAAM,CAAA,CACrCO,CAAAA,CAA6B,CAAC,CAAA,CAChCC,CAAAA,CAAY,CAAA,CAEVC,CAAAA,CAAc,KAAA,CAAA,CAAA,EAA2B,CAC7C,EAAA,CAAID,CAAAA,EAAaR,CAAAA,CAAM,MAAA,CAAQ,MAAA,CAE/B,IAAMU,CAAAA,CAAeF,CAAAA,CACrBA,CAAAA,EAAa,CAAA,CAEb,IAAMG,CAAAA,CAAUV,CAAAA,CACdD,CAAAA,CAAMU,CAAY,CAAA,CAClBA,CAAAA,CACAV,CAAAA,CAAM,MACR,CAAA,CAAE,IAAA,CAAMY,CAAAA,EAAW,CACjBV,CAAAA,CAAQQ,CAAY,CAAA,CAAIE,CAC1B,CAAC,CAAA,CAEDL,CAAAA,CAAU,IAAA,CAAKI,CAAO,CAAA,CACtB,MAAMA,CAAAA,CAGN,IAAME,CAAAA,CAAQN,CAAAA,CAAU,OAAA,CAAQI,CAAO,CAAA,CACnCE,CAAAA,CAAQ,CAAA,CAAA,EACVN,CAAAA,CAAU,MAAA,CAAOM,CAAAA,CAAO,CAAC,CAE7B,CAAA,CAGMC,CAAAA,CAAe,IAAA,CAAK,GAAA,CAAIR,CAAAA,CAAaN,CAAAA,CAAM,MAAM,CAAA,CACjDe,CAAAA,CAAkB,CAAC,CAAA,CACzB,GAAA,CAAA,IAASZ,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIW,CAAAA,CAAcX,CAAAA,EAAK,CAAA,CACrCY,CAAAA,CAAgB,IAAA,CAAKN,CAAAA,CAAY,CAAC,CAAA,CAOpC,GAAA,CAHA,MAAM,OAAA,CAAQ,GAAA,CAAIM,CAAe,CAAA,CAG1BP,CAAAA,CAAYR,CAAAA,CAAM,MAAA,CAAA,CACnBO,CAAAA,CAAU,MAAA,CAASD,CAAAA,CACrB,MAAMG,CAAAA,CAAY,CAAA,CAGlB,MAAM,OAAA,CAAQ,IAAA,CAAKF,CAAS,CAAA,CAKhC,OAAA,MAAM,OAAA,CAAQ,GAAA,CAAIA,CAAS,CAAA,CAEpBL,CACT,CCvFA,iDAAoB,IAIPc,EAAAA,CAAcC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqDdC,EAAAA,aAAmBD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUnBE,EAAAA,aAAkBF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqClBG,EAAAA,aAAwBH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQxBI,EAAAA,aAA+BJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA8C/BK,EAAAA,aAA8BL,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAyC9BM,EAAAA,aAAmBN,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AFKhC,CAAC,CG5MD,IAEaO,EAAAA,CAAcP,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AHqN3B,CAAC,CIvND,IAIaQ,EAAAA,CAAaR,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA+BbS,EAAAA,aAAmBT,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAgBnBU,EAAAA,aAAsBV,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAyEtBW,EAAAA,aAAoBX,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAYpBY,EAAAA,aAAoBZ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AJgNjC,CAAC,CKxVD,IAIaa,EAAAA,CAAYb,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAgDZc,EAAAA,aAAcd,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWde,EAAAA,aAAkBf,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQlBgB,EAAAA,aAAkBhB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AL0U/B,CAAC,CMjZD,IAKaiB,EAAAA,CAAWjB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ANsZxB,CAAC,CO3ZD,IAIakB,EAAAA,CAAclB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAoCdmB,EAAAA,aAAuBnB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQvBoB,EAAAA,aAAoBpB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWpBqB,EAAAA,aAAoBrB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;APuZjC,CAAC,CQldD,IAEasB,EAAAA,CAAgBtB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiBhBuB,EAAAA,aAAsBvB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWtBwB,EAAAA,aAAsBxB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQtByB,EAAAA,aAAsBzB,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ARgdnC,CAAC,CStfD,IAKa0B,EAAAA,CAAe1B,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiCf2B,EAAAA,aAAsB3B,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqBtB4B,EAAAA,aAAoB5B,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ATggBjC,CAAC,CU3jBD,IAIa6B,EAAAA,CAAW7B,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAoBX8B,EAAAA,aAAiB9B,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAYjB+B,EAAAA,aAAiB/B,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AVyjB9B,CAAC,CW7lBD,IAEagC,EAAAA,CAA6BhC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAa7BiC,EAAAA,aAAkBjC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AXqmB/B,CAAC,CYpnBD,IAKakC,EAAAA,CAAYlC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAsBZmC,EAAAA,aAAkBnC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AZmnB/B,CAAC,Ca9oBD,IAEaoC,EAAAA,CAAepC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AbopB5B,CAAC,CctpBD,IAKaqC,EAAAA,CAA0BrC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AdgqBvC,CAAC,CerqBD,IAKasC,EAAAA,CAA4BtC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAmC5BuC,EAAAA,aAAmCvC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA0BnCwC,EAAAA,aAAkCxC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AforB/C,CAAC,CgBtvBD,IAKayC,EAAAA,CAAgBzC,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA2ChB0C,EAAAA,aAAuB1C,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAgCvB2C,EAAAA,aAAsB3C,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AhB2wBnC,CAAC,CiB31BD,IAEa4C,EAAAA,CAAiB5C,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AjB02B9B,CAAC,CkB52BD,IAEa6C,EAAAA,CAAW7C,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAmBX8C,EAAAA,aAAkB9C,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AlBu3B/B,CAAC,CmB54BD,IAIa+C,EAAAA,CAAW/C,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA+CXgD,EAAAA,aAA0BhD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAS1BiD,EAAAA,aAAyBjD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUzBkD,EAAAA,aAAyBlD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUzBmD,EAAAA,aAAyBnD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AnBu4BtC,CAAC,CoBv9BD,IAEaoD,EAAAA,CAAWpD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAcXqD,EAAAA,cAAuBrD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ApBy9BpC,CAAC,CqBz+BD,IAIasD,EAAAA,CAAoBtD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA8BpBuD,EAAAA,cAAyBvD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUzBwD,EAAAA,cAAwBxD,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ArBy+BrC,CAAC,CsBrhCD,IAEayD,EAAAA,CAA4B,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA0I5BC,EAAAA,cAAc1D,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,EA4DfyD,EAAyB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAsFxBE,EAAAA,cAAoC3D,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AtBmhCjD,CAAC,CuBjzCD,IASa4D,EAAAA,CAAW5D,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AvBw0CxB,CAAC,CwBj1CD,IASa6D,EAAAA,CAAoB7D,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AxB02CjC,CAAC,CyBn3CD,IAUa8D,EAAAA,CAAuB9D,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,EAmDxByD,EAAyB,CAAA;AAAA;AAAA;AAAA;AAAA;AzB82CrC,CAAC,C0B36CD,IAKaM,EAAAA,CAAU/D,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA8BVgE,EAAAA,cAAkBhE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiBlBiE,EAAAA,cAAgBjE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAmBhBkE,EAAAA,cAAyBlE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA8BzBmE,EAAAA,cAAiBnE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQjBoE,EAAAA,cAAgBpE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWhBqE,EAAAA,cAAyBrE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUzBsE,EAAAA,cAAwBtE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWxBuE,EAAAA,cAAuBvE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQvBwE,EAAAA,cAAsBxE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A1Bm5CnC,CAAC,C2BxiDD,IAIayE,EAAAA,CAAqBzE,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAwBrB0E,EAAAA,cAAkC1E,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAelC2E,EAAAA,cAA0B3E,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiB1B4E,EAAAA,cAAuC5E,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A3B+hDpD,CAAC,C4B3lDD,IAKa6E,EAAAA,CAAQ7E,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqCR8E,EAAAA,cAAc9E,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWd+E,EAAAA,cAAc/E,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A5B2lD3B,CAAC,C6BhpDD,IAEagF,EAAAA,CAA6BhF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAY7BiF,EAAAA,cAAsBjF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A7BkqDnC,CAAC,C8BhrDD,IAKakF,EAAAA,CAAQlF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A9BisDrB,CAAC,C+BtsDD,IAKamF,EAAAA,CAAgBnF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAuBhBoF,EAAAA,cAAqBpF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A/BgtDlC,CAAC,CgC5uDD,IAEaqF,EAAAA,CAAoBrF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWpBsF,EAAAA,cAA6BtF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AhCmvD1C,CAAC,CiChwDD,IAQauF,EAAAA,CAAiCvF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAgBjCwF,EAAAA,cAAgCxF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAahCyF,EAAAA,cAAgCzF,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AjC4vD7C,CAAC,CkCjyDD,IAKa0F,EAAAA,CAAa1F,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAeb2F,EAAAA,cAA0B3F,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAU1B4F,EAAAA,cAA0B5F,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAU1B6F,EAAAA,cAAyB7F,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWzB8F,EAAAA,cAAmB9F,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAsBnB+F,EAAAA,cAAmB/F,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAuBnBgG,EAAAA,cAAmBhG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqBnBiG,EAAAA,cAA0BjG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AlCmxDvC,CAAC,CmCv4DD,IAKakG,EAAAA,CAAclG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAmCdmG,EAAAA,cAAqBnG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAYrBoG,EAAAA,cAAoBpG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAoBpBqG,EAAAA,cAAoBrG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAoBpBsG,EAAAA,cAA2BtG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAe3BuG,EAAAA,cAAavG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiDbwG,EAAAA,cAAUxG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA8CVyG,EAAAA,cAA2BzG,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAU3B0G,EAAAA,cAAwB1G,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA0BxB2G,EAAAA,cAA8B3G,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAa9B4G,EAAAA,cAAyB5G,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUzB6G,EAAAA,cAAiC7G,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWjC8G,EAAAA,cAAmC9G,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAcnC+G,EAAAA,cAAyB/G,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAczBgH,EAAAA,cAAiChH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAajCiH,EAAAA,cAAmCjH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAanCkH,EAAAA,cAAsBlH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQtBmH,EAAAA,cAAgCnH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUhCoH,EAAAA,cAA+BpH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAU/BqH,EAAAA,cAAsCrH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAUtCsH,EAAAA,cAA4BtH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAU5BuH,EAAAA,cAA+BvH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAU/BwH,EAAAA,cAA4BxH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQ5ByH,EAAAA,cAA4BzH,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQ5B0H,EAAAA,cAA2B1H,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AnCk1DxC,CAAC,CoCnuED,IAEa2H,EAAAA,CAAiC3H,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ApC6uE9C,CAAC,CqC/uED,IAIa4H,EAAAA,CAAoB5H,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA+BpB6H,EAAAA,cAAyB7H,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAyBzB8H,EAAAA,cAA2B9H,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ArC+uExC,CAAC,CsC3yED,IAKa+H,EAAAA,CAAU/H,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAsBVgI,EAAAA,cAAgBhI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AtC0yE7B,CAAC,CuCr0ED,IASaiI,EAAAA,CAAsBjI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiDtBkI,EAAAA,cAAsBlI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQtBmI,EAAAA,cAAsBnI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AvC8zEnC,CAAC,CwCh4ED,IAEaoI,EAAAA,CAA0BpI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQ1BqI,EAAAA,cAA8BrI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAQ9BsI,EAAAA,cAAiBtI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA2BjBuI,EAAAA,cAAwBvI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AxC83ErC,CAAC,CyC36ED,IAEawI,EAAAA,CAAyBxI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWzByI,EAAAA,cAAQzI,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAyBR0I,EAAAA,cAAc1I,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AzC26E3B,CAAC,C0Cj9ED,IAKa2I,EAAAA,CAAwB3I,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A1Co+ErC,CAAC,C2Cz+ED,IAKa4I,EAAAA,CAAS5I,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA+CT6I,EAAAA,cAAe7I,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAYf8I,EAAAA,cAAgB9I,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A3Cs+E7B,CAAC,C4CtiFD,IAKa+I,EAAAA,CAAc/I,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA4BdgJ,EAAAA,cAAoBhJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAapBiJ,EAAAA,cAAqBjJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A5CmiFlC,CAAC,C6CjlFD,IAKakJ,EAAAA,CAAkBlJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAoBlBmJ,EAAAA,cAAwBnJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWxBoJ,EAAAA,cAAyBpJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A7CglFtC,CAAC,C8CpnFD,IAEaqJ,EAAAA,CAAUrJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA4CVsJ,EAAAA,cAAgBtJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAWhBuJ,EAAAA,cAAiBvJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A9ConF9B,CAAC,C+C7qFD,IAOawJ,EAAAA,CAAsBxJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CA+BtByJ,EAAAA,cAA2BzJ,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAc3B0J,EAAAA,cAA6B1J,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A/C0qF1C,CAAC,CgD9tFD,IAOa2J,EAAAA,CAAoC3J,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAiCpC4J,EAAAA,cAAyC5J,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAczC6J,EAAAA,cAA2C7J,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AhD2tFxD,CAAC,CiDjxFD,IAEa8J,EAAAA,CAAwB9J,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAuDxB+J,EAAAA,cAA6B/J,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAa7BgK,EAAAA,cAA+BhK,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AjDmxF5C,CAAC,CkDz1FD,IAEaiK,EAAAA,CAAiBjK,mBAAAA,CAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AlD+1F9B,CAAC,CmD31FD,gFAAmB,IAEbkK,EAAAA,CAAc,CAAA,CAQpB,SAASC,EAAAA,CAAaC,CAAAA,CAAoC,CACxD,OAAO,IAAI,OAAA,CAASC,CAAAA,EAAY,CAC9B,UAAA,CAAW,CAAA,CAAA,EAAMA,CAAAA,CAAQD,CAAS,CAAA,CAAGA,CAAS,CAChD,CAAC,CACH,CAEA,IAAME,EAAAA,CAAe,CACnB,cAAA,CACA,mBAAA,CACA,cAAA,CACA,iCAAA,CACA,2BACF,CAAA,CAYA,MAAA,SAAsBC,CAAAA,CACpBC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CAAcV,EAAAA,CACF,CACZ,IAAIW,CAAAA,CAAa,CAAA,CAEjB,GAAA,CAAA,CAAA,CAAA,CACE,GAAI,CAEF,OADe,MAAML,CAAAA,CAAO,OAAA,CAAQC,CAAAA,CAAUC,CAAAA,CAAWC,CAAc,CAEzE,CAAA,KAAA,CAASG,CAAAA,CAAK,CAYZ,EAAA,CAXIA,CAAAA,CAAI,OAAA,CAAQ,QAAA,CAAS,oBAAoB,CAAA,EAAA,CAC3CC,mBAAAA,CAAO,KAAA,CACLC,gBAAAA,CAAO,GAAA,CACL,uMAGF,CACF,CAAA,CACA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,CAAA,CAGZV,EAAAA,CAAa,IAAA,CAAMW,CAAAA,EAAQH,CAAAA,CAAI,OAAA,CAAQ,QAAA,CAASG,CAAG,CAAC,CAAA,CACtD,MAAMH,CAAAA,CAIR,EAAA,CAAIA,CAAAA,CAAI,OAAA,CAAQ,UAAA,CAAW,iCAAiC,CAAA,CAAG,CAC7D,IAAMI,CAAAA,iBAAmBJ,CAAAA,qBAAI,QAAA,qBAAS,OAAA,6BAAS,GAAA,mBAAI,mBAAmB,GAAA,CAChEV,CAAAA,CAAYc,CAAAA,CACd,IAAI,IAAA,CAAKA,CAAgB,CAAA,CAAE,OAAA,CAAQ,CAAA,CAAI,IAAI,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,CAAA,CAAI,GAAA,CAC9D,GAAA,CAAO,EAAA,CACXH,mBAAAA,CAAO,GAAA,CACLC,gBAAAA,CAAO,MAAA,CACL,CAAA,qBAAA,EAAwBF,CAAAA,CAAI,OAAO,CAAA,eAAA,EAAkBV,CAAS,CAAA,EAAA,CAChE,CACF,CAAA,CAEA,MAAMD,EAAAA,CAAaC,CAAS,CAC9B,CAEA,EAAA,CAAIS,CAAAA,EAAcD,CAAAA,CAChB,MAAME,CAAAA,CAERD,CAAAA,EAAc,CAAA,CACdE,mBAAAA,CAAO,GAAA,CACLC,gBAAAA,CAAO,MAAA,CACL,CAAA,gBAAA,EAAmBF,CAAAA,CAAI,OAAO,CAAA,WAAA,EAAcD,CAAU,CAAA,CAAA,EAAID,CAAW,CAAA,GAAA,CACvE,CACF,CACF,CAEJ,CCzFA,IA0CMO,EAAAA,CAAY,EAAA,CAQlB,MAAA,SAAsBC,EAAAA,CACpBZ,CAAAA,CACuB,CACvB,IAAMa,CAAAA,CAA4B,CAAC,CAAA,CAC/BC,CAAAA,CAAS,CAAA,CAGTC,CAAAA,CAAiB,CAAA,CAAA,CACrB,EAAG,CACD,GAAM,CACJ,WAAA,CAAa,CAAE,KAAA,CAAAC,CAAM,CACvB,CAAA,CAAI,MAAMjB,CAAAA,CAMPC,CAAAA,CAAQtJ,EAAAA,CAAa,CACtB,KAAA,CAAOiK,EAAAA,CACP,MAAA,CAAAG,CACF,CAAC,CAAA,CACDD,CAAAA,CAAY,IAAA,CAAK,GAAGG,CAAK,CAAA,CACzBF,CAAAA,EAAUH,EAAAA,CACVI,CAAAA,CAAiBC,CAAAA,CAAM,MAAA,GAAWL,EACpC,CAAA,KAAA,CAASI,CAAAA,CAAAA,CAET,OAAOF,CAAAA,CAAY,IAAA,CAAK,CAACI,CAAAA,CAAGC,CAAAA,CAAAA,EAAMD,CAAAA,CAAE,IAAA,CAAK,aAAA,CAAcC,CAAAA,CAAE,IAAI,CAAC,CAChE,CAWA,MAAA,SAAsBC,EAAAA,CACpB,CACE,SAAA,CAAAC,CAAAA,CAAY,CAAC,CAAA,CACb,YAAA,CAAcC,CAAAA,CAAY,CAAC,CAAA,CAC3B,WAAA,CAAAR,CAAAA,CAAc,CAAC,CACjB,CAAA,CACAb,CAAAA,CACAsB,CAAAA,CAAc,CAAA,CAAA,CAC0B,CAExC,IAAMC,CAAAA,CAAiB,MAAMX,EAAAA,CAAoBZ,CAAM,CAAA,CAGjDwB,CAAAA,CAAoBC,iCAAAA,CAAMF,CAAgB,MAAM,CAAA,CAGhDG,CAAAA,CAAsBC,iCAAAA,CAC1B,GAAGC,iCAAAA,CACDR,CAAU,GAAA,CAAKS,CAAAA,EAAa,CAC1BA,CAAAA,CAAS,kBAAkB,CAAA,CAC3B,GAAGA,CAAAA,CAAS,oBAAoB,CAClC,CAAC,CACH,CAAA,CACA,GAAGD,iCAAAA,CAAQP,CAAU,GAAA,CAAKS,CAAAA,EAAaA,CAAAA,CAAS,eAAe,CAAC,CAAC,CAAA,CACjE,GAAGjB,CAAAA,CAAY,GAAA,CAAI,CAAC,CAAE,IAAA,CAAAkB,CAAK,CAAA,CAAA,EAAMA,CAAI,CACvC,CAAC,CAAA,CAAE,MAAA,CAAQC,CAAAA,EAAM,CAAC,CAACA,CAAC,CAAA,CACdC,CAAAA,CAAqBC,iCAAAA,CACzBR,CACAH,CAAAA,CAAe,GAAA,CAAI,CAAC,CAAE,IAAA,CAAAQ,CAAK,CAAA,CAAA,EAAMA,CAAI,CACvC,CAAA,CAGA,EAAA,CAAIE,CAAAA,CAAmB,MAAA,CAAS,CAAA,CAAG,CACjC1B,mBAAAA,CAAO,IAAA,CACLC,gBAAAA,CAAO,OAAA,CACL,CAAA,SAAA,EAAYyB,CAAAA,CAAmB,MAAM,CAAA,mBAAA,CACvC,CACF,CAAA,CACA,GAAM,CAAE,kBAAA,CAAAE,CAAmB,CAAA,CAAI,MAAMpC,CAAAA,CAMlCC,CAAAA,CAAQrJ,EAAoB,CAAA,CACzByL,CAAAA,CAAuBD,CAAAA,CAAmB,GAAA,CAAI,CAAC,CAAE,IAAA,CAAAJ,CAAK,CAAA,CAAA,EAAMA,CAAI,CAAA,CACtE,MAAMzN,CAAAA,CAAU2N,CAAAA,CAAoB,MAAOI,CAAAA,EAAe,CACxD9B,mBAAAA,CAAO,IAAA,CAAKC,gBAAAA,CAAO,OAAA,CAAQ,CAAA,oBAAA,EAAuB6B,CAAU,CAAA,GAAA,CAAK,CAAC,CAAA,CAClE,GAAM,CAAE,gBAAA,CAAAC,CAAiB,CAAA,CAAI,MAAMvC,CAAAA,CAMhCC,CAAAA,CAAQpJ,EAAAA,CAAmB,CAC5B,KAAA,CAAO,CACL,IAAA,CAAMyL,CAAAA,CACN,IAAA,CAAMD,CAAAA,CAAqB,QAAA,CAASC,CAAW,CAAA,CAC3CA,CAAAA,CACA,QAAA,CACJ,WAAA,CAAAf,CACF,CACF,CAAC,CAAA,CACDf,mBAAAA,CAAO,IAAA,CAAKC,gBAAAA,CAAO,KAAA,CAAM,CAAA,mBAAA,EAAsB6B,CAAU,CAAA,CAAA,CAAG,CAAC,CAAA,CAE7Db,CAAAA,CAAkBa,CAAW,CAAA,CAAIC,CAAAA,CAAiB,UACpD,CAAC,CACH,CACA,OAAOd,CACT,CCvJA,MAAA,SAAsBe,EAAAA,CACpBvC,CAAAA,CACA,CACE,UAAA,CAAAqC,CAAAA,CACA,kBAAA,CAAAG,CAAAA,CACA,YAAA,CAAAC,CAAAA,CACA,WAAA,CAAAnB,CAAAA,CAAc,CAAA,CAChB,CAAA,CAUe,CACf,MAAMvB,CAAAA,CAAmBC,CAAAA,CAAQnJ,EAAAA,CAAmB,CAClD,KAAA,CAAO,CACL,EAAA,CAAI4L,CAAAA,CACJ,aAAA,CAAeJ,CAAAA,CAAW,aAAA,CAC1B,gBAAA,CAAkBA,CAAAA,CAAW,gBAAA,CAC7B,KAAA,CAAOA,CAAAA,CAAW,KAAA,CAClB,WAAA,CAAaA,CAAAA,CAAW,WAAA,CACxB,YAAA,CAAcA,CAAAA,CAAW,YAAA,CACzB,kBAAA,CAAoBA,CAAAA,CAAW,kBAAA,CAC/B,YAAA,CAAcA,CAAAA,CAAW,YAAA,CACzB,yBAAA,CAA2BA,CAAAA,CAAW,yBAAA,CACtC,uBAAA,CAAyBA,CAAAA,CAAW,uBAAA,CACpC,cAAA,CAAgBA,CAAAA,CAAW,YAAA,CACvBA,CAAAA,CAAW,YAAA,CAAa,GAAA,CAAKK,CAAAA,EAASF,CAAAA,CAAmBE,CAAI,CAAA,CAAE,EAAE,CAAA,CACjE,KAAA,CAAA,CACJ,WAAA,CAAApB,CACF,CACF,CAAC,CACH,CC7CA,2DAMO,IA+CDX,EAAAA,CAAY,EAAA,CASlB,MAAA,SAAsBgC,EAAAA,CACpB3C,CAAAA,CACA4C,CAAAA,CACqB,CACrB,IAAMxB,CAAAA,CAAwB,CAAC,CAAA,CAC3BN,CAAAA,CAAS,CAAA,CAGTC,CAAAA,CAAiB,CAAA,CAAA,CACrB,EAAG,CACD,GAAM,CACJ,SAAA,CAAW,CAAE,KAAA,CAAAC,CAAM,CACrB,CAAA,CAAI,MAAMjB,CAAAA,CAMPC,CAAAA,CAAQ3J,EAAAA,CAAW,CACpB,KAAA,CAAOsK,EAAAA,CACP,MAAA,CAAAG,CAAAA,CACA,KAAA,CAAA8B,CACF,CAAC,CAAA,CACDxB,CAAAA,CAAU,IAAA,CAAK,GAAGJ,CAAK,CAAA,CACvBF,CAAAA,EAAUH,EAAAA,CACVI,CAAAA,CAAiBC,CAAAA,CAAM,MAAA,GAAWL,EACpC,CAAA,KAAA,CAASI,CAAAA,CAAAA,CAET,OAAOK,CAAAA,CAAU,IAAA,CAAK,CAACH,CAAAA,CAAGC,CAAAA,CAAAA,EAAMD,CAAAA,CAAE,KAAA,CAAM,aAAA,CAAcC,CAAAA,CAAE,KAAK,CAAC,CAChE,CAQA,MAAA,SAAsB2B,EAAAA,CACpB7C,CAAAA,CACA,CACE,QAAA,CAAA6B,CAAAA,CACA,gBAAA,CAAAiB,CAAAA,CACA,kBAAA,CAAAN,CACF,CAAA,CAQe,CAGf,IAAMO,CAAAA,CAAAA,CADU,MAAMJ,EAAAA,CAAkB3C,CAAAA,CAAQ6B,CAAAA,CAAS,KAAK,CAAA,CAAA,CAC7B,IAAA,CAC/B,CAAC,CAAE,KAAA,CAAAe,CAAM,CAAA,CAAA,EAAMA,CAAAA,GAAUf,CAAAA,CAAS,KACpC,CAAA,CAGMmB,CAAAA,iBAAiBnB,CAAAA,qBAAS,eAAe,CAAA,6BAAG,GAAA,mBAAKoB,CAAAA,EAAY,CACjE,IAAMC,CAAAA,CAAWV,CAAAA,CAAmBS,CAAO,CAAA,CAC3C,EAAA,CAAI,CAACC,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,CAAA,yCAAA,EAA4CD,CAAO,CAAA,CAAA;AC0wBzD,yBAAA;AACE;AAeA;AAAuE,4BAAA;ACp3BnF","file":"/home/runner/work/cli/cli/dist/chunk-UPUHHIXZ.cjs","sourcesContent":[null,"/**\n * Replace bluebird's mapSeries with a simple for loop\n *\n * @param array - The array to iterate over\n * @param iterator - The iterator function that receives (item, index)\n * @returns The results of the iterator function\n */\nexport async function mapSeries<R, U>(\n array: R[],\n iterator: (item: R, index: number, arrayLength: number) => Promise<U>,\n): Promise<U[]> {\n const results = [];\n for (let i = 0; i < array.length; i += 1) {\n results.push(await iterator(array[i], i, array.length));\n }\n return results;\n}\n\n/**\n * Replace bluebird's map with Promise.all\n *\n * @param array - The array to iterate over\n * @param iterator - The iterator function that receives (item, index, arrayLength)\n * @param options - Options\n * @returns The results of the iterator function\n */\nexport async function map<R, U>(\n array: R[],\n iterator: (item: R, index: number, arrayLength: number) => Promise<U>,\n options: {\n /** Concurrency level for the Promise.all call */\n concurrency?: number;\n } = {},\n): Promise<U[]> {\n const { concurrency = Infinity } = options;\n const results: U[] = new Array(array.length);\n const executing: Promise<void>[] = [];\n let nextIndex = 0;\n\n const executeNext = async (): Promise<void> => {\n if (nextIndex >= array.length) return;\n\n const currentIndex = nextIndex;\n nextIndex += 1;\n\n const promise = iterator(\n array[currentIndex],\n currentIndex,\n array.length,\n ).then((result) => {\n results[currentIndex] = result;\n });\n\n executing.push(promise);\n await promise;\n\n // Remove the completed promise from executing array\n const index = executing.indexOf(promise);\n if (index > -1) {\n executing.splice(index, 1);\n }\n };\n\n // Start initial batch of promises up to concurrency limit\n const initialBatch = Math.min(concurrency, array.length);\n const initialPromises = [];\n for (let i = 0; i < initialBatch; i += 1) {\n initialPromises.push(executeNext());\n }\n\n // Wait for initial batch to start\n await Promise.all(initialPromises);\n\n // Continue executing remaining items as slots become available\n while (nextIndex < array.length) {\n if (executing.length < concurrency) {\n await executeNext();\n } else {\n // Wait for any promise to complete before continuing\n await Promise.race(executing);\n }\n }\n\n // Wait for all remaining promises to complete\n await Promise.all(executing);\n\n return results;\n}\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const DATA_POINTS = gql`\n query TranscendCliDataPoints(\n $filterBy: DataPointFiltersInput\n $first: Int!\n $offset: Int!\n ) {\n dataPoints(\n filterBy: $filterBy\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n title {\n defaultMessage\n }\n description {\n defaultMessage\n }\n owners {\n email\n }\n teams {\n name\n }\n name\n path\n actionSettings {\n type\n active\n }\n dataCollection {\n title {\n defaultMessage\n }\n }\n dbIntegrationQueries {\n query\n suggestedQuery\n requestType\n }\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const DATA_POINT_COUNT = gql`\n query TranscendCliDataPointCount($filterBy: DataPointFiltersInput) {\n dataPoints(filterBy: $filterBy, useMaster: false) {\n totalCount\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - add orderBy\n// isExportCsv: true\nexport const SUB_DATA_POINTS = gql`\n query TranscendCliSubDataPoints(\n $filterBy: SubDataPointFiltersInput\n $first: Int!\n $offset: Int!\n ) {\n subDataPoints(\n filterBy: $filterBy\n first: $first\n offset: $offset\n useMaster: false\n ) {\n nodes {\n id\n name\n description\n purposes {\n name\n purpose\n }\n categories {\n name\n category\n }\n accessRequestVisibilityEnabled\n erasureRequestRedactionEnabled\n attributeValues {\n attributeKey {\n name\n }\n name\n }\n }\n }\n }\n`;\n\nexport const SUB_DATA_POINTS_COUNT = gql`\n query TranscendCliSubDataPointsCount($filterBy: SubDataPointFiltersInput) {\n subDataPoints(filterBy: $filterBy, useMaster: false) {\n totalCount\n }\n }\n`;\n\nexport const SUB_DATA_POINTS_WITH_GUESSES = gql`\n query TranscendCliSubDataPointGuesses(\n $filterBy: SubDataPointFiltersInput\n $first: Int!\n $offset: Int!\n ) {\n subDataPoints(\n filterBy: $filterBy\n first: $first\n offset: $offset\n useMaster: false\n ) {\n nodes {\n id\n name\n description\n purposes {\n name\n purpose\n }\n categories {\n name\n category\n }\n pendingCategoryGuesses {\n category {\n name\n category\n }\n status\n confidence\n classifierVersion\n }\n accessRequestVisibilityEnabled\n erasureRequestRedactionEnabled\n attributeValues {\n attributeKey {\n name\n }\n name\n }\n }\n }\n }\n`;\n\nexport const UPDATE_OR_CREATE_DATA_POINT = gql`\n mutation TranscendCliUpdateOrCreateDataPoint(\n $dataSiloId: ID!\n $name: String!\n $path: [String!]\n $title: String\n $description: String\n $ownerIds: [ID!]\n $ownerEmails: [String!]\n $teamNames: [String!]\n $teamIds: [ID!]\n $dataCollectionTag: String\n $querySuggestions: [DbIntegrationQuerySuggestionInput!]\n $enabledActions: [RequestActionObjectResolver!]\n $subDataPoints: [DataPointSubDataPointInput!]\n ) {\n updateOrCreateDataPoint(\n input: {\n dataSiloId: $dataSiloId\n name: $name\n path: $path\n title: $title\n teamNames: $teamNames\n ownerEmails: $ownerEmails\n dataCollectionTag: $dataCollectionTag\n description: $description\n ownerIds: $ownerIds\n teamIds: $teamIds\n querySuggestions: $querySuggestions\n enabledActions: $enabledActions\n subDataPoints: $subDataPoints\n }\n ) {\n dataPoint {\n id\n name\n }\n }\n }\n`;\n\nexport const DATAPOINT_EXPORT = gql`\n query TranscendCliDataPointCsvExport(\n $filterBy: DataPointFiltersInput\n $first: Int!\n ) {\n dataPoints(filterBy: $filterBy, first: $first, useMaster: false) {\n nodes {\n id\n title {\n defaultMessage\n }\n description {\n defaultMessage\n }\n owners {\n email\n }\n teams {\n name\n }\n name\n path\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const ENTRY_COUNT = gql`\n query TranscendCliEntryCount(\n $filterBy: UnstructuredSubDataPointRecommendationsFilterInput\n ) {\n unstructuredSubDataPointRecommendations(\n filterBy: $filterBy\n useMaster: false\n ) {\n totalCount\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const DATA_SILOS = gql`\n query TranscendCliDataSilos(\n $filterBy: DataSiloFiltersInput!\n $first: Int!\n $offset: Int!\n ) {\n dataSilos(\n filterBy: $filterBy\n first: $first\n offset: $offset\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC }\n ]\n useMaster: false\n ) {\n nodes {\n id\n title\n link\n type\n catalog {\n hasAvcFunctionality\n }\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const DATA_SILO_EXPORT = gql`\n query TranscendCliDataSiloExport(\n $filterBy: DataSiloFiltersInput!\n $first: Int!\n ) {\n dataSilos(filterBy: $filterBy, first: $first, useMaster: false) {\n nodes {\n id\n title\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const DATA_SILOS_ENRICHED = gql`\n query TranscendCliDataSilosEnriched(\n $filterBy: DataSiloFiltersInput!\n $first: Int!\n $offset: Int!\n ) {\n dataSilos(\n filterBy: $filterBy\n first: $first\n offset: $offset\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC }\n ]\n useMaster: false\n ) {\n nodes {\n id\n title\n description\n type\n outerType\n link\n country\n countrySubDivision\n url\n notifyEmailAddress\n attributeValues {\n attributeKey {\n name\n }\n name\n }\n apiKeys {\n title\n }\n subjectBlocklist {\n type\n }\n identifiers {\n name\n isConnected\n }\n dependentDataSilos {\n title\n }\n owners {\n email\n }\n teams {\n id\n name\n }\n catalog {\n hasAvcFunctionality\n }\n isLive\n promptAVendorEmailSendFrequency\n promptAVendorEmailSendType\n promptAVendorEmailIncludeIdentifiersAttachment\n promptAVendorEmailCompletionLinkType\n manualWorkRetryFrequency\n discoveredBy {\n title\n }\n businessEntities {\n title\n }\n }\n }\n }\n`;\n\nexport const UPDATE_DATA_SILOS = gql`\n mutation TranscendCliUpdateDataSilo($input: UpdateDataSilosInput!) {\n updateDataSilos(input: $input) {\n clientMutationId\n dataSilos {\n id\n title\n }\n }\n }\n`;\n\nexport const CREATE_DATA_SILOS = gql`\n mutation TranscendCliCreateDataSilo($input: [CreateDataSilosInput!]!) {\n createDataSilos(input: $input) {\n dataSilos {\n id\n title\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const ENRICHERS = gql`\n query TranscendCliEnrichers($title: String, $first: Int!, $offset: Int!) {\n enrichers(\n filterBy: { text: $title }\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC }\n ]\n ) {\n nodes {\n id\n title\n url\n type\n expirationDuration\n lookerQueryTitle\n testRegex\n transitionRequestStatus\n phoneNumbers\n regionList\n inputIdentifier {\n name\n }\n identifiers {\n name\n }\n dataSubjects {\n type\n }\n actions\n }\n }\n }\n`;\n\nexport interface Initializer {\n /** ID of enricher */\n id: string;\n /** Identifiers */\n identifiers: {\n /** Name of identifier */\n name: string;\n }[];\n}\n\nexport const INITIALIZER = gql`\n query TranscendCliInitializer {\n initializer {\n id\n identifiers {\n name\n }\n }\n }\n`;\n\nexport const CREATE_ENRICHER = gql`\n mutation TranscendCliCreateEnricher($input: EnricherInput!) {\n createEnricher(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_ENRICHER = gql`\n mutation TranscendCliUpdateEnricher($input: UpdateEnricherInput!) {\n updateEnricher(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const CATALOGS = gql`\n query TranscendCliCatalogs($first: Int!, $offset: Int!) {\n catalogs(first: $first, offset: $offset, filterBy: {}, useMaster: false) {\n nodes {\n integrationName\n title\n hasApiFunctionality\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const IDENTIFIERS = gql`\n query TranscendCliIdentifiers($first: Int!, $offset: Int!) {\n identifiers(\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n type\n regex\n selectOptions\n privacyCenterVisibility\n dataSubjects {\n type\n }\n isRequiredInForm\n placeholder\n displayTitle {\n defaultMessage\n }\n displayDescription {\n defaultMessage\n }\n displayOrder\n isUniqueOnPreferenceStore\n }\n }\n }\n`;\n\nexport const NEW_IDENTIFIER_TYPES = gql`\n query TranscendCliNewIdentifierTypes {\n newIdentifierTypes {\n name\n }\n }\n`;\n\nexport const CREATE_IDENTIFIER = gql`\n mutation TranscendCliCreateIdentifier($input: IdentifierInput!) {\n createIdentifier(input: $input) {\n identifier {\n id\n name\n }\n }\n }\n`;\n\nexport const UPDATE_IDENTIFIER = gql`\n mutation TranscendCliUpdateIdentifier($input: UpdateIdentifierInput!) {\n updateIdentifier(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const DATA_SUBJECTS = gql`\n query TranscendCliDataSubjects {\n internalSubjects {\n id\n title {\n defaultMessage\n }\n active\n type\n adminDashboardDefaultSilentMode\n actions {\n type\n }\n }\n }\n`;\n\nexport const CREATE_DATA_SUBJECT = gql`\n mutation TranscendCliCreateDataSubject($type: String!) {\n createSubject(input: { type: $type, title: $type, subjectClass: OTHER }) {\n subject {\n id\n type\n }\n }\n }\n`;\n\nexport const UPDATE_DATA_SUBJECT = gql`\n mutation TranscendCliUpdateDataSubject($input: UpdateSubjectInput!) {\n updateSubject(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const TOGGLE_DATA_SUBJECT = gql`\n mutation TranscendCliToggleDataSubject($input: ToggleSubjectInput!) {\n toggleSubject(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const REPOSITORIES = gql`\n query TranscendCliRepositories(\n $first: Int!\n $offset: Int!\n $input: RepositoryFiltersInput\n ) {\n repositories(\n first: $first\n offset: $offset\n filterBy: $input\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n description\n url\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n }\n }\n }\n`;\n\nexport const UPDATE_REPOSITORIES = gql`\n mutation TranscendCliUpdateRepositories($input: UpdateRepositoriesInput!) {\n updateRepositories(input: $input) {\n clientMutationId\n repositories {\n id\n name\n url\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n }\n }\n }\n`;\n\nexport const CREATE_REPOSITORY = gql`\n mutation TranscendCliCreateRepository($input: CreateRepositoryInput!) {\n createRepository(input: $input) {\n clientMutationId\n repository {\n id\n name\n url\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const API_KEYS = gql`\n query TranscendCliApiKeys($first: Int!, $offset: Int!, $titles: [String!]) {\n apiKeys(\n first: $first\n offset: $offset\n filterBy: { titles: $titles }\n useMaster: false\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC }\n ]\n ) {\n nodes {\n id\n title\n }\n }\n }\n`;\n\nexport const CREATE_API_KEY = gql`\n mutation TranscendCliCreateApiKey($input: ApiKeyInput!) {\n createApiKey(input: $input) {\n apiKey {\n id\n apiKey\n title\n }\n }\n }\n`;\n\nexport const DELETE_API_KEY = gql`\n mutation TranscendCliDeleteApiKey($id: ID!) {\n deleteApiKey(id: $id) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const ADD_SILO_DISCOVERY_RESULTS = gql`\n mutation AddSiloDiscoveryResults(\n $pluginId: ID!\n $rawResults: [SiloDiscoveryRawResultInput!]!\n ) {\n addSiloDiscoveryResults(\n input: { pluginId: $pluginId, rawResults: $rawResults }\n ) {\n success\n }\n }\n`;\n\nexport const ENABLED_PLUGINS = gql`\n query Plugins($dataSiloId: String!, $type: PluginType!) {\n plugins(filterBy: { dataSiloId: $dataSiloId, type: $type, enabled: true }) {\n plugins {\n id\n dataSilo {\n type\n }\n }\n totalCount\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const TEMPLATES = gql`\n query TranscendCliTemplates($title: String, $first: Int!, $offset: Int!) {\n templates(\n filterBy: { text: $title }\n first: $first\n offset: $offset\n useMaster: false\n ) {\n nodes {\n id\n title\n subject {\n defaultMessage\n }\n template {\n defaultMessage\n }\n }\n }\n }\n`;\n\nexport const CREATE_TEMPLATE = gql`\n mutation TranscendCliCreateTemplate($title: String!) {\n createTemplate(input: { title: $title, template: \"\", subject: $title }) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const ORGANIZATION = gql`\n query TranscendCliOrganization {\n organization {\n sombra {\n customerUrl\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\nexport const ATTRIBUTE_KEYS_REQUESTS = gql`\n query TranscendCliAttributeKeys($first: Int!, $offset: Int!) {\n attributeKeys(\n filterBy: { enabledOn: [request] }\n first: $first\n useMaster: false\n offset: $offset\n ) {\n nodes {\n id\n name\n type\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const SOFTWARE_DEVELOPMENT_KITS = gql`\n query TranscendCliSoftwareDevelopmentKits(\n $first: Int!\n $offset: Int!\n $input: SoftwareDevelopmentKitFiltersInput\n ) {\n softwareDevelopmentKits(\n first: $first\n offset: $offset\n filterBy: $input\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n description\n codePackageType\n documentationLinks\n repositoryUrl\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n }\n }\n }\n`;\n\nexport const UPDATE_SOFTWARE_DEVELOPMENT_KITS = gql`\n mutation TranscendCliUpdateSoftwareDevelopmentKits(\n $input: UpdateSoftwareDevelopmentKitsInput!\n ) {\n updateSoftwareDevelopmentKits(input: $input) {\n clientMutationId\n softwareDevelopmentKits {\n id\n name\n description\n codePackageType\n documentationLinks\n repositoryUrl\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n }\n }\n }\n`;\n\nexport const CREATE_SOFTWARE_DEVELOPMENT_KIT = gql`\n mutation TranscendCliCreateSoftwareDevelopmentKit(\n $input: CreateSoftwareDevelopmentKitInput!\n ) {\n createSoftwareDevelopmentKit(input: $input) {\n clientMutationId\n softwareDevelopmentKit {\n id\n name\n description\n codePackageType\n documentationLinks\n repositoryUrl\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const CODE_PACKAGES = gql`\n query TranscendCliCodePackages(\n $first: Int!\n $offset: Int!\n $input: CodePackageFiltersInput\n ) {\n codePackages(\n first: $first\n offset: $offset\n filterBy: $input\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n description\n type\n relativePath\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n repository {\n id\n name\n }\n dataSilo {\n id\n title\n type\n }\n }\n }\n }\n`;\n\nexport const UPDATE_CODE_PACKAGES = gql`\n mutation TranscendCliUpdateCodePackages($input: UpdateCodePackagesInput!) {\n updateCodePackages(input: $input) {\n clientMutationId\n codePackages {\n id\n name\n description\n type\n relativePath\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n repository {\n id\n name\n }\n dataSilo {\n id\n title\n type\n }\n }\n }\n }\n`;\n\nexport const CREATE_CODE_PACKAGE = gql`\n mutation TranscendCliCreateCodePackage($input: CreateCodePackageInput!) {\n createCodePackage(input: $input) {\n clientMutationId\n codePackage {\n id\n name\n description\n type\n relativePath\n teams {\n id\n name\n }\n owners {\n id\n email\n }\n repository {\n id\n name\n }\n dataSilo {\n id\n title\n type\n }\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const PROMPT_THREADS = gql`\n query TranscendCliPromptThreads(\n $first: Int!\n $offset: Int!\n $filterBy: PromptThreadFiltersInput!\n ) {\n promptThreads(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n threadId\n slackMessageTs\n slackTeamId\n slackChannelId\n slackChannelName\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const POLICIES = gql`\n query TranscendCliFetchPolicies($url: String!) {\n privacyCenterPolicies(lookup: { url: $url }) {\n id\n title {\n defaultMessage\n }\n disableEffectiveOn\n disabledLocales\n versions {\n effectiveOn\n content {\n defaultMessage\n }\n }\n }\n }\n`;\n\nexport const UPDATE_POLICIES = gql`\n mutation TranscendCliUpdatePolicies(\n $policies: [PolicyInput!]!\n $privacyCenterId: ID!\n ) {\n updatePolicies(\n input: {\n privacyCenterId: $privacyCenterId\n policies: $policies\n skipPublish: true\n }\n ) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const REQUESTS = gql`\n query TranscendCliRequests(\n $first: Int!\n $offset: Int!\n $filterBy: RequestFiltersInput!\n ) {\n requests(\n filterBy: $filterBy\n first: $first\n offset: $offset\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: id, direction: ASC }\n ]\n useMaster: false\n ) {\n nodes {\n id\n createdAt\n email\n link\n status\n details\n isTest\n locale\n origin\n isSilent\n coreIdentifier\n daysRemaining\n type\n subjectType\n country\n countrySubDivision\n attributeValues {\n id\n name\n attributeKey {\n id\n name\n }\n }\n }\n totalCount\n }\n }\n`;\n\nexport const APPROVE_PRIVACY_REQUEST = gql`\n mutation TranscendCliApprovePrivacyRequest($input: CommunicationInput!) {\n approveRequest(input: $input) {\n request {\n id\n }\n }\n }\n`;\nexport const CANCEL_PRIVACY_REQUEST = gql`\n mutation TranscendCliCancelPrivacyRequest($input: CommunicationInput!) {\n cancelRequest(input: $input) {\n request {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_PRIVACY_REQUEST = gql`\n mutation TranscendCliUpdatePrivacyRequest($input: UpdateRequestInput!) {\n updateRequest(input: $input) {\n request {\n id\n }\n }\n }\n`;\n\nexport const NOTIFY_ADDITIONAL_TIME = gql`\n mutation TranscendCliNotifyAdditionalTime($input: AdditionalTimeInput!) {\n notifyAdditionalTime(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const MESSAGES = gql`\n query TranscendCliFetchMessage {\n translatedMessages {\n id\n defaultMessage\n targetReactIntlId\n translations {\n locale\n value\n }\n }\n }\n`;\n\nexport const UPDATE_INTL_MESSAGES = gql`\n mutation TranscendCliUpdateIntlMessages($messages: [MessageInput!]!) {\n updateIntlMessages(input: { messages: $messages, skipPublish: true }) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const REQUEST_ENRICHERS = gql`\n query TranscendCliRequestEnrichers(\n $first: Int!\n $offset: Int!\n $requestId: ID!\n ) {\n requestEnrichers(\n input: { requestId: $requestId }\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC, model: enricher }\n ]\n ) {\n nodes {\n id\n status\n enricher {\n id\n type\n title\n }\n }\n totalCount\n }\n }\n`;\n\nexport const RETRY_REQUEST_ENRICHER = gql`\n mutation TranscendCliRetryRequestEnricher($requestEnricherId: ID!) {\n retryRequestEnricher(id: $requestEnricherId) {\n requestEnricher {\n id\n }\n }\n }\n`;\n\nexport const SKIP_REQUEST_ENRICHER = gql`\n mutation TranscendCliSkipRequestEnricher($requestEnricherId: ID!) {\n skipRequestEnricher(id: $requestEnricherId) {\n requestEnricher {\n id\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const ASSESSMENT_SECTION_FIELDS = `\n id\n title\n status\n index\n questions {\n id\n title\n index\n type\n subType\n placeholder\n description\n isRequired\n displayLogic\n riskLogic\n requireRiskEvaluation\n requireRiskMatrixEvaluation\n riskCategories {\n id\n title\n }\n riskFramework {\n id\n title\n description\n riskLevels {\n id\n title\n }\n riskCategories {\n id\n title\n }\n riskMatrixColumns {\n id\n title\n }\n riskMatrixRows {\n id\n title\n }\n riskMatrix {\n id\n title\n }\n creator {\n id\n email\n name\n }\n riskMatrixRowTitle\n riskMatrixColumnTitle\n }\n riskLevel {\n id\n title\n }\n reviewerRiskLevel {\n id\n title\n }\n riskLevelFromRiskMatrix {\n id\n title\n }\n answerOptions {\n id\n index\n value\n }\n selectedAnswers {\n ... on AssessmentAnswerInterface {\n id\n index\n value\n }\n }\n respondent {\n id\n email\n name\n }\n attributeKey {\n name\n }\n externalRespondentEmail\n comments {\n id\n content\n createdAt\n updatedAt\n author {\n id\n email\n name\n }\n }\n allowedMimeTypes\n updatedAt\n referenceId\n previousSubmissions {\n id\n updatedAt\n assessmentQuestionId\n answers {\n ... on AssessmentAnswerInterface {\n id\n index\n value\n }\n }\n }\n allowSelectOther\n syncModel\n syncColumn\n syncRowIds\n syncOverride\n }\n assignees {\n id\n email\n name\n }\n externalAssignees {\n id\n email\n }\n isReviewed\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: name, direction: ASC }\n// ]\nexport const ASSESSMENTS = gql`\n query TranscendCliAssessments(\n $first: Int!\n $offset: Int!\n $filterBy: AssessmentFormFiltersInput\n ) {\n assessmentForms(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n creator {\n id\n email\n name\n }\n lastEditor {\n id\n email\n name\n }\n title\n description\n status\n assignees {\n id\n email\n name\n }\n externalAssignees {\n id\n email\n }\n reviewers {\n id\n email\n name\n }\n isLocked\n isArchived\n isExternallyCreated\n dueDate\n createdAt\n updatedAt\n assignedAt\n submittedAt\n approvedAt\n rejectedAt\n titleIsInternal\n retentionSchedule {\n id\n type\n durationDays\n operation\n }\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n sections {\n ${ASSESSMENT_SECTION_FIELDS}\n }\n assessmentGroup {\n id\n title\n description\n }\n resources {\n resourceType\n ... on AttributeBusinessEntityResource {\n id\n title\n }\n ... on AttributeDataSiloResource {\n id\n title\n }\n ... on AttributeDataSubCategoryResource {\n id\n name\n category\n }\n ... on AttributeSubDataPointResource {\n id\n name\n }\n ... on AttributeProcessingPurposeSubCategoryResource {\n id\n name\n purpose\n }\n ... on AttributeRequestResource {\n id\n type\n }\n ... on AttributeVendorResource {\n id\n title\n }\n ... on AttributePromptResource {\n id\n title\n }\n ... on AttributePromptRunResource {\n id\n title\n }\n ... on AttributePromptGroupResource {\n id\n title\n }\n }\n syncedRows {\n resourceType\n ... on AttributeBusinessEntityResource {\n id\n title\n }\n ... on AttributeDataSiloResource {\n id\n title\n }\n ... on AttributeDataSubCategoryResource {\n id\n name\n category\n }\n ... on AttributeSubDataPointResource {\n id\n name\n }\n ... on AttributeProcessingPurposeSubCategoryResource {\n id\n name\n purpose\n }\n ... on AttributeVendorResource {\n id\n title\n }\n }\n }\n }\n }\n`;\n\nexport const IMPORT_ONE_TRUST_ASSESSMENT_FORMS = gql`\n mutation TranscendCliImportOneTrustAssessmentForms(\n $input: ImportOnetrustAssessmentsInput!\n ) {\n importOneTrustAssessmentForms(input: $input) {\n assessmentForms {\n id\n title\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: name, direction: ASC }\n// ]\nexport const PURPOSES = gql`\n query TranscendCliPurposes(\n $first: Int!\n $offset: Int!\n $filterBy: TrackingPurposeFiltersInput\n $input: TrackingPurposeInput!\n ) {\n purposes(\n first: $first\n offset: $offset\n filterBy: $filterBy\n input: $input\n ) {\n nodes {\n id\n name\n description\n defaultConsent\n trackingType\n configurable\n essential\n showInConsentManager\n isActive\n displayOrder\n optOutSignals\n deletedAt\n authLevel\n showInPrivacyCenter\n title\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: name, direction: ASC }\n// ]\nexport const PREFERENCE_TOPICS = gql`\n query TranscendCliPreferenceTopics(\n $first: Int!\n $offset: Int!\n $filterBy: PreferenceTopicFilterInput\n ) {\n preferenceTopics(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n slug\n type\n title {\n id\n defaultMessage\n }\n showInPrivacyCenter\n displayDescription {\n id\n defaultMessage\n }\n defaultConfiguration\n preferenceOptionValues {\n slug\n title {\n id\n defaultMessage\n }\n }\n purpose {\n trackingType\n }\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\nimport { ASSESSMENT_SECTION_FIELDS } from './assessment';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: name, direction: ASC }\n// ]\nexport const ASSESSMENT_TEMPLATES = gql`\n query TranscendCliAssessmentTemplates(\n $first: Int!\n $offset: Int!\n $filterBy: AssessmentFormTemplateFiltersInput\n ) {\n assessmentFormTemplates(\n first: $first\n offset: $offset\n filterBy: $filterBy\n ) {\n nodes {\n id\n creator {\n id\n email\n name\n }\n lastEditor {\n id\n email\n name\n }\n title\n description\n status\n source\n parentId\n isLocked\n isArchived\n createdAt\n updatedAt\n retentionSchedule {\n id\n type\n durationDays\n operation\n createdAt\n updatedAt\n }\n assessmentEmailSet {\n id\n title\n description\n isDefault\n templates {\n id\n title\n }\n }\n sections {\n ${ASSESSMENT_SECTION_FIELDS}\n }\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const PROMPTS = gql`\n query TranscendCliPrompts(\n $first: Int!\n $offset: Int!\n $filterBy: PromptFiltersInput\n ) {\n prompts(\n first: $first\n orderBy: [{ field: title, direction: ASC }]\n offset: $offset\n filterBy: $filterBy\n ) {\n nodes {\n id\n title\n status\n content\n temperature\n topP\n maxTokensToSample\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// orderBy: [{ field: title, direction: ASC }]\nexport const PROMPT_PARTIALS = gql`\n query TranscendCliPromptPartials($first: Int!, $offset: Int!) {\n promptPartials(first: $first, offset: $offset) {\n nodes {\n id\n title\n content\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// orderBy: [{ field: title, direction: ASC }]\nexport const PROMPT_GROUPS = gql`\n query TranscendCliPromptGroups($first: Int!, $offset: Int!) {\n promptGroups(\n first: $first\n\n offset: $offset\n ) {\n nodes {\n id\n title\n description\n prompts {\n title\n }\n }\n }\n }\n`;\n\nexport const PROMPTS_WITH_VARIABLES = gql`\n query TranscendCliPromptsWithVariables($input: PromptsWithVariablesInput!) {\n promptsWithVariables(input: $input) {\n prompts {\n id\n title\n content\n status\n temperature\n topP\n maxTokensToSample\n responseFormat\n }\n promptPartials {\n id\n title\n content\n slug\n }\n calculatedVariables {\n data\n name\n }\n runtimeVariables {\n name\n }\n }\n }\n`;\n\nexport const UPDATE_PROMPTS = gql`\n mutation TranscendCliUpdatePrompts($input: UpdatePromptsInput!) {\n updatePrompts(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const CREATE_PROMPT = gql`\n mutation TranscendCliCreatePrompt($input: CreatePromptInput!) {\n createPrompt(input: $input) {\n clientMutationId\n prompt {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_PROMPT_PARTIALS = gql`\n mutation TranscendCliUpdatePromptPartials(\n $input: UpdatePromptPartialsInput!\n ) {\n updatePromptPartials(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const CREATE_PROMPT_PARTIAL = gql`\n mutation TranscendCliCreatePromptPartial($input: CreatePromptPartialInput!) {\n createPromptPartial(input: $input) {\n clientMutationId\n promptPartial {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_PROMPT_GROUPS = gql`\n mutation TranscendCliUpdatePromptGroups($input: UpdatePromptGroupsInput!) {\n updatePromptGroups(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const CREATE_PROMPT_GROUP = gql`\n mutation TranscendCliCreatePromptPartial($input: CreatePromptGroupInput!) {\n createPromptGroup(input: $input) {\n clientMutationId\n promptGroup {\n id\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const REQUEST_DATA_SILOS = gql`\n query TranscendCliRequestDataSilos(\n $first: Int!\n $offset: Int!\n $filterBy: RequestDataSiloFiltersInput!\n ) {\n requestDataSilos(\n filterBy: $filterBy\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [\n { field: createdAt, direction: DESC }\n { field: title, direction: ASC, model: dataSilo }\n ]\n ) {\n nodes {\n id\n }\n totalCount\n }\n }\n`;\n\nexport const CHANGE_REQUEST_DATA_SILO_STATUS = gql`\n mutation TranscendCliMarkRequestDataSiloCompleted(\n $requestDataSiloId: ID!\n $status: UpdateRequestDataSiloStatus!\n ) {\n changeRequestDataSiloStatus(\n input: { id: $requestDataSiloId, status: $status }\n ) {\n requestDataSilo {\n id\n }\n }\n }\n`;\n\nexport const RETRY_REQUEST_DATA_SILO = gql`\n mutation TranscendCliRetryRequestDataSilo($requestDataSiloId: ID!) {\n retryRequestDataSilo(id: $requestDataSiloId) {\n requestDataSilo {\n id\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: DESC }\n// { field: title, direction: ASC, model: dataSilo }\n// ]\nexport const REDUCED_REQUESTS_FOR_DATA_SILO_COUNT = gql`\n query TranscendCliListReducedRequestsForDataSiloCount(\n $input: BulkCompletionReducedRequestInput!\n ) {\n listReducedRequestsForDataSilo(input: $input) {\n totalCount\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const TEAMS = gql`\n query TranscendCliTeams(\n $first: Int!\n $offset: Int!\n $input: TeamFiltersInput\n ) {\n teams(\n first: $first\n offset: $offset\n filterBy: $input\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n description\n ssoDepartment\n ssoGroup\n ssoTitle\n users {\n id\n email\n name\n }\n scopes {\n id\n name\n title\n }\n }\n }\n }\n`;\n\nexport const CREATE_TEAM = gql`\n mutation TranscendCliCreateTeam($input: TeamInput!) {\n createTeam(input: $input) {\n team {\n id\n name\n }\n }\n }\n`;\n\nexport const UPDATE_TEAM = gql`\n mutation TranscendCliUpdateTeam($input: UpdateTeamInput!) {\n updateTeam(input: $input) {\n team {\n id\n name\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const REMOVE_REQUEST_IDENTIFIERS = gql`\n mutation TranscendCliRemoveRequestIdentifiers(\n $input: RemoveRequestIdentifiersInput!\n ) {\n removeRequestIdentifiers(input: $input) {\n count\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const REQUEST_IDENTIFIERS = gql`\n query TranscendCliRequestIdentifiers(\n $first: Int!\n $offset: Int!\n $requestIds: [ID!]!\n ) {\n requestIdentifiers(\n input: { requestIds: $requestIds }\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n isVerifiedAtLeastOnce\n }\n totalCount\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const USERS = gql`\n query TranscendCliUsers(\n $first: Int!\n $offset: Int!\n $input: UserFiltersInput\n ) {\n users(\n first: $first\n offset: $offset\n filterBy: $input\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n email\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const REQUEST_FILES = gql`\n query TranscendCliRequestFiles(\n $first: Int!\n $offset: Int!\n $filterBy: RequestFileFiltersInput!\n ) {\n requestFiles(\n filterBy: $filterBy\n first: $first\n offset: $offset\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: id, direction: ASC }\n ]\n ) {\n nodes {\n remoteId\n fileName\n }\n }\n }\n`;\n\nexport const BULK_REQUEST_FILES = gql`\n query TranscendCliBulkRequestFiles(\n $filterBy: BulkRequestFilesFiltersInput!\n $first: Int!\n $after: String\n ) {\n bulkRequestFiles(filterBy: $filterBy, first: $first, after: $after) {\n nodes {\n remoteId\n fileName\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const REPORT_PROMPT_RUN = gql`\n mutation TranscendCliReportPromptRun($input: ReportPromptRunInput!) {\n reportPromptRun(input: $input) {\n clientMutationId\n promptRun {\n id\n }\n }\n }\n`;\n\nexport const ADD_MESSAGES_TO_PROMPT_RUN = gql`\n mutation TranscendCliAddMessagesToPromptRun(\n $input: AddMessagesToPromptRunInput!\n ) {\n addMessagesToPromptRun(input: $input) {\n clientMutationId\n promptRun {\n id\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: title, direction: ASC }\n// ]\nexport const GLOBAL_ACTION_ITEM_COLLECTIONS = gql`\n query TranscendCliGlobalActionItemCollectionss(\n $filterBy: GlobalActionItemCollectionFiltersInput!\n ) {\n globalActionItemCollections(filterBy: $filterBy) {\n nodes {\n id\n title\n description\n hidden\n productLine\n }\n }\n }\n`;\n\nexport const CREATE_ACTION_ITEM_COLLECTION = gql`\n mutation TranscendCliCreateActionItemCollection(\n $input: CreateActionItemCollectionInput!\n ) {\n createActionItemCollection(input: $input) {\n created {\n id\n title\n }\n }\n }\n`;\n\nexport const UPDATE_ACTION_ITEM_COLLECTION = gql`\n mutation TranscendCliUpdateActionItemCollection(\n $input: UpdateActionItemCollectionInput!\n ) {\n updateActionItemCollection(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const ATTRIBUTES = gql`\n query TranscendCliAttributes($first: Int!, $offset: Int!) {\n attributeKeys(first: $first, offset: $offset, useMaster: false) {\n nodes {\n id\n isCustom\n description\n enabledOn\n name\n type\n }\n }\n }\n`;\n\nexport const CREATE_ATTRIBUTE_VALUES = gql`\n mutation TranscendCliCreateAttributeValues(\n $input: [CreateAttributeValuesInput!]!\n ) {\n createAttributeValues(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_ATTRIBUTE_VALUES = gql`\n mutation TranscendCliUpdateAttributeValues(\n $input: [UpdateAttributeValueInput!]!\n ) {\n updateAttributeValues(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const DELETE_ATTRIBUTE_VALUE = gql`\n mutation TranscendCliDeleteAttributeValue($id: ID!) {\n deleteAttributeValue(id: $id) {\n clientMutationId\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const ATTRIBUTE_VALUES = gql`\n query TranscendCliAttributeValues(\n $first: Int!\n $offset: Int!\n $attributeKeyId: ID!\n ) {\n attributeValues(\n first: $first\n offset: $offset\n useMaster: false\n filterBy: { attributeKeys: [$attributeKeyId] }\n ) {\n nodes {\n id\n name\n description\n color\n }\n }\n }\n`;\n\nexport const CREATE_ATTRIBUTE = gql`\n mutation TranscendCliCreateAttribute(\n $name: String!\n $type: AttributeKeyType!\n $description: String\n $enabledOn: [AttributeSupportedResourceType!]\n ) {\n createAttributeKey(\n input: {\n name: $name\n type: $type\n description: $description\n enabledOn: $enabledOn\n }\n ) {\n clientMutationId\n attributeKey {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_ATTRIBUTE = gql`\n mutation TranscendCliCreateAttribute(\n $attributeKeyId: ID!\n $description: String\n $enabledOn: [AttributeSupportedResourceType!]\n ) {\n updateAttributeKey(\n input: {\n id: $attributeKeyId\n description: $description\n enabledOn: $enabledOn\n }\n ) {\n clientMutationId\n attributeKey {\n id\n }\n }\n }\n`;\n\nexport const SET_RESOURCE_ATTRIBUTES = gql`\n mutation TranscendCliSetResourceAttributes(\n $input: SetResourceAttributesInput!\n ) {\n setResourceAttributes(input: $input) {\n clientMutationId\n }\n }\n`;\n","/* eslint-disable max-lines */\nimport { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const EXPERIENCES = gql`\n query TranscendCliExperiences($first: Int!, $offset: Int!) {\n experiences(first: $first, offset: $offset, useMaster: false) {\n nodes {\n id\n name\n displayName\n regions {\n countrySubDivision\n country\n }\n operator\n displayPriority\n onConsentExpiry\n consentExpiry\n viewState\n purposes {\n name\n trackingType\n }\n optedOutPurposes {\n name\n trackingType\n }\n browserLanguages\n browserTimeZones\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// useMaster: false\n// isExportCsv: true\nexport const CONSENT_PARTITIONS = gql`\n query TranscendCliConsentPartitions($first: Int!, $offset: Int!) {\n consentPartitions(first: $first, offset: $offset) {\n nodes {\n id\n name\n partition\n }\n }\n }\n`;\n\nexport const CREATE_DATA_FLOWS = gql`\n mutation TranscendCliCreateDataFlows(\n $dataFlows: [DataFlowInput!]!\n $airgapBundleId: ID!\n $classifyService: Boolean\n ) {\n createDataFlows(\n input: {\n airgapBundleId: $airgapBundleId\n dataFlows: $dataFlows\n classifyService: $classifyService\n }\n ) {\n dataFlows {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_DATA_FLOWS = gql`\n mutation TranscendCliUpdateDataFlows(\n $airgapBundleId: ID!\n $dataFlows: [UpdateDataFlowInput!]!\n $classifyService: Boolean\n ) {\n updateDataFlows(\n input: {\n airgapBundleId: $airgapBundleId\n dataFlows: $dataFlows\n classifyService: $classifyService\n }\n ) {\n dataFlows {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_OR_CREATE_COOKIES = gql`\n mutation TranscendCliUpdateOrCreateCookies(\n $cookies: [UpdateOrCreateCookieInput!]!\n $airgapBundleId: ID!\n ) {\n updateOrCreateCookies(\n input: { airgapBundleId: $airgapBundleId, cookies: $cookies }\n ) {\n clientMutationId\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const DATA_FLOWS = gql`\n query TranscendCliDataFlows(\n $first: Int!\n $airgapBundleId: ID!\n $offset: Int!\n $status: ConsentTrackerStatus\n $showZeroActivity: Boolean\n ) {\n dataFlows(\n first: $first\n offset: $offset\n filterBy: { status: $status, showZeroActivity: $showZeroActivity }\n input: { airgapBundleId: $airgapBundleId }\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: value, direction: ASC }\n ]\n useMaster: false\n ) {\n nodes {\n id\n value\n type\n description\n trackingType\n service {\n integrationName\n }\n source\n status\n owners {\n email\n }\n teams {\n name\n }\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n }\n }\n }\n`;\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const COOKIES = gql`\n query TranscendCliCookies(\n $first: Int!\n $offset: Int!\n $airgapBundleId: ID!\n $status: ConsentTrackerStatus\n ) {\n cookies(\n first: $first\n offset: $offset\n filterBy: { status: $status }\n input: { airgapBundleId: $airgapBundleId }\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n useMaster: false\n ) {\n nodes {\n id\n name\n isRegex\n description\n trackingPurposes\n service {\n integrationName\n }\n source\n status\n owners {\n email\n }\n teams {\n name\n }\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n }\n }\n }\n`;\n\nexport const FETCH_CONSENT_MANAGER_ID = gql`\n query TranscendCliFetchConsentManagerId {\n consentManager {\n consentManager {\n id\n }\n }\n }\n`;\n\nexport const FETCH_CONSENT_MANAGER = gql`\n query TranscendCliFetchConsentManager {\n consentManager {\n consentManager {\n id\n bundleURL\n testBundleURL\n configuration {\n domains\n consentPrecedence\n unknownRequestPolicy\n unknownCookiePolicy\n syncEndpoint\n telemetryPartitioning\n signedIabAgreement\n syncGroups\n partition\n }\n partition {\n partition\n }\n }\n }\n }\n`;\n\nexport const FETCH_CONSENT_MANAGER_THEME = gql`\n query TranscendCliFetchConsentManagerTheme($airgapBundleId: ID!) {\n consentManagerTheme(input: { airgapBundleId: $airgapBundleId }) {\n theme {\n primaryColor\n fontColor\n privacyPolicy\n prompt\n }\n }\n }\n`;\n\nexport const CREATE_CONSENT_MANAGER = gql`\n mutation TranscendCliCreateConsentManager($privacyCenterId: ID!) {\n createConsentManager(input: { privacyCenterId: $privacyCenterId }) {\n consentManager {\n id\n }\n }\n }\n`;\n\nexport const UPDATE_CONSENT_MANAGER_VERSION = gql`\n mutation TranscendCliUpdateConsentManager(\n $airgapBundleId: ID!\n $version: String!\n ) {\n updateConsentManager(id: $airgapBundleId, input: { version: $version }) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_CONSENT_MANAGER_TO_LATEST = gql`\n mutation TranscendCliUpdateConsentManagerToLatest(\n $airgapBundleId: ID!\n $bundleType: ConsentBundleType!\n ) {\n updateConsentManagerToLatestVersion(\n id: $airgapBundleId\n input: { bundleType: $bundleType }\n ) {\n clientMutationId\n }\n }\n`;\n\nexport const DEPLOY_CONSENT_MANAGER = gql`\n mutation TranscendCliDeployConsentManager(\n $airgapBundleId: ID!\n $bundleType: ConsentBundleType!\n ) {\n deployConsentManagerBundle(\n id: $airgapBundleId\n input: { bundleType: $bundleType }\n ) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_CONSENT_MANAGER_DOMAINS = gql`\n mutation TranscendCliUpdateConsentManagerDomains(\n $airgapBundleId: ID!\n $domains: [String!]!\n ) {\n updateConsentManagerDomains(\n input: { id: $airgapBundleId, domains: $domains }\n ) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_CONSENT_MANAGER_PARTITION = gql`\n mutation TranscendCliUpdateConsentManagerPartition(\n $airgapBundleId: ID!\n $partitionId: ID!\n ) {\n updateConsentManagerPartition(\n input: { id: $airgapBundleId, partitionId: $partitionId }\n ) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_LOAD_OPTIONS = gql`\n mutation TranscendCliUpdateLoadOptions($input: UpdateLoadOptionsInput!) {\n updateLoadOptions(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const TOGGLE_UNKNOWN_REQUEST_POLICY = gql`\n mutation TranscendCliToggleUnknownRequestPolicy(\n $input: ToggleUnknownRequestPolicyInput!\n ) {\n toggleUnknownRequestPolicy(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const TOGGLE_UNKNOWN_COOKIE_POLICY = gql`\n mutation TranscendCliToggleUnknownCookiePolicy(\n $input: ToggleUnknownCookiePolicyInput!\n ) {\n toggleUnknownCookiePolicy(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const TOGGLE_TELEMETRY_PARTITION_STRATEGY = gql`\n mutation TranscendCliToggleTelemetryPartitionStrategy(\n $input: ToggleTelemetryPartitionStrategyInput!\n ) {\n toggleTelemetryPartitioning(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const TOGGLE_CONSENT_PRECEDENCE = gql`\n mutation TranscendCliToggleConsentPrecedence(\n $input: ToggleConsentPrecedenceInput!\n ) {\n toggleConsentPrecedence(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_CONSENT_MANAGER_THEME = gql`\n mutation TranscendCliUpdateConsentManagerTheme(\n $input: UpdateConsentManagerThemeInput!\n ) {\n updateConsentManagerTheme(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const UPDATE_CONSENT_EXPERIENCE = gql`\n mutation TranscendCliUpdateConsentExperience($input: UpdateExperienceInput!) {\n updateExperience(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const CREATE_CONSENT_EXPERIENCE = gql`\n mutation TranscendCliCreateConsentExperience($input: CreateExperienceInput!) {\n createExperience(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const CREATE_CONSENT_PARTITION = gql`\n mutation TranscendCliCreateConsentPartition(\n $input: CreateConsentPartitionInput!\n ) {\n createConsentPartition(input: $input) {\n clientMutationId\n }\n }\n`;\n/* eslint-enable max-lines */\n","import { gql } from 'graphql-request';\n\nexport const CONSENT_MANAGER_ANALYTICS_DATA = gql`\n query TranscendCliConsentManagerAnalyticsData($input: AnalyticsInput!) {\n analyticsData(input: $input) {\n series {\n name\n points {\n key\n value\n }\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\nexport const BUSINESS_ENTITIES = gql`\n query TranscendCliBusinessEntities($first: Int!, $offset: Int!) {\n businessEntities(\n first: $first\n offset: $offset\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC }\n ]\n useMaster: false\n ) {\n nodes {\n id\n title\n description\n dataProtectionOfficerName\n dataProtectionOfficerEmail\n address\n headquarterCountry\n headquarterSubDivision\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n }\n }\n }\n`;\n\nexport const CREATE_BUSINESS_ENTITY = gql`\n mutation TranscendCliCreateBusinessEntity(\n $input: CreateBusinessEntityInput!\n ) {\n createBusinessEntity(input: $input) {\n businessEntity {\n id\n title\n description\n dataProtectionOfficerName\n dataProtectionOfficerEmail\n address\n headquarterCountry\n headquarterSubDivision\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n }\n }\n }\n`;\n\nexport const UPDATE_BUSINESS_ENTITIES = gql`\n mutation TranscendCliUpdateBusinessEntities(\n $input: [UpdateBusinessEntityInput!]!\n ) {\n updateBusinessEntities(input: { businessEntities: $input }) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// TODO: https://transcend.height.app/T-27909 - order by createdAt\nexport const ACTIONS = gql`\n query TranscendCliActions($first: Int!, $offset: Int!) {\n actions(\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [{ field: type, direction: ASC }]\n ) {\n nodes {\n id\n type\n skipSecondaryIfNoFiles\n skipDownloadableStep\n requiresReview\n regionList\n regionDetectionMethod\n waitingPeriod\n }\n }\n }\n`;\n\nexport const UPDATE_ACTION = gql`\n mutation TranscendCliUpdateAction($input: UpdateActionInput!) {\n updateAction(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: title, direction: ASC }\n// ]\nexport const GLOBAL_ACTION_ITEMS = gql`\n query TranscendCliGlobalActionItems(\n $first: Int!\n $offset: Int!\n $filterBy: GlobalActionItemFiltersInput!\n ) {\n globalActionItems(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n ids\n count\n teams {\n id\n name\n }\n customerExperienceActionItemIds\n users {\n id\n email\n }\n collections {\n title\n id\n }\n dueDate\n priority\n titles\n resolved\n notes\n links\n type\n additionalContexts {\n iconOverride\n requestId\n dataSiloId\n requestType\n latestAirgapVersion\n parentTitle\n }\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n }\n }\n }\n`;\n\nexport const UPDATE_ACTION_ITEMS = gql`\n mutation TranscendCliUpdateActionItems($input: UpdateActionItemsInput!) {\n updateActionItems(input: $input) {\n clientMutationId\n }\n }\n`;\n\nexport const CREATE_ACTION_ITEMS = gql`\n mutation TranscendCliCreateActionItems($input: [CreateActionItemsInput!]!) {\n createActionItems(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const FETCH_PRIVACY_CENTER_ID = gql`\n query TranscendCliFetchPrivacyCenterId($url: String!) {\n privacyCenter(lookup: { url: $url }) {\n id\n }\n }\n`;\n\nexport const DEPLOYED_PRIVACY_CENTER_URL = gql`\n query TranscendCliDeployedPrivacyCenterUrl {\n organization {\n deployedPrivacyCenterUrl\n }\n }\n`;\n\nexport const PRIVACY_CENTER = gql`\n query TranscendCliFetchPrivacyCenters($url: String!) {\n privacyCenter(lookup: { url: $url }) {\n id\n url\n isDisabled\n showPrivacyRequestButton\n showPolicies\n showTrackingTechnologies\n showCookies\n showDataFlows\n showConsentManager\n showManageYourPrivacy\n showMarketingPreferences\n locales\n defaultLocale\n preferBrowserDefaultLocale\n supportEmail\n replyToEmail\n useNoReplyEmailAddress\n useCustomEmailDomain\n transformAccessReportJsonToCsv\n themeStr\n }\n }\n`;\n\nexport const UPDATE_PRIVACY_CENTER = gql`\n mutation TranscendCliUpdatePrivacyCenter($input: UpdatePrivacyCenterInput!) {\n updatePrivacyCenter(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const DETERMINE_LOGIN_METHOD = gql`\n mutation TranscendCliDetermineLoginMethod($email: String!) {\n determineLoginMethod(input: { email: $email }) {\n loginMethod {\n email\n sombraPublicKey\n }\n }\n }\n`;\n\nexport const LOGIN = gql`\n mutation TranscendCliLogin(\n $email: String!\n $password: String!\n $publicKey: String!\n ) {\n login(\n input: { email: $email, password: $password }\n publicKey: $publicKey\n ) {\n user {\n roles {\n id\n organization {\n name\n id\n uri\n parentOrganizationId\n }\n }\n }\n }\n }\n`;\n\nexport const ASSUME_ROLE = gql`\n mutation TranscendCliAssumeRole($id: ID!, $publicKey: String!) {\n assumeRole(id: $id, publicKey: $publicKey) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const LARGE_LANGUAGE_MODELS = gql`\n query TranscendCliLargeLanguageModels(\n $first: Int!\n $offset: Int!\n $filterBy: LargeLanguageModelFiltersInput\n ) {\n largeLanguageModels(\n first: $first\n orderBy: [\n { field: name, direction: ASC }\n { field: client, direction: ASC }\n { field: isTranscendHosted, direction: ASC }\n ]\n offset: $offset\n filterBy: $filterBy\n ) {\n nodes {\n id\n name\n client\n isTranscendHosted\n }\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const AGENTS = gql`\n query TranscendCliAgents(\n $first: Int!\n $offset: Int!\n $filterBy: AgentFiltersInput\n ) {\n agents(\n first: $first\n offset: $offset\n filterBy: $filterBy\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n agentId\n instructions\n description\n codeInterpreterEnabled\n retrievalEnabled\n prompt {\n title\n }\n largeLanguageModel {\n name\n client\n }\n teams {\n name\n }\n owners {\n email\n }\n agentFunctions {\n name\n }\n agentFiles {\n name\n }\n }\n }\n }\n`;\n\nexport const CREATE_AGENT = gql`\n mutation TranscendCliCreateAgent($input: CreateAgentInput!) {\n createAgent(input: $input) {\n agent {\n id\n name\n agentId\n }\n }\n }\n`;\n\nexport const UPDATE_AGENTS = gql`\n mutation TranscendCliUpdateAgents($input: UpdateAgentsInput!) {\n updateAgents(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const AGENT_FILES = gql`\n query TranscendCliAgentFiles(\n $first: Int!\n $offset: Int!\n $filterBy: AgentFileFiltersInput\n ) {\n agentFiles(\n first: $first\n offset: $offset\n filterBy: $filterBy\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n description\n fileId\n size\n purpose\n initialFileName\n }\n }\n }\n`;\n\nexport const CREATE_AGENT_FILE = gql`\n mutation TranscendCliCreateAgentFile($input: CreateAgentFileInput!) {\n createAgentFile(input: $input) {\n agentFile {\n id\n name\n fileId\n initialFileName\n }\n }\n }\n`;\n\nexport const UPDATE_AGENT_FILES = gql`\n mutation TranscendCliUpdateAgentFiles($input: UpdateAgentFilesInput!) {\n updateAgentFiles(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// isExportCsv: true\n// useMaster: false\nexport const AGENT_FUNCTIONS = gql`\n query TranscendCliAgentFunctions($first: Int!, $offset: Int!) {\n agentFunctions(\n first: $first\n offset: $offset\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: name, direction: ASC }\n ]\n ) {\n nodes {\n id\n name\n description\n parameters\n }\n }\n }\n`;\n\nexport const CREATE_AGENT_FUNCTION = gql`\n mutation TranscendCliCreateAgentFunction($input: CreateAgentFunctionInput!) {\n createAgentFunction(input: $input) {\n agentFunction {\n id\n name\n }\n }\n }\n`;\n\nexport const UPDATE_AGENT_FUNCTIONS = gql`\n mutation TranscendCliUpdateAgentFunctions(\n $input: UpdateAgentFunctionsInput!\n ) {\n updateAgentFunctions(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const VENDORS = gql`\n query TranscendCliVendors($first: Int!, $offset: Int!) {\n vendors(\n first: $first\n offset: $offset\n useMaster: false\n isExportCsv: true\n orderBy: [\n { field: createdAt, direction: ASC }\n { field: title, direction: ASC }\n ]\n ) {\n nodes {\n id\n title\n description\n dataProcessingAgreementLink\n contactName\n contactEmail\n contactPhone\n address\n headquarterCountry\n headquarterSubDivision\n websiteUrl\n businessEntity {\n title\n }\n teams {\n name\n }\n owners {\n email\n }\n attributeValues {\n attributeKey {\n name\n }\n name\n }\n }\n }\n }\n`;\n\nexport const CREATE_VENDOR = gql`\n mutation TranscendCliCreateVendor($input: CreateVendorInput!) {\n createVendor(input: $input) {\n vendor {\n id\n title\n }\n }\n }\n`;\n\nexport const UPDATE_VENDORS = gql`\n mutation TranscendCliUpdateVendor($input: UpdateVendorsInput!) {\n updateVendors(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: name, direction: ASC }\n// ]\nexport const DATA_SUB_CATEGORIES = gql`\n query TranscendCliDataSubCategories($first: Int!, $offset: Int!) {\n dataSubCategories(\n first: $first\n offset: $offset\n isExportCsv: true\n useMaster: false\n ) {\n nodes {\n id\n name\n category\n description\n regex\n teams {\n name\n }\n owners {\n email\n }\n attributeValues {\n attributeKey {\n name\n }\n name\n }\n }\n }\n }\n`;\n\nexport const CREATE_DATA_SUB_CATEGORY = gql`\n mutation TranscendCliCreateDataSubCategory(\n $input: CreateDataInventorySubCategoryInput!\n ) {\n createDataSubCategory(input: $input) {\n dataSubCategory {\n id\n name\n category\n }\n }\n }\n`;\n\nexport const UPDATE_DATA_SUB_CATEGORIES = gql`\n mutation TranscendCliUpdateDataSubCategories(\n $input: UpdateDataSubCategoriesInput!\n ) {\n updateDataSubCategories(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\n// TODO: https://transcend.height.app/T-27909 - enable optimizations\n// orderBy: [\n// { field: createdAt, direction: ASC }\n// { field: name, direction: ASC }\n// ]\nexport const PROCESSING_PURPOSE_SUB_CATEGORIES = gql`\n query TranscendCliProcessingPurposeSubCategories(\n $first: Int!\n $offset: Int!\n ) {\n processingPurposeSubCategories(\n first: $first\n offset: $offset\n isExportCsv: true\n useMaster: false\n ) {\n nodes {\n id\n name\n purpose\n description\n teams {\n name\n }\n owners {\n email\n }\n attributeValues {\n attributeKey {\n name\n }\n name\n }\n }\n }\n }\n`;\n\nexport const CREATE_PROCESSING_PURPOSE_SUB_CATEGORY = gql`\n mutation TranscendCliCreateProcessingPurposeSubCategory(\n $input: CreateProcessingPurposeCategoryInput!\n ) {\n createProcessingPurposeSubCategory(input: $input) {\n processingPurposeSubCategory {\n id\n name\n purpose\n }\n }\n }\n`;\n\nexport const UPDATE_PROCESSING_PURPOSE_SUB_CATEGORIES = gql`\n mutation TranscendCliUpdateProcessingPurposeSubCategories(\n $input: UpdateProcessingPurposeSubCategoriesInput!\n ) {\n updateProcessingPurposeSubCategories(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const PROCESSING_ACTIVITIES = gql`\n query TranscendCliProcessingActivities($first: Int!, $offset: Int!) {\n processingActivities(first: $first, offset: $offset, useMaster: false) {\n nodes {\n id\n title\n description\n securityMeasureDetails\n controllerships\n storageRegions {\n countrySubDivision\n country\n }\n transferRegions {\n countrySubDivision\n country\n }\n retentionType\n retentionPeriod\n dataProtectionImpactAssessmentLink\n dataProtectionImpactAssessmentStatus\n attributeValues {\n name\n attributeKey {\n name\n }\n }\n dataSilos {\n title\n }\n dataSubjects {\n type\n }\n teams {\n name\n }\n owners {\n email\n }\n processingPurposeSubCategories {\n name\n purpose\n }\n dataSubCategories {\n name\n category\n }\n saaSCategories {\n title\n }\n }\n }\n }\n`;\n\nexport const CREATE_PROCESSING_ACTIVITY = gql`\n mutation TranscendCliCreateProcessingActivity(\n $input: CreateProcessingActivityInput!\n ) {\n createProcessingActivity(input: $input) {\n processingActivity {\n id\n title\n }\n }\n }\n`;\n\nexport const UPDATE_PROCESSING_ACTIVITIES = gql`\n mutation TranscendCliUpdateProcessingActivities(\n $input: UpdateProcessingActivitiesInput!\n ) {\n updateProcessingActivities(input: $input) {\n clientMutationId\n }\n }\n`;\n","import { gql } from 'graphql-request';\n\nexport const SOMBRA_VERSION = gql`\n query TranscendSombraVersion {\n organization {\n sombra {\n version\n }\n }\n }\n`;\n","import type {\n GraphQLClient,\n RequestDocument,\n Variables,\n} from 'graphql-request';\nimport { logger } from '../../logger';\nimport colors from 'colors';\n\nconst MAX_RETRIES = 4;\n\n/**\n * Sleep in a promise\n *\n * @param sleepTime - The time to sleep in milliseconds.\n * @returns Resolves promise\n */\nfunction sleepPromise(sleepTime: number): Promise<number> {\n return new Promise((resolve) => {\n setTimeout(() => resolve(sleepTime), sleepTime);\n });\n}\n\nconst KNOWN_ERRORS = [\n 'syntax error',\n 'got invalid value',\n 'Client error',\n 'cannot affect row a second time',\n 'GRAPHQL_VALIDATION_FAILED',\n];\n\n/**\n * Make a GraphQL request with retries\n *\n * @param client - GraphQL client\n * @param document - document\n * @param variables - Variable\n * @param requestHeaders - Headers\n * @param maxRequests - Max number of requests\n * @returns Response\n */\nexport async function makeGraphQLRequest<T, V extends Variables = Variables>(\n client: GraphQLClient,\n document: RequestDocument,\n variables?: V,\n requestHeaders?: Record<string, string> | string[][] | Headers,\n maxRequests = MAX_RETRIES,\n): Promise<T> {\n let retryCount = 0;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const result = await client.request(document, variables, requestHeaders);\n return result as T;\n } catch (err) {\n if (err.message.includes('API key is invalid')) {\n logger.error(\n colors.red(\n 'API key is invalid. ' +\n 'Please ensure that the key provided to `transcendAuth` has the proper scope and is not expired, ' +\n 'and that `transcendUrl` corresponds to the correct backend for your organization.',\n ),\n );\n process.exit(1);\n }\n\n if (KNOWN_ERRORS.some((msg) => err.message.includes(msg))) {\n throw err;\n }\n\n // wait for rate limit to resolve\n if (err.message.startsWith('Client error: Too many requests')) {\n const rateLimitResetAt = err.response.headers?.get('x-ratelimit-reset');\n const sleepTime = rateLimitResetAt\n ? new Date(rateLimitResetAt).getTime() - new Date().getTime() + 100\n : 1000 * 10;\n logger.log(\n colors.yellow(\n `DETECTED RATE LIMIT: ${err.message}. Sleeping for ${sleepTime}ms`,\n ),\n );\n\n await sleepPromise(sleepTime);\n }\n\n if (retryCount >= maxRequests) {\n throw err;\n }\n retryCount += 1;\n logger.log(\n colors.yellow(\n `REQUEST FAILED: ${err.message}. Retrying ${retryCount}/${maxRequests}...`,\n ),\n );\n }\n }\n}\n","import { GraphQLClient } from 'graphql-request';\nimport { IdentifierType, RequestAction } from '@transcend-io/privacy-types';\nimport { CREATE_IDENTIFIER, IDENTIFIERS, NEW_IDENTIFIER_TYPES } from './gqls';\nimport { keyBy, uniq, flatten, difference } from 'lodash-es';\nimport { TranscendInput } from '../../codecs';\nimport { logger } from '../../logger';\nimport colors from 'colors';\nimport { mapSeries } from '../bluebird-replace';\nimport { makeGraphQLRequest } from './makeGraphQLRequest';\n\nexport interface Identifier {\n /** ID of identifier */\n id: string;\n /** Name of identifier */\n name: string;\n /** The type of identifier */\n type: IdentifierType;\n /** Regular expression to */\n regex: string;\n /** The set of options that the identifier */\n selectOptions: string[];\n /** Whether identifier is enabled on privacy center */\n privacyCenterVisibility: RequestAction[];\n /** Enabled data subjects that are exposed this identifier on the privacy center */\n dataSubjects: {\n /** type of data subjects */\n type: string;\n }[];\n /** Whether identifier is a required field in privacy center form */\n isRequiredInForm: boolean;\n /** Identifier placeholder text */\n placeholder: string;\n /** Display title for identifier */\n displayTitle: {\n /** Default message */\n defaultMessage: string;\n };\n /** Display description for identifier */\n displayDescription: {\n /** Default */\n defaultMessage: string;\n };\n /** Display order */\n displayOrder: number;\n /** does this identifier uniquely identify a consent record */\n isUniqueOnPreferenceStore: boolean;\n}\n\nconst PAGE_SIZE = 20;\n\n/**\n * Fetch all identifiers in the organization\n *\n * @param client - GraphQL client\n * @returns All identifiers in the organization\n */\nexport async function fetchAllIdentifiers(\n client: GraphQLClient,\n): Promise<Identifier[]> {\n const identifiers: Identifier[] = [];\n let offset = 0;\n\n // Whether to continue looping\n let shouldContinue = false;\n do {\n const {\n identifiers: { nodes },\n } = await makeGraphQLRequest<{\n /** Identifiers */\n identifiers: {\n /** List */\n nodes: Identifier[];\n };\n }>(client, IDENTIFIERS, {\n first: PAGE_SIZE,\n offset,\n });\n identifiers.push(...nodes);\n offset += PAGE_SIZE;\n shouldContinue = nodes.length === PAGE_SIZE;\n } while (shouldContinue);\n\n return identifiers.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Fetch all identifiers and if any are found in the config that are\n * missing, create those identifiers.\n *\n * @param input - Transcend input\n * @param client - GraphQL client\n * @param skipPublish - When true, skip publishing to privacy center\n * @returns A map from identifier name to Identifier\n */\nexport async function fetchIdentifiersAndCreateMissing(\n {\n enrichers = [],\n 'data-silos': dataSilos = [],\n identifiers = [],\n }: TranscendInput,\n client: GraphQLClient,\n skipPublish = false,\n): Promise<{ [k in string]: Identifier }> {\n // Grab all existing identifiers\n const allIdentifiers = await fetchAllIdentifiers(client);\n\n // Create a map\n const identifiersByName = keyBy(allIdentifiers, 'name');\n\n // Determine expected set of identifiers\n const expectedIdentifiers = uniq([\n ...flatten(\n enrichers.map((enricher) => [\n enricher['input-identifier'],\n ...enricher['output-identifiers'],\n ]),\n ),\n ...flatten(dataSilos.map((dataSilo) => dataSilo['identity-keys'])),\n ...identifiers.map(({ name }) => name),\n ]).filter((x) => !!x);\n const missingIdentifiers = difference(\n expectedIdentifiers,\n allIdentifiers.map(({ name }) => name),\n );\n\n // If there are missing identifiers, create new ones\n if (missingIdentifiers.length > 0) {\n logger.info(\n colors.magenta(\n `Creating ${missingIdentifiers.length} new identifiers...`,\n ),\n );\n const { newIdentifierTypes } = await makeGraphQLRequest<{\n /** Query response */\n newIdentifierTypes: {\n /** Name of identifier type remaining */\n name: string;\n }[];\n }>(client, NEW_IDENTIFIER_TYPES);\n const nativeTypesRemaining = newIdentifierTypes.map(({ name }) => name);\n await mapSeries(missingIdentifiers, async (identifier) => {\n logger.info(colors.magenta(`Creating identifier ${identifier}...`));\n const { createIdentifier } = await makeGraphQLRequest<{\n /** createIdentifier Response */\n createIdentifier: {\n /** Created identifier */\n identifier: Identifier;\n };\n }>(client, CREATE_IDENTIFIER, {\n input: {\n name: identifier,\n type: nativeTypesRemaining.includes(identifier!)\n ? identifier\n : 'custom',\n skipPublish,\n },\n });\n logger.info(colors.green(`Created identifier ${identifier}!`));\n\n identifiersByName[identifier!] = createIdentifier.identifier;\n });\n }\n return identifiersByName;\n}\n","import { IdentifierInput } from '../../codecs';\nimport { GraphQLClient } from 'graphql-request';\nimport { UPDATE_IDENTIFIER } from './gqls';\nimport { makeGraphQLRequest } from './makeGraphQLRequest';\nimport type { DataSubject } from './fetchDataSubjects';\n\n/**\n * Sync the consent manager\n *\n * @param client - GraphQL client\n * @param options - Options\n */\nexport async function syncIdentifier(\n client: GraphQLClient,\n {\n identifier,\n dataSubjectsByName,\n identifierId,\n skipPublish = false,\n }: {\n /** Identifier update input */\n identifier: IdentifierInput;\n /** Data subject lookup by name */\n dataSubjectsByName: { [k in string]: DataSubject };\n /** Existing identifier Id */\n identifierId: string;\n /** When true, skip publishing to privacy center */\n skipPublish?: boolean;\n },\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_IDENTIFIER, {\n input: {\n id: identifierId,\n selectOptions: identifier.selectOptions,\n isRequiredInForm: identifier.isRequiredInForm,\n regex: identifier.regex,\n placeholder: identifier.placeholder,\n displayTitle: identifier.displayTitle,\n displayDescription: identifier.displayDescription,\n displayOrder: identifier.displayOrder,\n isUniqueOnPreferenceStore: identifier.isUniqueOnPreferenceStore,\n privacyCenterVisibility: identifier.privacyCenterVisibility,\n dataSubjectIds: identifier.dataSubjects\n ? identifier.dataSubjects.map((type) => dataSubjectsByName[type].id)\n : undefined,\n skipPublish,\n },\n });\n}\n","import { EnricherInput } from '../../codecs';\nimport { GraphQLClient } from 'graphql-request';\nimport { ENRICHERS, CREATE_ENRICHER, UPDATE_ENRICHER } from './gqls';\nimport {\n EnricherType,\n IsoCountryCode,\n IsoCountrySubdivisionCode,\n PreflightRequestStatus,\n RequestAction,\n} from '@transcend-io/privacy-types';\nimport { Identifier } from './fetchIdentifiers';\nimport { makeGraphQLRequest } from './makeGraphQLRequest';\nimport { DataSubject } from './fetchDataSubjects';\n\nexport interface Enricher {\n /** ID of enricher */\n id: string;\n /** Title of enricher */\n title: string;\n /** URL of enricher */\n url: string;\n /** Server silo */\n type: EnricherType;\n /** Input identifier */\n inputIdentifier: {\n /** Identifier name */\n name: string;\n };\n /** The selected actions */\n actions: RequestAction[];\n /** Output identifiers */\n identifiers: {\n /** Identifier name */\n name: string;\n }[];\n /** Data subjects that the preflight check is configured for */\n dataSubjects: {\n /** Data subject type */\n type: string;\n }[];\n /** The duration (in ms) that the enricher should take to execute. - BigInt */\n expirationDuration: string;\n /** Looker query title */\n lookerQueryTitle?: string;\n /** A regular expression that can be used to match on for cancelation */\n testRegex?: string;\n /** The status that the enricher should transfer to when condition is met. */\n transitionRequestStatus?: PreflightRequestStatus;\n /** The twilio phone number to send from */\n phoneNumbers: string[];\n /**\n * The list of regions that should trigger the enrichment condition\n */\n regionList: (IsoCountryCode | IsoCountrySubdivisionCode)[];\n}\n\nconst PAGE_SIZE = 20;\n\n/**\n * Fetch all enrichers in the organization\n *\n * @param client - GraphQL client\n * @param title - Filter by title\n * @returns All enrichers in the organization\n */\nexport async function fetchAllEnrichers(\n client: GraphQLClient,\n title?: string,\n): Promise<Enricher[]> {\n const enrichers: Enricher[] = [];\n let offset = 0;\n\n // Whether to continue looping\n let shouldContinue = false;\n do {\n const {\n enrichers: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n enrichers: {\n /** List of matches */\n nodes: Enricher[];\n };\n }>(client, ENRICHERS, {\n first: PAGE_SIZE,\n offset,\n title,\n });\n enrichers.push(...nodes);\n offset += PAGE_SIZE;\n shouldContinue = nodes.length === PAGE_SIZE;\n } while (shouldContinue);\n\n return enrichers.sort((a, b) => a.title.localeCompare(b.title));\n}\n\n/**\n * Sync an enricher configuration\n *\n * @param client - GraphQL client\n * @param options - Options\n */\nexport async function syncEnricher(\n client: GraphQLClient,\n {\n enricher,\n identifierByName,\n dataSubjectsByName,\n }: {\n /** The enricher input */\n enricher: EnricherInput;\n /** Index of identifiers in the organization */\n identifierByName: { [name in string]: Identifier };\n /** Lookup data subject by name */\n dataSubjectsByName: { [name in string]: DataSubject };\n },\n): Promise<void> {\n // Whether to continue looping\n const matches = await fetchAllEnrichers(client, enricher.title);\n const existingEnricher = matches.find(\n ({ title }) => title === enricher.title,\n );\n\n // Map to data subject Ids\n const dataSubjectIds = enricher['data-subjects']?.map((subject) => {\n const existing = dataSubjectsByName[subject];\n if (!existing) {\n throw new Error(`Failed to find a data subject with name: ${subject}`);\n }\n return existing.id;\n });\n\n // If enricher exists, update it, else create new\n const inputIdentifier = enricher['input-identifier'];\n const actionUpdates =\n enricher['privacy-actions'] || Object.values(RequestAction);\n if (existingEnricher) {\n await makeGraphQLRequest(client, UPDATE_ENRICHER, {\n input: {\n id: existingEnricher.id,\n title: enricher.title,\n url: enricher.url,\n headers: enricher.headers,\n testRegex: enricher.testRegex,\n lookerQueryTitle: enricher.lookerQueryTitle,\n expirationDuration:\n typeof enricher.expirationDuration === 'number'\n ? enricher.expirationDuration.toString()\n : undefined,\n transitionRequestStatus: enricher.transitionRequestStatus,\n phoneNumbers: enricher.phoneNumbers,\n regionList: enricher.regionList,\n dataSubjectIds,\n description: enricher.description || '',\n inputIdentifier: inputIdentifier\n ? identifierByName[inputIdentifier].id\n : undefined,\n identifiers: enricher['output-identifiers'].map(\n (id) => identifierByName[id].id,\n ),\n ...(existingEnricher.type === EnricherType.Sombra\n ? {}\n : { actions: actionUpdates }),\n },\n });\n } else if (inputIdentifier) {\n await makeGraphQLRequest(client, CREATE_ENRICHER, {\n input: {\n title: enricher.title,\n url: enricher.url,\n type: enricher.type || EnricherType.Server,\n headers: enricher.headers,\n testRegex: enricher.testRegex,\n lookerQueryTitle: enricher.lookerQueryTitle,\n expirationDuration:\n typeof enricher.expirationDuration === 'number'\n ? enricher.expirationDuration.toString()\n : undefined,\n transitionRequestStatus: enricher.transitionRequestStatus,\n phoneNumbers: enricher.phoneNumbers,\n dataSubjectIds,\n regionList: enricher.regionList,\n description: enricher.description || '',\n inputIdentifier: identifierByName[inputIdentifier].id,\n identifiers: enricher['output-identifiers'].map(\n (id) => identifierByName[id].id,\n ),\n actions: actionUpdates,\n },\n });\n }\n}\n","/* eslint-disable max-lines */\nimport cliProgress from 'cli-progress';\nimport {\n DataCategoryInput,\n DataSiloInput,\n ProcessingPurposeInput,\n} from '../../codecs';\nimport { GraphQLClient } from 'graphql-request';\nimport { logger } from '../../logger';\nimport colors from 'colors';\nimport { mapSeries, map } from '../bluebird-replace';\nimport {\n DATA_SILOS,\n CREATE_DATA_SILOS,\n UPDATE_OR_CREATE_DATA_POINT,\n DATA_POINTS,\n SUB_DATA_POINTS,\n UPDATE_DATA_SILOS,\n DATA_SILOS_ENRICHED,\n SUB_DATA_POINTS_WITH_GUESSES,\n} from './gqls';\nimport {\n convertToDataSubjectBlockList,\n DataSubject,\n} from './fetchDataSubjects';\nimport { ApiKey } from './fetchApiKeys';\nimport {\n IsoCountryCode,\n IsoCountrySubdivisionCode,\n PromptAVendorEmailCompletionLinkType,\n PromptAVendorEmailSendType,\n ConfidenceLabel,\n RequestActionObjectResolver,\n SubDataPointDataSubCategoryGuessStatus,\n} from '@transcend-io/privacy-types';\nimport { sortBy, chunk, keyBy } from 'lodash-es';\nimport { makeGraphQLRequest } from './makeGraphQLRequest';\nimport { apply } from '@transcend-io/type-utils';\n\nexport interface DataSiloAttributeValue {\n /** Key associated to value */\n attributeKey: {\n /** Name of key */\n name: string;\n };\n /** Name of value */\n name: string;\n}\nexport interface DataSilo {\n /** ID of dataSilo */\n id: string;\n /** Title of dataSilo */\n title: string;\n /** Type of silo */\n type: string;\n /** The link to the data silo */\n link: string;\n /** Attribute labels */\n attributeValues: DataSiloAttributeValue[];\n /** description */\n description: string;\n /** Metadata for this data silo */\n catalog: {\n /** Whether the data silo supports automated vendor coordination */\n hasAvcFunctionality: boolean;\n };\n}\n\nconst BATCH_SILOS_LIMIT = 20;\n\n/**\n * Fetch all dataSilos in the organization\n *\n * @param client - GraphQL client\n * @param title - Filter by title\n * @returns All dataSilos in the organization\n */\nexport async function fetchAllDataSilos<TDataSilo extends DataSilo>(\n client: GraphQLClient,\n {\n titles,\n pageSize,\n ids = [],\n gql = DATA_SILOS,\n integrationNames = [],\n }: {\n /** Page size to fetch datapoints in */\n pageSize: number;\n /** Title */\n titles?: string[];\n /** IDs */\n ids?: string[];\n /** Set of integration names to fetch */\n integrationNames?: string[];\n /** GQL query for data silos */\n gql?: string;\n },\n): Promise<TDataSilo[]> {\n logger.info(\n colors.magenta(\n `Fetching ${ids.length === 0 ? 'all' : ids.length} Data Silos...`,\n ),\n );\n\n const dataSilos: TDataSilo[] = [];\n let offset = 0;\n\n // Whether to continue looping\n let shouldContinue = false;\n do {\n const {\n dataSilos: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n dataSilos: {\n /** List of matches */\n nodes: TDataSilo[];\n };\n }>(client, gql, {\n filterBy: {\n ids: ids.length > 0 ? ids : undefined,\n type: integrationNames.length > 0 ? integrationNames : undefined,\n titles,\n },\n first: pageSize,\n offset,\n });\n dataSilos.push(...nodes);\n offset += pageSize;\n shouldContinue = nodes.length === pageSize;\n } while (shouldContinue);\n logger.info(\n colors.green(\n `Found a total of ${dataSilos.length} data silo${\n ids.length > 0 ? ` matching IDs ${ids.join(',')}` : ''\n }s${\n integrationNames.length > 0\n ? ` matching integrationNames ${integrationNames.join(',')}`\n : ''\n }`,\n ),\n );\n\n return dataSilos.sort((a, b) => a.title.localeCompare(b.title));\n}\n\nexport interface SubDataPoint {\n /** Name (or key) of the subdatapoint */\n name: string;\n /** The description */\n description?: string;\n /** Personal data category */\n categories: DataCategoryInput[];\n /** The processing purpose for this sub datapoint */\n purposes: ProcessingPurposeInput[];\n /**\n * When true, this subdatapoint should be revealed in a data access request.\n * When false, this field should be redacted\n */\n accessRequestVisibilityEnabled: boolean;\n /**\n * When true, this subdatapoint should be redacted during an erasure request.\n * There normally is a choice of enabling hard deletion or redaction at the\n * datapoint level, but if redaction is enabled, this column can be used\n * to define which fields should be redacted.\n */\n erasureRequestRedactionEnabled: boolean;\n /** Attribute attached to subdatapoint */\n attributeValues: DataSiloAttributeValue[];\n /** Data category guesses that are output by the classifier */\n pendingCategoryGuesses?: {\n /** Data category being guessed */\n category: DataCategoryInput;\n /** Status of guess */\n status: SubDataPointDataSubCategoryGuessStatus;\n /** Confidence level of guess */\n confidence: number;\n /** Confidence label */\n confidenceLabel: ConfidenceLabel;\n /** classifier version that produced the guess */\n classifierVersion: number;\n }[];\n}\n\ninterface DataPoint {\n /** ID of dataPoint */\n id: string;\n /** Title of dataPoint */\n title: {\n /** Default message */\n defaultMessage: string;\n };\n /** The path to this data point */\n path: string[];\n /** Description */\n description: {\n /** Default message */\n defaultMessage: string;\n };\n /** Name */\n name: string;\n /** Global actions */\n actionSettings: {\n /** Action type */\n type: RequestActionObjectResolver;\n /** Is enabled */\n active: boolean;\n }[];\n /** Data collection tag for privacy request download zip labeling */\n dataCollection?: {\n /** Title of data collection */\n title: {\n /** Default message (since message can be translated) */\n defaultMessage: string;\n };\n };\n /** Metadata for this data silo */\n catalog: {\n /** Whether the data silo supports automated vendor coordination */\n hasAvcFunctionality: boolean;\n };\n /** Owners of the datapoint */\n owners: {\n /** Email address of the owner */\n email: string;\n }[];\n /** Teams that own the datapoint */\n teams: {\n /** Name of the team */\n name: string;\n }[];\n /** Database integration queries */\n dbIntegrationQueries: {\n /** Approved query */\n query: string | null;\n /** Suggested query */\n suggestedQuery: string | null;\n /** Request action */\n requestType: RequestActionObjectResolver;\n }[];\n}\n\ninterface DataPointWithSubDataPoint extends DataPoint {\n /** The associated subdatapoints */\n subDataPoints: SubDataPoint[];\n}\n\n/**\n * Helper to fetch all subdatapoints for a given datapoint\n *\n * @param client - The GraphQL client\n * @param dataPointId - The datapoint ID\n * @param options - Options\n * @returns The list of subdatapoints\n */\nexport async function fetchAllSubDataPoints(\n client: GraphQLClient,\n dataPointId: string,\n {\n debug,\n includeGuessedCategories,\n pageSize,\n }: {\n /** Debug logs */\n debug: boolean;\n /** Page size */\n pageSize: number;\n /** When true, metadata around guessed data categories should be included */\n includeGuessedCategories?: boolean;\n },\n): Promise<SubDataPoint[]> {\n const subDataPoints: SubDataPoint[] = [];\n\n let offset = 0;\n\n let shouldContinue = false;\n do {\n try {\n if (debug) {\n logger.log(\n colors.magenta(`Pulling in subdatapoints for offset ${offset}`),\n );\n }\n const {\n subDataPoints: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n subDataPoints: {\n /** List of matches */\n nodes: SubDataPoint[];\n };\n }>(\n client,\n includeGuessedCategories\n ? SUB_DATA_POINTS_WITH_GUESSES\n : SUB_DATA_POINTS,\n {\n first: pageSize,\n filterBy: {\n dataPoints: [dataPointId],\n },\n offset,\n },\n );\n\n subDataPoints.push(...nodes);\n offset += pageSize;\n shouldContinue = nodes.length === pageSize;\n\n if (debug) {\n logger.log(\n colors.green(\n `Pulled in subdatapoints for offset ${offset} for dataPointId=${dataPointId}`,\n ),\n );\n }\n } catch (err) {\n logger.error(\n colors.red(\n `An error fetching subdatapoints for offset ${offset} for dataPointId=${dataPointId}`,\n ),\n );\n throw err;\n }\n } while (shouldContinue);\n return sortBy(subDataPoints, 'name');\n}\n\n/**\n * Fetch all datapoints for a data silo\n *\n * @param client - GraphQL client\n * @param dataSiloId - Data silo ID\n * @param options - Options\n * @returns List of datapoints\n */\nexport async function fetchAllDataPoints(\n client: GraphQLClient,\n dataSiloId: string,\n {\n debug,\n pageSize,\n skipSubDatapoints,\n includeGuessedCategories,\n }: {\n /** Debug logs */\n debug: boolean;\n /** Page size */\n pageSize: number;\n /** Skip fetching of subdatapoints */\n skipSubDatapoints?: boolean;\n /** When true, metadata around guessed data categories should be included */\n includeGuessedCategories?: boolean;\n },\n): Promise<DataPointWithSubDataPoint[]> {\n const dataPoints: DataPointWithSubDataPoint[] = [];\n\n // TODO: https://transcend.height.app/T-40481 - add cursor pagination\n let offset = 0;\n\n // Whether to continue looping\n let shouldContinue = false;\n do {\n if (debug) {\n logger.info(colors.magenta(`Fetching datapoints with offset: ${offset}`));\n }\n\n const {\n dataPoints: { nodes },\n } = await makeGraphQLRequest<{\n /** Query response */\n dataPoints: {\n /** List of matches */\n nodes: DataPoint[];\n };\n }>(client, DATA_POINTS, {\n first: pageSize,\n filterBy: {\n dataSilos: [dataSiloId],\n },\n offset,\n });\n\n if (debug) {\n logger.info(\n colors.magenta(\n `Fetched ${nodes.length} datapoints at offset: ${offset}`,\n ),\n );\n }\n\n if (!skipSubDatapoints) {\n await map(\n nodes,\n /* eslint-disable no-loop-func */\n async (node) => {\n try {\n if (debug) {\n logger.info(\n colors.magenta(\n `Fetching subdatapoints for ${node.name} for datapoint offset ${offset}`,\n ),\n );\n }\n\n const subDataPoints = await fetchAllSubDataPoints(client, node.id, {\n pageSize: 1000, // max page size\n debug,\n includeGuessedCategories,\n });\n dataPoints.push({\n ...node,\n subDataPoints: subDataPoints.sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n });\n\n if (debug) {\n logger.info(\n colors.green(\n `Successfully fetched subdatapoints for ${node.name}`,\n ),\n );\n }\n } catch (err) {\n logger.error(\n colors.red(\n `An error fetching subdatapoints for ${node.name} datapoint offset ${offset}`,\n ),\n );\n throw err;\n }\n },\n /* eslint-enable no-loop-func */\n {\n concurrency: 5,\n },\n );\n\n if (debug) {\n logger.info(\n colors.green(\n `Fetched all subdatapoints for page of datapoints at offset: ${offset}`,\n ),\n );\n }\n }\n\n offset += pageSize;\n shouldContinue = nodes.length === pageSize;\n } while (shouldContinue);\n return dataPoints.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport interface DataSiloEnriched {\n /** ID of dataSilo */\n id: string;\n /** Title of dataSilo */\n title: string;\n /** Type of silo */\n type: string;\n /** Link to silo */\n link: string;\n /** Outer type of silo */\n outerType: string;\n /** Description of data silo */\n description: string;\n /** Webhook URL */\n url?: string;\n /** Email address of user to notify for prompt a person use case */\n notifyEmailAddress?: string;\n /** Associated API keys */\n apiKeys: {\n /** Title */\n title: string;\n }[];\n /** Data subject block list */\n subjectBlocklist: {\n /** Type of data subject */\n type: string;\n }[];\n /** Identifiers */\n identifiers: {\n /** Name of identifier */\n name: string;\n /** True if identifier is wired */\n isConnected: boolean;\n }[];\n /** Dependent data silos */\n dependentDataSilos: {\n /** Title of silo */\n title: string;\n }[];\n /** Silo owners */\n owners: {\n /** Email owners */\n email: string;\n }[];\n /** The teams assigned to this data silo */\n teams: {\n /** Name of the team assigned to this data silo */\n name: string;\n }[];\n /** Metadata for this data silo */\n catalog: {\n /** Whether the data silo supports automated vendor coordination */\n hasAvcFunctionality: boolean;\n };\n /** Silo is live */\n isLive: boolean;\n /** Hosting country of data silo */\n country?: IsoCountryCode;\n /** Hosting subdivision data silo */\n countrySubDivision?: IsoCountrySubdivisionCode;\n /**\n * The frequency with which we should be sending emails for this data silo, in milliseconds.\n */\n promptAVendorEmailSendFrequency: number;\n /**\n * The type of emails to send for this data silo, i.e. send an email for each DSR, across all open DSRs,\n * or per profile in a DSR.\n */\n promptAVendorEmailSendType: PromptAVendorEmailSendType;\n /**\n * Indicates whether prompt-a-vendor emails should include a list of identifiers\n * in addition to a link to the bulk processing UI.\n */\n promptAVendorEmailIncludeIdentifiersAttachment: boolean;\n /**\n * Indicates what kind of link to generate as part of the emails sent out for this Prompt-a-Vendor silo.\n */\n promptAVendorEmailCompletionLinkType: PromptAVendorEmailCompletionLinkType;\n /**\n * The frequency with which we should retry sending emails for this data silo, in milliseconds.\n * Needs to be a string because the number can be larger than the MAX_INT\n */\n manualWorkRetryFrequency: string;\n /** Attribute values tagged to data silo */\n attributeValues: DataSiloAttributeValue[];\n /**\n * The data silos that discovered this particular data silo\n */\n discoveredBy: {\n /** Title of data silo */\n title: string;\n }[];\n /**\n * The business entities assigned directly to this data silo\n */\n businessEntities: {\n /** Title of business entity */\n title: string;\n }[];\n}\n\n/**\n * Fetch all dataSilos with additional metadata\n *\n * @param client - GraphQL client\n * @param options - Filter options\n * @returns All dataSilos in the organization\n */\nexport async function fetchEnrichedDataSilos(\n client: GraphQLClient,\n {\n ids,\n pageSize,\n titles,\n debug,\n skipDatapoints,\n skipSubDatapoints,\n includeGuessedCategories,\n integrationNames,\n }: {\n /** Page size */\n pageSize: number;\n /** Filter by IDs */\n ids?: string[];\n /** Enable debug logs */\n debug: boolean;\n /** Filter by title */\n titles?: string[];\n /** Integration names */\n integrationNames?: string[];\n /** Skip fetching of datapoints */\n skipDatapoints?: boolean;\n /** Skip fetching of subdatapoints */\n skipSubDatapoints?: boolean;\n /** When true, metadata around guessed data categories should be included */\n includeGuessedCategories?: boolean;\n },\n): Promise<[DataSiloEnriched, DataPointWithSubDataPoint[]][]> {\n const dataSilos: [DataSiloEnriched, DataPointWithSubDataPoint[]][] = [];\n\n // Grab silos\n const silos = await fetchAllDataSilos<DataSiloEnriched>(client, {\n titles,\n ids,\n integrationNames,\n pageSize,\n gql: DATA_SILOS_ENRICHED,\n });\n\n // Graph datapoints for each silo\n if (!skipDatapoints) {\n await mapSeries(silos, async (silo, index) => {\n logger.info(\n colors.magenta(\n `[${index + 1}/${silos.length}] Fetching data silo - ${silo.title}`,\n ),\n );\n\n const dataPoints = await fetchAllDataPoints(client, silo.id, {\n debug,\n pageSize,\n skipSubDatapoints,\n includeGuessedCategories,\n });\n\n if (debug) {\n logger.info(\n colors.green(\n `[${index + 1}/${\n silos.length\n }] Successfully fetched datapoint for - ${silo.title}`,\n ),\n );\n }\n\n dataSilos.push([silo, dataPoints]);\n });\n }\n\n logger.info(\n colors.green(\n `Successfully fetched all ${silos.length} data silo configurations`,\n ),\n );\n\n return dataSilos;\n}\n\n/**\n * Sync a data silo configuration\n *\n * @param dataSilos - Data silos to sync\n * @param client - GraphQL client\n * @param options - Options\n * @returns Data silo info\n */\nexport async function syncDataSilos(\n dataSilos: DataSiloInput[],\n client: GraphQLClient,\n {\n pageSize,\n dataSubjectsByName,\n apiKeysByTitle,\n }: {\n /** Page size */\n pageSize: number;\n /** The data subjects in the organization */\n dataSubjectsByName: { [type in string]: DataSubject };\n /** API key title to API key */\n apiKeysByTitle: { [title in string]: ApiKey };\n },\n): Promise<{\n /** Whether successfully updated */\n success: boolean;\n /** A mapping between data silo title to data silo ID */\n dataSiloTitleToId: { [k in string]: string };\n}> {\n let encounteredError = false;\n\n // Time duration\n const t0 = new Date().getTime();\n logger.info(colors.magenta(`Syncing \"${dataSilos.length}\" data silos...`));\n\n // Determine the set of data silos that already exist\n const existingDataSilos = await fetchAllDataSilos(client, {\n titles: dataSilos.map(({ title }) => title),\n pageSize,\n });\n\n // Create a mapping of title -> existing silo, if it exists\n const existingDataSiloByTitle = keyBy<Pick<DataSilo, 'id' | 'title'>>(\n existingDataSilos,\n 'title',\n );\n\n // Create new silos that do not exist\n const newDataSiloInputs = dataSilos.filter(\n ({ title }) => !existingDataSiloByTitle[title],\n );\n if (newDataSiloInputs.length > 0) {\n logger.info(\n colors.magenta(\n `Creating \"${newDataSiloInputs.length}\" data silos that did not exist...`,\n ),\n );\n\n // Batch the creation\n const chunked = chunk(newDataSiloInputs, BATCH_SILOS_LIMIT);\n await mapSeries(chunked, async (dependencyUpdateChunk) => {\n const {\n createDataSilos: { dataSilos },\n } = await makeGraphQLRequest<{\n /** Mutation result */\n createDataSilos: {\n /** New data silos */\n dataSilos: Pick<DataSilo, 'id' | 'title'>[];\n };\n }>(client, CREATE_DATA_SILOS, {\n input: dependencyUpdateChunk.map((input) => ({\n name: input['outer-type'] || input.integrationName,\n title: input.title,\n country: input.country,\n countrySubDivision: input.countrySubDivision,\n })),\n });\n\n // save mapping of title and id\n dataSilos.forEach((silo) => {\n existingDataSiloByTitle[silo.title] = silo;\n });\n });\n\n logger.info(\n colors.green(\n `Successfully created \"${newDataSiloInputs.length}\" data silos!`,\n ),\n );\n }\n\n // Batch the updates\n const chunkedUpdates = chunk(dataSilos, BATCH_SILOS_LIMIT);\n await mapSeries(chunkedUpdates, async (dataSiloUpdateChunk, ind) => {\n logger.info(\n colors.magenta(\n `[Batch ${ind + 1}/${chunkedUpdates.length}] Syncing \"${\n dataSiloUpdateChunk.length\n }\" data silos`,\n ),\n );\n await makeGraphQLRequest<{\n /** Mutation result */\n updateDataSilos: {\n /** New data silos */\n dataSilos: Pick<DataSilo, 'id' | 'title'>[];\n };\n }>(client, UPDATE_DATA_SILOS, {\n input: {\n dataSilos: dataSiloUpdateChunk.map((input) => ({\n id: existingDataSiloByTitle[input.title].id,\n country: input.country,\n countrySubDivision: input.countrySubDivision,\n url: input.url,\n headers: input.headers,\n description: input.description,\n identifiers: input['identity-keys'],\n isLive: !input.disabled,\n ownerEmails: input.owners,\n teamNames: input.teams,\n // clear out if not specified, otherwise the update needs to be applied after\n // all data silos are created\n dependedOnDataSiloTitles: input['deletion-dependencies']\n ? undefined\n : [],\n apiKeyId: input['api-key-title']\n ? apiKeysByTitle[input['api-key-title']].id\n : undefined,\n dataSubjectBlockListIds: input['data-subjects']\n ? convertToDataSubjectBlockList(\n input['data-subjects'],\n dataSubjectsByName,\n )\n : undefined,\n attributes: input.attributes,\n businessEntityTitles: input.businessEntityTitles,\n // AVC settings\n notifyEmailAddress: input['email-settings']?.['notify-email-address'],\n promptAVendorEmailSendFrequency:\n input['email-settings']?.['send-frequency'],\n promptAVendorEmailSendType: input['email-settings']?.['send-type'],\n promptAVendorEmailIncludeIdentifiersAttachment:\n input['email-settings']?.['include-identifiers-attachment'],\n promptAVendorEmailCompletionLinkType:\n input['email-settings']?.['completion-link-type'],\n manualWorkRetryFrequency:\n input['email-settings']?.['manual-work-retry-frequency'],\n })),\n },\n });\n logger.info(\n colors.green(\n `[Batch ${ind + 1}/${chunkedUpdates.length}] Synced \"${\n dataSiloUpdateChunk.length\n }\" data silos!`,\n ),\n );\n });\n\n // Sync datapoints\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n const dataSilosWithDataPoints = dataSilos.filter(\n ({ datapoints = [] }) => datapoints.length > 0,\n );\n const totalDataPoints = dataSilos\n .map(({ datapoints = [] }) => datapoints.length)\n .reduce((acc, count) => acc + count, 0);\n logger.info(\n colors.magenta(\n `Syncing \"${totalDataPoints}\" datapoints from \"${dataSilosWithDataPoints.length}\" data silos...`,\n ),\n );\n progressBar.start(totalDataPoints, 0);\n let total = 0;\n\n await map(\n dataSilosWithDataPoints,\n async ({ datapoints, title }) => {\n if (datapoints) {\n await mapSeries(datapoints, async (datapoint) => {\n const fields = datapoint.fields\n ? datapoint.fields.map(\n ({\n key,\n description,\n categories,\n purposes,\n attributes,\n ...rest\n }) =>\n // TODO: Support setting title separately from the 'key/name'\n ({\n name: key,\n description,\n categories: !categories\n ? undefined\n : categories.map((category) => ({\n ...category,\n name: category.name || 'Other',\n })),\n purposes: !purposes\n ? undefined\n : purposes.map((purpose) => ({\n ...purpose,\n name: purpose.name || 'Other',\n })),\n attributes,\n accessRequestVisibilityEnabled:\n rest['access-request-visibility-enabled'],\n erasureRequestRedactionEnabled:\n rest['erasure-request-redaction-enabled'],\n }),\n )\n : undefined;\n\n const payload = {\n dataSiloId: existingDataSiloByTitle[title].id,\n path: datapoint.path,\n name: datapoint.key,\n title: datapoint.title,\n description: datapoint.description,\n ...(datapoint.owners\n ? {\n ownerEmails: datapoint.owners,\n }\n : {}),\n ...(datapoint.teams\n ? {\n teamNames: datapoint.teams,\n }\n : {}),\n ...(datapoint['data-collection-tag']\n ? { dataCollectionTag: datapoint['data-collection-tag'] }\n : {}),\n querySuggestions: !datapoint['privacy-action-queries']\n ? undefined\n : Object.entries(datapoint['privacy-action-queries']).map(\n ([key, value]) => ({\n requestType: key,\n suggestedQuery: value,\n }),\n ),\n enabledActions: datapoint['privacy-actions'] || [], // clear out when not specified\n subDataPoints: fields,\n };\n\n // Ensure no duplicate sub-datapoints are provided\n const subDataPointsToUpdate = (payload.subDataPoints || []).map(\n ({ name }) => name,\n );\n const duplicateDataPoints = subDataPointsToUpdate.filter(\n (name, index) => subDataPointsToUpdate.indexOf(name) !== index,\n );\n if (duplicateDataPoints.length > 0) {\n logger.info(\n colors.red(\n `\\nCannot update datapoint \"${\n datapoint.key\n }\" as it has duplicate sub-datapoints with the same name: \\n${duplicateDataPoints.join(\n '\\n',\n )}`,\n ),\n );\n encounteredError = true;\n } else {\n try {\n await makeGraphQLRequest(\n client,\n UPDATE_OR_CREATE_DATA_POINT,\n payload,\n );\n } catch (err) {\n logger.info(\n colors.red(\n `\\nFailed to update datapoint \"${datapoint.key}\" for data silo \"${title}\"! - \\n${err.message}`,\n ),\n );\n encounteredError = true;\n }\n }\n total += 1;\n progressBar.update(total);\n });\n }\n },\n {\n concurrency: 10,\n },\n );\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Synced \"${\n dataSilos.length\n }\" data silos and \"${totalDataPoints}\" datapoints in \"${\n totalTime / 1000\n }\" seconds!`,\n ),\n );\n return {\n success: !encounteredError,\n dataSiloTitleToId: apply(existingDataSiloByTitle, ({ id }) => id),\n };\n}\n\n/**\n * Sync data silo dependencies\n *\n * @param client - GraphQL client\n * @param dependencyUpdates - Mapping from [data silo ID, dependency titles]\n * @returns True upon success\n */\nexport async function syncDataSiloDependencies(\n client: GraphQLClient,\n dependencyUpdates: [string, string[]][],\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(\n colors.magenta(\n `Syncing \"${dependencyUpdates.length}\" data silo dependencies...`,\n ),\n );\n\n // Batch the updates\n const chunkedUpdates = chunk(dependencyUpdates, BATCH_SILOS_LIMIT);\n await mapSeries(chunkedUpdates, async (dependencyUpdateChunk, ind) => {\n logger.info(\n colors.magenta(\n `[Batch ${ind}/${dependencyUpdateChunk.length}] Updating \"${dependencyUpdateChunk.length}\" data silos...`,\n ),\n );\n try {\n await makeGraphQLRequest<{\n /** Mutation result */\n updateDataSilos: {\n /** New data silos */\n dataSilos: Pick<DataSilo, 'id' | 'title'>[];\n };\n }>(client, UPDATE_DATA_SILOS, {\n input: {\n dataSilos: dependencyUpdateChunk.map(\n ([id, dependedOnDataSiloTitles]) => ({\n id,\n dependedOnDataSiloTitles,\n }),\n ),\n },\n });\n logger.info(\n colors.green(\n `[Batch ${ind + 1}/${dependencyUpdateChunk.length}] ` +\n `Synced \"${dependencyUpdateChunk.length}\" data silos!`,\n ),\n );\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(\n `[Batch ${ind + 1}/${dependencyUpdateChunk.length}] ` +\n `Failed to update \"${dependencyUpdateChunk.length}\" silos! - ${err.message}`,\n ),\n );\n }\n });\n return !encounteredError;\n}\n/* eslint-enable max-lines */\n","import { GraphQLClient } from 'graphql-request';\nimport { API_KEYS } from './gqls';\nimport { keyBy, uniq, difference } from 'lodash-es';\nimport { logger } from '../../logger';\nimport colors from 'colors';\nimport { TranscendInput } from '../../codecs';\nimport { makeGraphQLRequest } from './makeGraphQLRequest';\n\nexport interface ApiKey {\n /** ID of API key */\n id: string;\n /** Title of API key */\n title: string;\n}\n\nconst PAGE_SIZE = 20;\n\nconst ADMIN_LINK = 'https://app.transcend.io/infrastructure/api-keys';\n\n/**\n * Fetch all API keys in an organization\n *\n * @param client - Client\n * @param titles - Filter on titles\n * @returns API keys\n */\nexport async function fetchAllApiKeys(\n client: GraphQLClient,\n titles?: string[],\n): Promise<ApiKey[]> {\n const apiKeys: ApiKey[] = [];\n let offset = 0;\n\n // Paginate\n let shouldContinue = false;\n do {\n const {\n apiKeys: { nodes },\n } = await makeGraphQLRequest<{\n /** API keys */\n apiKeys: {\n /** List */\n nodes: ApiKey[];\n };\n }>(client, API_KEYS, {\n first: PAGE_SIZE,\n offset,\n titles,\n });\n apiKeys.push(...nodes);\n offset += PAGE_SIZE;\n shouldContinue = nodes.length === PAGE_SIZE;\n } while (shouldContinue);\n return apiKeys.sort((a, b) => a.title.localeCompare(b.title));\n}\n\n/**\n * Fetch all apiKeys and if any are found in the config that are\n * missing, create those apiKeys.\n *\n * @param apiKeyInputs - API keys to fetch metadata on\n * @param client - GraphQL client\n * @param fetchAll - When true, fetch all API keys\n * @returns A map from apiKey title to Identifier\n */\nexport async function fetchApiKeys(\n {\n 'api-keys': apiKeyInputs = [],\n 'data-silos': dataSilos = [],\n }: TranscendInput,\n client: GraphQLClient,\n fetchAll = false,\n): Promise<{ [k in string]: ApiKey }> {\n logger.info(\n colors.magenta(\n `Fetching ${fetchAll ? 'all' : apiKeyInputs.length} API keys...`,\n ),\n );\n const titles = apiKeyInputs.map(({ title }) => title);\n const expectedApiKeyTitles = uniq(\n dataSilos\n .map((silo) => silo['api-key-title'])\n .filter((x): x is string => !!x),\n );\n const allTitlesExpected = [...expectedApiKeyTitles, ...titles];\n const apiKeys = await fetchAllApiKeys(\n client,\n fetchAll ? undefined : [...expectedApiKeyTitles, ...titles],\n );\n\n // Create a map\n const apiKeysByTitle = keyBy(apiKeys, 'title');\n\n // Determine expected set of apiKeys expected\n const missingApiKeys = difference(\n allTitlesExpected,\n apiKeys.map(({ title }) => title),\n );\n\n // If there are missing apiKeys, throw an error\n if (missingApiKeys.length > 0) {\n logger.info(\n colors.red(\n `Failed to find API keys \"${missingApiKeys.join(\n '\", \"',\n )}\"! Make sure these API keys are created at: ${ADMIN_LINK}`,\n ),\n );\n process.exit(1);\n }\n return apiKeysByTitle;\n}\n"]}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _chunkAMO6I4AOcjs = require('./chunk-AMO6I4AO.cjs');var _chunkPTQHBKJUcjs = require('./chunk-PTQHBKJU.cjs');require('./chunk-7G4SCKPN.cjs');require('./chunk-MBB6OD4E.cjs');var _chunkWKCTKYN4cjs = require('./chunk-WKCTKYN4.cjs');require('./chunk-QEM6S2W7.cjs');require('./chunk-LCDYXJN6.cjs');var _chunkUPUHHIXZcjs = require('./chunk-UPUHHIXZ.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');require('./chunk-6IHSPKMP.cjs');require('./chunk-DBYKJZEA.cjs');require('./chunk-Q7I37FJV.cjs');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);var _privacytypes = require('@transcend-io/privacy-types');async function x({auth:f,bundleTypes:r=[_privacytypes.ConsentBundleType.Production,_privacytypes.ConsentBundleType.Test],deploy:i,transcendUrl:s}){_chunkWKCTKYN4cjs.a.call(void 0, this.process.exit);let t=await _chunkAMO6I4AOcjs.b.call(void 0, f);typeof t=="string"?(await _chunkPTQHBKJUcjs.a.call(void 0, {deploy:i,transcendUrl:s,auth:t,bundleTypes:r}),_chunkZUNVPK23cjs.a.info(_colors2.default.green("Successfully updated Consent Manager!"))):(await _chunkUPUHHIXZcjs.a.call(void 0, t,async e=>{_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Updating Consent Manager for organization "${e.organizationName}"...`)),await _chunkPTQHBKJUcjs.a.call(void 0, {deploy:i,transcendUrl:s,auth:e.apiKey,bundleTypes:r}),_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully updated Consent Manager for organization "${e.organizationName}"!`))}),_chunkZUNVPK23cjs.a.info(_colors2.default.green("Successfully updated Consent Managers!")))}exports.updateConsentManager = x;
2
- //# sourceMappingURL=impl-5BNP4JYG.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/impl-5BNP4JYG.cjs","../src/commands/consent/update-consent-manager/impl.ts"],"names":["updateConsentManager","auth","bundleTypes","ConsentBundleType","deploy","transcendUrl","doneInputValidation","apiKeyOrList","validateTranscendAuth","updateConsentManagerVersionToLatest","logger","colors","mapSeries","apiKey"],"mappings":"AAAA,iOAAwC,wDAAoC,gCAA6B,gCAA6B,wDAAyC,gCAA6B,gCAA6B,wDAAyC,wDAAyC,gCAA6B,gCAA6B,gCAA6B,gFCC/X,2DACe,MAelC,SAAsBA,CAAAA,CAEpB,CACE,IAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CAAc,CAACC,+BAAAA,CAAkB,UAAA,CAAYA,+BAAAA,CAAkB,IAAI,CAAA,CACnE,MAAA,CAAAC,CAAAA,CACA,YAAA,CAAAC,CACF,CAAA,CACe,CACfC,iCAAAA,IAAoB,CAAK,OAAA,CAAQ,IAAI,CAAA,CAGrC,IAAMC,CAAAA,CAAe,MAAMC,iCAAAA,CAA0B,CAAA,CAGjD,OAAOD,CAAAA,EAAiB,QAAA,CAAA,CAE1B,MAAME,iCAAAA,CACJ,MAAA,CAAAL,CAAAA,CACA,YAAA,CAAAC,CAAAA,CACA,IAAA,CAAME,CAAAA,CACN,WAAA,CAAAL,CACF,CAAC,CAAA,CACDQ,mBAAAA,CAAO,IAAA,CAAKC,gBAAAA,CAAO,KAAA,CAAM,uCAAuC,CAAC,CAAA,CAAA,CAAA,CAEjE,MAAMC,iCAAAA,CAAUL,CAAc,MAAOM,CAAAA,EAAW,CAC9CH,mBAAAA,CAAO,IAAA,CACLC,gBAAAA,CAAO,OAAA,CACL,CAAA,2CAAA,EAA8CE,CAAAA,CAAO,gBAAgB,CAAA,IAAA,CACvE,CACF,CAAA,CAEA,MAAMJ,iCAAAA,CACJ,MAAA,CAAAL,CAAAA,CACA,YAAA,CAAAC,CAAAA,CACA,IAAA,CAAMQ,CAAAA,CAAO,MAAA,CACb,WAAA,CAAAX,CACF,CAAC,CAAA,CAEDQ,mBAAAA,CAAO,IAAA,CACLC,gBAAAA,CAAO,KAAA,CACL,CAAA,uDAAA,EAA0DE,CAAAA,CAAO,gBAAgB,CAAA,EAAA,CACnF,CACF,CACF,CAAC,CAAA,CACDH,mBAAAA,CAAO,IAAA,CAAKC,gBAAAA,CAAO,KAAA,CAAM,wCAAwC,CAAC,CAAA,CAEtE,CAAA,iCAAA","file":"/home/runner/work/cli/cli/dist/impl-5BNP4JYG.cjs","sourcesContent":[null,"import type { LocalContext } from '../../../context';\nimport colors from 'colors';\nimport { ConsentBundleType } from '@transcend-io/privacy-types';\nimport { mapSeries } from '../../../lib/bluebird-replace';\n\nimport { logger } from '../../../logger';\nimport { updateConsentManagerVersionToLatest } from '../../../lib/consent-manager';\nimport { validateTranscendAuth } from '../../../lib/api-keys';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation';\n\nexport interface UpdateConsentManagerCommandFlags {\n auth: string;\n bundleTypes: ConsentBundleType[];\n deploy: boolean;\n transcendUrl: string;\n}\n\nexport async function updateConsentManager(\n this: LocalContext,\n {\n auth,\n bundleTypes = [ConsentBundleType.Production, ConsentBundleType.Test],\n deploy,\n transcendUrl,\n }: UpdateConsentManagerCommandFlags,\n): Promise<void> {\n doneInputValidation(this.process.exit);\n\n // Parse authentication as API key or path to list of API keys\n const apiKeyOrList = await validateTranscendAuth(auth);\n\n // Handle single update\n if (typeof apiKeyOrList === 'string') {\n // Update consent manager\n await updateConsentManagerVersionToLatest({\n deploy,\n transcendUrl,\n auth: apiKeyOrList,\n bundleTypes,\n });\n logger.info(colors.green('Successfully updated Consent Manager!'));\n } else {\n await mapSeries(apiKeyOrList, async (apiKey) => {\n logger.info(\n colors.magenta(\n `Updating Consent Manager for organization \"${apiKey.organizationName}\"...`,\n ),\n );\n\n await updateConsentManagerVersionToLatest({\n deploy,\n transcendUrl,\n auth: apiKey.apiKey,\n bundleTypes,\n });\n\n logger.info(\n colors.green(\n `Successfully updated Consent Manager for organization \"${apiKey.organizationName}\"!`,\n ),\n );\n });\n logger.info(colors.green('Successfully updated Consent Managers!'));\n }\n}\n"]}
@@ -1,12 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunk56TB3NTQcjs = require('./chunk-56TB3NTQ.cjs');require('./chunk-TD7ADMVO.cjs');var _chunkMBB6OD4Ecjs = require('./chunk-MBB6OD4E.cjs');var _chunkWKCTKYN4cjs = require('./chunk-WKCTKYN4.cjs');require('./chunk-LCDYXJN6.cjs');var _chunkUPUHHIXZcjs = require('./chunk-UPUHHIXZ.cjs');var _chunkZUNVPK23cjs = require('./chunk-ZUNVPK23.cjs');require('./chunk-6IHSPKMP.cjs');var _chunkDBYKJZEAcjs = require('./chunk-DBYKJZEA.cjs');require('./chunk-Q7I37FJV.cjs');var _colors = require('colors'); var _colors2 = _interopRequireDefault(_colors);var _cliprogress = require('cli-progress'); var _cliprogress2 = _interopRequireDefault(_cliprogress);var _persistedstate = require('@transcend-io/persisted-state');var _iots = require('io-ts'); var A = _interopRequireWildcard(_iots); var T = _interopRequireWildcard(_iots); var o = _interopRequireWildcard(_iots);var _privacytypes = require('@transcend-io/privacy-types');var _typeutils = require('@transcend-io/type-utils');var Se=T.intersection([T.type({nodes:T.array(_privacytypes.PreferenceQueryResponseItem)}),T.partial({cursor:T.string})]),Ie=["ENOTFOUND","ETIMEDOUT","504 Gateway Time-out","Task timed out after"];async function fe(m,{identifiers:n,partitionKey:w,skipLogging:d=!1}){let s=[],u=_chunkDBYKJZEAcjs.b.call(void 0, n,100),i=new Date().getTime(),t=new _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic);d||t.start(n.length,0);let c=0;await _chunkUPUHHIXZcjs.b.call(void 0, u,async e=>{let a=0,g=3;for(;a<g;)try{let p=await m.post(`v1/preferences/${w}/query`,{json:{filter:{identifiers:e},limit:e.length}}).json(),h=_typeutils.decodeCodec.call(void 0, Se,p);s.push(...h.nodes),c+=e.length,t.update(c);break}catch(p){a+=1;let h=_optionalChain([p, 'optionalAccess', _2 => _2.response, 'optionalAccess', _3 => _3.body])||_optionalChain([p, 'optionalAccess', _4 => _4.message])||"";if(a>=g||!Ie.some(P=>h.includes(P)))throw new Error(`Received an error from server after ${a} attempts: ${h}`);_chunkZUNVPK23cjs.a.warn(_colors2.default.yellow(`[RETRYING FAILED REQUEST - Attempt ${a}] Failed to fetch ${e.length} user preferences from partition ${w}: ${h}`))}},{concurrency:40}),t.stop();let r=new Date().getTime()-i;return d||_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Completed download in "${r/1e3}" seconds.`)),s}function Q({row:m,columnToPurposeName:n,purposeSlugs:w,preferenceTopics:d}){let s={};return Object.entries(n).forEach(([u,{purpose:i,preference:t,valueMapping:c}])=>{if(!w.includes(i))throw new Error(`Invalid purpose slug: ${i}, expected: ${w.join(", ")}`);if(t){let f=d.find(g=>g.slug===t&&g.purpose.trackingType===i);if(!f){let g=d.filter(p=>p.purpose.trackingType===i).map(p=>p.slug);throw new Error(`Invalid preference slug: ${t} for purpose: ${i}. Allowed preference slugs for purpose are: ${g.join(",")}`)}s[i]||(s[i]={preferences:[]}),s[i].preferences||(s[i].preferences=[]);let r=m[u],e=c[r],a=typeof e=="string"&&e.trim()||null;switch(f.type){case _privacytypes.PreferenceTopicType.Boolean:if(typeof e!="boolean")throw new Error(`Invalid value for boolean preference: ${t}, expected boolean, got: ${r}`);s[i].preferences.push({topic:t,choice:{booleanValue:e}});break;case _privacytypes.PreferenceTopicType.Select:if(typeof e!="string"&&e!==null)throw new Error(`Invalid value for select preference: ${t}, expected string or null, got: ${r}`);if(a&&!f.preferenceOptionValues.map(({slug:g})=>g).includes(a))throw new Error(`Invalid value for select preference: ${t}, expected one of: ${f.preferenceOptionValues.map(({slug:g})=>g).join(", ")}, got: ${r}`);s[i].preferences.push({topic:t,choice:{selectValue:a}});break;case _privacytypes.PreferenceTopicType.MultiSelect:if(typeof r!="string")throw new Error(`Invalid value for multi select preference: ${t}, expected string, got: ${r}`);s[i].preferences.push({topic:t,choice:{selectValues:_chunkMBB6OD4Ecjs.n.call(void 0, r).map(g=>{let p=c[g];if(typeof p!="string")throw new Error(`Invalid value for multi select preference: ${t}, expected one of: ${f.preferenceOptionValues.map(({slug:h})=>h).join(", ")}, got: ${g}`);return p}).sort((g,p)=>g.localeCompare(p))}});break;default:throw new Error(`Unknown preference type: ${f.type}`)}}else s[i]?s[i].enabled=c[m[u]]===!0:s[i]={enabled:c[m[u]]===!0}}),_typeutils.apply.call(void 0, s,(u,i)=>{if(typeof u.enabled!="boolean")throw new Error(`No mapping provided for purpose.enabled=true/false value: ${i}`);return{...u,enabled:u.enabled}})}var _inquirer = require('inquirer'); var _inquirer2 = _interopRequireDefault(_inquirer);var L="[NONE]";async function ue(m,n){let w=_chunkDBYKJZEAcjs.j.call(void 0, m.map(s=>Object.keys(s)).flat()),d=_chunkDBYKJZEAcjs.c.call(void 0, w,[...n.identifierColumn?[n.identifierColumn]:[],...Object.keys(n.columnToPurposeName)]);if(!n.timestampColum){let{timestampName:s}=await _inquirer2.default.prompt([{name:"timestampName",message:"Choose the column that will be used as the timestamp of last preference update",type:"list",default:d.find(u=>u.toLowerCase().includes("date"))||d.find(u=>u.toLowerCase().includes("time"))||d[0],choices:[...d,L]}]);n.timestampColum=s}if(_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Using timestamp column "${n.timestampColum}"`)),n.timestampColum!==L){let s=m.map((u,i)=>u[n.timestampColum]?null:[i]).filter(u=>!!u).flat();if(s.length>0)throw new Error(`The timestamp column "${n.timestampColum}" is missing a value for the following rows: ${s.join(`
2
- `)}`);_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`The timestamp column "${n.timestampColum}" is present for all row`))}return n}async function de(m,n){let w=_chunkDBYKJZEAcjs.j.call(void 0, m.map(t=>Object.keys(t)).flat()),d=_chunkDBYKJZEAcjs.c.call(void 0, w,[...n.identifierColumn?[n.identifierColumn]:[],...Object.keys(n.columnToPurposeName)]);if(!n.identifierColumn){let{identifierName:t}=await _inquirer2.default.prompt([{name:"identifierName",message:"Choose the column that will be used as the identifier to upload consent preferences by",type:"list",default:d.find(c=>c.toLowerCase().includes("email"))||d[0],choices:d}]);n.identifierColumn=t}_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Using identifier column "${n.identifierColumn}"`));let s=m.map((t,c)=>t[n.identifierColumn]?null:[c]).filter(t=>!!t).flat();if(s.length>0){let t=`The identifier column "${n.identifierColumn}" is missing a value for the following rows: ${s.join(", ")}`;if(_chunkZUNVPK23cjs.a.warn(_colors2.default.yellow(t)),!await _chunk56TB3NTQcjs.a.call(void 0, {message:"Would you like to skip rows missing an identifier?"}))throw new Error(t);let f=m.length;m=m.filter(r=>r[n.identifierColumn]),_chunkZUNVPK23cjs.a.info(_colors2.default.yellow(`Skipped ${f-m.length} rows missing an identifier`))}_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`The identifier column "${n.identifierColumn}" is present for all rows`));let u=_chunkDBYKJZEAcjs.d.call(void 0, m,n.identifierColumn),i=Object.entries(u).filter(([,t])=>t.length>1);if(i.length>0){let t=`The identifier column "${n.identifierColumn}" has duplicate values for the following rows: ${i.slice(0,10).map(([f,r])=>`${f} (${r.length})`).join(`
3
- `)}`;if(_chunkZUNVPK23cjs.a.warn(_colors2.default.yellow(t)),!await _chunk56TB3NTQcjs.a.call(void 0, {message:"Would you like to automatically take the latest update?"}))throw new Error(t);m=Object.entries(u).map(([,f])=>f.sort((e,a)=>new Date(a[n.timestampColum]).getTime()-new Date(e[n.timestampColum]).getTime())[0]).filter(f=>f)}return{currentState:n,preferences:m}}async function ge(m,n,{purposeSlugs:w,preferenceTopics:d,forceTriggerWorkflows:s}){let u=_chunkDBYKJZEAcjs.j.call(void 0, m.map(c=>Object.keys(c)).flat()),i=_chunkDBYKJZEAcjs.c.call(void 0, u,[...n.identifierColumn?[n.identifierColumn]:[],...n.timestampColum?[n.timestampColum]:[]]);if(i.length===0){if(s)return n;throw new Error("No other columns to process")}let t=[...w,...d.map(c=>`${c.purpose.trackingType}->${c.slug}`)];return await _chunkUPUHHIXZcjs.a.call(void 0, i,async c=>{let f=_chunkDBYKJZEAcjs.j.call(void 0, m.map(e=>e[c])),r=n.columnToPurposeName[c];if(r)_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Column "${c}" is associated with purpose "${r.purpose}"`));else{let{purposeName:e}=await _inquirer2.default.prompt([{name:"purposeName",message:`Choose the purpose that column ${c} is associated with`,type:"list",default:t.find(p=>p.startsWith(w[0])),choices:t}]),[a,g]=e.split("->");r={purpose:a,preference:g||null,valueMapping:{}}}await _chunkUPUHHIXZcjs.a.call(void 0, f,async e=>{if(r.valueMapping[e]!==void 0){_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Value "${e}" is associated with purpose value "${r.valueMapping[e]}"`));return}if(r.preference===null){let{purposeValue:a}=await _inquirer2.default.prompt([{name:"purposeValue",message:`Choose the purpose value for value "${e}" associated with purpose "${r.purpose}"`,type:"confirm",default:e!=="false"}]);r.valueMapping[e]=a}if(r.preference!==null){let a=d.find(p=>p.slug===r.preference);if(!a){_chunkZUNVPK23cjs.a.error(_colors2.default.red(`Preference topic "${r.preference}" not found`));return}let g=a.preferenceOptionValues.map(({slug:p})=>p);if(a.type===_privacytypes.PreferenceTopicType.Boolean){let{preferenceValue:p}=await _inquirer2.default.prompt([{name:"preferenceValue",message:`Choose the preference value for "${a.slug}" value "${e}" associated with purpose "${r.purpose}"`,type:"confirm",default:e!=="false"}]);r.valueMapping[e]=p;return}if(a.type===_privacytypes.PreferenceTopicType.Select){let{preferenceValue:p}=await _inquirer2.default.prompt([{name:"preferenceValue",message:`Choose the preference value for "${a.slug}" value "${e}" associated with purpose "${r.purpose}"`,type:"list",choices:g,default:g.find(h=>h===e)}]);r.valueMapping[e]=p;return}if(a.type===_privacytypes.PreferenceTopicType.MultiSelect){let p=_chunkMBB6OD4Ecjs.n.call(void 0, e);await _chunkUPUHHIXZcjs.a.call(void 0, p,async h=>{if(r.valueMapping[h]!==void 0)return;let{preferenceValue:P}=await _inquirer2.default.prompt([{name:"preferenceValue",message:`Choose the preference value for "${a.slug}" value "${h}" associated with purpose "${r.purpose}"`,type:"list",choices:g,default:g.find(y=>y===h)}]);r.valueMapping[h]=P});return}throw new Error(`Unknown preference topic type: ${a.type}`)}}),n.columnToPurposeName[c]=r}),n}function he({currentConsentRecord:m,pendingUpdates:n,preferenceTopics:w}){return Object.entries(n).every(([d,{preferences:s=[],enabled:u}])=>{let i=m.purposes.find(c=>c.purpose===d);return!!i&&i.enabled===u?s.every(({topic:c,choice:f})=>i.preferences&&i.preferences.find(r=>{if(r.topic!==c)return!1;let e=w.find(a=>a.slug===c&&a.purpose.trackingType===d);if(!e)throw new Error(`Could not find preference topic for ${c}`);switch(e.type){case _privacytypes.PreferenceTopicType.Boolean:return r.choice.booleanValue===f.booleanValue;case _privacytypes.PreferenceTopicType.Select:return r.choice.selectValue===f.selectValue;case _privacytypes.PreferenceTopicType.MultiSelect:let a=(r.choice.selectValues||[]).sort(),g=(f.selectValues||[]).sort();return a.length===g.length&&a.every((p,h)=>p===g[h]);default:throw new Error(`Unknown preference topic type: ${e.type}`)}})):!1})}function we({currentConsentRecord:m,pendingUpdates:n,preferenceTopics:w}){return!!Object.entries(n).find(([d,{preferences:s=[],enabled:u}])=>{let i=m.purposes.find(t=>t.purpose===d);return i?i.enabled!==u?!0:!!s.find(({topic:t,choice:c})=>{let f=(i.preferences||[]).find(e=>e.topic===t);if(!f)return!1;let r=w.find(e=>e.slug===t&&e.purpose.trackingType===d);if(!r)throw new Error(`Could not find preference topic for ${t}`);switch(r.type){case _privacytypes.PreferenceTopicType.Boolean:return f.choice.booleanValue!==c.booleanValue;case _privacytypes.PreferenceTopicType.Select:return f.choice.selectValue!==c.selectValue;case _privacytypes.PreferenceTopicType.MultiSelect:let e=(f.choice.selectValues||[]).sort(),a=(c.selectValues||[]).sort();return e.length!==a.length||!e.every((g,p)=>g===a[p]);default:throw new Error(`Unknown preference topic type: ${r.type}`)}}):!1})}async function Pe({file:m,sombra:n,purposeSlugs:w,preferenceTopics:d,partitionKey:s,skipExistingRecordCheck:u,forceTriggerWorkflows:i},t){let c=new Date().getTime(),f=t.getValue("fileMetadata");_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Reading in file: "${m}"`));let r=_chunkMBB6OD4Ecjs.q.call(void 0, m,A.record(A.string,A.string)),e={columnToPurposeName:{},pendingSafeUpdates:{},pendingConflictUpdates:{},skippedUpdates:{},...f[m]||{},lastFetchedAt:new Date().toISOString()};e=await ue(r,e),f[m]=e,await t.setValue(f,"fileMetadata");let a=await de(r,e);e=a.currentState,r=a.preferences,f[m]=e,await t.setValue(f,"fileMetadata"),e=await ge(r,e,{preferenceTopics:d,purposeSlugs:w,forceTriggerWorkflows:i}),f[m]=e,await t.setValue(f,"fileMetadata");let g=r.map(y=>y[e.identifierColumn]),p=u?[]:await fe(n,{identifiers:g.map(y=>({value:y})),partitionKey:s}),h=_chunkDBYKJZEAcjs.e.call(void 0, p,"userId");e.pendingConflictUpdates={},e.pendingSafeUpdates={},e.skippedUpdates={},r.forEach(y=>{let $=y[e.identifierColumn],E=Q({row:y,columnToPurposeName:e.columnToPurposeName,preferenceTopics:d,purposeSlugs:w}),U=h[$];if(i&&!U)throw new Error(`No existing consent record found for user with id: ${$}.
4
- When 'forceTriggerWorkflows' is set all the user identifiers should contain a consent record`);if(U&&he({currentConsentRecord:U,pendingUpdates:E,preferenceTopics:d})&&!i){e.skippedUpdates[$]=y;return}if(U&&we({currentConsentRecord:U,pendingUpdates:E,preferenceTopics:d})){e.pendingConflictUpdates[$]={row:y,record:U};return}e.pendingSafeUpdates[$]=y}),f[m]=e,await t.setValue(f,"fileMetadata");let P=new Date().getTime();_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully pre-processed file: "${m}" in ${(P-c)/1e3}s`))}var je=o.type({purpose:o.string,preference:o.union([o.string,o.null]),valueMapping:o.record(o.string,o.union([o.string,o.boolean,o.null]))}),Ae=o.intersection([o.type({columnToPurposeName:o.record(o.string,je),lastFetchedAt:o.string,pendingSafeUpdates:o.record(o.string,o.record(o.string,o.string)),pendingConflictUpdates:o.record(o.string,o.type({record:_privacytypes.PreferenceQueryResponseItem,row:o.record(o.string,o.string)})),skippedUpdates:o.record(o.string,o.record(o.string,o.string))}),o.partial({identifierColumn:o.string,timestampColum:o.string})]),$e=o.type({fileMetadata:o.record(o.string,Ae),failingUpdates:o.record(o.string,o.type({uploadedAt:o.string,error:o.string,update:_privacytypes.PreferenceUpdateItem})),pendingUpdates:o.record(o.string,_privacytypes.PreferenceUpdateItem)});async function Te({auth:m,sombraAuth:n,receiptFilepath:w,file:d,partition:s,isSilent:u=!0,dryRun:i=!1,skipWorkflowTriggers:t=!1,skipConflictUpdates:c=!1,skipExistingRecordCheck:f=!1,attributes:r=[],transcendUrl:e,forceTriggerWorkflows:a=!1}){let g=_chunkMBB6OD4Ecjs.p.call(void 0, r),p=new (0, _persistedstate.PersistedState)(w,$e,{fileMetadata:{},failingUpdates:{},pendingUpdates:{}}),h=p.getValue("failingUpdates"),P=p.getValue("pendingUpdates"),y=p.getValue("fileMetadata");_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Restored cache, there are:
5
- ${Object.values(h).length} failing requests to be retried
6
- ${Object.values(P).length} pending requests to be processed
7
- The following files are stored in cache and will be used:
8
- ${Object.keys(y).map(b=>b).join(`
9
- `)}
10
- The following file will be processed: ${d}
11
- `));let $=_chunkUPUHHIXZcjs.Wd.call(void 0, e,m),[E,U,X]=await Promise.all([_chunkUPUHHIXZcjs.Xd.call(void 0, e,m,n),a?Promise.resolve([]):_chunkUPUHHIXZcjs.Uc.call(void 0, $),a?Promise.resolve([]):_chunkUPUHHIXZcjs.fe.call(void 0, $)]);await Pe({file:d,purposeSlugs:U.map(b=>b.trackingType),preferenceTopics:X,sombra:E,partitionKey:s,skipExistingRecordCheck:f,forceTriggerWorkflows:a},p);let x={};y=p.getValue("fileMetadata");let M=y[d];if(_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Found ${Object.entries(M.pendingSafeUpdates).length} safe updates in ${d}`)),_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Found ${Object.entries(M.pendingConflictUpdates).length} conflict updates in ${d}`)),_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Found ${Object.entries(M.skippedUpdates).length} skipped updates in ${d}`)),Object.entries({...M.pendingSafeUpdates,...c?{}:_typeutils.apply.call(void 0, M.pendingConflictUpdates,({row:b})=>b)}).forEach(([b,C])=>{let D=M.timestampColum===L?new Date:new Date(C[M.timestampColum]),R=Q({row:C,columnToPurposeName:M.columnToPurposeName,preferenceTopics:X,purposeSlugs:U.map(O=>O.trackingType)});x[b]={userId:b,partition:s,timestamp:D.toISOString(),purposes:Object.entries(R).map(([O,Re])=>({...Re,purpose:O,workflowSettings:{attributes:g,isSilent:u,skipWorkflowTrigger:t}}))}}),await p.setValue(x,"pendingUpdates"),await p.setValue({},"failingUpdates"),i){_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Dry run complete, exiting. ${Object.values(x).length} pending updates. Check file: ${w}`));return}_chunkZUNVPK23cjs.a.info(_colors2.default.magenta(`Uploading ${Object.values(x).length} preferences to partition: ${s}`));let Ue=new Date().getTime(),G=new _cliprogress2.default.SingleBar({},_cliprogress2.default.Presets.shades_classic),Z=0,W=Object.entries(x),ke=_chunkDBYKJZEAcjs.b.call(void 0, W,t?100:10);G.start(W.length,0),await _chunkUPUHHIXZcjs.b.call(void 0, ke,async b=>{try{await E.put("v1/preferences",{json:{records:b.map(([,C])=>C),skipWorkflowTriggers:t,forceTriggerWorkflows:a}}).json()}catch(C){try{let R=JSON.parse(_optionalChain([C, 'optionalAccess', _5 => _5.response, 'optionalAccess', _6 => _6.body])||"{}");R.error&&_chunkZUNVPK23cjs.a.error(_colors2.default.red(`Error: ${R.error}`))}catch (e2){}_chunkZUNVPK23cjs.a.error(_colors2.default.red(`Failed to upload ${b.length} user preferences to partition ${s}: ${_optionalChain([C, 'optionalAccess', _7 => _7.response, 'optionalAccess', _8 => _8.body])||_optionalChain([C, 'optionalAccess', _9 => _9.message])}`));let D=p.getValue("failingUpdates");b.forEach(([R,O])=>{D[R]={uploadedAt:new Date().toISOString(),update:O,error:_optionalChain([C, 'optionalAccess', _10 => _10.response, 'optionalAccess', _11 => _11.body])||_optionalChain([C, 'optionalAccess', _12 => _12.message])||"Unknown error"}}),await p.setValue(D,"failingUpdates")}Z+=b.length,G.update(Z)},{concurrency:40}),G.stop();let Me=new Date().getTime()-Ue;_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Successfully uploaded ${W.length} user preferences to partition ${s} in "${Me/1e3}" seconds!`))}var _fs = require('fs');var _path = require('path');async function kr({auth:m,partition:n,sombraAuth:w,transcendUrl:d,file:s="",directory:u,dryRun:i,skipExistingRecordCheck:t,receiptFileDir:c,skipWorkflowTriggers:f,forceTriggerWorkflows:r,skipConflictUpdates:e,isSilent:a,attributes:g,concurrency:p}){u&&s&&(_chunkZUNVPK23cjs.a.error(_colors2.default.red("Cannot provide both a directory and a file. Please provide only one.")),this.process.exit(1)),!s&&!u&&(_chunkZUNVPK23cjs.a.error(_colors2.default.red("A file or directory must be provided. Please provide one using --file=./preferences.csv or --directory=./preferences")),this.process.exit(1)),_chunkWKCTKYN4cjs.a.call(void 0, this.process.exit);let h=[];if(u)try{let y=_fs.readdirSync.call(void 0, u).filter($=>$.endsWith(".csv"));y.length===0&&(_chunkZUNVPK23cjs.a.error(_colors2.default.red(`No CSV files found in directory: ${u}`)),this.process.exit(1)),h.push(...y.map($=>_path.join.call(void 0, u,$)))}catch(P){_chunkZUNVPK23cjs.a.error(_colors2.default.red(`Failed to read directory: ${u}`)),_chunkZUNVPK23cjs.a.error(_colors2.default.red(P.message)),this.process.exit(1)}else try{s.endsWith(".csv")||(_chunkZUNVPK23cjs.a.error(_colors2.default.red("File must be a CSV file")),this.process.exit(1)),h.push(s)}catch(P){_chunkZUNVPK23cjs.a.error(_colors2.default.red(`Failed to access file: ${s}`)),_chunkZUNVPK23cjs.a.error(_colors2.default.red(P.message)),this.process.exit(1)}_chunkZUNVPK23cjs.a.info(_colors2.default.green(`Processing ${h.length} consent preferences files for partition: ${n}`)),_chunkZUNVPK23cjs.a.debug(`Files to process: ${h.join(", ")}`),t&&_chunkZUNVPK23cjs.a.info(_colors2.default.bgYellow(`Skipping existing record check: ${t}`)),await _chunkUPUHHIXZcjs.b.call(void 0, h,async P=>{let y=_path.basename.call(void 0, P).replace(".csv","");await Te({receiptFilepath:_path.join.call(void 0, c,`${y}-receipts.json`),auth:m,sombraAuth:w,file:P,partition:n,transcendUrl:d,skipConflictUpdates:e,skipWorkflowTriggers:f,skipExistingRecordCheck:t,isSilent:a,dryRun:i,attributes:_chunkMBB6OD4Ecjs.n.call(void 0, g),forceTriggerWorkflows:r})},{concurrency:p})}exports.uploadPreferences = kr;
12
- //# sourceMappingURL=impl-5MGEJPTO.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/cli/cli/dist/impl-5MGEJPTO.cjs","../src/commands/consent/upload-preferences/impl.ts","../src/lib/preference-management/uploadPreferenceManagementPreferencesInteractive.ts","../src/lib/preference-management/parsePreferenceManagementCsv.ts","../src/lib/preference-management/getPreferencesForIdentifiers.ts","../src/lib/preference-management/parsePreferenceIdentifiersFromCsv.ts","../src/lib/preference-management/parsePreferenceAndPurposeValuesFromCsv.ts"],"names":["PreferenceRecordsQueryResponse","PreferenceQueryResponseItem","MSGS","getPreferencesForIdentifiers","sombra","identifiers","partitionKey","skipLogging","results","groupedIdentifiers","chunk_default","t0","progressBar","cliProgress","total","map","group","attempts","maxAttempts","rawResult","result","decodeCodec","err","msg","errorMessage"],"mappings":"AAAA,u/BAAwC,gCAA6B,wDAAyD,wDAA0C,gCAA6B,wDAAoF,wDAAyC,gCAA6B,wDAAuE,gCAA6B,gFCChb,qGCWK,+DAEO,qJCXZ,2DCHyB,qDAKhB,IAKtBA,EAAAA,CAAmC,CAAA,CAAA,YAAA,CAAa,CAClD,CAAA,CAAA,IAAA,CAAK,CACL,KAAA,CAAS,CAAA,CAAA,KAAA,CAAMC,yCAA2B,CAC5C,CAAC,CAAA,CACC,CAAA,CAAA,OAAA,CAAQ,CAER,MAAA,CAAU,CAAA,CAAA,MACZ,CAAC,CACH,CAAC,CAAA,CAEKC,EAAAA,CAAO,CACX,WAAA,CACA,WAAA,CACA,sBAAA,CACA,sBACF,CAAA,CASA,MAAA,SAAsBC,EAAAA,CACpBC,CAAAA,CACA,CACE,WAAA,CAAAC,CAAAA,CACA,YAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CAAc,CAAA,CAChB,CAAA,CAWwC,CACxC,IAAMC,CAAAA,CAAyC,CAAC,CAAA,CAC1CC,CAAAA,CAAqBC,iCAAAA,CAAML,CAAa,GAAG,CAAA,CAG3CM,CAAAA,CAAK,IAAI,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,CAAA,CACxBC,CAAAA,CAAc,IAAIC,qBAAAA,CAAY,SAAA,CAClC,CAAC,CAAA,CACDA,qBAAAA,CAAY,OAAA,CAAQ,cACtB,CAAA,CACKN,CAAAA,EACHK,CAAAA,CAAY,KAAA,CAAMP,CAAAA,CAAY,MAAA,CAAQ,CAAC,CAAA,CAGzC,IAAIS,CAAAA,CAAQ,CAAA,CACZ,MAAMC,iCAAAA,CACJN,CACA,MAAOO,CAAAA,EAAU,CAEf,IAAIC,CAAAA,CAAW,CAAA,CACTC,CAAAA,CAAc,CAAA,CACpB,GAAA,CAAA,CAAOD,CAAAA,CAAWC,CAAAA,CAAAA,CAChB,GAAI,CACF,IAAMC,CAAAA,CAAY,MAAMf,CAAAA,CACrB,IAAA,CAAK,CAAA,eAAA,EAAkBE,CAAY,CAAA,MAAA,CAAA,CAAU,CAC5C,IAAA,CAAM,CACJ,MAAA,CAAQ,CACN,WAAA,CAAaU,CACf,CAAA,CACA,KAAA,CAAOA,CAAAA,CAAM,MACf,CACF,CAAC,CAAA,CACA,IAAA,CAAK,CAAA,CAEFI,CAAAA,CAASC,oCAAAA,EAAYrB,CAAgCmB,CAAS,CAAA,CACpEX,CAAAA,CAAQ,IAAA,CAAK,GAAGY,CAAAA,CAAO,KAAK,CAAA,CAC5BN,CAAAA,EAASE,CAAAA,CAAM,MAAA,CACfJ,CAAAA,CAAY,MAAA,CAAOE,CAAK,CAAA,CACxB,KACF,CAAA,KAAA,CAASQ,CAAAA,CAAK,CACZL,CAAAA,EAAY,CAAA,CACZ,IAAMM,CAAAA,iBAAMD,CAAAA,6BAAK,QAAA,6BAAU,MAAA,kBAAQA,CAAAA,6BAAK,SAAA,EAAW,EAAA,CACnD,EAAA,CACEL,CAAAA,EAAYC,CAAAA,EACZ,CAAChB,EAAAA,CAAK,IAAA,CAAMsB,CAAAA,EAAiBD,CAAAA,CAAI,QAAA,CAASC,CAAY,CAAC,CAAA,CAEvD,MAAM,IAAI,KAAA,CACR,CAAA,oCAAA,EAAuCP,CAAQ,CAAA,WAAA,EAAcM,CAAG,CAAA,CAAA;ACclE;ACEW;AJ5ErB,oGAAA;AAoDM;AAGA;AAAA;AAKQ;AAAK;AACgC,sCAAA;AA4IvC","file":"/home/runner/work/cli/cli/dist/impl-5MGEJPTO.cjs","sourcesContent":[null,"import type { LocalContext } from '../../../context';\nimport colors from 'colors';\n\nimport { logger } from '../../../logger';\nimport { uploadPreferenceManagementPreferencesInteractive } from '../../../lib/preference-management';\nimport { splitCsvToList } from '../../../lib/requests';\nimport { readdirSync } from 'node:fs';\nimport { map } from '../../../lib/bluebird-replace';\nimport { basename, join } from 'node:path';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation';\n\nexport interface UploadPreferencesCommandFlags {\n auth: string;\n partition: string;\n sombraAuth?: string;\n transcendUrl: string;\n file?: string;\n directory?: string;\n dryRun: boolean;\n skipExistingRecordCheck: boolean;\n receiptFileDir: string;\n skipWorkflowTriggers: boolean;\n forceTriggerWorkflows: boolean;\n skipConflictUpdates: boolean;\n isSilent: boolean;\n attributes: string;\n receiptFilepath: string;\n concurrency: number;\n}\n\nexport async function uploadPreferences(\n this: LocalContext,\n {\n auth,\n partition,\n sombraAuth,\n transcendUrl,\n file = '',\n directory,\n dryRun,\n skipExistingRecordCheck,\n receiptFileDir,\n skipWorkflowTriggers,\n forceTriggerWorkflows,\n skipConflictUpdates,\n isSilent,\n attributes,\n concurrency,\n }: UploadPreferencesCommandFlags,\n): Promise<void> {\n if (!!directory && !!file) {\n logger.error(\n colors.red(\n 'Cannot provide both a directory and a file. Please provide only one.',\n ),\n );\n this.process.exit(1);\n }\n\n if (!file && !directory) {\n logger.error(\n colors.red(\n 'A file or directory must be provided. Please provide one using --file=./preferences.csv or --directory=./preferences',\n ),\n );\n this.process.exit(1);\n }\n\n doneInputValidation(this.process.exit);\n\n const files: string[] = [];\n\n if (directory) {\n try {\n const filesInDirectory = readdirSync(directory);\n const csvFiles = filesInDirectory.filter((file) => file.endsWith('.csv'));\n\n if (csvFiles.length === 0) {\n logger.error(\n colors.red(`No CSV files found in directory: ${directory}`),\n );\n this.process.exit(1);\n }\n\n // Add full paths for each CSV file\n files.push(...csvFiles.map((file) => join(directory, file)));\n } catch (err) {\n logger.error(colors.red(`Failed to read directory: ${directory}`));\n logger.error(colors.red((err as Error).message));\n this.process.exit(1);\n }\n } else {\n try {\n // Verify file exists and is a CSV\n if (!file.endsWith('.csv')) {\n logger.error(colors.red('File must be a CSV file'));\n this.process.exit(1);\n }\n files.push(file);\n } catch (err) {\n logger.error(colors.red(`Failed to access file: ${file}`));\n logger.error(colors.red((err as Error).message));\n this.process.exit(1);\n }\n }\n\n logger.info(\n colors.green(\n `Processing ${files.length} consent preferences files for partition: ${partition}`,\n ),\n );\n logger.debug(`Files to process: ${files.join(', ')}`);\n\n if (skipExistingRecordCheck) {\n logger.info(\n colors.bgYellow(\n `Skipping existing record check: ${skipExistingRecordCheck}`,\n ),\n );\n }\n\n await map(\n files,\n async (filePath) => {\n const fileName = basename(filePath).replace('.csv', '');\n await uploadPreferenceManagementPreferencesInteractive({\n receiptFilepath: join(receiptFileDir, `${fileName}-receipts.json`),\n auth,\n sombraAuth,\n file: filePath,\n partition,\n transcendUrl,\n skipConflictUpdates,\n skipWorkflowTriggers,\n skipExistingRecordCheck,\n isSilent,\n dryRun,\n attributes: splitCsvToList(attributes),\n forceTriggerWorkflows,\n });\n },\n { concurrency },\n );\n}\n","import {\n buildTranscendGraphQLClient,\n createSombraGotInstance,\n fetchAllPurposes,\n fetchAllPreferenceTopics,\n PreferenceTopic,\n Purpose,\n} from '../graphql';\nimport colors from 'colors';\nimport { map } from '../bluebird-replace';\nimport { chunk } from 'lodash-es';\nimport { logger } from '../../logger';\nimport cliProgress from 'cli-progress';\nimport { parseAttributesFromString } from '../requests';\nimport { PersistedState } from '@transcend-io/persisted-state';\nimport { parsePreferenceManagementCsvWithCache } from './parsePreferenceManagementCsv';\nimport { PreferenceState } from './codecs';\nimport { PreferenceUpdateItem } from '@transcend-io/privacy-types';\nimport { apply } from '@transcend-io/type-utils';\nimport { NONE_PREFERENCE_MAP } from './parsePreferenceTimestampsFromCsv';\nimport { getPreferenceUpdatesFromRow } from './getPreferenceUpdatesFromRow';\n\n/**\n * Upload a set of consent preferences\n *\n * @param options - Options\n */\nexport async function uploadPreferenceManagementPreferencesInteractive({\n auth,\n sombraAuth,\n receiptFilepath,\n file,\n partition,\n isSilent = true,\n dryRun = false,\n skipWorkflowTriggers = false,\n skipConflictUpdates = false,\n skipExistingRecordCheck = false,\n attributes = [],\n transcendUrl,\n forceTriggerWorkflows = false,\n}: {\n /** The Transcend API key */\n auth: string;\n /** Sombra API key authentication */\n sombraAuth?: string;\n /** Partition key */\n partition: string;\n /** File where to store receipt and continue from where left off */\n receiptFilepath: string;\n /** The file to process */\n file: string;\n /** API URL for Transcend backend */\n transcendUrl: string;\n /** Whether to do a dry run */\n dryRun?: boolean;\n /** Whether to upload as isSilent */\n isSilent?: boolean;\n /** Attributes string pre-parse. In format Key:Value */\n attributes?: string[];\n /** Skip workflow triggers */\n skipWorkflowTriggers?: boolean;\n /**\n * When true, only update preferences that do not conflict with existing\n * preferences. When false, update all preferences in CSV based on timestamp.\n */\n skipConflictUpdates?: boolean;\n /** Whether to skip the check for existing records. SHOULD ONLY BE USED FOR INITIAL UPLOAD */\n skipExistingRecordCheck?: boolean;\n /** Whether to force trigger workflows */\n forceTriggerWorkflows?: boolean;\n}): Promise<void> {\n // Parse out the extra attributes to apply to all requests uploaded\n const parsedAttributes = parseAttributesFromString(attributes);\n\n // Create a new state file to store the requests from this run\n const preferenceState = new PersistedState(receiptFilepath, PreferenceState, {\n fileMetadata: {},\n failingUpdates: {},\n pendingUpdates: {},\n });\n const failingRequests = preferenceState.getValue('failingUpdates');\n const pendingRequests = preferenceState.getValue('pendingUpdates');\n let fileMetadata = preferenceState.getValue('fileMetadata');\n\n logger.info(\n colors.magenta(\n 'Restored cache, there are: \\n' +\n `${\n Object.values(failingRequests).length\n } failing requests to be retried\\n` +\n `${\n Object.values(pendingRequests).length\n } pending requests to be processed\\n` +\n `The following files are stored in cache and will be used:\\n${Object.keys(\n fileMetadata,\n )\n .map((x) => x)\n .join('\\n')}\\n` +\n `The following file will be processed: ${file}\\n`,\n ),\n );\n\n // Create GraphQL client to connect to Transcend backend\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n const [sombra, purposes, preferenceTopics] = await Promise.all([\n // Create sombra instance to communicate with\n createSombraGotInstance(transcendUrl, auth, sombraAuth),\n // get all purposes and topics\n forceTriggerWorkflows\n ? Promise.resolve([] as Purpose[])\n : fetchAllPurposes(client),\n forceTriggerWorkflows\n ? Promise.resolve([] as PreferenceTopic[])\n : fetchAllPreferenceTopics(client),\n ]);\n\n // Process the file\n await parsePreferenceManagementCsvWithCache(\n {\n file,\n purposeSlugs: purposes.map((x) => x.trackingType),\n preferenceTopics,\n sombra,\n partitionKey: partition,\n skipExistingRecordCheck,\n forceTriggerWorkflows,\n },\n preferenceState,\n );\n\n // Construct the pending updates\n const pendingUpdates: Record<string, PreferenceUpdateItem> = {};\n fileMetadata = preferenceState.getValue('fileMetadata');\n const metadata = fileMetadata[file];\n\n logger.info(\n colors.magenta(\n `Found ${\n Object.entries(metadata.pendingSafeUpdates).length\n } safe updates in ${file}`,\n ),\n );\n logger.info(\n colors.magenta(\n `Found ${\n Object.entries(metadata.pendingConflictUpdates).length\n } conflict updates in ${file}`,\n ),\n );\n logger.info(\n colors.magenta(\n `Found ${\n Object.entries(metadata.skippedUpdates).length\n } skipped updates in ${file}`,\n ),\n );\n\n // Update either safe updates only or safe + conflict\n Object.entries({\n ...metadata.pendingSafeUpdates,\n ...(skipConflictUpdates\n ? {}\n : apply(metadata.pendingConflictUpdates, ({ row }) => row)),\n }).forEach(([userId, update]) => {\n // Determine timestamp\n const timestamp =\n metadata.timestampColum === NONE_PREFERENCE_MAP\n ? new Date()\n : new Date(update[metadata.timestampColum!]);\n\n // Determine updates\n const updates = getPreferenceUpdatesFromRow({\n row: update,\n columnToPurposeName: metadata.columnToPurposeName,\n preferenceTopics,\n purposeSlugs: purposes.map((x) => x.trackingType),\n });\n pendingUpdates[userId] = {\n userId,\n partition,\n timestamp: timestamp.toISOString(),\n purposes: Object.entries(updates).map(([purpose, value]) => ({\n ...value,\n purpose,\n workflowSettings: {\n attributes: parsedAttributes,\n isSilent,\n skipWorkflowTrigger: skipWorkflowTriggers,\n },\n })),\n };\n });\n await preferenceState.setValue(pendingUpdates, 'pendingUpdates');\n await preferenceState.setValue({}, 'failingUpdates');\n\n // Exist early if dry run\n if (dryRun) {\n logger.info(\n colors.green(\n `Dry run complete, exiting. ${\n Object.values(pendingUpdates).length\n } pending updates. Check file: ${receiptFilepath}`,\n ),\n );\n return;\n }\n\n logger.info(\n colors.magenta(\n `Uploading ${\n Object.values(pendingUpdates).length\n } preferences to partition: ${partition}`,\n ),\n );\n\n // Time duration\n const t0 = new Date().getTime();\n\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n\n // Build a GraphQL client\n let total = 0;\n const updatesToRun = Object.entries(pendingUpdates);\n const chunkedUpdates = chunk(updatesToRun, skipWorkflowTriggers ? 100 : 10);\n progressBar.start(updatesToRun.length, 0);\n await map(\n chunkedUpdates,\n async (currentChunk) => {\n // Make the request\n try {\n await sombra\n .put('v1/preferences', {\n json: {\n records: currentChunk.map(([, update]) => update),\n skipWorkflowTriggers,\n forceTriggerWorkflows,\n },\n })\n .json();\n } catch (err) {\n try {\n const parsed = JSON.parse(err?.response?.body || '{}');\n if (parsed.error) {\n logger.error(colors.red(`Error: ${parsed.error}`));\n }\n } catch (e) {\n // continue\n }\n logger.error(\n colors.red(\n `Failed to upload ${\n currentChunk.length\n } user preferences to partition ${partition}: ${\n err?.response?.body || err?.message\n }`,\n ),\n );\n const failingUpdates = preferenceState.getValue('failingUpdates');\n currentChunk.forEach(([userId, update]) => {\n failingUpdates[userId] = {\n uploadedAt: new Date().toISOString(),\n update,\n error: err?.response?.body || err?.message || 'Unknown error',\n };\n });\n await preferenceState.setValue(failingUpdates, 'failingUpdates');\n }\n\n total += currentChunk.length;\n progressBar.update(total);\n },\n {\n concurrency: 40,\n },\n );\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n logger.info(\n colors.green(\n `Successfully uploaded ${\n updatesToRun.length\n } user preferences to partition ${partition} in \"${\n totalTime / 1000\n }\" seconds!`,\n ),\n );\n}\n","import { PersistedState } from '@transcend-io/persisted-state';\nimport type { Got } from 'got';\nimport { keyBy } from 'lodash-es';\nimport * as t from 'io-ts';\nimport colors from 'colors';\nimport { FileMetadataState, PreferenceState } from './codecs';\nimport { logger } from '../../logger';\nimport { readCsv } from '../requests';\nimport { getPreferencesForIdentifiers } from './getPreferencesForIdentifiers';\nimport { PreferenceTopic } from '../graphql';\nimport { getPreferenceUpdatesFromRow } from './getPreferenceUpdatesFromRow';\nimport { parsePreferenceTimestampsFromCsv } from './parsePreferenceTimestampsFromCsv';\nimport { parsePreferenceIdentifiersFromCsv } from './parsePreferenceIdentifiersFromCsv';\nimport { parsePreferenceAndPurposeValuesFromCsv } from './parsePreferenceAndPurposeValuesFromCsv';\nimport { checkIfPendingPreferenceUpdatesAreNoOp } from './checkIfPendingPreferenceUpdatesAreNoOp';\nimport { checkIfPendingPreferenceUpdatesCauseConflict } from './checkIfPendingPreferenceUpdatesCauseConflict';\n\n/**\n * Parse a file into the cache\n *\n *\n * @param options - Options\n * @param cache - The cache to store the parsed file in\n * @returns The cache with the parsed file\n */\nexport async function parsePreferenceManagementCsvWithCache(\n {\n file,\n sombra,\n purposeSlugs,\n preferenceTopics,\n partitionKey,\n skipExistingRecordCheck,\n forceTriggerWorkflows,\n }: {\n /** File to parse */\n file: string;\n /** The purpose slugs that are allowed to be updated */\n purposeSlugs: string[];\n /** The preference topics */\n preferenceTopics: PreferenceTopic[];\n /** Sombra got instance */\n sombra: Got;\n /** Partition key */\n partitionKey: string;\n /** Whether to skip the check for existing records. SHOULD ONLY BE USED FOR INITIAL UPLOAD */\n skipExistingRecordCheck: boolean;\n /** Wheather to force workflow triggers */\n forceTriggerWorkflows: boolean;\n },\n cache: PersistedState<typeof PreferenceState>,\n): Promise<void> {\n // Start the timer\n const t0 = new Date().getTime();\n\n // Get the current metadata\n const fileMetadata = cache.getValue('fileMetadata');\n\n // Read in the file\n logger.info(colors.magenta(`Reading in file: \"${file}\"`));\n let preferences = readCsv(file, t.record(t.string, t.string));\n\n // start building the cache, can use previous cache as well\n let currentState: FileMetadataState = {\n columnToPurposeName: {},\n pendingSafeUpdates: {},\n pendingConflictUpdates: {},\n skippedUpdates: {},\n // Load in the last fetched time\n ...((fileMetadata[file] || {}) as Partial<FileMetadataState>),\n lastFetchedAt: new Date().toISOString(),\n };\n\n // Validate that all timestamps are present in the file\n currentState = await parsePreferenceTimestampsFromCsv(\n preferences,\n currentState,\n );\n fileMetadata[file] = currentState;\n await cache.setValue(fileMetadata, 'fileMetadata');\n\n // Validate that all identifiers are present and unique\n const result = await parsePreferenceIdentifiersFromCsv(\n preferences,\n currentState,\n );\n currentState = result.currentState;\n preferences = result.preferences;\n fileMetadata[file] = currentState;\n await cache.setValue(fileMetadata, 'fileMetadata');\n\n // Ensure all other columns are mapped to purpose and preference\n // slug values\n currentState = await parsePreferenceAndPurposeValuesFromCsv(\n preferences,\n currentState,\n {\n preferenceTopics,\n purposeSlugs,\n forceTriggerWorkflows,\n },\n );\n fileMetadata[file] = currentState;\n await cache.setValue(fileMetadata, 'fileMetadata');\n\n // Grab existing preference store records\n const identifiers = preferences.map(\n (pref) => pref[currentState.identifierColumn!],\n );\n const existingConsentRecords = skipExistingRecordCheck\n ? []\n : await getPreferencesForIdentifiers(sombra, {\n identifiers: identifiers.map((x) => ({ value: x })),\n partitionKey,\n });\n const consentRecordByIdentifier = keyBy(existingConsentRecords, 'userId');\n\n // Clear out previous updates\n currentState.pendingConflictUpdates = {};\n currentState.pendingSafeUpdates = {};\n currentState.skippedUpdates = {};\n\n // Process each row\n preferences.forEach((pref) => {\n // Grab unique Id for the user\n const userId = pref[currentState.identifierColumn!];\n\n // determine updates for user\n const pendingUpdates = getPreferenceUpdatesFromRow({\n row: pref,\n columnToPurposeName: currentState.columnToPurposeName,\n preferenceTopics,\n purposeSlugs,\n });\n\n // Grab current state of the update\n const currentConsentRecord = consentRecordByIdentifier[userId];\n if (forceTriggerWorkflows && !currentConsentRecord) {\n throw new Error(\n `No existing consent record found for user with id: ${userId}. \n When 'forceTriggerWorkflows' is set all the user identifiers should contain a consent record`,\n );\n }\n // Check if the update can be skipped\n // this is the case if a record exists, and the purpose\n // and preference values are all in sync\n if (\n currentConsentRecord &&\n checkIfPendingPreferenceUpdatesAreNoOp({\n currentConsentRecord,\n pendingUpdates,\n preferenceTopics,\n }) &&\n !forceTriggerWorkflows\n ) {\n currentState.skippedUpdates[userId] = pref;\n return;\n }\n\n // Determine if there are any conflicts\n if (\n currentConsentRecord &&\n checkIfPendingPreferenceUpdatesCauseConflict({\n currentConsentRecord,\n pendingUpdates,\n preferenceTopics,\n })\n ) {\n currentState.pendingConflictUpdates[userId] = {\n row: pref,\n record: currentConsentRecord,\n };\n return;\n }\n\n // Add to pending updates\n currentState.pendingSafeUpdates[userId] = pref;\n });\n\n // Read in the file\n fileMetadata[file] = currentState;\n await cache.setValue(fileMetadata, 'fileMetadata');\n const t1 = new Date().getTime();\n logger.info(\n colors.green(\n `Successfully pre-processed file: \"${file}\" in ${(t1 - t0) / 1000}s`,\n ),\n );\n}\n","import { PreferenceQueryResponseItem } from '@transcend-io/privacy-types';\nimport type { Got } from 'got';\nimport colors from 'colors';\nimport cliProgress from 'cli-progress';\nimport { chunk } from 'lodash-es';\nimport { decodeCodec } from '@transcend-io/type-utils';\nimport * as t from 'io-ts';\nimport { map } from '../bluebird-replace';\nimport { logger } from '../../logger';\n\nconst PreferenceRecordsQueryResponse = t.intersection([\n t.type({\n nodes: t.array(PreferenceQueryResponseItem),\n }),\n t.partial({\n /** The base64 encoded(PreferenceStorePaginationKey) cursor for pagination */\n cursor: t.string,\n }),\n]);\n\nconst MSGS = [\n 'ENOTFOUND',\n 'ETIMEDOUT',\n '504 Gateway Time-out',\n 'Task timed out after',\n];\n\n/**\n * Grab the current consent preference values for a list of identifiers\n *\n * @param sombra - Backend to make API call to\n * @param options - Options\n * @returns Plaintext context information\n */\nexport async function getPreferencesForIdentifiers(\n sombra: Got,\n {\n identifiers,\n partitionKey,\n skipLogging = false,\n }: {\n /** The list of identifiers to look up */\n identifiers: {\n /** The value of the identifier */\n value: string;\n }[];\n /** The partition key to look up */\n partitionKey: string;\n /** Whether to skip logging */\n skipLogging?: boolean;\n },\n): Promise<PreferenceQueryResponseItem[]> {\n const results: PreferenceQueryResponseItem[] = [];\n const groupedIdentifiers = chunk(identifiers, 100);\n\n // create a new progress bar instance and use shades_classic theme\n const t0 = new Date().getTime();\n const progressBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n if (!skipLogging) {\n progressBar.start(identifiers.length, 0);\n }\n\n let total = 0;\n await map(\n groupedIdentifiers,\n async (group) => {\n // Make the request with retry logic\n let attempts = 0;\n const maxAttempts = 3;\n while (attempts < maxAttempts) {\n try {\n const rawResult = await sombra\n .post(`v1/preferences/${partitionKey}/query`, {\n json: {\n filter: {\n identifiers: group,\n },\n limit: group.length,\n },\n })\n .json();\n\n const result = decodeCodec(PreferenceRecordsQueryResponse, rawResult);\n results.push(...result.nodes);\n total += group.length;\n progressBar.update(total);\n break; // Exit loop if successful\n } catch (err) {\n attempts += 1;\n const msg = err?.response?.body || err?.message || '';\n if (\n attempts >= maxAttempts ||\n !MSGS.some((errorMessage) => msg.includes(errorMessage))\n ) {\n throw new Error(\n `Received an error from server after ${attempts} attempts: ${msg}`,\n );\n }\n\n logger.warn(\n colors.yellow(\n `[RETRYING FAILED REQUEST - Attempt ${attempts}] ` +\n `Failed to fetch ${group.length} user preferences from partition ${partitionKey}: ${msg}`,\n ),\n );\n }\n }\n },\n {\n concurrency: 40,\n },\n );\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n if (!skipLogging) {\n // Log completion time\n logger.info(\n colors.green(`Completed download in \"${totalTime / 1000}\" seconds.`),\n );\n }\n\n return results;\n}\n","import { uniq, groupBy, difference } from 'lodash-es';\nimport colors from 'colors';\nimport inquirer from 'inquirer';\nimport { FileMetadataState } from './codecs';\nimport { logger } from '../../logger';\nimport { inquirerConfirmBoolean } from '../helpers';\n\n/* eslint-disable no-param-reassign */\n\n/**\n * Parse identifiers from a CSV list of preferences\n *\n * Ensures that all rows have a valid identifier\n * and that all identifiers are unique.\n *\n * @param preferences - List of preferences\n * @param currentState - The current file metadata state for parsing this list\n * @returns The updated file metadata state\n */\nexport async function parsePreferenceIdentifiersFromCsv(\n preferences: Record<string, string>[],\n currentState: FileMetadataState,\n): Promise<{\n /** The updated state */\n currentState: FileMetadataState;\n /** The updated preferences */\n preferences: Record<string, string>[];\n}> {\n // Determine columns to map\n const columnNames = uniq(preferences.map((x) => Object.keys(x)).flat());\n\n // Determine the columns that could potentially be used for identifier\n const remainingColumnsForIdentifier = difference(columnNames, [\n ...(currentState.identifierColumn ? [currentState.identifierColumn] : []),\n ...Object.keys(currentState.columnToPurposeName),\n ]);\n\n // Determine the identifier column to work off of\n if (!currentState.identifierColumn) {\n const { identifierName } = await inquirer.prompt<{\n /** Identifier name */\n identifierName: string;\n }>([\n {\n name: 'identifierName',\n message:\n 'Choose the column that will be used as the identifier to upload consent preferences by',\n type: 'list',\n default:\n remainingColumnsForIdentifier.find((col) =>\n col.toLowerCase().includes('email'),\n ) || remainingColumnsForIdentifier[0],\n choices: remainingColumnsForIdentifier,\n },\n ]);\n currentState.identifierColumn = identifierName;\n }\n logger.info(\n colors.magenta(\n `Using identifier column \"${currentState.identifierColumn}\"`,\n ),\n );\n\n // Validate that the identifier column is present for all rows and unique\n const identifierColumnsMissing = preferences\n .map((pref, ind) => (pref[currentState.identifierColumn!] ? null : [ind]))\n .filter((x): x is number[] => !!x)\n .flat();\n if (identifierColumnsMissing.length > 0) {\n const msg = `The identifier column \"${\n currentState.identifierColumn\n }\" is missing a value for the following rows: ${identifierColumnsMissing.join(\n ', ',\n )}`;\n logger.warn(colors.yellow(msg));\n\n // Ask user if they would like to skip rows missing an identifier\n const skip = await inquirerConfirmBoolean({\n message: 'Would you like to skip rows missing an identifier?',\n });\n if (!skip) {\n throw new Error(msg);\n }\n\n // Filter out rows missing an identifier\n const previous = preferences.length;\n preferences = preferences.filter(\n (pref) => pref[currentState.identifierColumn!],\n );\n logger.info(\n colors.yellow(\n `Skipped ${previous - preferences.length} rows missing an identifier`,\n ),\n );\n }\n logger.info(\n colors.magenta(\n `The identifier column \"${currentState.identifierColumn}\" is present for all rows`,\n ),\n );\n\n // Validate that all identifiers are unique\n const rowsByUserId = groupBy(preferences, currentState.identifierColumn);\n const duplicateIdentifiers = Object.entries(rowsByUserId).filter(\n ([, rows]) => rows.length > 1,\n );\n if (duplicateIdentifiers.length > 0) {\n const msg = `The identifier column \"${\n currentState.identifierColumn\n }\" has duplicate values for the following rows: ${duplicateIdentifiers\n .slice(0, 10)\n .map(([userId, rows]) => `${userId} (${rows.length})`)\n .join('\\n')}`;\n logger.warn(colors.yellow(msg));\n\n // Ask user if they would like to take the most recent update\n // for each duplicate identifier\n const skip = await inquirerConfirmBoolean({\n message: 'Would you like to automatically take the latest update?',\n });\n if (!skip) {\n throw new Error(msg);\n }\n preferences = Object.entries(rowsByUserId)\n .map(([, rows]) => {\n const sorted = rows.sort(\n (a, b) =>\n new Date(b[currentState.timestampColum!]).getTime() -\n new Date(a[currentState.timestampColum!]).getTime(),\n );\n return sorted[0];\n })\n .filter((x) => x);\n }\n\n return { currentState, preferences };\n}\n/* eslint-enable no-param-reassign */\n","import { uniq, difference } from 'lodash-es';\nimport colors from 'colors';\nimport inquirer from 'inquirer';\nimport { FileMetadataState } from './codecs';\nimport { logger } from '../../logger';\nimport { mapSeries } from '../bluebird-replace';\nimport { PreferenceTopic } from '../graphql';\nimport { PreferenceTopicType } from '@transcend-io/privacy-types';\nimport { splitCsvToList } from '../requests';\n\n/* eslint-disable no-param-reassign */\n\n/**\n * Parse out the purpose.enabled and preference values from a CSV file\n *\n * @param preferences - List of preferences\n * @param currentState - The current file metadata state for parsing this list\n * @param options - Options\n * @returns The updated file metadata state\n */\nexport async function parsePreferenceAndPurposeValuesFromCsv(\n preferences: Record<string, string>[],\n currentState: FileMetadataState,\n {\n purposeSlugs,\n preferenceTopics,\n forceTriggerWorkflows,\n }: {\n /** The purpose slugs that are allowed to be updated */\n purposeSlugs: string[];\n /** The preference topics */\n preferenceTopics: PreferenceTopic[];\n /** Force workflow triggers */\n forceTriggerWorkflows: boolean;\n },\n): Promise<FileMetadataState> {\n // Determine columns to map\n const columnNames = uniq(preferences.map((x) => Object.keys(x)).flat());\n\n // Determine the columns that could potentially be used for identifier\n const otherColumns = difference(columnNames, [\n ...(currentState.identifierColumn ? [currentState.identifierColumn] : []),\n ...(currentState.timestampColum ? [currentState.timestampColum] : []),\n ]);\n if (otherColumns.length === 0) {\n if (forceTriggerWorkflows) {\n return currentState;\n }\n throw new Error('No other columns to process');\n }\n\n // The purpose and preferences to map to\n const purposeNames = [\n ...purposeSlugs,\n ...preferenceTopics.map((x) => `${x.purpose.trackingType}->${x.slug}`),\n ];\n\n // Ensure all columns are accounted for\n await mapSeries(otherColumns, async (col) => {\n // Determine the unique values to map in this column\n const uniqueValues = uniq(preferences.map((x) => x[col]));\n\n // Map the column to a purpose\n let purposeMapping = currentState.columnToPurposeName[col];\n if (purposeMapping) {\n logger.info(\n colors.magenta(\n `Column \"${col}\" is associated with purpose \"${purposeMapping.purpose}\"`,\n ),\n );\n } else {\n const { purposeName } = await inquirer.prompt<{\n /** purpose name */\n purposeName: string;\n }>([\n {\n name: 'purposeName',\n message: `Choose the purpose that column ${col} is associated with`,\n type: 'list',\n default: purposeNames.find((x) => x.startsWith(purposeSlugs[0])),\n choices: purposeNames,\n },\n ]);\n const [purposeSlug, preferenceSlug] = purposeName.split('->');\n purposeMapping = {\n purpose: purposeSlug,\n preference: preferenceSlug || null,\n valueMapping: {},\n };\n }\n\n // map each value to the purpose value\n await mapSeries(uniqueValues, async (value) => {\n if (purposeMapping.valueMapping[value] !== undefined) {\n logger.info(\n colors.magenta(\n `Value \"${value}\" is associated with purpose value \"${purposeMapping.valueMapping[value]}\"`,\n ),\n );\n return;\n }\n // if preference is null, this column is just for the purpose\n if (purposeMapping.preference === null) {\n const { purposeValue } = await inquirer.prompt<{\n /** purpose value */\n purposeValue: boolean;\n }>([\n {\n name: 'purposeValue',\n message: `Choose the purpose value for value \"${value}\" associated with purpose \"${purposeMapping.purpose}\"`,\n type: 'confirm',\n default: value !== 'false',\n },\n ]);\n purposeMapping.valueMapping[value] = purposeValue;\n }\n\n // if preference is not null, this column is for a specific preference\n if (purposeMapping.preference !== null) {\n const preferenceTopic = preferenceTopics.find(\n (x) => x.slug === purposeMapping.preference,\n );\n if (!preferenceTopic) {\n logger.error(\n colors.red(\n `Preference topic \"${purposeMapping.preference}\" not found`,\n ),\n );\n return;\n }\n const preferenceOptions = preferenceTopic.preferenceOptionValues.map(\n ({ slug }) => slug,\n );\n\n if (preferenceTopic.type === PreferenceTopicType.Boolean) {\n const { preferenceValue } = await inquirer.prompt<{\n /** purpose value */\n preferenceValue: boolean;\n }>([\n {\n name: 'preferenceValue',\n message:\n // eslint-disable-next-line max-len\n `Choose the preference value for \"${preferenceTopic.slug}\" value \"${value}\" associated with purpose \"${purposeMapping.purpose}\"`,\n type: 'confirm',\n default: value !== 'false',\n },\n ]);\n purposeMapping.valueMapping[value] = preferenceValue;\n return;\n }\n\n if (preferenceTopic.type === PreferenceTopicType.Select) {\n const { preferenceValue } = await inquirer.prompt<{\n /** purpose value */\n preferenceValue: boolean;\n }>([\n {\n name: 'preferenceValue',\n // eslint-disable-next-line max-len\n message: `Choose the preference value for \"${preferenceTopic.slug}\" value \"${value}\" associated with purpose \"${purposeMapping.purpose}\"`,\n type: 'list',\n choices: preferenceOptions,\n default: preferenceOptions.find((x) => x === value),\n },\n ]);\n purposeMapping.valueMapping[value] = preferenceValue;\n return;\n }\n\n if (preferenceTopic.type === PreferenceTopicType.MultiSelect) {\n const parsedValues = splitCsvToList(value);\n // need to do this serially\n await mapSeries(parsedValues, async (parsedValue) => {\n // if we already have a value, skip re-processing it again\n if (purposeMapping.valueMapping[parsedValue] !== undefined) {\n return;\n }\n const { preferenceValue } = await inquirer.prompt<{\n /** purpose value */\n preferenceValue: boolean;\n }>([\n {\n name: 'preferenceValue',\n // eslint-disable-next-line max-len\n message: `Choose the preference value for \"${preferenceTopic.slug}\" value \"${parsedValue}\" associated with purpose \"${purposeMapping.purpose}\"`,\n type: 'list',\n choices: preferenceOptions,\n default: preferenceOptions.find((x) => x === parsedValue),\n },\n ]);\n purposeMapping.valueMapping[parsedValue] = preferenceValue;\n });\n return;\n }\n\n throw new Error(\n `Unknown preference topic type: ${preferenceTopic.type}`,\n );\n }\n });\n\n currentState.columnToPurposeName[col] = purposeMapping;\n });\n\n return currentState;\n}\n/* eslint-enable no-param-reassign */\n"]}