@transcend-io/cli 9.0.0 → 10.0.0
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.
- package/LICENSE +201 -0
- package/README.md +26 -34
- package/dist/RateCounter-DFL_mnk2.mjs +2 -0
- package/dist/RateCounter-DFL_mnk2.mjs.map +1 -0
- package/dist/RequestDataSilo-_Iv44M9u.mjs +51 -0
- package/dist/RequestDataSilo-_Iv44M9u.mjs.map +1 -0
- package/dist/app-By_zDIkK.mjs +131 -0
- package/dist/app-By_zDIkK.mjs.map +1 -0
- package/dist/approvePrivacyRequests-1cguqGqq.mjs +2 -0
- package/dist/approvePrivacyRequests-1cguqGqq.mjs.map +1 -0
- package/dist/assessment-BDywVaGR.mjs +284 -0
- package/dist/assessment-BDywVaGR.mjs.map +1 -0
- package/dist/bin/bash-complete.mjs +1 -1
- package/dist/bin/bash-complete.mjs.map +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/bin/deprecated-command.mjs +1 -1
- package/dist/bin/deprecated-command.mjs.map +1 -1
- package/dist/bluebird-CUitXgsY.mjs +2 -0
- package/dist/bluebird-CUitXgsY.mjs.map +1 -0
- package/dist/buildXdiSyncEndpoint-BMaMHO7Z.mjs +9 -0
- package/dist/buildXdiSyncEndpoint-BMaMHO7Z.mjs.map +1 -0
- package/dist/bulkRestartRequests-DEPSHov-.mjs +2 -0
- package/dist/bulkRestartRequests-DEPSHov-.mjs.map +1 -0
- package/dist/bulkRetryEnrichers-BLkcFKXC.mjs +2 -0
- package/dist/bulkRetryEnrichers-BLkcFKXC.mjs.map +1 -0
- package/dist/cancelPrivacyRequests-C8MZQvsq.mjs +2 -0
- package/dist/cancelPrivacyRequests-C8MZQvsq.mjs.map +1 -0
- package/dist/codecs-BE3Wmoh8.mjs +2 -0
- package/dist/codecs-BE3Wmoh8.mjs.map +1 -0
- package/dist/codecs-Dx_vGxsl.mjs +2 -0
- package/dist/codecs-Dx_vGxsl.mjs.map +1 -0
- package/dist/{command-BlHM1nCd.mjs → command-BUnCUxva.mjs} +2 -2
- package/dist/command-BUnCUxva.mjs.map +1 -0
- package/dist/consentManagersToBusinessEntities-BDgOFga7.mjs +5 -0
- package/dist/consentManagersToBusinessEntities-BDgOFga7.mjs.map +1 -0
- package/dist/constants-AFtS5Nad.mjs +4 -0
- package/dist/constants-AFtS5Nad.mjs.map +1 -0
- package/dist/constants-CeMiHaHx.mjs +2 -0
- package/dist/constants-CeMiHaHx.mjs.map +1 -0
- package/dist/constants-lIvXgkdp.mjs +2 -0
- package/dist/constants-lIvXgkdp.mjs.map +1 -0
- package/dist/{context-bkKpii_t.mjs → context-CdSyuBlf.mjs} +1 -1
- package/dist/context-CdSyuBlf.mjs.map +1 -0
- package/dist/{pooling-BkZAO1Zs.mjs → createExtraKeyHandler-C_0EVj10.mjs} +5 -5
- package/dist/createExtraKeyHandler-C_0EVj10.mjs.map +1 -0
- package/dist/createPreferenceAccessTokens-6WLr6z-l.mjs +10 -0
- package/dist/createPreferenceAccessTokens-6WLr6z-l.mjs.map +1 -0
- package/dist/createSombraGotInstance-CahOgD6V.mjs +10 -0
- package/dist/createSombraGotInstance-CahOgD6V.mjs.map +1 -0
- package/dist/{dataFlowsToDataSilos-RAhfPV0l.mjs → dataFlowsToDataSilos-NhvBw1iy.mjs} +1 -1
- package/dist/dataFlowsToDataSilos-NhvBw1iy.mjs.map +1 -0
- package/dist/dataSilo-DrFetFXw.mjs +302 -0
- package/dist/dataSilo-DrFetFXw.mjs.map +1 -0
- package/dist/dataSubject-y_aXI0pa.mjs +92 -0
- package/dist/dataSubject-y_aXI0pa.mjs.map +1 -0
- package/dist/{done-input-validation-CcZtaz03.mjs → done-input-validation-DLR0-MJ7.mjs} +1 -1
- package/dist/{done-input-validation-CcZtaz03.mjs.map → done-input-validation-DLR0-MJ7.mjs.map} +1 -1
- package/dist/downloadPrivacyRequestFiles-B2yduagB.mjs +2 -0
- package/dist/downloadPrivacyRequestFiles-B2yduagB.mjs.map +1 -0
- package/dist/enums-CyFTrzXY.mjs.map +1 -1
- package/dist/extractClientError-DPjv09EH.mjs +2 -0
- package/dist/extractClientError-DPjv09EH.mjs.map +1 -0
- package/dist/extractErrorMessage-CPnTsT1S.mjs +2 -0
- package/dist/extractErrorMessage-CPnTsT1S.mjs.map +1 -0
- package/dist/fetchAllActions-C0l3wjQV.mjs +832 -0
- package/dist/fetchAllActions-C0l3wjQV.mjs.map +1 -0
- package/dist/fetchAllDataFlows-AQ9j_NRa.mjs +2 -0
- package/dist/fetchAllDataFlows-AQ9j_NRa.mjs.map +1 -0
- package/dist/fetchAllPreferenceTopics-Bn9PG-rO.mjs +36 -0
- package/dist/fetchAllPreferenceTopics-Bn9PG-rO.mjs.map +1 -0
- package/dist/fetchAllPurposes-CykSkZRY.mjs +29 -0
- package/dist/fetchAllPurposes-CykSkZRY.mjs.map +1 -0
- package/dist/fetchAllPurposesAndPreferences-Dog6N9L2.mjs +2 -0
- package/dist/fetchAllPurposesAndPreferences-Dog6N9L2.mjs.map +1 -0
- package/dist/fetchAllRequestEnrichers-q34mRuE5.mjs +42 -0
- package/dist/fetchAllRequestEnrichers-q34mRuE5.mjs.map +1 -0
- package/dist/fetchAllRequestIdentifiers-YP-geTV4.mjs +10 -0
- package/dist/fetchAllRequestIdentifiers-YP-geTV4.mjs.map +1 -0
- package/dist/fetchAllRequests-DEPTEUbi.mjs +2 -0
- package/dist/fetchAllRequests-DEPTEUbi.mjs.map +1 -0
- package/dist/fetchApiKeys-DkBco7W0.mjs +33 -0
- package/dist/fetchApiKeys-DkBco7W0.mjs.map +1 -0
- package/dist/fetchCatalogs-CBk871k6.mjs +12 -0
- package/dist/fetchCatalogs-CBk871k6.mjs.map +1 -0
- package/dist/fetchConsentManagerId-DHDA5Py9.mjs +321 -0
- package/dist/fetchConsentManagerId-DHDA5Py9.mjs.map +1 -0
- package/dist/fetchIdentifiers-DjqjUnaw.mjs +54 -0
- package/dist/fetchIdentifiers-DjqjUnaw.mjs.map +1 -0
- package/dist/fetchRequestDataSilo-CF6XOTQ-.mjs +2 -0
- package/dist/fetchRequestDataSilo-CF6XOTQ-.mjs.map +1 -0
- package/dist/fetchRequestFilesForRequest-DrHGOdih.mjs +33 -0
- package/dist/fetchRequestFilesForRequest-DrHGOdih.mjs.map +1 -0
- package/dist/generateCrossAccountApiKeys-F11uqpc5.mjs +33 -0
- package/dist/generateCrossAccountApiKeys-F11uqpc5.mjs.map +1 -0
- package/dist/impl--Lmj1RHh2.mjs +2 -0
- package/dist/impl--Lmj1RHh2.mjs.map +1 -0
- package/dist/impl-0ooudQ_J2.mjs +4 -0
- package/dist/impl-0ooudQ_J2.mjs.map +1 -0
- package/dist/{impl-BYBNi68b.mjs → impl-1U4QBT_L.mjs} +2 -2
- package/dist/impl-1U4QBT_L.mjs.map +1 -0
- package/dist/impl-2FbPcOv_2.mjs +2 -0
- package/dist/impl-2FbPcOv_2.mjs.map +1 -0
- package/dist/impl-ArGeiHuz.mjs +2 -0
- package/dist/impl-ArGeiHuz.mjs.map +1 -0
- package/dist/impl-B8iVBYdg.mjs +2 -0
- package/dist/impl-B8iVBYdg.mjs.map +1 -0
- package/dist/impl-BWjBYTQZ.mjs +2 -0
- package/dist/impl-BWjBYTQZ.mjs.map +1 -0
- package/dist/impl-Bc8Es_bT.mjs +7 -0
- package/dist/impl-Bc8Es_bT.mjs.map +1 -0
- package/dist/impl-BkyC7nnu.mjs +2 -0
- package/dist/impl-BkyC7nnu.mjs.map +1 -0
- package/dist/impl-BpUksm1b2.mjs +2 -0
- package/dist/impl-BpUksm1b2.mjs.map +1 -0
- package/dist/impl-BzupMfJi.mjs +12 -0
- package/dist/impl-BzupMfJi.mjs.map +1 -0
- package/dist/impl-C05tQHSq.mjs +2 -0
- package/dist/impl-C05tQHSq.mjs.map +1 -0
- package/dist/impl-CMX0qQr_2.mjs +2 -0
- package/dist/impl-CMX0qQr_2.mjs.map +1 -0
- package/dist/impl-CWHnw3oX.mjs +2 -0
- package/dist/impl-CWHnw3oX.mjs.map +1 -0
- package/dist/impl-CXK-D84c.mjs +4 -0
- package/dist/impl-CXK-D84c.mjs.map +1 -0
- package/dist/impl-CdoTu8TH.mjs +2 -0
- package/dist/impl-CdoTu8TH.mjs.map +1 -0
- package/dist/impl-CeLfAnyA2.mjs +2 -0
- package/dist/impl-CeLfAnyA2.mjs.map +1 -0
- package/dist/impl-Cgg_bv7j.mjs +2 -0
- package/dist/impl-Cgg_bv7j.mjs.map +1 -0
- package/dist/impl-CoLIqiH-2.mjs +2 -0
- package/dist/impl-CoLIqiH-2.mjs.map +1 -0
- package/dist/impl-Cq_RqK0_2.mjs +2 -0
- package/dist/impl-Cq_RqK0_2.mjs.map +1 -0
- package/dist/{impl-CIJ6P1GD.mjs → impl-Cwj9LeEI.mjs} +3 -3
- package/dist/impl-Cwj9LeEI.mjs.map +1 -0
- package/dist/impl-CyJBbyuF.mjs +2 -0
- package/dist/impl-CyJBbyuF.mjs.map +1 -0
- package/dist/impl-D-cp0CYr.mjs +2 -0
- package/dist/impl-D-cp0CYr.mjs.map +1 -0
- package/dist/impl-D-ldjJzl2.mjs +2 -0
- package/dist/impl-D-ldjJzl2.mjs.map +1 -0
- package/dist/impl-D6nwGrO8.mjs +2 -0
- package/dist/impl-D6nwGrO8.mjs.map +1 -0
- package/dist/impl-DGRuk3AB.mjs +2 -0
- package/dist/impl-DGRuk3AB.mjs.map +1 -0
- package/dist/impl-DXWN22xV.mjs +2 -0
- package/dist/impl-DXWN22xV.mjs.map +1 -0
- package/dist/impl-DZnSlfwn2.mjs +2 -0
- package/dist/impl-DZnSlfwn2.mjs.map +1 -0
- package/dist/impl-DcC8_dCy.mjs +2 -0
- package/dist/impl-DcC8_dCy.mjs.map +1 -0
- package/dist/impl-Dfc_yQML2.mjs +2 -0
- package/dist/impl-Dfc_yQML2.mjs.map +1 -0
- package/dist/impl-DgyjJ8RY2.mjs +2 -0
- package/dist/impl-DgyjJ8RY2.mjs.map +1 -0
- package/dist/impl-DhIyASha.mjs +2 -0
- package/dist/impl-DhIyASha.mjs.map +1 -0
- package/dist/impl-Dny1LX9A.mjs +2 -0
- package/dist/impl-Dny1LX9A.mjs.map +1 -0
- package/dist/impl-G1brwI4o.mjs +2 -0
- package/dist/impl-G1brwI4o.mjs.map +1 -0
- package/dist/impl-KV3yZaHz2.mjs +2 -0
- package/dist/impl-KV3yZaHz2.mjs.map +1 -0
- package/dist/impl-Rt3C_fDF.mjs +2 -0
- package/dist/impl-Rt3C_fDF.mjs.map +1 -0
- package/dist/impl-VHp2K2bg.mjs +2 -0
- package/dist/impl-VHp2K2bg.mjs.map +1 -0
- package/dist/impl-Zr8uLP_n.mjs +2 -0
- package/dist/impl-Zr8uLP_n.mjs.map +1 -0
- package/dist/impl-dEQtD5uE.mjs +2 -0
- package/dist/impl-dEQtD5uE.mjs.map +1 -0
- package/dist/impl-dlRlTYAQ.mjs +2 -0
- package/dist/impl-dlRlTYAQ.mjs.map +1 -0
- package/dist/impl-f4UPMoS_2.mjs +2 -0
- package/dist/impl-f4UPMoS_2.mjs.map +1 -0
- package/dist/impl-ph0q6K3i.mjs +2 -0
- package/dist/impl-ph0q6K3i.mjs.map +1 -0
- package/dist/impl-r8tHyAHB.mjs +2 -0
- package/dist/impl-r8tHyAHB.mjs.map +1 -0
- package/dist/impl-y1I9Muyc2.mjs +2 -0
- package/dist/impl-y1I9Muyc2.mjs.map +1 -0
- package/dist/index.d.mts +44 -32
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +78 -4
- package/dist/index.mjs.map +1 -1
- package/dist/inquirer-BgNcicZ4.mjs +2 -0
- package/dist/inquirer-BgNcicZ4.mjs.map +1 -0
- package/dist/listFiles-qzyQMaYH.mjs +2 -0
- package/dist/listFiles-qzyQMaYH.mjs.map +1 -0
- package/dist/{logger-Bj782ZYD.mjs → logger-B-LXIf3U.mjs} +1 -1
- package/dist/{logger-Bj782ZYD.mjs.map → logger-B-LXIf3U.mjs.map} +1 -1
- package/dist/makeGraphQLRequest-G078PsEL.mjs +2 -0
- package/dist/makeGraphQLRequest-G078PsEL.mjs.map +1 -0
- package/dist/markRequestDataSiloIdsCompleted-DmAz-R0M.mjs +2 -0
- package/dist/markRequestDataSiloIdsCompleted-DmAz-R0M.mjs.map +1 -0
- package/dist/markSilentPrivacyRequests-s7_aBROE.mjs +2 -0
- package/dist/markSilentPrivacyRequests-s7_aBROE.mjs.map +1 -0
- package/dist/mergeTranscendInputs-C64BJsse.mjs +2 -0
- package/dist/mergeTranscendInputs-C64BJsse.mjs.map +1 -0
- package/dist/notifyPrivacyRequestsAdditionalTime-BvXIXZYu.mjs +2 -0
- package/dist/notifyPrivacyRequestsAdditionalTime-BvXIXZYu.mjs.map +1 -0
- package/dist/package-BjNQxHlz.mjs +2 -0
- package/dist/package-BjNQxHlz.mjs.map +1 -0
- package/dist/parquetToCsvOneFile-DZVKXrjn.mjs +6 -0
- package/dist/parquetToCsvOneFile-DZVKXrjn.mjs.map +1 -0
- package/dist/parseAttributesFromString-CZStzJc0.mjs +2 -0
- package/dist/parseAttributesFromString-CZStzJc0.mjs.map +1 -0
- package/dist/pullAllDatapoints-DiMWp8a7.mjs +45 -0
- package/dist/pullAllDatapoints-DiMWp8a7.mjs.map +1 -0
- package/dist/pullChunkedCustomSiloOutstandingIdentifiers-DgWgggQt.mjs +2 -0
- package/dist/pullChunkedCustomSiloOutstandingIdentifiers-DgWgggQt.mjs.map +1 -0
- package/dist/pullConsentManagerMetrics-pFRPXTHJ.mjs +2 -0
- package/dist/pullConsentManagerMetrics-pFRPXTHJ.mjs.map +1 -0
- package/dist/pullManualEnrichmentIdentifiersToCsv-DA_4rIzW.mjs +2 -0
- package/dist/pullManualEnrichmentIdentifiersToCsv-DA_4rIzW.mjs.map +1 -0
- package/dist/pullTranscendConfiguration-D2cYlu6V.mjs +80 -0
- package/dist/pullTranscendConfiguration-D2cYlu6V.mjs.map +1 -0
- package/dist/pullUnstructuredSubDataPointRecommendations-C4aVhH-W.mjs +38 -0
- package/dist/pullUnstructuredSubDataPointRecommendations-C4aVhH-W.mjs.map +1 -0
- package/dist/pushCronIdentifiersFromCsv-C34TB9tG.mjs +2 -0
- package/dist/pushCronIdentifiersFromCsv-C34TB9tG.mjs.map +1 -0
- package/dist/pushManualEnrichmentIdentifiersFromCsv-CGS9E3Ft.mjs +2 -0
- package/dist/pushManualEnrichmentIdentifiersFromCsv-CGS9E3Ft.mjs.map +1 -0
- package/dist/readCsv-CyOL7eCc.mjs +2 -0
- package/dist/readCsv-CyOL7eCc.mjs.map +1 -0
- package/dist/{readTranscendYaml-DhKG1ViI.mjs → readTranscendYaml-D-J1ilS0.mjs} +2 -2
- package/dist/readTranscendYaml-D-J1ilS0.mjs.map +1 -0
- package/dist/removeUnverifiedRequestIdentifiers-pGGOFbfE.mjs +35 -0
- package/dist/removeUnverifiedRequestIdentifiers-pGGOFbfE.mjs.map +1 -0
- package/dist/request-CAsR6CMY.mjs +117 -0
- package/dist/request-CAsR6CMY.mjs.map +1 -0
- package/dist/retryRequestDataSilos-DXwN5uPw.mjs +2 -0
- package/dist/retryRequestDataSilos-DXwN5uPw.mjs.map +1 -0
- package/dist/skipPreflightJobs-BNQhuPZ8.mjs +2 -0
- package/dist/skipPreflightJobs-BNQhuPZ8.mjs.map +1 -0
- package/dist/skipRequestDataSilos-C39ji4lO.mjs +2 -0
- package/dist/skipRequestDataSilos-C39ji4lO.mjs.map +1 -0
- package/dist/splitCsvToList-BRq_CIfd.mjs +2 -0
- package/dist/splitCsvToList-BRq_CIfd.mjs.map +1 -0
- package/dist/streamPrivacyRequestsToCsv-C8lquiyd.mjs +2 -0
- package/dist/streamPrivacyRequestsToCsv-C8lquiyd.mjs.map +1 -0
- package/dist/syncCodePackages-BHgjfXCI.mjs +232 -0
- package/dist/syncCodePackages-BHgjfXCI.mjs.map +1 -0
- package/dist/syncCookies-CiLtxDFf.mjs +2 -0
- package/dist/syncCookies-CiLtxDFf.mjs.map +1 -0
- package/dist/syncDataFlows-DmBUs3G_.mjs +2 -0
- package/dist/syncDataFlows-DmBUs3G_.mjs.map +1 -0
- package/dist/syncTemplates-BNu1_dmW.mjs +23 -0
- package/dist/syncTemplates-BNu1_dmW.mjs.map +1 -0
- package/dist/time-Bl_c3W8U.mjs +2 -0
- package/dist/time-Bl_c3W8U.mjs.map +1 -0
- package/dist/types-B4CVJCpj.mjs +2 -0
- package/dist/types-B4CVJCpj.mjs.map +1 -0
- package/dist/updateConsentManagerVersionToLatest-BBMN94Hs.mjs +2 -0
- package/dist/updateConsentManagerVersionToLatest-BBMN94Hs.mjs.map +1 -0
- package/dist/uploadConsents-BbR7_sSt.mjs +2 -0
- package/dist/uploadConsents-BbR7_sSt.mjs.map +1 -0
- package/dist/uploadCookiesFromCsv-BKZx_E_2.mjs +2 -0
- package/dist/uploadCookiesFromCsv-BKZx_E_2.mjs.map +1 -0
- package/dist/uploadDataFlowsFromCsv-CJFVLvCJ.mjs +2 -0
- package/dist/uploadDataFlowsFromCsv-CJFVLvCJ.mjs.map +1 -0
- package/dist/uploadPrivacyRequestsFromCsv-BmP1JluQ.mjs +17 -0
- package/dist/uploadPrivacyRequestsFromCsv-BmP1JluQ.mjs.map +1 -0
- package/dist/uploadSiloDiscoveryResults-XpDp2u35.mjs +20 -0
- package/dist/uploadSiloDiscoveryResults-XpDp2u35.mjs.map +1 -0
- package/dist/validateTranscendAuth-1W1IylqE.mjs +2 -0
- package/dist/validateTranscendAuth-1W1IylqE.mjs.map +1 -0
- package/dist/withPreferenceRetry-Cb5S310L.mjs +2 -0
- package/dist/withPreferenceRetry-Cb5S310L.mjs.map +1 -0
- package/dist/writeCsv-B51ulrVl.mjs +6 -0
- package/dist/writeCsv-B51ulrVl.mjs.map +1 -0
- package/package.json +34 -53
- package/dist/api-keys-C7JLTDUZ.mjs +0 -2
- package/dist/api-keys-C7JLTDUZ.mjs.map +0 -1
- package/dist/app-Dti3qTxV.mjs +0 -131
- package/dist/app-Dti3qTxV.mjs.map +0 -1
- package/dist/buildAIIntegrationType-Bk0EbFKV.mjs +0 -2
- package/dist/buildAIIntegrationType-Bk0EbFKV.mjs.map +0 -1
- package/dist/code-scanning-3tLsE1W5.mjs +0 -4
- package/dist/code-scanning-3tLsE1W5.mjs.map +0 -1
- package/dist/codecs-TR6p48v3.mjs +0 -2
- package/dist/codecs-TR6p48v3.mjs.map +0 -1
- package/dist/command-BlHM1nCd.mjs.map +0 -1
- package/dist/consent-manager-BoaaMjRQ.mjs +0 -12
- package/dist/consent-manager-BoaaMjRQ.mjs.map +0 -1
- package/dist/constants-DdeeX81W.mjs +0 -2
- package/dist/constants-DdeeX81W.mjs.map +0 -1
- package/dist/context-bkKpii_t.mjs.map +0 -1
- package/dist/cron-DOicA1l8.mjs +0 -2
- package/dist/cron-DOicA1l8.mjs.map +0 -1
- package/dist/data-inventory-OeEcogPl.mjs +0 -75
- package/dist/data-inventory-OeEcogPl.mjs.map +0 -1
- package/dist/dataFlowsToDataSilos-RAhfPV0l.mjs.map +0 -1
- package/dist/impl--Ov8Om49.mjs +0 -2
- package/dist/impl--Ov8Om49.mjs.map +0 -1
- package/dist/impl-4BP7gY61.mjs +0 -2
- package/dist/impl-4BP7gY61.mjs.map +0 -1
- package/dist/impl-B0d5M861.mjs +0 -2
- package/dist/impl-B0d5M861.mjs.map +0 -1
- package/dist/impl-B40z0Aoz2.mjs +0 -2
- package/dist/impl-B40z0Aoz2.mjs.map +0 -1
- package/dist/impl-B8CoAX4t.mjs +0 -2
- package/dist/impl-B8CoAX4t.mjs.map +0 -1
- package/dist/impl-BDKBhSiG2.mjs +0 -2
- package/dist/impl-BDKBhSiG2.mjs.map +0 -1
- package/dist/impl-BEzyqD_12.mjs +0 -2
- package/dist/impl-BEzyqD_12.mjs.map +0 -1
- package/dist/impl-BI4zCNs0.mjs +0 -2
- package/dist/impl-BI4zCNs0.mjs.map +0 -1
- package/dist/impl-BJ9Ge6Wf2.mjs +0 -2
- package/dist/impl-BJ9Ge6Wf2.mjs.map +0 -1
- package/dist/impl-BPz3SpXo2.mjs +0 -2
- package/dist/impl-BPz3SpXo2.mjs.map +0 -1
- package/dist/impl-BYBNi68b.mjs.map +0 -1
- package/dist/impl-Bh04BLeU2.mjs +0 -2
- package/dist/impl-Bh04BLeU2.mjs.map +0 -1
- package/dist/impl-BhMd6_J22.mjs +0 -2
- package/dist/impl-BhMd6_J22.mjs.map +0 -1
- package/dist/impl-BiWrlucD.mjs +0 -2
- package/dist/impl-BiWrlucD.mjs.map +0 -1
- package/dist/impl-BpMKYqSR.mjs +0 -2
- package/dist/impl-BpMKYqSR.mjs.map +0 -1
- package/dist/impl-BraVBCrF2.mjs +0 -4
- package/dist/impl-BraVBCrF2.mjs.map +0 -1
- package/dist/impl-BvTvjK72.mjs +0 -2
- package/dist/impl-BvTvjK72.mjs.map +0 -1
- package/dist/impl-BvZai1Pf2.mjs +0 -2
- package/dist/impl-BvZai1Pf2.mjs.map +0 -1
- package/dist/impl-C73Uh2Ze.mjs +0 -2
- package/dist/impl-C73Uh2Ze.mjs.map +0 -1
- package/dist/impl-CIJ6P1GD.mjs.map +0 -1
- package/dist/impl-CNiEzL3_2.mjs +0 -2
- package/dist/impl-CNiEzL3_2.mjs.map +0 -1
- package/dist/impl-CTPHR7O62.mjs +0 -2
- package/dist/impl-CTPHR7O62.mjs.map +0 -1
- package/dist/impl-CU29SrJb2.mjs +0 -2
- package/dist/impl-CU29SrJb2.mjs.map +0 -1
- package/dist/impl-CaTnsoDi.mjs +0 -2
- package/dist/impl-CaTnsoDi.mjs.map +0 -1
- package/dist/impl-CiQeM677.mjs +0 -2
- package/dist/impl-CiQeM677.mjs.map +0 -1
- package/dist/impl-CkY0wfCz.mjs +0 -2
- package/dist/impl-CkY0wfCz.mjs.map +0 -1
- package/dist/impl-CoZhgLjC.mjs +0 -12
- package/dist/impl-CoZhgLjC.mjs.map +0 -1
- package/dist/impl-CvxsioT4.mjs +0 -2
- package/dist/impl-CvxsioT4.mjs.map +0 -1
- package/dist/impl-D2HalFgB2.mjs +0 -2
- package/dist/impl-D2HalFgB2.mjs.map +0 -1
- package/dist/impl-DFNq8PBe.mjs +0 -2
- package/dist/impl-DFNq8PBe.mjs.map +0 -1
- package/dist/impl-DOgLpdLw.mjs +0 -2
- package/dist/impl-DOgLpdLw.mjs.map +0 -1
- package/dist/impl-DP757pBT.mjs +0 -2
- package/dist/impl-DP757pBT.mjs.map +0 -1
- package/dist/impl-DVDN007x.mjs +0 -2
- package/dist/impl-DVDN007x.mjs.map +0 -1
- package/dist/impl-DfKI4fmI.mjs +0 -2
- package/dist/impl-DfKI4fmI.mjs.map +0 -1
- package/dist/impl-DgsWGnhH.mjs +0 -2
- package/dist/impl-DgsWGnhH.mjs.map +0 -1
- package/dist/impl-DzSmriDw.mjs +0 -2
- package/dist/impl-DzSmriDw.mjs.map +0 -1
- package/dist/impl-EhTHDCC1.mjs +0 -2
- package/dist/impl-EhTHDCC1.mjs.map +0 -1
- package/dist/impl-J-dQqTZJ2.mjs +0 -2
- package/dist/impl-J-dQqTZJ2.mjs.map +0 -1
- package/dist/impl-SxwaNC4m2.mjs +0 -2
- package/dist/impl-SxwaNC4m2.mjs.map +0 -1
- package/dist/impl-fESuqAH1.mjs +0 -2
- package/dist/impl-fESuqAH1.mjs.map +0 -1
- package/dist/impl-gYrR3kIh.mjs +0 -4
- package/dist/impl-gYrR3kIh.mjs.map +0 -1
- package/dist/impl-iwjvzA7a.mjs +0 -2
- package/dist/impl-iwjvzA7a.mjs.map +0 -1
- package/dist/impl-nKY3m-Vx.mjs +0 -2
- package/dist/impl-nKY3m-Vx.mjs.map +0 -1
- package/dist/impl-qiK6VF4F2.mjs +0 -2
- package/dist/impl-qiK6VF4F2.mjs.map +0 -1
- package/dist/manual-enrichment-CYoZNBjO.mjs +0 -2
- package/dist/manual-enrichment-CYoZNBjO.mjs.map +0 -1
- package/dist/mergeTranscendInputs-Coj_e2N3.mjs +0 -2
- package/dist/mergeTranscendInputs-Coj_e2N3.mjs.map +0 -1
- package/dist/pooling-BkZAO1Zs.mjs.map +0 -1
- package/dist/preference-management-BHj26bmE.mjs +0 -7
- package/dist/preference-management-BHj26bmE.mjs.map +0 -1
- package/dist/readTranscendYaml-DhKG1ViI.mjs.map +0 -1
- package/dist/syncConfigurationToTranscend-wWSbGVrI.mjs +0 -3010
- package/dist/syncConfigurationToTranscend-wWSbGVrI.mjs.map +0 -1
- package/dist/uploadConsents-nsjKy1I4.mjs +0 -2
- package/dist/uploadConsents-nsjKy1I4.mjs.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./logger-B-LXIf3U.mjs";import{n as t,t as n}from"./bluebird-CUitXgsY.mjs";import{i as r,r as i}from"./dataSubject-y_aXI0pa.mjs";import{n as a,o}from"./fetchIdentifiers-DjqjUnaw.mjs";import{n as s}from"./fetchApiKeys-DkBco7W0.mjs";import{n as c}from"./syncTemplates-BNu1_dmW.mjs";import{$ as l,At as u,B as d,C as f,Ct as p,Dt as m,E as h,Et as g,F as _,G as v,H as y,I as b,K as x,L as S,Lt as C,M as ee,Mt as w,N as T,O as E,P as D,Rt as O,S as k,St as A,T as j,U as M,Ut as N,Vt as P,X as F,Z as I,a as te,b as ne,bt as L,ct as R,d as re,et as z,f as B,ft as V,g as H,h as U,ht as ie,jt as ae,k as oe,kt as se,mt as ce,n as le,nt as ue,p as de,q as fe,r as pe,rt as me,st as he,t as ge,u as _e,ut as ve,vt as ye,w as be,wt as xe,x as Se,y as Ce,yt as we,z as Te,zt as Ee}from"./fetchAllActions-C0l3wjQV.mjs";import{t as De}from"./fetchAllPurposes-CykSkZRY.mjs";import{C as Oe,D as ke,E as Ae,S as je,T as Me,a as Ne,b as Pe,d as Fe,i as Ie,j as Le,k as Re,u as ze,w as Be,x as Ve}from"./fetchConsentManagerId-DHDA5Py9.mjs";import{t as W}from"./makeGraphQLRequest-G078PsEL.mjs";import{t as He}from"./syncCookies-CiLtxDFf.mjs";import{n as Ue}from"./syncDataFlows-DmBUs3G_.mjs";import{IsoCountryCode as We,IsoCountrySubdivisionCode as Ge}from"@transcend-io/privacy-types";import{chunk as G,difference as Ke,groupBy as qe,keyBy as K,uniq as Je}from"lodash-es";import{getEntries as Ye}from"@transcend-io/type-utils";import q from"colors";import{InitialViewState as Xe,OnConsentExpiry as Ze}from"@transcend-io/airgap.js-types";const Qe=[...Object.values(We),...Object.values(Ge)];async function J(e,{action:t,actionId:n,skipPublish:r=!1}){await W(e,V,{input:{id:n,skipSecondaryIfNoFiles:t.skipSecondaryIfNoFiles,skipDownloadableStep:t.skipDownloadableStep,requiresReview:t.requiresReview,waitingPeriod:t.waitingPeriod,skipPublish:r,regionList:t.regionBlockList?Ke(Qe,t.regionBlockList):t.regionList,regionDetectionMethod:t.regionDetectionMethod}})}async function Y(e,t){let{createActionItemCollection:n}=await W(e,xe,{input:{title:t.title,description:t.description||``,hidden:t.hidden||!1,productLine:t.productLine}});return n.created}async function X(e,t,n){await W(e,g,{input:{id:n,title:t.title,description:t.description,hidden:t.hidden,productLine:t.productLine}})}async function Z(n,r){let i=!1;e.info(q.magenta(`Syncing "${r.length}" action item collections...`));let a=K(await B(n),`title`);return await t(r.filter(e=>!a[e.title]),async t=>{try{await Y(n,t),e.info(q.green(`Successfully created action item collection "${t.title}"!`))}catch(n){i=!0,e.info(q.red(`Failed to create action item collection "${t.title}"! - ${n.message}`))}}),await t(r.map(e=>[e,a[e.title]?.id]).filter(e=>!!e[1]),async([t,r])=>{try{await X(n,t,r),e.info(q.green(`Successfully synced action item collection "${t.title}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync action item collection "${t.title}"! - ${n.message}`))}}),!i}async function Q(e,n,r,i={}){await t(G(n,100),async t=>{await W(e,R,{input:t.map(e=>({title:e.title,type:e.type,priorityOverride:e.priority,dueDate:e.dueDate,customerExperienceActionItemId:e.customerExperienceActionItemId,resolved:e.resolved,notes:e.notes,link:e.link,assigneesUserEmails:e.users,assigneesTeamNames:e.teams,...(e.attributes,{}),collectionIds:e.collections.map(e=>r[e].id)}))})})}async function $e(e,t,n,r={}){let i=e=>{let t=r[e];if(!t)throw Error(`Attribute key "${e}" does not exist!`);return t.id};await W(e,ve,{input:{ids:[n],title:t.title,priorityOverride:t.priority,dueDate:t.dueDate,resolved:t.resolved,customerExperienceActionItemId:t.customerExperienceActionItemId,notes:t.notes,link:t.link,assigneesUserEmails:t.users,assigneesTeamNames:t.teams,...t.attributes?{attributes:t.attributes.map(({key:e,values:t})=>({attributeKeyId:i(e),attributeValueNames:t}))}:{}}})}function et({title:e,collections:t}){return`${e}-${t.map(e=>e.title).sort().join(`-`)}`}function tt({title:e,collections:t}){return`${e}-${t.sort().join(`-`)}`}async function nt(n,r){let i=!1;e.info(q.magenta(`Syncing "${r.length}" actionItems...`));let a=r.some(e=>e.attributes&&e.attributes.length>0),[o,s,c]=await Promise.all([b(n),B(n),a?ee(n):[]]),l=K(s,`title`),u=K(o,et),d=K(c,`name`),f=K(o.filter(e=>!!e.customerExperienceActionItemIds),({customerExperienceActionItemIds:e})=>e[0]),p=Je(r.map(e=>e.collections).flat()).filter(e=>!l[e]);if(p.length>0)return e.info(q.red(`Missing action item collections: "${p.join(`", "`)}" - please create them first!`)),!1;let m=r.filter(e=>!u[tt(e)]&&!f[e.customerExperienceActionItemId]);if(m.length>0)try{e.info(q.magenta(`Creating "${m.length}" actionItems...`)),await Q(n,m,l,d),e.info(q.green(`Successfully created "${m.length}" actionItems!`))}catch(t){i=!0,e.info(q.red(`Failed to create action items! - ${t.message}`))}return await t(r.map(e=>[e,u[tt(e)]?.id||f[e.customerExperienceActionItemId]?.id]).filter(e=>!!e[1]),async([t,r])=>{try{await $e(n,t,r,d),e.info(q.green(`Successfully synced action item "${t.title}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync action item "${t.title}"! - ${n.message}`))}}),!i}async function rt(e,t){let{createAgentFile:n}=await W(e,l,{input:{name:t.name,description:t.description,fileId:t.fileId,size:t.size,purpose:t.purpose,fileUploadedAt:new Date,agentIds:[]}});return n.agentFile}async function it(e,t){await W(e,z,{input:{agentFiles:t.map(([e,t])=>({id:t,name:e.name,description:e.description,fileId:e.fileId,size:e.size,purpose:e.purpose}))}})}async function at(n,r){e.info(q.magenta(`Syncing "${r.length}" agent files...`));let i=!1,a=K(await _(n),`name`);await t(r.filter(e=>!a[e.name]),async t=>{try{let r=await rt(n,t);a[r.name]=r,e.info(q.green(`Successfully synced agent file "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync agent file "${t.name}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" agent files!`)),await it(n,r.map(e=>[e,a[e.name].id])),e.info(q.green(`Successfully synced "${r.length}" agent files!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" agent files! - ${t.message}`))}return!i}async function ot(e,t){let{createAgentFunction:n}=await W(e,F,{input:{name:t.name,description:t.description,parameters:t.parameters,agentIds:[]}});return n.agentFunction}async function st(e,t){await W(e,I,{input:{agentFunctions:t.map(([e,t])=>({id:t,name:e.name,description:e.description,parameters:e.parameters}))}})}async function ct(n,r){e.info(q.magenta(`Syncing "${r.length}" agent functions...`));let i=!1,a=K(await D(n),`name`);await t(r.filter(e=>!a[e.name]),async t=>{try{let r=await ot(n,t);a[r.name]=r,e.info(q.green(`Successfully synced agent function "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync agent function "${t.name}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" agent functions!`)),await st(n,r.map(e=>[e,a[e.name].id])),e.info(q.green(`Successfully synced "${r.length}" agent functions!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" agent functions! - ${t.message}`))}return!i}async function lt(e,t){let{createAgent:n}=await W(e,ue,{input:{name:t.name,description:t.description,codeInterpreterEnabled:t.codeInterpreterEnabled,retrievalEnabled:t.retrievalEnabled,promptTitle:t.prompt,largeLanguageModelName:t[`large-language-model`].name,largeLanguageModelClient:t[`large-language-model`].client}});return n.agent}async function ut(e,t){await W(e,me,{input:{agents:t.map(([e,t])=>({id:t,name:e.name,description:e.description,codeInterpreterEnabled:e.codeInterpreterEnabled,retrievalEnabled:e.retrievalEnabled}))}})}async function dt(n,r){e.info(q.magenta(`Syncing "${r.length}" agents...`));let i=!1,a=K(await T(n),`name`);await t(r.filter(e=>!a[e.name]),async t=>{try{let r=await lt(n,t);a[r.name]=r,e.info(q.green(`Successfully synced agent "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync agent "${t.name}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" agents!`)),await ut(n,r.map(e=>[e,a[e.name].id])),e.info(q.green(`Successfully synced "${r.length}" agents!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" agents ! - ${t.message}`))}return!i}async function ft(t,r,{existingAttribute:i,deleteExtraAttributeValues:a}){let o={name:r.name,enabledOn:r.resources},s;if(i)await W(t,A,{attributeKeyId:i.id,description:i.isCustom?r.description:void 0,...o}),s=i.id;else{let{createAttributeKey:{attributeKey:e}}=await W(t,ye,{type:r.type,description:r.description,...o});s=e.id}let c=K(i?.values||[],`name`),{existingValues:l=[],newValues:u=[]}=qe(r.values||[],e=>c[e.name]?`existingValues`:`newValues`),d=Ke((i?.values||[]).map(({name:e})=>e),(r.values||[]).map(({name:e})=>e));u.length>0&&(await W(t,we,{input:u.map(({name:e,...t})=>({name:e,attributeKeyId:s,...t}))}),e.info(q.green(`Created ${u.length} attribute values`))),l.length>0&&(await W(t,p,{input:l.map(({name:e,...t})=>({id:c[e].id,name:e,description:c[e].description,color:c[e].color,...t,attributeKeyId:s}))}),e.info(q.green(`Updated ${l.length} attribute values`))),d.length>0&&a&&(await n(d,async e=>{await W(t,L,{id:c[e].id})},{concurrency:10}),e.info(q.green(`Deleted ${d.length} attribute values`)))}async function pt(e,t){let{createBusinessEntity:n}=await W(e,ce,{input:{title:t.title,description:t.description,address:t.address,headquarterCountry:t.headquarterCountry,headquarterSubDivision:t.headquarterSubDivision,dataProtectionOfficerName:t.dataProtectionOfficerName,dataProtectionOfficerEmail:t.dataProtectionOfficerEmail,attributes:t.attributes,teamNames:t.teams,ownerEmails:t.owners}});return n.businessEntity}async function mt(e,n){await t(G(n,100),async t=>{await W(e,ie,{input:t.map(([e,t])=>({id:t,title:e.title,description:e.description,address:e.address,headquarterCountry:e.headquarterCountry,headquarterSubDivision:e.headquarterSubDivision,dataProtectionOfficerName:e.dataProtectionOfficerName,dataProtectionOfficerEmail:e.dataProtectionOfficerEmail,attributes:e.attributes,teamNames:e.teams,ownerEmails:e.owners}))})})}async function ht(n,r){e.info(q.magenta(`Syncing "${r.length}" business entities...`));let i=!1,a=K(await oe(n),`title`);await t(r.filter(e=>!a[e.title]),async t=>{try{let r=await pt(n,t);a[r.title]=r,e.info(q.green(`Successfully synced business entity "${t.title}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync business entity "${t.title}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" business entities!`)),await mt(n,r.map(e=>[e,a[e.title].id])),e.info(q.green(`Successfully synced "${r.length}" business entities!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" business entities ! - ${t.message}`))}return!i}const gt=`https://app.transcend.io/consent-manager/regional-experiences/purposes`;async function _t(t,r){let i=K(await Ie(t),`name`),a=K(await De(t),`trackingType`);await n(r,async(n,r)=>{let o=n.purposes?.map((e,t)=>{let n=a[e.trackingType];if(!n)throw Error(`Invalid purpose trackingType provided at consentManager.experiences[${r}].purposes[${t}]: ${e.trackingType}. See list of valid purposes ${gt}`);return n.id}),s=n.optedOutPurposes?.map((e,t)=>{let n=a[e.trackingType];if(!n)throw Error(`Invalid purpose trackingType provided at consentManager.experiences[${r}].optedOutPurposes[${t}]: ${e.trackingType}. See list of valid purposes ${gt}`);return n.id}),c=i[n.name];c?(await W(t,Be,{input:{id:c.id,name:n.displayName,regions:n.regions,operator:n.operator,onConsentExpiry:n.onConsentExpiry,consentExpiry:n.consentExpiry,displayPriority:n.displayPriority===c.displayPriority?void 0:n.displayPriority,viewState:n.viewState,purposes:o,optedOutPurposes:s,browserLanguages:n.browserLanguages,browserTimeZones:n.browserTimeZones}}),e.info(q.green(`Successfully synced consent experience "${n.name}"!`))):(await W(t,ze,{input:{name:n.name,displayName:n.displayName,regions:n.regions,operator:n.operator,onConsentExpiry:n.onConsentExpiry||Ze.Prompt,consentExpiry:n.consentExpiry,displayPriority:n.displayPriority,viewState:n.viewState||Xe.Hidden,purposes:o||[],optedOutPurposes:s||[],browserLanguages:n.browserLanguages,browserTimeZones:n.browserTimeZones}}),e.info(q.green(`Successfully created consent experience "${n.name}"!`)))},{concurrency:10})}async function vt(e,t){let n;try{n=await Ne(e,1)}catch(r){if(r.message.includes(`AirgapBundle not found`)){let r=await h(e),{createConsentManager:i}=await W(e,Fe,{domains:t.domains,privacyCenterId:r});n=i.consentManager.id}else throw r}if(t.domains&&await W(e,Me,{domains:t.domains,airgapBundleId:n}),t.partition){let r=(await le(e)).find(e=>e.name===t.partition);if(!r)throw Error(`Partition "${t.partition}" not found. Please create the partition first.`);await W(e,Ae,{partitionId:r.id,airgapBundleId:n})}t.version&&await W(e,Re,{airgapBundleId:n,version:t.version}),t.signedIabAgreement&&await W(e,Le,{input:{id:n,...t.signedIabAgreement?{signedIabAgreement:t.signedIabAgreement}:{}}}),t.unknownRequestPolicy&&await W(e,Oe,{input:{id:n,unknownRequestPolicy:t.unknownRequestPolicy}}),t.unknownRequestPolicy&&await W(e,je,{input:{id:n,unknownCookiePolicy:t.unknownCookiePolicy}}),t.telemetryPartitioning&&await W(e,Ve,{input:{id:n,strategy:t.telemetryPartitioning}}),t.consentPrecedence&&await W(e,Pe,{input:{id:n,consentPrecedence:t.consentPrecedence}}),t.experiences&&await _t(e,t.experiences),t.theme&&await W(e,ke,{input:{airgapBundleId:n,...t.theme}})}async function yt(e,t){let{createDataCategory:n}=await W(e,M,{input:{name:t.name,category:t.category,description:t.description}});return n.dataCategory}async function bt(e,t){await W(e,v,{input:{dataSubCategories:t.map(([e,t])=>({id:t,description:e.description,attributes:e.attributes}))}})}async function xt(n,r){e.info(q.magenta(`Syncing "${r.length}" data categories...`));let i=!1,a=K(await E(n),({name:e,category:t})=>`${e}:${t}`);await t(r.filter(e=>!a[`${e.name}:${e.category}`]),async t=>{try{let r=await yt(n,t);a[`${r.name}:${r.category}`]=r,e.info(q.green(`Successfully synced data category "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync data category "${t.name}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" data categories!`)),await bt(n,r.map(e=>[e,a[`${e.name}:${e.category}`].id])),e.info(q.green(`Successfully synced "${r.length}" data categories!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" data categories ! - ${t.message}`))}return!i}async function St(e,{dataSubject:t,dataSubjectId:n,skipPublish:a=!1}){await W(e,r,{input:{id:n,title:t.title,adminDashboardDefaultSilentMode:t.adminDashboardDefaultSilentMode,actions:t.actions,skipPublish:a&&t.active===void 0}}),typeof t.active==`boolean`&&await W(e,i,{input:{id:n,active:t.active,skipPublish:a}})}async function Ct(e,{identifier:t,dataSubjectsByName:n,identifierId:r,skipPublish:i=!1}){await W(e,o,{input:{id:r,selectOptions:t.selectOptions,isRequiredInForm:t.isRequiredInForm,regex:t.regex,placeholder:t.placeholder,displayTitle:t.displayTitle,displayDescription:t.displayDescription,displayOrder:t.displayOrder,isUniqueOnPreferenceStore:t.isUniqueOnPreferenceStore,privacyCenterVisibility:t.privacyCenterVisibility,dataSubjectIds:t.dataSubjects?t.dataSubjects.map(e=>n[e].id):void 0,skipPublish:i}})}async function wt(e,n){await t(G(n,100),async t=>{await W(e,P,{messages:t.map(e=>({...e.id.includes(`.`)?{}:{id:e.id},defaultMessage:e.defaultMessage,targetReactIntlId:e.targetReactIntlId,translations:e.translations?Object.entries(e.translations).map(([e,t])=>({locale:e,value:t})):void 0}))})})}async function Tt(t,n){let r=!1;e.info(q.magenta(`Syncing "${n.length}" messages...`));let i=n.filter(e=>n.filter(t=>e.id===t.id).length>1);if(i.length>0)throw Error(`Failed to upload messages as there were non-unique entries found: ${i.map(({id:e})=>e).join(`,`)}`);try{e.info(q.magenta(`Upserting "${n.length}" new messages...`)),await wt(t,n),e.info(q.green(`Successfully synced ${n.length} messages!`))}catch(t){r=!0,e.info(q.red(`Failed to create messages! - ${t.message}`))}return!r}async function $(e,n){let r=await h(e);await t(G(n,100),async t=>{await W(e,N,{privacyCenterId:r,policies:t.map(([e,t])=>({id:t,title:e.title,disableEffectiveOn:e.disableEffectiveOn,disabledLocales:e.disabledLocales,...e.effectiveOn||e.content?{version:{...e.effectiveOn?{effectiveOn:e.effectiveOn}:{},...e.content?{content:{defaultMessage:e.content}}:{}}}:{}}))})})}async function Et(t,n){let r=!1;e.info(q.magenta(`Syncing "${n.length}" policies...`));let i=n.filter(e=>n.filter(t=>e.title===t.title).length>1);if(i.length>0)throw Error(`Failed to upload policies as there were non-unique entries found: ${i.map(({title:e})=>e).join(`,`)}`);let a=K(await j(t),({title:e})=>e.defaultMessage);try{e.info(q.magenta(`Upserting "${n.length}" new policies...`)),await $(t,n.map(e=>[e,a[e.title]?.id])),e.info(q.green(`Successfully synced ${n.length} policies!`))}catch(t){r=!0,e.info(q.red(`Failed to create policies! - ${t.message}`))}return!r}async function Dt(t,n){let r=!1;e.info(q.magenta(`Syncing privacy center...`));let i=await h(t);try{await W(t,he,{input:{privacyCenterId:i,transformAccessReportJsonToCsv:n.transformAccessReportJsonToCsv,useCustomEmailDomain:n.useCustomEmailDomain,useNoReplyEmailAddress:n.useNoReplyEmailAddress,replyToEmail:n.replyToEmail,supportEmail:n.supportEmail,preferBrowserDefaultLocale:n.preferBrowserDefaultLocale,defaultLocale:n.defaultLocale,locales:n.locales,showMarketingPreferences:n.showMarketingPreferences,showManageYourPrivacy:n.showManageYourPrivacy,showPolicies:n.showPolicies,showConsentManager:n.showConsentManager,showDataFlows:n.showDataFlows,showCookies:n.showCookies,showTrackingTechnologies:n.showTrackingTechnologies,showPrivacyRequestButton:n.showPrivacyRequestButton,isDisabled:n.isDisabled,...n.theme?{colorPalette:n.theme.colors,componentStyles:n.theme.componentStyles,textStyles:n.theme.textStyles}:{}}}),e.info(q.green(`Successfully synced privacy center!`))}catch(t){r=!0,e.info(q.red(`Failed to create privacy center! - ${t.message}`))}return!r}async function Ot(e,t){let{createProcessingActivity:n}=await W(e,S,{input:{title:t.title,description:t.description}});return n.processingActivity}async function kt(e,t){let n=t.filter(([,e])=>e===void 0).map(([{title:e}])=>e);if(n.length>0)throw Error(`The following ${n.length} processing activities do not exist and thus can't be updated: "${n.join(`", "`)}"`);await W(e,Te,{input:{processingActivities:t.map(([{processingSubPurposes:e,dataSubCategories:t,saaSCategories:n,...r},i])=>({dataSubCategoryInputs:t?.map(({category:e,name:t})=>({category:e,name:t??``})),processingPurposeSubCategoryInputs:e?.map(({purpose:e,name:t})=>({purpose:e,name:t??`Other`})),saaSCategoryTitles:n,...r,id:i}))}})}async function At(n,r){let i=!1;e.info(q.magenta(`Syncing "${r.length}" processing activities...`));let a=K(await be(n),`title`),o=r.filter(e=>!a[e.title]);o.length>0&&e.info(q.magenta(`Creating "${o.length}" new processing activities...`)),await t(o,async t=>{try{let r=await Ot(n,t);a[r.title]=r,e.info(q.green(`Successfully created processing activity "${t.title}"!`))}catch(n){i=!0,e.info(q.red(`Failed to create processing activity "${t.title}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" processing activities!`)),await kt(n,r.map(e=>[e,a[e.title]?.id])),e.info(q.green(`Successfully synced "${r.length}" processingActivities!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" processingActivities! - ${t.message}`))}return!i}async function jt(e,t){let{createProcessingPurposeSubCategory:n}=await W(e,d,{input:{name:t.name,purpose:t.purpose,description:t.description}});return n.processingPurposeSubCategory}async function Mt(e,t){await W(e,y,{input:{processingPurposeSubCategories:t.map(([e,t])=>({id:t,description:e.description,attributes:e.attributes}))}})}async function Nt(n,r){e.info(q.magenta(`Syncing "${r.length}" processing purposes...`));let i=!1,a=K(await f(n),({name:e,purpose:t})=>`${e}:${t}`);await t(r.filter(e=>!a[`${e.name}:${e.purpose}`]),async t=>{try{let r=await jt(n,t);a[`${r.name}:${r.purpose}`]=r,e.info(q.green(`Successfully synced processing purpose "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync processing purpose "${t.name}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" processing purposes!`)),await Mt(n,r.map(e=>[e,a[`${e.name}:${e.purpose}`].id])),e.info(q.green(`Successfully synced "${r.length}" processing purposes!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" processing purposes ! - ${t.message}`))}return!i}async function Pt(t,n){let{createPrompt:{prompt:r}}=await W(t,u,{input:n});return e.info(q.green(`Successfully created prompt "${n.title}"!`)),r.id}async function Ft(t,n){await W(t,C,{input:{prompts:n.map(([e,t])=>({...e,id:t}))}}),e.info(q.green(`Successfully updated ${n.length} prompts!`))}async function It(t,r,i=20){let a=!1;e.info(q.magenta(`Syncing "${r.length}" prompts...`));let o=K(await de(t),`title`),s=r.map(e=>[e,o[e.title]?.id]),c=s.filter(([,e])=>!e).map(([e])=>e);try{e.info(q.magenta(`Creating "${c.length}" new prompts...`)),await n(c,async e=>{await Pt(t,e)},{concurrency:i}),e.info(q.green(`Successfully synced ${c.length} prompts!`))}catch(t){a=!0,e.info(q.red(`Failed to create prompts! - ${t.message}`))}let l=s.filter(e=>!!e[1]);try{e.info(q.magenta(`Updating "${l.length}" prompts...`)),await Ft(t,l),e.info(q.green(`Successfully updated "${l.length}" prompts!`))}catch(t){a=!0,e.info(q.red(`Failed to create prompts! - ${t.message}`))}return e.info(q.green(`Synced "${r.length}" prompts!`)),!a}async function Lt(e,t){let{createVendor:n}=await W(e,x,{input:{title:t.title,description:t.description,address:t.address,headquarterCountry:t.headquarterCountry,headquarterSubDivision:t.headquarterSubDivision,dataProcessingAgreementLink:t.dataProcessingAgreementLink,contactName:t.contactName,contactPhone:t.contactPhone,websiteUrl:t.websiteUrl}});return n.vendor}async function Rt(e,t){await W(e,fe,{input:{vendors:t.map(([e,t])=>({id:t,title:e.title,description:e.description,address:e.address,headquarterCountry:e.headquarterCountry,headquarterSubDivision:e.headquarterSubDivision,dataProcessingAgreementLink:e.dataProcessingAgreementLink,contactName:e.contactName,contactPhone:e.contactPhone,websiteUrl:e.websiteUrl,attributes:e.attributes}))}})}async function zt(n,r){e.info(q.magenta(`Syncing "${r.length}" vendors...`));let i=!1,a=K(await Se(n),`title`);await t(r.filter(e=>!a[e.title]),async t=>{try{let r=await Lt(n,t);a[r.title]=r,e.info(q.green(`Successfully synced vendor "${t.title}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync vendor "${t.title}"! - ${n.message}`))}});try{e.info(q.magenta(`Updating "${r.length}" vendors!`)),await Rt(n,r.map(e=>[e,a[e.title].id])),e.info(q.green(`Successfully synced "${r.length}" vendors!`))}catch(t){i=!0,e.info(q.red(`Failed to sync "${r.length}" vendors ! - ${t.message}`))}return!i}function Bt(e){let t=e.split(`,`).filter(e=>!!e),n={};return t.forEach(e=>{let[t,r]=e.split(`:`);if(!t||!r)throw Error(`Invalid variable: ${e}. Expected format: key:value`);n[t]=r}),n}async function Vt(t,n){let{createPromptGroup:{promptGroup:r}}=await W(t,ae,{input:n});return e.info(q.green(`Successfully created prompt group "${n.title}"!`)),r.id}async function Ht(t,n){await W(t,O,{input:{promptGroups:n.map(([e,t])=>({...e,id:t}))}}),e.info(q.green(`Successfully updated ${n.length} prompt groups!`))}async function Ut(t,r,i=20){let a=!1;e.info(q.magenta(`Syncing "${r.length}" prompt groups...`));let o=await H(t),s=K(await de(t),`title`),c=K(o,`title`),l=r.map(e=>[e,c[e.title]?.id]),u=l.filter(([,e])=>!e).map(([e])=>e);try{e.info(q.magenta(`Creating "${u.length}" new prompt groups...`)),await n(u,async e=>{await Vt(t,{...e,promptIds:e.prompts.map(e=>{let t=s[e];if(!t)throw Error(`Failed to find prompt with title: "${e}"`);return t.id})})},{concurrency:i}),e.info(q.green(`Successfully synced ${u.length} prompt groups!`))}catch(t){a=!0,e.info(q.red(`Failed to create prompt groups! - ${t.message}`))}let d=l.filter(e=>!!e[1]);try{e.info(q.magenta(`Updating "${d.length}" prompt groups...`)),await Ht(t,d.map(([{prompts:e,...t},n])=>[{...t,promptIds:e.map(e=>{let t=s[e];if(!t)throw Error(`Failed to find prompt with title: "${e}"`);return t.id})},n])),e.info(q.green(`Successfully updated "${d.length}" prompt groups!`))}catch(t){a=!0,e.info(q.red(`Failed to create prompt groups! - ${t.message}`))}return e.info(q.green(`Synced "${r.length}" prompt groups!`)),!a}async function Wt(t,n){let{createPromptPartial:{promptPartial:r}}=await W(t,w,{input:n});return e.info(q.green(`Successfully created prompt partial "${n.title}"!`)),r.id}async function Gt(t,n){await W(t,Ee,{input:{promptPartials:n.map(([e,t])=>({...e,id:t}))}}),e.info(q.green(`Successfully updated ${n.length} prompt partials!`))}async function Kt(t,r,i=20){let a=!1;e.info(q.magenta(`Syncing "${r.length}" prompt partials...`));let o=K(await U(t),`title`),s=r.map(e=>[e,o[e.title]?.id]),c=s.filter(([,e])=>!e).map(([e])=>e);try{e.info(q.magenta(`Creating "${c.length}" new prompt partials...`)),await n(c,async e=>{await Wt(t,e)},{concurrency:i}),e.info(q.green(`Successfully synced ${c.length} prompt partials!`))}catch(t){a=!0,e.info(q.red(`Failed to create prompt partials! - ${t.message}`))}let l=s.filter(e=>!!e[1]);try{e.info(q.magenta(`Updating "${l.length}" prompt partials...`)),await Gt(t,l),e.info(q.green(`Successfully updated "${l.length}" prompt partials!`))}catch(t){a=!0,e.info(q.red(`Failed to create prompt partials! - ${t.message}`))}return e.info(q.green(`Synced "${r.length}" prompt partials!`)),!a}async function qt(e,t){let{createTeam:n}=await W(e,m,{input:{name:t.name,description:t.description,ssoTitle:t[`sso-title`],ssoDepartment:t[`sso-department`],ssoGroup:t[`sso-group`],scopes:t.scopes,userEmails:t.users}});return n.team}async function Jt(e,t,n){let{updateTeam:r}=await W(e,se,{input:{id:n,name:t.name,description:t.description,ssoTitle:t[`sso-title`],ssoDepartment:t[`sso-department`],ssoGroup:t[`sso-group`],scopes:t.scopes,userEmails:t.users}});return r.team}async function Yt(n,r){e.info(q.magenta(`Syncing "${r.length}" teams...`));let i=!1,a=K(await k(n),`name`),o=r.filter(e=>!a[e.name]),s=r.filter(e=>!!a[e.name]);return await t(o,async t=>{try{let r=await qt(n,t);a[r.name]=r,e.info(q.green(`Successfully created team "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync team "${t.name}"! - ${n.message}`))}}),await t(s,async t=>{try{let r=await Jt(n,t,a[t.name].id);a[r.name]=r,e.info(q.green(`Successfully updated team "${t.name}"!`))}catch(n){i=!0,e.info(q.red(`Failed to sync team "${t.name}"! - ${n.message}`))}}),!i}async function Xt(t,r,{pageSize:i=50,publishToPrivacyCenter:o=!0,classifyService:l=!1,deleteExtraAttributeValues:u=!1}){let d=!1;e.info(q.magenta(`Fetching data with page size ${i}...`));let{templates:f,attributes:p,actions:m,identifiers:h,"data-subjects":g,"business-entities":_,enrichers:v,cookies:y,"consent-manager":b,"data-silos":x,"data-flows":S,prompts:C,"prompt-groups":w,"prompt-partials":T,agents:E,"agent-functions":D,"agent-files":O,vendors:k,"data-categories":A,"processing-activities":j,"processing-purposes":M,"action-items":N,"action-item-collections":P,teams:F,"privacy-center":I,messages:L,policies:R,partitions:z}=t,[B,V,H]=await Promise.all([v||h?a(t,r,!o):{},x||g||v||j?Ce(t,r):{},x&&x.map(e=>e[`api-key-title`]||[]).reduce((e,t)=>e+t.length,0)>0?s(t,r):{}]);if(b){e.info(q.magenta(`Syncing consent manager...`));try{await vt(r,b),e.info(q.green(`Successfully synced consent manager!`))}catch(t){d=!0,e.info(q.red(`Failed to sync consent manager! - ${t.message}`))}}if(C){let e=await It(r,C);d||=!e}if(T){let e=await Kt(r,T);d||=!e}if(w){let e=await Ut(r,w);d||=!e}if(F){let e=await Yt(r,F);d||=!e}if(f&&(e.info(q.magenta(`Syncing "${f.length}" email templates...`)),await n(f,async t=>{e.info(q.magenta(`Syncing template "${t.title}"...`));try{await c(t,r),e.info(q.green(`Successfully synced template "${t.title}"!`))}catch(n){d=!0,e.info(q.red(`Failed to sync template "${t.title}"! - ${n.message}`))}},{concurrency:10}),e.info(q.green(`Synced "${f.length}" email templates!`))),_){let e=await ht(r,_);d||=!e}if(k){let e=await zt(r,k);d||=!e}if(A){let e=await xt(r,A);d||=!e}if(M){let e=await Nt(r,M);d||=!e}if(z){let e=await pe(r,z);d||=!e}if(E){let e=await dt(r,E);d||=!e}if(D){let e=await ct(r,D);d||=!e}if(O){let e=await at(r,O);d||=!e}if(y){let e=await He(r,y);d||=!e}if(P){let e=await Z(r,P);d||=!e}if(p){e.info(q.magenta(`Syncing "${p.length}" attributes...`));let t=await ee(r);await n(p,async n=>{let i=t.find(e=>e.name===n.name);e.info(q.magenta(`Syncing attribute "${n.name}"...`));try{await ft(r,n,{existingAttribute:i,deleteExtraAttributeValues:u}),e.info(q.green(`Successfully synced attribute "${n.name}"!`))}catch(t){d=!0,e.info(q.red(`Failed to sync attribute "${n.name}"! - ${t.message}`))}},{concurrency:10}),e.info(q.green(`Synced "${p.length}" attributes!`))}if(N){let e=await nt(r,N);d||=!e}if(v&&(e.info(q.magenta(`Syncing "${v.length}" enrichers...`)),await n(v,async t=>{e.info(q.magenta(`Syncing enricher "${t.title}"...`));try{await te(r,{enricher:t,identifierByName:B,dataSubjectsByName:V}),e.info(q.green(`Successfully synced enricher "${t.title}"!`))}catch(n){d=!0,e.info(q.red(`Failed to sync enricher "${t.title}"! - ${n.message}`))}},{concurrency:10}),e.info(q.green(`Synced "${v.length}" enrichers!`))),h&&(e.info(q.magenta(`Syncing "${h.length}" identifiers...`)),await n(h,async t=>{let n=B[t.name];if(!n)throw Error(`Failed to find identifier with name: ${t.type}. Should have been auto-created by cli.`);e.info(q.magenta(`Syncing identifier "${t.type}"...`));try{await Ct(r,{identifier:t,dataSubjectsByName:V,identifierId:n.id,skipPublish:!o}),e.info(q.green(`Successfully synced identifier "${t.type}"!`))}catch(n){d=!0,e.info(q.red(`Failed to sync identifier "${t.type}"! - ${n.message}`))}},{concurrency:10}),e.info(q.green(`Synced "${h.length}" identifiers!`))),m){e.info(q.magenta(`Syncing "${m.length}" actions...`));let t=await ge(r);await n(m,async n=>{let i=t.find(e=>e.type===n.type);if(!i)throw Error(`Failed to find action with type: ${n.type}. Should have already existing in the organization.`);e.info(q.magenta(`Syncing action "${n.type}"...`));try{await J(r,{action:n,actionId:i.id,skipPublish:!o}),e.info(q.green(`Successfully synced action "${n.type}"!`))}catch(t){d=!0,e.info(q.red(`Failed to sync action "${n.type}"! - ${t.message}`))}},{concurrency:10}),e.info(q.green(`Synced "${m.length}" actions!`))}if(g){e.info(q.magenta(`Syncing "${g.length}" data subjects...`));let t=await ne(r);await n(g,async n=>{let i=t.find(e=>e.type===n.type);if(!i)throw Error(`Failed to find data subject with type: ${n.type}. Should have already existing in the organization.`);e.info(q.magenta(`Syncing data subject "${n.type}"...`));try{await St(r,{dataSubject:n,dataSubjectId:i.id,skipPublish:!o}),e.info(q.green(`Successfully synced data subject "${n.type}"!`))}catch(t){d=!0,e.info(q.red(`Failed to sync data subject "${n.type}"! - ${t.message}`))}},{concurrency:10}),e.info(q.green(`Synced "${g.length}" data subjects!`))}if(S){let e=await Ue(r,S,l);d||=!e}if(I){let e=await Dt(r,I);d||=!e}if(L){let e=await Tt(r,L);d||=!e}if(R){let e=await Et(r,R);d||=!e}let U=[];if(x){let{success:e,dataSiloTitleToId:t}=await re(x,r,{dataSubjectsByName:V,apiKeysByTitle:H,pageSize:i});x?.forEach(e=>{e[`deletion-dependencies`]&&U.push([t[e.title],e[`deletion-dependencies`]])}),d||=!e}if(U.length>0&&await _e(r,U),j){let e=await At(r,j);d||=!e}return d}function Zt(e,...t){let n=JSON.parse(JSON.stringify(e));return t.forEach(e=>{Ye(e).forEach(([e,t])=>{n[e]===void 0?n[e]=t:Array.isArray(t)?n[e]=[...n[e],...t]:n[e]=t})}),n}export{lt as A,nt as B,bt as C,ht as D,pt as E,st as F,J as G,Y as H,rt as I,at as L,ut as M,ot as N,mt as O,ct as P,it as R,xt as S,_t as T,Z as U,$e as V,X as W,Tt as _,zt as a,St as b,It as c,Nt as d,Mt as f,$ as g,Et as h,Lt as i,dt as j,ft as k,Ft as l,Dt as m,Xt as n,Rt as o,At as p,Bt as r,Pt as s,Zt as t,jt as u,wt as v,vt as w,yt as x,Ct as y,Q as z};
|
|
2
|
+
//# sourceMappingURL=mergeTranscendInputs-C64BJsse.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeTranscendInputs-C64BJsse.mjs","names":["MAX_PAGE_SIZE"],"sources":["../src/lib/graphql/syncAction.ts","../src/lib/graphql/syncActionItemCollections.ts","../src/lib/graphql/syncActionItems.ts","../src/lib/graphql/syncAgentFiles.ts","../src/lib/graphql/syncAgentFunctions.ts","../src/lib/graphql/syncAgents.ts","../src/lib/graphql/syncAttribute.ts","../src/lib/graphql/syncBusinessEntities.ts","../src/lib/graphql/syncConsentManager.ts","../src/lib/graphql/syncDataCategories.ts","../src/lib/graphql/syncDataSubject.ts","../src/lib/graphql/syncIdentifier.ts","../src/lib/graphql/syncIntlMessages.ts","../src/lib/graphql/syncPolicies.ts","../src/lib/graphql/syncPrivacyCenter.ts","../src/lib/graphql/syncProcessingActivities.ts","../src/lib/graphql/syncProcessingPurposes.ts","../src/lib/graphql/syncPrompts.ts","../src/lib/graphql/syncVendors.ts","../src/lib/helpers/parseVariablesFromString.ts","../src/lib/graphql/syncPromptGroups.ts","../src/lib/graphql/syncPromptPartials.ts","../src/lib/graphql/syncTeams.ts","../src/lib/graphql/syncConfigurationToTranscend.ts","../src/lib/mergeTranscendInputs.ts"],"sourcesContent":["import { IsoCountryCode, IsoCountrySubdivisionCode } from '@transcend-io/privacy-types';\nimport { GraphQLClient } from 'graphql-request';\nimport { difference } from 'lodash-es';\n\nimport { ActionInput } from '../../codecs.js';\nimport { UPDATE_ACTION } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\nconst ALL_COUNTRIES_AND_SUBDIVISIONS = [\n ...Object.values(IsoCountryCode),\n ...Object.values(IsoCountrySubdivisionCode),\n];\n\n/**\n * Sync the consent manager\n *\n * @param client - GraphQL client\n * @param options - Options\n */\nexport async function syncAction(\n client: GraphQLClient,\n {\n action,\n actionId,\n skipPublish = false,\n }: {\n /** Action update input */\n action: ActionInput;\n /** Existing action Id */\n actionId: string;\n /** When true, skip publishing to privacy center */\n skipPublish?: boolean;\n },\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_ACTION, {\n input: {\n id: actionId,\n skipSecondaryIfNoFiles: action.skipSecondaryIfNoFiles,\n skipDownloadableStep: action.skipDownloadableStep,\n requiresReview: action.requiresReview,\n waitingPeriod: action.waitingPeriod,\n skipPublish,\n regionList: action.regionBlockList\n ? difference(ALL_COUNTRIES_AND_SUBDIVISIONS, action.regionBlockList)\n : action.regionList,\n regionDetectionMethod: action.regionDetectionMethod,\n },\n });\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { ActionItemCollectionInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport {\n ActionItemCollection,\n fetchAllActionItemCollections,\n} from './fetchAllActionItemCollections.js';\nimport { UPDATE_ACTION_ITEM_COLLECTION, CREATE_ACTION_ITEM_COLLECTION } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new action item collection\n *\n * @param client - GraphQL client\n * @param actionItemCollection - Input\n * @returns Created action item collection\n */\nexport async function createActionItemCollection(\n client: GraphQLClient,\n actionItemCollection: ActionItemCollectionInput,\n): Promise<Pick<ActionItemCollection, 'id' | 'title'>> {\n const input = {\n title: actionItemCollection.title,\n description: actionItemCollection.description || '',\n hidden: actionItemCollection.hidden || false,\n productLine: actionItemCollection.productLine,\n };\n\n const { createActionItemCollection } = await makeGraphQLRequest<{\n /** Create actionItemCollection mutation */\n createActionItemCollection: {\n /** Created actionItemCollection */\n created: ActionItemCollection;\n };\n }>(client, CREATE_ACTION_ITEM_COLLECTION, {\n input,\n });\n return createActionItemCollection.created;\n}\n\n/**\n * Input to update actionItem collection\n *\n * @param client - GraphQL client\n * @param input - Input to update\n * @param actionItemCollectionId - ID of action item collection to update\n */\nexport async function updateActionItemCollection(\n client: GraphQLClient,\n input: ActionItemCollectionInput,\n actionItemCollectionId: string,\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_ACTION_ITEM_COLLECTION, {\n input: {\n id: actionItemCollectionId,\n title: input.title,\n description: input.description,\n hidden: input.hidden,\n productLine: input.productLine,\n },\n });\n}\n\n/**\n * Sync the action item collections\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncActionItemCollections(\n client: GraphQLClient,\n inputs: ActionItemCollectionInput[],\n): Promise<boolean> {\n let encounteredError = false;\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" action item collections...`));\n\n // Fetch existing\n const existingActionItemCollections = await fetchAllActionItemCollections(client);\n\n // Look up by title\n const collectionByTitle: { [k in string]: ActionItemCollection } = keyBy(\n existingActionItemCollections,\n 'title',\n );\n\n // Create new actionItems\n const newCollections = inputs.filter((input) => !collectionByTitle[input.title]);\n\n // Create new actionItem collections\n await mapSeries(newCollections, async (input) => {\n try {\n await createActionItemCollection(client, input);\n logger.info(colors.green(`Successfully created action item collection \"${input.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to create action item collection \"${input.title}\"! - ${err.message}`),\n );\n }\n });\n\n // Update all actionItems\n const actionItemsToUpdate = inputs\n .map((input) => [input, collectionByTitle[input.title]?.id])\n .filter((x): x is [ActionItemCollectionInput, string] => !!x[1]);\n await mapSeries(actionItemsToUpdate, async ([input, actionItemId]) => {\n try {\n await updateActionItemCollection(client, input, actionItemId);\n logger.info(colors.green(`Successfully synced action item collection \"${input.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync action item collection \"${input.title}\"! - ${err.message}`),\n );\n }\n });\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { uniq, keyBy, chunk } from 'lodash-es';\n\nimport { ActionItemInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport {\n ActionItemCollection,\n fetchAllActionItemCollections,\n} from './fetchAllActionItemCollections.js';\nimport { fetchAllActionItems, ActionItem } from './fetchAllActionItems.js';\nimport { Attribute, fetchAllAttributes } from './fetchAllAttributes.js';\nimport { UPDATE_ACTION_ITEMS, CREATE_ACTION_ITEMS } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new actionItem\n *\n * @param client - GraphQL client\n * @param actionItems - Action item inputs\n * @param actionItemCollectionByTitle - Action item collections indexed by title\n * @param attributeKeysByName - Lookup attribute by name\n */\nexport async function createActionItems(\n client: GraphQLClient,\n actionItems: ActionItemInput[],\n actionItemCollectionByTitle: { [k in string]: ActionItemCollection },\n // TODO: https://transcend.height.app/T-38961 - insert attributes\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n attributeKeysByName: { [k in string]: Attribute } = {},\n): Promise<void> {\n // TODO: https://transcend.height.app/T-38961 - insert attributes\n // const getAttribute = (key: string): string => {\n // const existing = attributeKeysByName[key];\n // if (!existing) {\n // throw new Error(`Attribute key \"${key}\" does not exist!`);\n // }\n // return existing.id;\n // };\n const chunked = chunk(actionItems, 100);\n await mapSeries(chunked, async (chunkToUpload) => {\n await makeGraphQLRequest(client, CREATE_ACTION_ITEMS, {\n input: chunkToUpload.map((actionItem) => ({\n title: actionItem.title,\n type: actionItem.type,\n priorityOverride: actionItem.priority,\n dueDate: actionItem.dueDate,\n customerExperienceActionItemId: actionItem.customerExperienceActionItemId,\n resolved: actionItem.resolved,\n notes: actionItem.notes,\n link: actionItem.link,\n assigneesUserEmails: actionItem.users,\n assigneesTeamNames: actionItem.teams,\n ...(actionItem.attributes\n ? {\n // TODO: https://transcend.height.app/T-38961 - insert attributes\n // attributes: actionItem.attributes.map(({ key, values }) => ({\n // attributeKeyId: getAttribute(key),\n // attributeValueNames: values,\n // })),\n }\n : {}),\n collectionIds: actionItem.collections.map(\n (collectionTitle) => actionItemCollectionByTitle[collectionTitle].id,\n ),\n })),\n });\n });\n}\n\n/**\n * Input to update actionItems\n *\n * @param client - GraphQL client\n * @param input - Input to update\n * @param actionItemId - ID of action item to update\n * @param attributeKeysByName - Attribute keys by name\n */\nexport async function updateActionItem(\n client: GraphQLClient,\n input: ActionItemInput,\n actionItemId: string,\n attributeKeysByName: {\n [k in string]: Attribute;\n } = {},\n): Promise<void> {\n const getAttribute = (key: string): string => {\n const existing = attributeKeysByName[key];\n if (!existing) {\n throw new Error(`Attribute key \"${key}\" does not exist!`);\n }\n return existing.id;\n };\n await makeGraphQLRequest(client, UPDATE_ACTION_ITEMS, {\n input: {\n ids: [actionItemId],\n title: input.title,\n priorityOverride: input.priority,\n dueDate: input.dueDate,\n resolved: input.resolved,\n customerExperienceActionItemId: input.customerExperienceActionItemId,\n notes: input.notes,\n link: input.link,\n assigneesUserEmails: input.users,\n assigneesTeamNames: input.teams,\n ...(input.attributes\n ? {\n attributes: input.attributes.map(({ key, values }) => ({\n attributeKeyId: getAttribute(key),\n attributeValueNames: values,\n })),\n }\n : {}),\n },\n });\n}\n\n/**\n * Convert action item to a unique key\n *\n * @param actionItem - action item\n * @returns Unique key\n */\nfunction actionItemToUniqueCode({\n title,\n collections,\n}: Pick<ActionItem, 'title' | 'collections'>): string {\n return `${title}-${collections\n .map((c) => c.title)\n .sort()\n .join('-')}`;\n}\n\n/**\n * Convert action item to a unique key\n *\n * @param actionItem - action item\n * @returns Unique key\n */\nfunction actionItemInputToUniqueCode({\n title,\n collections,\n}: Pick<ActionItemInput, 'title' | 'collections'>): string {\n return `${title}-${collections.sort().join('-')}`;\n}\n\n/**\n * Sync the action item\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncActionItems(\n client: GraphQLClient,\n inputs: ActionItemInput[],\n): Promise<boolean> {\n let encounteredError = false;\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" actionItems...`));\n\n // Determine if attributes are syncing\n const hasAttributes = inputs.some((input) => input.attributes && input.attributes.length > 0);\n\n // Fetch existing\n const [existingActionItems, existingActionItemCollections, attributeKeys] = await Promise.all([\n fetchAllActionItems(client),\n fetchAllActionItemCollections(client),\n hasAttributes ? fetchAllAttributes(client) : [],\n ]);\n\n // Look up by title\n const actionItemCollectionByTitle: { [k in string]: ActionItemCollection } = keyBy(\n existingActionItemCollections,\n 'title',\n );\n const actionItemByTitle: { [k in string]: ActionItem } = keyBy(\n existingActionItems,\n actionItemToUniqueCode,\n );\n const attributeKeysByName = keyBy(attributeKeys, 'name');\n const actionItemByCxId: { [k in string]: ActionItem } = keyBy(\n existingActionItems.filter((x) => !!x.customerExperienceActionItemIds),\n ({ customerExperienceActionItemIds }) => customerExperienceActionItemIds[0],\n );\n\n // Ensure all collections exist\n const missingCollections = uniq(inputs.map((input) => input.collections).flat()).filter(\n (collectionTitle) => !actionItemCollectionByTitle[collectionTitle],\n );\n if (missingCollections.length > 0) {\n logger.info(\n colors.red(\n `Missing action item collections: \"${missingCollections.join(\n '\", \"',\n )}\" - please create them first!`,\n ),\n );\n return false;\n }\n\n // Create new actionItems\n const newActionItems = inputs.filter(\n (input) =>\n !actionItemByTitle[actionItemInputToUniqueCode(input)] &&\n !actionItemByCxId[input.customerExperienceActionItemId!],\n );\n\n // Create new actionItems\n if (newActionItems.length > 0) {\n try {\n logger.info(colors.magenta(`Creating \"${newActionItems.length}\" actionItems...`));\n await createActionItems(\n client,\n newActionItems,\n actionItemCollectionByTitle,\n attributeKeysByName,\n );\n logger.info(colors.green(`Successfully created \"${newActionItems.length}\" actionItems!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create action items! - ${err.message}`));\n }\n }\n\n // Update all actionItems\n const actionItemsToUpdate = inputs\n .map((input) => [\n input,\n actionItemByTitle[actionItemInputToUniqueCode(input)]?.id ||\n actionItemByCxId[input.customerExperienceActionItemId!]?.id,\n ])\n .filter((x): x is [ActionItemInput, string] => !!x[1]);\n await mapSeries(actionItemsToUpdate, async ([input, actionItemId]) => {\n try {\n await updateActionItem(client, input, actionItemId, attributeKeysByName);\n logger.info(colors.green(`Successfully synced action item \"${input.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync action item \"${input.title}\"! - ${err.message}`));\n }\n });\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { AgentFileInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllAgentFiles, AgentFile } from './fetchAllAgentFiles.js';\nimport { UPDATE_AGENT_FILES, CREATE_AGENT_FILE } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new agent file\n *\n * @param client - GraphQL client\n * @param agentFile - Input\n * @returns Created agent file\n */\nexport async function createAgentFile(\n client: GraphQLClient,\n agentFile: AgentFileInput,\n): Promise<Pick<AgentFile, 'id' | 'name' | 'fileId'>> {\n const input = {\n name: agentFile.name,\n description: agentFile.description,\n fileId: agentFile.fileId,\n size: agentFile.size,\n purpose: agentFile.purpose,\n fileUploadedAt: new Date(),\n agentIds: [],\n // TODO: https://transcend.height.app/T-31994 - sync agents\n };\n\n const { createAgentFile } = await makeGraphQLRequest<{\n /** Create agent file mutation */\n createAgentFile: {\n /** Created agent file */\n agentFile: AgentFile;\n };\n }>(client, CREATE_AGENT_FILE, {\n input,\n });\n return createAgentFile.agentFile;\n}\n\n/**\n * Input to update agent files\n *\n * @param client - GraphQL client\n * @param agentFileIdPairs - [AgentFileInput, agentFileId] list\n */\nexport async function updateAgentFiles(\n client: GraphQLClient,\n agentFileIdPairs: [AgentFileInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_AGENT_FILES, {\n input: {\n agentFiles: agentFileIdPairs.map(([agentFile, id]) => ({\n id,\n name: agentFile.name,\n description: agentFile.description,\n fileId: agentFile.fileId,\n size: agentFile.size,\n purpose: agentFile.purpose,\n })),\n },\n });\n}\n\n/**\n * Sync the data inventory agent files\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncAgentFiles(\n client: GraphQLClient,\n inputs: AgentFileInput[],\n): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" agent files...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingAgentFiles = await fetchAllAgentFiles(client);\n\n // Look up by name\n const agentFileByName: {\n [k in string]: Pick<AgentFile, 'id' | 'name' | 'fileId'>;\n } = keyBy(existingAgentFiles, 'name');\n\n // Create new agent files\n const newAgentFiles = inputs.filter((input) => !agentFileByName[input.name]);\n\n // Create new agent files\n await mapSeries(newAgentFiles, async (agentFile) => {\n try {\n const newAgentFile = await createAgentFile(client, agentFile);\n agentFileByName[newAgentFile.name] = newAgentFile;\n logger.info(colors.green(`Successfully synced agent file \"${agentFile.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync agent file \"${agentFile.name}\"! - ${err.message}`));\n }\n });\n\n // Update all agent files\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" agent files!`));\n await updateAgentFiles(\n client,\n inputs.map((input) => [input, agentFileByName[input.name].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" agent files!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync \"${inputs.length}\" agent files! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { AgentFunctionInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllAgentFunctions, AgentFunction } from './fetchAllAgentFunctions.js';\nimport { UPDATE_AGENT_FUNCTIONS, CREATE_AGENT_FUNCTION } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new agent function\n *\n * @param client - GraphQL client\n * @param agentFunction - Input\n * @returns Created agent function\n */\nexport async function createAgentFunction(\n client: GraphQLClient,\n agentFunction: AgentFunctionInput,\n): Promise<Pick<AgentFunction, 'id' | 'name'>> {\n const input = {\n name: agentFunction.name,\n description: agentFunction.description,\n parameters: agentFunction.parameters,\n agentIds: [],\n // TODO: https://transcend.height.app/T-31994 - sync agents\n };\n\n const { createAgentFunction } = await makeGraphQLRequest<{\n /** Create agent function mutation */\n createAgentFunction: {\n /** Created agent function */\n agentFunction: AgentFunction;\n };\n }>(client, CREATE_AGENT_FUNCTION, {\n input,\n });\n return createAgentFunction.agentFunction;\n}\n\n/**\n * Input to update agent functions\n *\n * @param client - GraphQL client\n * @param agentFunctionIdPairs - [AgentFunctionInput, agentFunctionId] list\n */\nexport async function updateAgentFunctions(\n client: GraphQLClient,\n agentFunctionIdPairs: [AgentFunctionInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_AGENT_FUNCTIONS, {\n input: {\n agentFunctions: agentFunctionIdPairs.map(([agentFunction, id]) => ({\n id,\n name: agentFunction.name,\n description: agentFunction.description,\n parameters: agentFunction.parameters,\n })),\n },\n });\n}\n\n/**\n * Sync the data inventory agent functions\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncAgentFunctions(\n client: GraphQLClient,\n inputs: AgentFunctionInput[],\n): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" agent functions...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingAgentFunctions = await fetchAllAgentFunctions(client);\n\n // Look up by name\n const agentFunctionByName: {\n [k in string]: Pick<AgentFunction, 'id' | 'name'>;\n } = keyBy(existingAgentFunctions, 'name');\n\n // Create new agent functions\n const newAgentFunctions = inputs.filter((input) => !agentFunctionByName[input.name]);\n\n // Create new agent functions\n await mapSeries(newAgentFunctions, async (agentFunction) => {\n try {\n const newAgentFunction = await createAgentFunction(client, agentFunction);\n agentFunctionByName[newAgentFunction.name] = newAgentFunction;\n logger.info(colors.green(`Successfully synced agent function \"${agentFunction.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync agent function \"${agentFunction.name}\"! - ${err.message}`),\n );\n }\n });\n\n // Update all agent functions\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" agent functions!`));\n await updateAgentFunctions(\n client,\n inputs.map((input) => [input, agentFunctionByName[input.name].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" agent functions!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync \"${inputs.length}\" agent functions! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { AgentInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllAgents, Agent } from './fetchAllAgents.js';\nimport { UPDATE_AGENTS, CREATE_AGENT } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new agent\n *\n * @param client - GraphQL client\n * @param agent - Input\n * @returns Created agent\n */\nexport async function createAgent(\n client: GraphQLClient,\n agent: AgentInput,\n): Promise<Pick<Agent, 'id' | 'name' | 'agentId'>> {\n const input = {\n name: agent.name,\n description: agent.description,\n codeInterpreterEnabled: agent.codeInterpreterEnabled,\n retrievalEnabled: agent.retrievalEnabled,\n promptTitle: agent.prompt,\n largeLanguageModelName: agent['large-language-model'].name,\n largeLanguageModelClient: agent['large-language-model'].client,\n // TODO: https://transcend.height.app/T-32760 - agentFunction, agentFile\n // TODO: https://transcend.height.app/T-31994 - owners and teams\n };\n\n const { createAgent } = await makeGraphQLRequest<{\n /** Create agent mutation */\n createAgent: {\n /** Created agent */\n agent: Agent;\n };\n }>(client, CREATE_AGENT, {\n input,\n });\n return createAgent.agent;\n}\n\n/**\n * Input to update agents\n *\n * @param client - GraphQL client\n * @param agentIdParis - [AgentInput, agentId] list\n */\nexport async function updateAgents(\n client: GraphQLClient,\n agentIdParis: [AgentInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_AGENTS, {\n input: {\n agents: agentIdParis.map(([agent, id]) => ({\n id,\n name: agent.name,\n description: agent.description,\n codeInterpreterEnabled: agent.codeInterpreterEnabled,\n retrievalEnabled: agent.retrievalEnabled,\n // TODO: https://transcend.height.app/T-31995 - prompt, largeLanguageModel, agentFunction, agentFile\n })),\n },\n });\n}\n\n/**\n * Sync the data inventory agents\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncAgents(client: GraphQLClient, inputs: AgentInput[]): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" agents...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingAgents = await fetchAllAgents(client);\n\n // Look up by name\n const agentByName: {\n [k in string]: Pick<Agent, 'id' | 'name' | 'agentId'>;\n } = keyBy(existingAgents, 'name');\n\n // Create new agents\n const newAgents = inputs.filter((input) => !agentByName[input.name]);\n\n // Create new agents\n await mapSeries(newAgents, async (agent) => {\n try {\n const newAgent = await createAgent(client, agent);\n agentByName[newAgent.name] = newAgent;\n logger.info(colors.green(`Successfully synced agent \"${agent.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync agent \"${agent.name}\"! - ${err.message}`));\n }\n });\n\n // Update all agents\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" agents!`));\n await updateAgents(\n client,\n inputs.map((input) => [input, agentByName[input.name].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" agents!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync \"${inputs.length}\" agents ! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy, difference, groupBy } from 'lodash-es';\n\nimport { AttributeInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport { Attribute } from './fetchAllAttributes.js';\nimport {\n CREATE_ATTRIBUTE,\n CREATE_ATTRIBUTE_VALUES,\n DELETE_ATTRIBUTE_VALUE,\n UPDATE_ATTRIBUTE,\n UPDATE_ATTRIBUTE_VALUES,\n} from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Sync attribute\n *\n * @param client - GraphQL client\n * @param attribute - The attribute input\n * @param options - Options\n */\nexport async function syncAttribute(\n client: GraphQLClient,\n attribute: AttributeInput,\n {\n existingAttribute,\n deleteExtraAttributeValues,\n }: {\n /** The existing attribute configuration if it exists */\n existingAttribute?: Attribute;\n /** When true, delete extra attributes not specified in the list of values */\n deleteExtraAttributeValues?: boolean;\n },\n): Promise<void> {\n // attribute key input\n const input = {\n name: attribute.name,\n enabledOn: attribute.resources,\n };\n\n // create or update attribute key\n let attributeKeyId: string;\n if (!existingAttribute) {\n const {\n createAttributeKey: { attributeKey },\n } = await makeGraphQLRequest<{\n /** Create attribute key response */\n createAttributeKey: {\n /** Attribute key */\n attributeKey: {\n /** ID */\n id: string;\n };\n };\n }>(client, CREATE_ATTRIBUTE, {\n type: attribute.type,\n description: attribute.description,\n ...input,\n });\n attributeKeyId = attributeKey.id;\n } else {\n await makeGraphQLRequest(client, UPDATE_ATTRIBUTE, {\n attributeKeyId: existingAttribute.id,\n description: existingAttribute.isCustom ? attribute.description : undefined,\n ...input,\n });\n attributeKeyId = existingAttribute.id;\n }\n\n // upsert attribute values\n const existingAttributeMap = keyBy(existingAttribute?.values || [], 'name');\n const { existingValues = [], newValues = [] } = groupBy(attribute.values || [], (field) =>\n existingAttributeMap[field.name] ? 'existingValues' : 'newValues',\n );\n const removedValues = difference(\n (existingAttribute?.values || []).map(({ name }) => name),\n (attribute.values || []).map(({ name }) => name),\n );\n\n // Create new attribute values\n if (newValues.length > 0) {\n await makeGraphQLRequest(client, CREATE_ATTRIBUTE_VALUES, {\n input: newValues.map(({ name, ...rest }) => ({\n name,\n attributeKeyId,\n ...rest,\n })),\n });\n logger.info(colors.green(`Created ${newValues.length} attribute values`));\n }\n\n // Update existing attribute values\n if (existingValues.length > 0) {\n await makeGraphQLRequest(client, UPDATE_ATTRIBUTE_VALUES, {\n input: existingValues.map(({ name, ...rest }) => ({\n id: existingAttributeMap[name].id,\n name,\n description: existingAttributeMap[name].description,\n color: existingAttributeMap[name].color,\n ...rest,\n attributeKeyId,\n })),\n });\n logger.info(colors.green(`Updated ${existingValues.length} attribute values`));\n }\n\n // Delete removed attribute values\n if (removedValues.length > 0 && deleteExtraAttributeValues) {\n await map(\n removedValues,\n async (value) => {\n await makeGraphQLRequest(client, DELETE_ATTRIBUTE_VALUE, {\n id: existingAttributeMap[value].id,\n });\n },\n {\n concurrency: 10,\n },\n );\n logger.info(colors.green(`Deleted ${removedValues.length} attribute values`));\n }\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy, chunk } from 'lodash-es';\n\nimport { BusinessEntityInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllBusinessEntities, BusinessEntity } from './fetchAllBusinessEntities.js';\nimport { UPDATE_BUSINESS_ENTITIES, CREATE_BUSINESS_ENTITY } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new business entity\n *\n * @param client - GraphQL client\n * @param businessEntity - Input\n * @returns Created business entity\n */\nexport async function createBusinessEntity(\n client: GraphQLClient,\n businessEntity: BusinessEntityInput,\n): Promise<BusinessEntity> {\n const input = {\n title: businessEntity.title,\n description: businessEntity.description,\n address: businessEntity.address,\n headquarterCountry: businessEntity.headquarterCountry,\n headquarterSubDivision: businessEntity.headquarterSubDivision,\n dataProtectionOfficerName: businessEntity.dataProtectionOfficerName,\n dataProtectionOfficerEmail: businessEntity.dataProtectionOfficerEmail,\n attributes: businessEntity.attributes,\n teamNames: businessEntity.teams,\n ownerEmails: businessEntity.owners,\n };\n\n const { createBusinessEntity } = await makeGraphQLRequest<{\n /** Create business entity mutation */\n createBusinessEntity: {\n /** Created business entity */\n businessEntity: BusinessEntity;\n };\n }>(client, CREATE_BUSINESS_ENTITY, {\n input,\n });\n return createBusinessEntity.businessEntity;\n}\n\n/**\n * Input to update business entities\n *\n * @param client - GraphQL client\n * @param businessEntityIdParis - [BusinessEntityInput, businessEntityId] list\n */\nexport async function updateBusinessEntities(\n client: GraphQLClient,\n businessEntityIdParis: [BusinessEntityInput, string][],\n): Promise<void> {\n const chunkedUpdates = chunk(businessEntityIdParis, 100);\n await mapSeries(chunkedUpdates, async (chunked) => {\n await makeGraphQLRequest(client, UPDATE_BUSINESS_ENTITIES, {\n input: chunked.map(([businessEntity, id]) => ({\n id,\n title: businessEntity.title,\n description: businessEntity.description,\n address: businessEntity.address,\n headquarterCountry: businessEntity.headquarterCountry,\n headquarterSubDivision: businessEntity.headquarterSubDivision,\n dataProtectionOfficerName: businessEntity.dataProtectionOfficerName,\n dataProtectionOfficerEmail: businessEntity.dataProtectionOfficerEmail,\n attributes: businessEntity.attributes,\n teamNames: businessEntity.teams,\n ownerEmails: businessEntity.owners,\n })),\n });\n });\n}\n\n/**\n * Sync the data inventory business entities\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncBusinessEntities(\n client: GraphQLClient,\n inputs: BusinessEntityInput[],\n): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" business entities...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingBusinessEntities = await fetchAllBusinessEntities(client);\n\n // Look up by title\n const businessEntityByTitle = keyBy(existingBusinessEntities, 'title');\n\n // Create new business entities\n const newBusinessEntities = inputs.filter((input) => !businessEntityByTitle[input.title]);\n\n // Create new business entities\n await mapSeries(newBusinessEntities, async (businessEntity) => {\n try {\n const newBusinessEntity = await createBusinessEntity(client, businessEntity);\n businessEntityByTitle[newBusinessEntity.title] = newBusinessEntity;\n logger.info(colors.green(`Successfully synced business entity \"${businessEntity.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync business entity \"${businessEntity.title}\"! - ${err.message}`),\n );\n }\n });\n\n // Update all business entities\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" business entities!`));\n await updateBusinessEntities(\n client,\n inputs.map((input) => [input, businessEntityByTitle[input.title].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" business entities!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync \"${inputs.length}\" business entities ! - ${err.message}`),\n );\n }\n\n return !encounteredError;\n}\n","import { InitialViewState, OnConsentExpiry } from '@transcend-io/airgap.js-types';\nimport colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { ConsentManageExperienceInput, ConsentManagerInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport { fetchAllPurposes } from './fetchAllPurposes.js';\nimport { fetchConsentManagerId, fetchConsentManagerExperiences } from './fetchConsentManagerId.js';\nimport { fetchPrivacyCenterId } from './fetchPrivacyCenterId.js';\nimport {\n UPDATE_CONSENT_MANAGER_DOMAINS,\n CREATE_CONSENT_MANAGER,\n UPDATE_LOAD_OPTIONS,\n UPDATE_CONSENT_MANAGER_PARTITION,\n UPDATE_CONSENT_MANAGER_VERSION,\n TOGGLE_TELEMETRY_PARTITION_STRATEGY,\n TOGGLE_UNKNOWN_COOKIE_POLICY,\n TOGGLE_CONSENT_PRECEDENCE,\n TOGGLE_UNKNOWN_REQUEST_POLICY,\n UPDATE_CONSENT_EXPERIENCE,\n CREATE_CONSENT_EXPERIENCE,\n UPDATE_CONSENT_MANAGER_THEME,\n} from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\nimport { fetchPartitions } from './syncPartitions.js';\n\nconst PURPOSES_LINK = 'https://app.transcend.io/consent-manager/regional-experiences/purposes';\n\n/**\n * Sync consent manager experiences up to Transcend\n *\n * @param client - GraphQL client\n * @param experiences - The experience inputs\n */\nexport async function syncConsentManagerExperiences(\n client: GraphQLClient,\n experiences: ConsentManageExperienceInput[],\n): Promise<void> {\n // Fetch existing experiences and\n const existingExperiences = await fetchConsentManagerExperiences(client);\n const experienceLookup = keyBy(existingExperiences, 'name');\n\n // Fetch existing purposes\n const purposes = await fetchAllPurposes(client);\n const purposeLookup = keyBy(purposes, 'trackingType');\n\n // Bulk update or create experiences\n await map(\n experiences,\n async (exp, ind) => {\n // Purpose IDs\n const purposeIds = exp.purposes?.map((purpose, ind2) => {\n const existingPurpose = purposeLookup[purpose.trackingType];\n if (!existingPurpose) {\n throw new Error(\n `Invalid purpose trackingType provided at consentManager.experiences[${ind}].purposes[${ind2}]: ` +\n `${purpose.trackingType}. See list of valid purposes ${PURPOSES_LINK}`,\n );\n }\n return existingPurpose.id;\n });\n const optedOutPurposeIds = exp.optedOutPurposes?.map((purpose, ind2) => {\n const existingPurpose = purposeLookup[purpose.trackingType];\n if (!existingPurpose) {\n throw new Error(\n `Invalid purpose trackingType provided at consentManager.experiences[${ind}].optedOutPurposes[${ind2}]: ` +\n `${purpose.trackingType}. See list of valid purposes ${PURPOSES_LINK}`,\n );\n }\n return existingPurpose.id;\n });\n\n // update experience\n const existingExperience = experienceLookup[exp.name];\n if (existingExperience) {\n await makeGraphQLRequest(client, UPDATE_CONSENT_EXPERIENCE, {\n input: {\n id: existingExperience.id,\n name: exp.displayName,\n regions: exp.regions,\n operator: exp.operator,\n onConsentExpiry: exp.onConsentExpiry,\n consentExpiry: exp.consentExpiry,\n displayPriority:\n exp.displayPriority !== existingExperience.displayPriority\n ? exp.displayPriority\n : undefined,\n viewState: exp.viewState,\n purposes: purposeIds,\n optedOutPurposes: optedOutPurposeIds,\n browserLanguages: exp.browserLanguages,\n browserTimeZones: exp.browserTimeZones,\n },\n });\n logger.info(colors.green(`Successfully synced consent experience \"${exp.name}\"!`));\n } else {\n // create new experience\n await makeGraphQLRequest(client, CREATE_CONSENT_EXPERIENCE, {\n input: {\n name: exp.name,\n displayName: exp.displayName,\n regions: exp.regions,\n operator: exp.operator,\n onConsentExpiry: exp.onConsentExpiry || OnConsentExpiry.Prompt,\n consentExpiry: exp.consentExpiry,\n displayPriority: exp.displayPriority,\n viewState: exp.viewState || InitialViewState.Hidden,\n purposes: purposeIds || [],\n optedOutPurposes: optedOutPurposeIds || [],\n browserLanguages: exp.browserLanguages,\n browserTimeZones: exp.browserTimeZones,\n },\n });\n logger.info(colors.green(`Successfully created consent experience \"${exp.name}\"!`));\n }\n },\n {\n concurrency: 10,\n },\n );\n}\n\n/**\n * Sync the consent manager\n *\n * @param client - GraphQL client\n * @param consentManager - The consent manager input\n */\nexport async function syncConsentManager(\n client: GraphQLClient,\n consentManager: ConsentManagerInput,\n): Promise<void> {\n let airgapBundleId: string;\n\n // ensure the consent manager is created and deployed\n try {\n airgapBundleId = await fetchConsentManagerId(client, 1);\n } catch (err) {\n // TODO: https://transcend.height.app/T-23778\n if (err.message.includes('AirgapBundle not found')) {\n const privacyCenterId = await fetchPrivacyCenterId(client);\n\n const { createConsentManager } = await makeGraphQLRequest<{\n /** Create consent manager */\n createConsentManager: {\n /** Consent manager */\n consentManager: {\n /** ID */\n id: string;\n };\n };\n }>(client, CREATE_CONSENT_MANAGER, {\n domains: consentManager.domains,\n privacyCenterId,\n });\n airgapBundleId = createConsentManager.consentManager.id;\n } else {\n throw err;\n }\n }\n\n // sync domains\n if (consentManager.domains) {\n await makeGraphQLRequest(client, UPDATE_CONSENT_MANAGER_DOMAINS, {\n domains: consentManager.domains,\n airgapBundleId,\n });\n }\n\n // sync partition\n if (consentManager.partition) {\n const partitions = await fetchPartitions(client);\n const partitionToUpdate = partitions.find((part) => part.name === consentManager.partition);\n if (!partitionToUpdate) {\n throw new Error(\n `Partition \"${consentManager.partition}\" not found. Please create the partition first.`,\n );\n }\n await makeGraphQLRequest(client, UPDATE_CONSENT_MANAGER_PARTITION, {\n partitionId: partitionToUpdate.id,\n airgapBundleId,\n });\n }\n\n if (consentManager.version) {\n await makeGraphQLRequest(client, UPDATE_CONSENT_MANAGER_VERSION, {\n airgapBundleId,\n version: consentManager.version,\n });\n }\n\n // sync signed IAB agreement\n if (consentManager.signedIabAgreement) {\n await makeGraphQLRequest(client, UPDATE_LOAD_OPTIONS, {\n input: {\n id: airgapBundleId,\n ...(consentManager.signedIabAgreement\n ? { signedIabAgreement: consentManager.signedIabAgreement }\n : {}),\n },\n });\n }\n\n // sync default request policy\n if (consentManager.unknownRequestPolicy) {\n await makeGraphQLRequest(client, TOGGLE_UNKNOWN_REQUEST_POLICY, {\n input: {\n id: airgapBundleId,\n unknownRequestPolicy: consentManager.unknownRequestPolicy,\n },\n });\n }\n\n // sync default cookie policy\n if (consentManager.unknownRequestPolicy) {\n await makeGraphQLRequest(client, TOGGLE_UNKNOWN_COOKIE_POLICY, {\n input: {\n id: airgapBundleId,\n unknownCookiePolicy: consentManager.unknownCookiePolicy,\n },\n });\n }\n\n // sync telemetry partition strategy\n if (consentManager.telemetryPartitioning) {\n await makeGraphQLRequest(client, TOGGLE_TELEMETRY_PARTITION_STRATEGY, {\n input: {\n id: airgapBundleId,\n strategy: consentManager.telemetryPartitioning,\n },\n });\n }\n\n // sync telemetry partition strategy\n if (consentManager.consentPrecedence) {\n await makeGraphQLRequest(client, TOGGLE_CONSENT_PRECEDENCE, {\n input: {\n id: airgapBundleId,\n consentPrecedence: consentManager.consentPrecedence,\n },\n });\n }\n\n // Update experience configurations\n if (consentManager.experiences) {\n await syncConsentManagerExperiences(client, consentManager.experiences);\n }\n\n // update theme\n if (consentManager.theme) {\n await makeGraphQLRequest(client, UPDATE_CONSENT_MANAGER_THEME, {\n input: {\n airgapBundleId,\n ...consentManager.theme,\n },\n });\n }\n\n // TODO: https://transcend.height.app/T-23875\n // syncEndpoint: string;\n // TODO: https://transcend.height.app/T-23919\n // syncGroups: string;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { DataCategoryInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllDataCategories, DataSubCategory } from './fetchAllDataCategories.js';\nimport { UPDATE_DATA_SUB_CATEGORIES, CREATE_DATA_SUB_CATEGORY } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new data category\n *\n * @param client - GraphQL client\n * @param dataCategory - Input\n * @returns Created data category\n */\nexport async function createDataCategory(\n client: GraphQLClient,\n dataCategory: DataCategoryInput,\n): Promise<Pick<DataSubCategory, 'id' | 'name' | 'category'>> {\n const input = {\n name: dataCategory.name,\n category: dataCategory.category,\n description: dataCategory.description,\n // TODO: https://transcend.height.app/T-31994 - add attributes, teams, owners\n };\n\n const { createDataCategory } = await makeGraphQLRequest<{\n /** Create data category mutation */\n createDataCategory: {\n /** Created data category */\n dataCategory: DataSubCategory;\n };\n }>(client, CREATE_DATA_SUB_CATEGORY, {\n input,\n });\n return createDataCategory.dataCategory;\n}\n\n/**\n * Input to update data categories\n *\n * @param client - GraphQL client\n * @param dataCategoryIdPairs - [DataCategoryInput, dataCategoryId] list\n */\nexport async function updateDataCategories(\n client: GraphQLClient,\n dataCategoryIdPairs: [DataCategoryInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_DATA_SUB_CATEGORIES, {\n input: {\n dataSubCategories: dataCategoryIdPairs.map(([dataCategory, id]) => ({\n id,\n description: dataCategory.description,\n // TODO: https://transcend.height.app/T-31994 - add teams, owners\n attributes: dataCategory.attributes,\n })),\n },\n });\n}\n\n/**\n * Sync the data inventory data categories\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncDataCategories(\n client: GraphQLClient,\n inputs: DataCategoryInput[],\n): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" data categories...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingDataCategories = await fetchAllDataCategories(client);\n\n // Look up by name\n const dataCategoryByName: {\n [k in string]: Pick<DataSubCategory, 'id' | 'name' | 'category'>;\n } = keyBy(existingDataCategories, ({ name, category }) => `${name}:${category}`);\n\n // Create new data categories\n const newDataCategories = inputs.filter(\n (input) => !dataCategoryByName[`${input.name}:${input.category}`],\n );\n\n // Create new data categories\n await mapSeries(newDataCategories, async (dataCategory) => {\n try {\n const newDataCategory = await createDataCategory(client, dataCategory);\n dataCategoryByName[`${newDataCategory.name}:${newDataCategory.category}`] = newDataCategory;\n logger.info(colors.green(`Successfully synced data category \"${dataCategory.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync data category \"${dataCategory.name}\"! - ${err.message}`),\n );\n }\n });\n\n // Update all data categories\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" data categories!`));\n await updateDataCategories(\n client,\n inputs.map((input) => [input, dataCategoryByName[`${input.name}:${input.category}`].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" data categories!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync \"${inputs.length}\" data categories ! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import { GraphQLClient } from 'graphql-request';\n\nimport { DataSubjectInput } from '../../codecs.js';\nimport { UPDATE_DATA_SUBJECT, TOGGLE_DATA_SUBJECT } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Sync the data subjects\n *\n * @param client - GraphQL client\n * @param options - Options\n */\nexport async function syncDataSubject(\n client: GraphQLClient,\n {\n dataSubject,\n dataSubjectId,\n skipPublish = false,\n }: {\n /** DataSubject update input */\n dataSubject: DataSubjectInput;\n /** Existing data subject Id */\n dataSubjectId: string;\n /** When true, skip publishing to privacy center */\n skipPublish?: boolean;\n },\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_DATA_SUBJECT, {\n input: {\n id: dataSubjectId,\n title: dataSubject.title,\n adminDashboardDefaultSilentMode: dataSubject.adminDashboardDefaultSilentMode,\n actions: dataSubject.actions,\n skipPublish: skipPublish && typeof dataSubject.active === 'undefined',\n },\n });\n\n if (typeof dataSubject.active === 'boolean') {\n await makeGraphQLRequest(client, TOGGLE_DATA_SUBJECT, {\n input: {\n id: dataSubjectId,\n active: dataSubject.active,\n skipPublish,\n },\n });\n }\n}\n","import { GraphQLClient } from 'graphql-request';\n\nimport { IdentifierInput } from '../../codecs.js';\nimport type { DataSubject } from './fetchDataSubjects.js';\nimport { UPDATE_IDENTIFIER } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\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 colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { chunk } from 'lodash-es';\n\nimport { IntlMessageInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { UPDATE_INTL_MESSAGES } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\nconst MAX_PAGE_SIZE = 100;\n\n/**\n * Update or create intl messages\n *\n * @param client - GraphQL client\n * @param messageInputs - List of message inputs\n */\nexport async function updateIntlMessages(\n client: GraphQLClient,\n messageInputs: IntlMessageInput[],\n): Promise<void> {\n // Batch update messages\n await mapSeries(chunk(messageInputs, MAX_PAGE_SIZE), async (page) => {\n await makeGraphQLRequest(client, UPDATE_INTL_MESSAGES, {\n messages: page.map((message) => ({\n ...(message.id.includes('.') ? {} : { id: message.id }),\n defaultMessage: message.defaultMessage,\n targetReactIntlId: message.targetReactIntlId,\n translations: !message.translations\n ? undefined\n : Object.entries(message.translations).map(([locale, value]) => ({\n locale,\n value,\n })),\n })),\n });\n });\n}\n\n/**\n * Sync the set of messages from the YML interface into the product\n *\n * @param client - GraphQL client\n * @param messages - messages to sync\n * @returns True upon success, false upon failure\n */\nexport async function syncIntlMessages(\n client: GraphQLClient,\n messages: IntlMessageInput[],\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(colors.magenta(`Syncing \"${messages.length}\" messages...`));\n\n // Ensure no duplicates are being uploaded\n const notUnique = messages.filter(\n (message) => messages.filter((pol) => message.id === pol.id).length > 1,\n );\n if (notUnique.length > 0) {\n throw new Error(\n `Failed to upload messages as there were non-unique entries found: ${notUnique\n .map(({ id }) => id)\n .join(',')}`,\n );\n }\n\n try {\n logger.info(colors.magenta(`Upserting \"${messages.length}\" new messages...`));\n await updateIntlMessages(client, messages);\n logger.info(colors.green(`Successfully synced ${messages.length} messages!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create messages! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { chunk, keyBy } from 'lodash-es';\n\nimport { PolicyInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllPolicies } from './fetchAllPolicies.js';\nimport { fetchPrivacyCenterId } from './fetchPrivacyCenterId.js';\nimport { UPDATE_POLICIES } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\nconst MAX_PAGE_SIZE = 100;\n\n/**\n * Update or create policies\n *\n * @param client - GraphQL client\n * @param policyInputs - List of policy input\n */\nexport async function updatePolicies(\n client: GraphQLClient,\n policyInputs: [PolicyInput, string | undefined][],\n): Promise<void> {\n const privacyCenterId = await fetchPrivacyCenterId(client);\n\n // Batch update policies\n await mapSeries(chunk(policyInputs, MAX_PAGE_SIZE), async (page) => {\n await makeGraphQLRequest(client, UPDATE_POLICIES, {\n privacyCenterId,\n policies: page.map(([policy, policyId]) => ({\n id: policyId,\n title: policy.title,\n disableEffectiveOn: policy.disableEffectiveOn,\n disabledLocales: policy.disabledLocales,\n ...(policy.effectiveOn || policy.content\n ? {\n version: {\n ...(policy.effectiveOn ? { effectiveOn: policy.effectiveOn } : {}),\n ...(policy.content\n ? {\n content: {\n defaultMessage: policy.content,\n },\n }\n : {}),\n },\n }\n : {}),\n })),\n });\n });\n}\n\n/**\n * Sync the set of policies from the YML interface into the product\n *\n * @param client - GraphQL client\n * @param policies - policies to sync\n * @returns True upon success, false upon failure\n */\nexport async function syncPolicies(\n client: GraphQLClient,\n policies: PolicyInput[],\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(colors.magenta(`Syncing \"${policies.length}\" policies...`));\n\n // Ensure no duplicates are being uploaded\n const notUnique = policies.filter(\n (policy) => policies.filter((pol) => policy.title === pol.title).length > 1,\n );\n if (notUnique.length > 0) {\n throw new Error(\n `Failed to upload policies as there were non-unique entries found: ${notUnique\n .map(({ title }) => title)\n .join(',')}`,\n );\n }\n\n // Grab existing policies\n const existingPolicies = await fetchAllPolicies(client);\n const policiesById = keyBy(existingPolicies, ({ title }) => title.defaultMessage);\n\n try {\n logger.info(colors.magenta(`Upserting \"${policies.length}\" new policies...`));\n await updatePolicies(\n client,\n policies.map((policy) => [policy, policiesById[policy.title]?.id]),\n );\n logger.info(colors.green(`Successfully synced ${policies.length} policies!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create policies! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\n\nimport { PrivacyCenterInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { fetchPrivacyCenterId } from './fetchPrivacyCenterId.js';\nimport { UPDATE_PRIVACY_CENTER } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Sync the privacy center\n *\n * @param client - GraphQL client\n * @param privacyCenter - The privacy center input\n * @returns Whether the privacy center was synced successfully\n */\nexport async function syncPrivacyCenter(\n client: GraphQLClient,\n privacyCenter: PrivacyCenterInput,\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(colors.magenta('Syncing privacy center...'));\n\n // Grab the privacy center ID\n const privacyCenterId = await fetchPrivacyCenterId(client);\n\n try {\n await makeGraphQLRequest(client, UPDATE_PRIVACY_CENTER, {\n input: {\n privacyCenterId,\n transformAccessReportJsonToCsv: privacyCenter.transformAccessReportJsonToCsv,\n useCustomEmailDomain: privacyCenter.useCustomEmailDomain,\n useNoReplyEmailAddress: privacyCenter.useNoReplyEmailAddress,\n replyToEmail: privacyCenter.replyToEmail,\n supportEmail: privacyCenter.supportEmail,\n preferBrowserDefaultLocale: privacyCenter.preferBrowserDefaultLocale,\n defaultLocale: privacyCenter.defaultLocale,\n locales: privacyCenter.locales,\n showMarketingPreferences: privacyCenter.showMarketingPreferences,\n showManageYourPrivacy: privacyCenter.showManageYourPrivacy,\n showPolicies: privacyCenter.showPolicies,\n showConsentManager: privacyCenter.showConsentManager,\n showDataFlows: privacyCenter.showDataFlows,\n showCookies: privacyCenter.showCookies,\n showTrackingTechnologies: privacyCenter.showTrackingTechnologies,\n showPrivacyRequestButton: privacyCenter.showPrivacyRequestButton,\n isDisabled: privacyCenter.isDisabled,\n ...(privacyCenter.theme\n ? {\n colorPalette: privacyCenter.theme.colors,\n componentStyles: privacyCenter.theme.componentStyles,\n textStyles: privacyCenter.theme.textStyles,\n }\n : {}),\n },\n });\n logger.info(colors.green('Successfully synced privacy center!'));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create privacy center! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { ProcessingActivityInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport {\n fetchAllProcessingActivities,\n ProcessingActivity,\n} from './fetchAllProcessingActivities.js';\nimport { UPDATE_PROCESSING_ACTIVITIES, CREATE_PROCESSING_ACTIVITY } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Create a new processing activity, setting only title and description\n *\n * @param client - GraphQL client\n * @param processingActivity - Input\n * @returns Created processingActivity\n */\nasync function createProcessingActivity(\n client: GraphQLClient,\n processingActivity: ProcessingActivityInput,\n): Promise<Pick<ProcessingActivity, 'id' | 'title'>> {\n const input = {\n title: processingActivity.title,\n description: processingActivity.description,\n };\n\n const { createProcessingActivity } = await makeGraphQLRequest<{\n /** Create processingActivity mutation */\n createProcessingActivity: {\n /** Created processingActivity */\n processingActivity: ProcessingActivity;\n };\n }>(client, CREATE_PROCESSING_ACTIVITY, {\n input,\n });\n return createProcessingActivity.processingActivity;\n}\n\n/**\n * Update a list of processing activities.\n *\n * @param client - GraphQL client\n * @param processingActivityIdPairs - [ProcessingActivityInput, processingActivityId] list\n */\nasync function updateProcessingActivities(\n client: GraphQLClient,\n processingActivityIdPairs: [ProcessingActivityInput, string][],\n): Promise<void> {\n const invalidProcessingActivityTitles = processingActivityIdPairs\n .filter(([, id]) => id === undefined)\n .map(([{ title }]) => title);\n if (invalidProcessingActivityTitles.length > 0) {\n // We always attempt to create processing activities before updating them, but if creation failed\n // (for example, due to insufficient scope), this provides a better error message\n throw new Error(\n `The following ${\n invalidProcessingActivityTitles.length\n } processing activities do not exist and thus can't be updated: \"${invalidProcessingActivityTitles.join(\n '\", \"',\n )}\"`,\n );\n }\n await makeGraphQLRequest(client, UPDATE_PROCESSING_ACTIVITIES, {\n input: {\n processingActivities: processingActivityIdPairs.map(\n ([\n { processingSubPurposes, dataSubCategories, saaSCategories, ...processingActivity },\n id,\n ]) => ({\n dataSubCategoryInputs: dataSubCategories?.map(({ category, name }) => ({\n category,\n name: name ?? '',\n })),\n processingPurposeSubCategoryInputs: processingSubPurposes?.map(({ purpose, name }) => ({\n purpose,\n name: name ?? 'Other',\n })),\n saaSCategoryTitles: saaSCategories,\n ...processingActivity,\n id,\n }),\n ),\n },\n });\n}\n\n/**\n * Sync the data inventory processing activities\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncProcessingActivities(\n client: GraphQLClient,\n inputs: ProcessingActivityInput[],\n): Promise<boolean> {\n let encounteredError = false;\n\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" processing activities...`));\n const existingProcessingActivities = await fetchAllProcessingActivities(client);\n\n // Look up by title\n const processingActivityByTitle: Record<string, Pick<ProcessingActivity, 'id' | 'title'>> = keyBy(\n existingProcessingActivities,\n 'title',\n );\n\n // Create new processingActivities\n const newProcessingActivities = inputs.filter((input) => !processingActivityByTitle[input.title]);\n if (newProcessingActivities.length > 0) {\n logger.info(\n colors.magenta(`Creating \"${newProcessingActivities.length}\" new processing activities...`),\n );\n }\n await mapSeries(newProcessingActivities, async (processingActivity) => {\n try {\n const newProcessingActivity = await createProcessingActivity(client, processingActivity);\n // Augment processingActivityByTitle with newly-created processing activity\n processingActivityByTitle[newProcessingActivity.title] = newProcessingActivity;\n logger.info(\n colors.green(`Successfully created processing activity \"${processingActivity.title}\"!`),\n );\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(\n `Failed to create processing activity \"${processingActivity.title}\"! - ${err.message}`,\n ),\n );\n }\n });\n\n // Update all processing activities\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" processing activities!`));\n await updateProcessingActivities(\n client,\n inputs.map((input) => [\n input,\n // This processing activity might not exist if the `create` step failed\n processingActivityByTitle[input.title]?.id,\n ]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" processingActivities!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync \"${inputs.length}\" processingActivities! - ${err.message}`),\n );\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { ProcessingPurposeInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport {\n fetchAllProcessingPurposes,\n ProcessingPurposeSubCategory,\n} from './fetchAllProcessingPurposes.js';\nimport {\n UPDATE_PROCESSING_PURPOSE_SUB_CATEGORIES,\n CREATE_PROCESSING_PURPOSE_SUB_CATEGORY,\n} from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new processing purpose\n *\n * @param client - GraphQL client\n * @param processingPurpose - Input\n * @returns Created processing purpose\n */\nexport async function createProcessingPurpose(\n client: GraphQLClient,\n processingPurpose: ProcessingPurposeInput,\n): Promise<Pick<ProcessingPurposeSubCategory, 'id' | 'name' | 'purpose'>> {\n const input = {\n name: processingPurpose.name,\n purpose: processingPurpose.purpose,\n description: processingPurpose.description,\n // TODO: https://transcend.height.app/T-31994 - add attributes, teams, owners\n };\n\n const { createProcessingPurposeSubCategory } = await makeGraphQLRequest<{\n /** Create processing purpose mutation */\n createProcessingPurposeSubCategory: {\n /** Created processing purpose */\n processingPurposeSubCategory: ProcessingPurposeSubCategory;\n };\n }>(client, CREATE_PROCESSING_PURPOSE_SUB_CATEGORY, {\n input,\n });\n return createProcessingPurposeSubCategory.processingPurposeSubCategory;\n}\n\n/**\n * Input to update processing purposes\n *\n * @param client - GraphQL client\n * @param processingPurposeIdPairs - [ProcessingPurposeInput, processingPurposeId] list\n */\nexport async function updateProcessingPurposes(\n client: GraphQLClient,\n processingPurposeIdPairs: [ProcessingPurposeInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_PROCESSING_PURPOSE_SUB_CATEGORIES, {\n input: {\n processingPurposeSubCategories: processingPurposeIdPairs.map(([processingPurpose, id]) => ({\n id,\n description: processingPurpose.description,\n // TODO: https://transcend.height.app/T-31994 - add teams, owners\n attributes: processingPurpose.attributes,\n })),\n },\n });\n}\n\n/**\n * Sync the data inventory processing purposes\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncProcessingPurposes(\n client: GraphQLClient,\n inputs: ProcessingPurposeInput[],\n): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" processing purposes...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingProcessingPurposes = await fetchAllProcessingPurposes(client);\n\n // Look up by name\n const processingPurposeByName: {\n [k in string]: Pick<ProcessingPurposeSubCategory, 'id' | 'name'>;\n } = keyBy(existingProcessingPurposes, ({ name, purpose }) => `${name}:${purpose}`);\n\n // Create new processing purposes\n const newProcessingPurposes = inputs.filter(\n (input) => !processingPurposeByName[`${input.name}:${input.purpose}`],\n );\n\n // Create new processing purposes\n await mapSeries(newProcessingPurposes, async (processingPurpose) => {\n try {\n const newProcessingPurpose = await createProcessingPurpose(client, processingPurpose);\n processingPurposeByName[`${newProcessingPurpose.name}:${newProcessingPurpose.purpose}`] =\n newProcessingPurpose;\n logger.info(\n colors.green(`Successfully synced processing purpose \"${processingPurpose.name}\"!`),\n );\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(\n `Failed to sync processing purpose \"${processingPurpose.name}\"! - ${err.message}`,\n ),\n );\n }\n });\n\n // Update all processing purposes\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" processing purposes!`));\n await updateProcessingPurposes(\n client,\n inputs.map((input) => [input, processingPurposeByName[`${input.name}:${input.purpose}`].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" processing purposes!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync \"${inputs.length}\" processing purposes ! - ${err.message}`),\n );\n }\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { PromptInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport { fetchAllPrompts } from './fetchPrompts.js';\nimport { UPDATE_PROMPTS, CREATE_PROMPT } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Create a new prompt\n *\n * @param client - GraphQL client\n * @param input - Prompt input\n * @returns Prompt ID\n */\nexport async function createPrompt(\n client: GraphQLClient,\n input: {\n /** Title of prompt */\n title: string;\n /** Prompt content */\n content: string;\n },\n): Promise<string> {\n const {\n createPrompt: { prompt },\n } = await makeGraphQLRequest<{\n /** createPrompt mutation */\n createPrompt: {\n /** Prompt */\n prompt: {\n /** ID */\n id: string;\n };\n };\n }>(client, CREATE_PROMPT, {\n // TODO: https://transcend.height.app/T-31994 - include models and groups, teams, users\n input,\n });\n logger.info(colors.green(`Successfully created prompt \"${input.title}\"!`));\n return prompt.id;\n}\n\n/**\n * Update a set of existing prompts\n *\n * @param client - GraphQL client\n * @param input - Prompt input\n */\nexport async function updatePrompts(\n client: GraphQLClient,\n input: [PromptInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_PROMPTS, {\n input: {\n prompts: input.map(([input, id]) => ({\n ...input,\n id,\n })),\n },\n });\n logger.info(colors.green(`Successfully updated ${input.length} prompts!`));\n}\n\n/**\n * Sync the prompts\n *\n * @param client - GraphQL client\n * @param prompts - Prompts\n * @param concurrency - Concurrency\n * @returns True if synced successfully\n */\nexport async function syncPrompts(\n client: GraphQLClient,\n prompts: PromptInput[],\n concurrency = 20,\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(colors.magenta(`Syncing \"${prompts.length}\" prompts...`));\n\n // Index existing prompts\n const existing = await fetchAllPrompts(client);\n const promptByTitle = keyBy(existing, 'title');\n\n // Determine which prompts are new vs existing\n const mapPromptsToExisting = prompts.map((promptInput) => [\n promptInput,\n promptByTitle[promptInput.title]?.id,\n ]);\n\n // Create the new prompts\n const newPrompts = mapPromptsToExisting\n .filter(([, existing]) => !existing)\n .map(([promptInput]) => promptInput as PromptInput);\n try {\n logger.info(colors.magenta(`Creating \"${newPrompts.length}\" new prompts...`));\n await map(\n newPrompts,\n async (prompt) => {\n await createPrompt(client, prompt);\n },\n {\n concurrency,\n },\n );\n logger.info(colors.green(`Successfully synced ${newPrompts.length} prompts!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create prompts! - ${err.message}`));\n }\n\n // Update existing prompts\n const existingPrompts = mapPromptsToExisting.filter((x): x is [PromptInput, string] => !!x[1]);\n try {\n logger.info(colors.magenta(`Updating \"${existingPrompts.length}\" prompts...`));\n await updatePrompts(client, existingPrompts);\n logger.info(colors.green(`Successfully updated \"${existingPrompts.length}\" prompts!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create prompts! - ${err.message}`));\n }\n\n logger.info(colors.green(`Synced \"${prompts.length}\" prompts!`));\n\n // Return true upon success\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { VendorInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllVendors, Vendor } from './fetchAllVendors.js';\nimport { UPDATE_VENDORS, CREATE_VENDOR } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new vendor\n *\n * @param client - GraphQL client\n * @param vendor - Input\n * @returns Created vendor\n */\nexport async function createVendor(\n client: GraphQLClient,\n vendor: VendorInput,\n): Promise<Pick<Vendor, 'id' | 'title'>> {\n const input = {\n title: vendor.title,\n description: vendor.description,\n address: vendor.address,\n headquarterCountry: vendor.headquarterCountry,\n headquarterSubDivision: vendor.headquarterSubDivision,\n dataProcessingAgreementLink: vendor.dataProcessingAgreementLink,\n contactName: vendor.contactName,\n contactPhone: vendor.contactPhone,\n websiteUrl: vendor.websiteUrl,\n // TODO: https://transcend.height.app/T-31994 - add attributes, teams, owners\n };\n\n const { createVendor } = await makeGraphQLRequest<{\n /** Create vendor mutation */\n createVendor: {\n /** Created vendor */\n vendor: Vendor;\n };\n }>(client, CREATE_VENDOR, {\n input,\n });\n return createVendor.vendor;\n}\n\n/**\n * Input to update vendors\n *\n * @param client - GraphQL client\n * @param vendorIdParis - [VendorInput, vendorId] list\n */\nexport async function updateVendors(\n client: GraphQLClient,\n vendorIdParis: [VendorInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_VENDORS, {\n input: {\n vendors: vendorIdParis.map(([vendor, id]) => ({\n id,\n title: vendor.title,\n description: vendor.description,\n address: vendor.address,\n headquarterCountry: vendor.headquarterCountry,\n headquarterSubDivision: vendor.headquarterSubDivision,\n dataProcessingAgreementLink: vendor.dataProcessingAgreementLink,\n contactName: vendor.contactName,\n contactPhone: vendor.contactPhone,\n websiteUrl: vendor.websiteUrl,\n // TODO: https://transcend.height.app/T-31994 - add teams, owners\n attributes: vendor.attributes,\n })),\n },\n });\n}\n\n/**\n * Sync the data inventory vendors\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncVendors(client: GraphQLClient, inputs: VendorInput[]): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" vendors...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingVendors = await fetchAllVendors(client);\n\n // Look up by title\n const vendorByTitle: { [k in string]: Pick<Vendor, 'id' | 'title'> } = keyBy(\n existingVendors,\n 'title',\n );\n\n // Create new vendors\n const newVendors = inputs.filter((input) => !vendorByTitle[input.title]);\n\n // Create new vendors\n await mapSeries(newVendors, async (vendor) => {\n try {\n const newVendor = await createVendor(client, vendor);\n vendorByTitle[newVendor.title] = newVendor;\n logger.info(colors.green(`Successfully synced vendor \"${vendor.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync vendor \"${vendor.title}\"! - ${err.message}`));\n }\n });\n\n // Update all vendors\n try {\n logger.info(colors.magenta(`Updating \"${inputs.length}\" vendors!`));\n await updateVendors(\n client,\n inputs.map((input) => [input, vendorByTitle[input.title].id]),\n );\n logger.info(colors.green(`Successfully synced \"${inputs.length}\" vendors!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync \"${inputs.length}\" vendors ! - ${err.message}`));\n }\n\n return !encounteredError;\n}\n","/**\n * Parse variables from string\n *\n * @param variables - Variables as string\n * @returns Variables as object\n */\nexport function parseVariablesFromString(variables: string): {\n [k in string]: string;\n} {\n // Parse out the variables\n const splitVars = variables.split(',').filter((x) => !!x);\n const vars: { [k in string]: string } = {};\n splitVars.forEach((variable) => {\n const [k, v] = variable.split(':');\n if (!k || !v) {\n throw new Error(`Invalid variable: ${variable}. Expected format: key:value`);\n }\n vars[k] = v;\n });\n return vars;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { PromptGroupInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport { fetchAllPromptGroups } from './fetchPromptGroups.js';\nimport { fetchAllPrompts } from './fetchPrompts.js';\nimport { UPDATE_PROMPT_GROUPS, CREATE_PROMPT_GROUP } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\nexport interface EditPromptGroupInput {\n /** Title of prompt group */\n title: string;\n /** Prompt group description */\n description: string;\n /** Prompt IDs */\n promptIds: string[];\n}\n\n/**\n * Create a new prompt group\n *\n * @param client - GraphQL client\n * @param input - Prompt input\n * @returns Prompt group ID\n */\nexport async function createPromptGroup(\n client: GraphQLClient,\n input: EditPromptGroupInput,\n): Promise<string> {\n const {\n createPromptGroup: { promptGroup },\n } = await makeGraphQLRequest<{\n /** createPromptGroup mutation */\n createPromptGroup: {\n /** Prompt group */\n promptGroup: {\n /** ID */\n id: string;\n };\n };\n }>(client, CREATE_PROMPT_GROUP, {\n input,\n });\n logger.info(colors.green(`Successfully created prompt group \"${input.title}\"!`));\n return promptGroup.id;\n}\n\n/**\n * Update a set of existing prompt groups\n *\n * @param client - GraphQL client\n * @param input - Prompt input\n */\nexport async function updatePromptGroups(\n client: GraphQLClient,\n input: [EditPromptGroupInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_PROMPT_GROUPS, {\n input: {\n promptGroups: input.map(([input, id]) => ({\n ...input,\n id,\n })),\n },\n });\n logger.info(colors.green(`Successfully updated ${input.length} prompt groups!`));\n}\n\n/**\n * Sync the prompt groups\n *\n * @param client - GraphQL client\n * @param promptGroups - PromptGroups\n * @param concurrency - Concurrency\n * @returns True if synced successfully\n */\nexport async function syncPromptGroups(\n client: GraphQLClient,\n promptGroups: PromptGroupInput[],\n concurrency = 20,\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(colors.magenta(`Syncing \"${promptGroups.length}\" prompt groups...`));\n\n // Index existing prompt groups\n const existing = await fetchAllPromptGroups(client);\n const existingPrompts = await fetchAllPrompts(client);\n const promptByTitle = keyBy(existingPrompts, 'title');\n const promptGroupByTitle = keyBy(existing, 'title');\n\n // Determine which promptGroups are new vs existing\n const mapPromptGroupsToExisting = promptGroups.map((promptInput) => [\n promptInput,\n promptGroupByTitle[promptInput.title]?.id,\n ]);\n\n // Create the new promptGroups\n const newPromptGroups = mapPromptGroupsToExisting\n .filter(([, existing]) => !existing)\n .map(([promptInput]) => promptInput as PromptGroupInput);\n try {\n logger.info(colors.magenta(`Creating \"${newPromptGroups.length}\" new prompt groups...`));\n await map(\n newPromptGroups,\n async (prompt) => {\n await createPromptGroup(client, {\n ...prompt,\n promptIds: prompt.prompts.map((title) => {\n const prompt = promptByTitle[title];\n if (!prompt) {\n throw new Error(`Failed to find prompt with title: \"${title}\"`);\n }\n return prompt.id;\n }),\n });\n },\n {\n concurrency,\n },\n );\n logger.info(colors.green(`Successfully synced ${newPromptGroups.length} prompt groups!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create prompt groups! - ${err.message}`));\n }\n\n // Update existing promptGroups\n const existingPromptGroups = mapPromptGroupsToExisting.filter(\n (x): x is [PromptGroupInput, string] => !!x[1],\n );\n try {\n logger.info(colors.magenta(`Updating \"${existingPromptGroups.length}\" prompt groups...`));\n await updatePromptGroups(\n client,\n existingPromptGroups.map(([{ prompts, ...input }, id]) => [\n {\n ...input,\n promptIds: prompts.map((title) => {\n const prompt = promptByTitle[title];\n if (!prompt) {\n throw new Error(`Failed to find prompt with title: \"${title}\"`);\n }\n return prompt.id;\n }),\n },\n id,\n ]),\n );\n logger.info(\n colors.green(`Successfully updated \"${existingPromptGroups.length}\" prompt groups!`),\n );\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create prompt groups! - ${err.message}`));\n }\n\n logger.info(colors.green(`Synced \"${promptGroups.length}\" prompt groups!`));\n\n // Return true upon success\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { PromptPartialInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport { fetchAllPromptPartials } from './fetchPromptPartials.js';\nimport { UPDATE_PROMPT_PARTIALS, CREATE_PROMPT_PARTIAL } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Create a new prompt partial\n *\n * @param client - GraphQL client\n * @param input - Prompt input\n * @returns Prompt partial ID\n */\nexport async function createPromptPartial(\n client: GraphQLClient,\n input: {\n /** Title of prompt partial */\n title: string;\n /** Prompt content */\n content: string;\n },\n): Promise<string> {\n const {\n createPromptPartial: { promptPartial },\n } = await makeGraphQLRequest<{\n /** createPromptPartial mutation */\n createPromptPartial: {\n /** Prompt partial */\n promptPartial: {\n /** ID */\n id: string;\n };\n };\n }>(client, CREATE_PROMPT_PARTIAL, {\n input,\n });\n logger.info(colors.green(`Successfully created prompt partial \"${input.title}\"!`));\n return promptPartial.id;\n}\n\n/**\n * Update a set of existing prompt partials\n *\n * @param client - GraphQL client\n * @param input - Prompt input\n */\nexport async function updatePromptPartials(\n client: GraphQLClient,\n input: [PromptPartialInput, string][],\n): Promise<void> {\n await makeGraphQLRequest(client, UPDATE_PROMPT_PARTIALS, {\n input: {\n promptPartials: input.map(([input, id]) => ({\n ...input,\n id,\n })),\n },\n });\n logger.info(colors.green(`Successfully updated ${input.length} prompt partials!`));\n}\n\n/**\n * Sync the prompt partials\n *\n * @param client - GraphQL client\n * @param promptPartials - PromptPartials\n * @param concurrency - Concurrency\n * @returns True if synced successfully\n */\nexport async function syncPromptPartials(\n client: GraphQLClient,\n promptPartials: PromptPartialInput[],\n concurrency = 20,\n): Promise<boolean> {\n let encounteredError = false;\n logger.info(colors.magenta(`Syncing \"${promptPartials.length}\" prompt partials...`));\n\n // Index existing prompt partials\n const existing = await fetchAllPromptPartials(client);\n const promptPartialByTitle = keyBy(existing, 'title');\n\n // Determine which promptPartials are new vs existing\n const mapPromptPartialsToExisting = promptPartials.map((promptInput) => [\n promptInput,\n promptPartialByTitle[promptInput.title]?.id,\n ]);\n\n // Create the new promptPartials\n const newPromptPartials = mapPromptPartialsToExisting\n .filter(([, existing]) => !existing)\n .map(([promptInput]) => promptInput as PromptPartialInput);\n try {\n logger.info(colors.magenta(`Creating \"${newPromptPartials.length}\" new prompt partials...`));\n await map(\n newPromptPartials,\n async (prompt) => {\n await createPromptPartial(client, prompt);\n },\n {\n concurrency,\n },\n );\n logger.info(colors.green(`Successfully synced ${newPromptPartials.length} prompt partials!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create prompt partials! - ${err.message}`));\n }\n\n // Update existing promptPartials\n const existingPromptPartials = mapPromptPartialsToExisting.filter(\n (x): x is [PromptPartialInput, string] => !!x[1],\n );\n try {\n logger.info(colors.magenta(`Updating \"${existingPromptPartials.length}\" prompt partials...`));\n await updatePromptPartials(client, existingPromptPartials);\n logger.info(\n colors.green(`Successfully updated \"${existingPromptPartials.length}\" prompt partials!`),\n );\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to create prompt partials! - ${err.message}`));\n }\n\n logger.info(colors.green(`Synced \"${promptPartials.length}\" prompt partials!`));\n\n // Return true upon success\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\nimport { keyBy } from 'lodash-es';\n\nimport { TeamInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { mapSeries } from '../bluebird.js';\nimport { fetchAllTeams, Team } from './fetchAllTeams.js';\nimport { UPDATE_TEAM, CREATE_TEAM } from './gqls/index.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Input to create a new team\n *\n * @param client - GraphQL client\n * @param team - Input\n * @returns Created team\n */\nexport async function createTeam(\n client: GraphQLClient,\n team: TeamInput,\n): Promise<Pick<Team, 'id' | 'name'>> {\n const input = {\n name: team.name,\n description: team.description,\n ssoTitle: team['sso-title'],\n ssoDepartment: team['sso-department'],\n ssoGroup: team['sso-group'],\n scopes: team.scopes,\n userEmails: team.users,\n };\n\n const { createTeam } = await makeGraphQLRequest<{\n /** Create team mutation */\n createTeam: {\n /** Created team */\n team: Team;\n };\n }>(client, CREATE_TEAM, {\n input,\n });\n return createTeam.team;\n}\n\n/**\n * Input to update teams\n *\n * @param client - GraphQL client\n * @param input - Team input to update\n * @param teamId - ID of team\n * @returns Updated team\n */\nexport async function updateTeam(\n client: GraphQLClient,\n input: TeamInput,\n teamId: string,\n): Promise<Pick<Team, 'id' | 'name'>> {\n const { updateTeam } = await makeGraphQLRequest<{\n /** Update team mutation */\n updateTeam: {\n /** Updated team */\n team: Team;\n };\n }>(client, UPDATE_TEAM, {\n input: {\n id: teamId,\n name: input.name,\n description: input.description,\n ssoTitle: input['sso-title'],\n ssoDepartment: input['sso-department'],\n ssoGroup: input['sso-group'],\n scopes: input.scopes,\n userEmails: input.users,\n },\n });\n return updateTeam.team;\n}\n\n/**\n * Sync the teams\n *\n * @param client - GraphQL client\n * @param inputs - Inputs to create\n * @returns True if run without error, returns false if an error occurred\n */\nexport async function syncTeams(client: GraphQLClient, inputs: TeamInput[]): Promise<boolean> {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${inputs.length}\" teams...`));\n\n let encounteredError = false;\n\n // Fetch existing\n const existingTeams = await fetchAllTeams(client);\n\n // Look up by name\n const teamsByName: { [k in string]: Pick<Team, 'id' | 'name'> } = keyBy(existingTeams, 'name');\n\n // Create new teams\n const newTeams = inputs.filter((input) => !teamsByName[input.name]);\n const updatedTeams = inputs.filter((input) => !!teamsByName[input.name]);\n\n // Create new teams\n await mapSeries(newTeams, async (team) => {\n try {\n const newTeam = await createTeam(client, team);\n teamsByName[newTeam.name] = newTeam;\n logger.info(colors.green(`Successfully created team \"${team.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync team \"${team.name}\"! - ${err.message}`));\n }\n });\n\n // Update all teams\n await mapSeries(updatedTeams, async (input) => {\n try {\n const newTeam = await updateTeam(client, input, teamsByName[input.name].id);\n teamsByName[newTeam.name] = newTeam;\n logger.info(colors.green(`Successfully updated team \"${input.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync team \"${input.name}\"! - ${err.message}`));\n }\n });\n\n return !encounteredError;\n}\n","import colors from 'colors';\nimport { GraphQLClient } from 'graphql-request';\n\n/* eslint-disable max-lines */\nimport { TranscendInput } from '../../codecs.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport { fetchAllActions } from './fetchAllActions.js';\nimport { fetchAllAttributes } from './fetchAllAttributes.js';\nimport { fetchApiKeys } from './fetchApiKeys.js';\nimport { fetchAllDataSubjects, ensureAllDataSubjectsExist } from './fetchDataSubjects.js';\nimport { fetchIdentifiersAndCreateMissing, Identifier } from './fetchIdentifiers.js';\nimport { syncAction } from './syncAction.js';\nimport { syncActionItemCollections } from './syncActionItemCollections.js';\nimport { syncActionItems } from './syncActionItems.js';\nimport { syncAgentFiles } from './syncAgentFiles.js';\nimport { syncAgentFunctions } from './syncAgentFunctions.js';\nimport { syncAgents } from './syncAgents.js';\nimport { syncAttribute } from './syncAttribute.js';\nimport { syncBusinessEntities } from './syncBusinessEntities.js';\nimport { syncConsentManager } from './syncConsentManager.js';\nimport { syncCookies } from './syncCookies.js';\nimport { syncDataCategories } from './syncDataCategories.js';\nimport { syncDataFlows } from './syncDataFlows.js';\nimport { syncDataSiloDependencies, syncDataSilos } from './syncDataSilos.js';\nimport { syncDataSubject } from './syncDataSubject.js';\nimport { syncEnricher } from './syncEnrichers.js';\nimport { syncIdentifier } from './syncIdentifier.js';\nimport { syncIntlMessages } from './syncIntlMessages.js';\nimport { syncPartitions } from './syncPartitions.js';\nimport { syncPolicies } from './syncPolicies.js';\nimport { syncPrivacyCenter } from './syncPrivacyCenter.js';\nimport { syncProcessingActivities } from './syncProcessingActivities.js';\nimport { syncProcessingPurposes } from './syncProcessingPurposes.js';\nimport { syncPromptGroups } from './syncPromptGroups.js';\nimport { syncPromptPartials } from './syncPromptPartials.js';\nimport { syncPrompts } from './syncPrompts.js';\nimport { syncTeams } from './syncTeams.js';\nimport { syncTemplate } from './syncTemplates.js';\nimport { syncVendors } from './syncVendors.js';\n\nconst CONCURRENCY = 10;\n\n/**\n * Sync the yaml input back to Transcend using the GraphQL APIs\n *\n * @param input - The yml input\n * @param client - GraphQL client\n * @param pageSize - Page size\n * @returns True if an error was encountered\n */\nexport async function syncConfigurationToTranscend(\n input: TranscendInput,\n client: GraphQLClient,\n {\n pageSize = 50,\n // TODO: https://transcend.height.app/T-23779\n publishToPrivacyCenter = true,\n classifyService = false,\n deleteExtraAttributeValues = false,\n }: {\n /** Page size */\n pageSize?: number;\n /** When true, skip publishing to privacy center */\n publishToPrivacyCenter?: boolean;\n /** When true, delete any attributes being synced up */\n deleteExtraAttributeValues?: boolean;\n /** classify data flow service if missing */\n classifyService?: boolean;\n },\n): Promise<boolean> {\n let encounteredError = false;\n\n logger.info(colors.magenta(`Fetching data with page size ${pageSize}...`));\n\n const {\n templates,\n attributes,\n actions,\n identifiers,\n 'data-subjects': dataSubjects,\n 'business-entities': businessEntities,\n enrichers,\n cookies,\n 'consent-manager': consentManager,\n 'data-silos': dataSilos,\n 'data-flows': dataFlows,\n prompts,\n 'prompt-groups': promptGroups,\n 'prompt-partials': promptPartials,\n agents,\n 'agent-functions': agentFunctions,\n 'agent-files': agentFiles,\n vendors,\n 'data-categories': dataCategories,\n 'processing-activities': processingActivities,\n 'processing-purposes': processingPurposes,\n 'action-items': actionItems,\n 'action-item-collections': actionItemCollections,\n teams,\n 'privacy-center': privacyCenter,\n messages,\n policies,\n partitions,\n } = input;\n\n const [identifierByName, dataSubjectsByName, apiKeyTitleMap] = await Promise.all([\n // Ensure all identifiers are created and create a map from name -> identifier.id\n enrichers || identifiers\n ? fetchIdentifiersAndCreateMissing(input, client, !publishToPrivacyCenter)\n : ({} as { [k in string]: Identifier }),\n // Grab all data subjects in the organization\n dataSilos || dataSubjects || enrichers || processingActivities\n ? ensureAllDataSubjectsExist(input, client)\n : {},\n // Grab API keys\n dataSilos &&\n dataSilos\n .map((dataSilo) => dataSilo['api-key-title'] || [])\n .reduce((acc, lst) => acc + lst.length, 0) > 0\n ? fetchApiKeys(input, client)\n : {},\n ]);\n\n // Sync consent manager\n if (consentManager) {\n logger.info(colors.magenta('Syncing consent manager...'));\n try {\n await syncConsentManager(client, consentManager);\n logger.info(colors.green('Successfully synced consent manager!'));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync consent manager! - ${err.message}`));\n }\n }\n\n // Sync prompts\n if (prompts) {\n const promptsSuccess = await syncPrompts(client, prompts);\n encounteredError = encounteredError || !promptsSuccess;\n }\n if (promptPartials) {\n const promptsSuccess = await syncPromptPartials(client, promptPartials);\n encounteredError = encounteredError || !promptsSuccess;\n }\n if (promptGroups) {\n const promptsSuccess = await syncPromptGroups(client, promptGroups);\n encounteredError = encounteredError || !promptsSuccess;\n }\n\n if (teams) {\n const teamsSuccess = await syncTeams(client, teams);\n encounteredError = encounteredError || !teamsSuccess;\n }\n\n // Sync email templates\n if (templates) {\n logger.info(colors.magenta(`Syncing \"${templates.length}\" email templates...`));\n await map(\n templates,\n async (template) => {\n logger.info(colors.magenta(`Syncing template \"${template.title}\"...`));\n try {\n await syncTemplate(template, client);\n logger.info(colors.green(`Successfully synced template \"${template.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync template \"${template.title}\"! - ${err.message}`));\n }\n },\n {\n concurrency: CONCURRENCY,\n },\n );\n logger.info(colors.green(`Synced \"${templates.length}\" email templates!`));\n }\n\n // Sync business entities\n if (businessEntities) {\n const businessEntitySuccess = await syncBusinessEntities(client, businessEntities);\n encounteredError = encounteredError || !businessEntitySuccess;\n }\n\n // Sync vendors\n if (vendors) {\n const vendorsSuccess = await syncVendors(client, vendors);\n encounteredError = encounteredError || !vendorsSuccess;\n }\n\n // Sync data categories\n if (dataCategories) {\n const dataCategoriesSuccess = await syncDataCategories(client, dataCategories);\n encounteredError = encounteredError || !dataCategoriesSuccess;\n }\n\n // Sync processing purposes\n if (processingPurposes) {\n const processingPurposesSuccess = await syncProcessingPurposes(client, processingPurposes);\n encounteredError = encounteredError || !processingPurposesSuccess;\n }\n\n // Sync partitions\n if (partitions) {\n const partitionsSuccess = await syncPartitions(client, partitions);\n encounteredError = encounteredError || !partitionsSuccess;\n }\n\n // Sync agents\n if (agents) {\n const agentsSuccess = await syncAgents(client, agents);\n encounteredError = encounteredError || !agentsSuccess;\n }\n\n // Sync agent functions\n if (agentFunctions) {\n const agentFunctionsSuccess = await syncAgentFunctions(client, agentFunctions);\n encounteredError = encounteredError || !agentFunctionsSuccess;\n }\n\n // Sync agent files\n if (agentFiles) {\n const agentFilesSuccess = await syncAgentFiles(client, agentFiles);\n encounteredError = encounteredError || !agentFilesSuccess;\n }\n\n // Sync cookies\n if (cookies) {\n const cookiesSuccess = await syncCookies(client, cookies);\n encounteredError = encounteredError || !cookiesSuccess;\n }\n\n // Sync action item collections\n if (actionItemCollections) {\n const actionItemCollectionsSuccess = await syncActionItemCollections(\n client,\n actionItemCollections,\n );\n encounteredError = encounteredError || !actionItemCollectionsSuccess;\n }\n\n // Sync attributes\n if (attributes) {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${attributes.length}\" attributes...`));\n const existingAttributes = await fetchAllAttributes(client);\n await map(\n attributes,\n async (attribute) => {\n const existing = existingAttributes.find((attr) => attr.name === attribute.name);\n\n logger.info(colors.magenta(`Syncing attribute \"${attribute.name}\"...`));\n try {\n await syncAttribute(client, attribute, {\n existingAttribute: existing,\n deleteExtraAttributeValues,\n });\n logger.info(colors.green(`Successfully synced attribute \"${attribute.name}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync attribute \"${attribute.name}\"! - ${err.message}`));\n }\n },\n {\n concurrency: CONCURRENCY,\n },\n );\n logger.info(colors.green(`Synced \"${attributes.length}\" attributes!`));\n }\n\n // Sync action items\n if (actionItems) {\n const actionItemsSuccess = await syncActionItems(client, actionItems);\n encounteredError = encounteredError || !actionItemsSuccess;\n }\n\n // Sync enrichers\n if (enrichers) {\n logger.info(colors.magenta(`Syncing \"${enrichers.length}\" enrichers...`));\n await map(\n enrichers,\n async (enricher) => {\n logger.info(colors.magenta(`Syncing enricher \"${enricher.title}\"...`));\n try {\n await syncEnricher(client, {\n enricher,\n identifierByName,\n dataSubjectsByName,\n });\n logger.info(colors.green(`Successfully synced enricher \"${enricher.title}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync enricher \"${enricher.title}\"! - ${err.message}`));\n }\n },\n {\n concurrency: CONCURRENCY,\n },\n );\n logger.info(colors.green(`Synced \"${enrichers.length}\" enrichers!`));\n }\n\n // Sync identifiers\n if (identifiers) {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${identifiers.length}\" identifiers...`));\n await map(\n identifiers,\n async (identifier) => {\n const existing = identifierByName[identifier.name];\n if (!existing) {\n throw new Error(\n `Failed to find identifier with name: ${identifier.type}. Should have been auto-created by cli.`,\n );\n }\n\n logger.info(colors.magenta(`Syncing identifier \"${identifier.type}\"...`));\n try {\n await syncIdentifier(client, {\n identifier,\n dataSubjectsByName,\n identifierId: existing.id,\n skipPublish: !publishToPrivacyCenter,\n });\n logger.info(colors.green(`Successfully synced identifier \"${identifier.type}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync identifier \"${identifier.type}\"! - ${err.message}`),\n );\n }\n },\n {\n concurrency: CONCURRENCY,\n },\n );\n logger.info(colors.green(`Synced \"${identifiers.length}\" identifiers!`));\n }\n\n // Sync actions\n if (actions) {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${actions.length}\" actions...`));\n const existingActions = await fetchAllActions(client);\n await map(\n actions,\n async (action) => {\n const existing = existingActions.find((act) => act.type === action.type);\n if (!existing) {\n throw new Error(\n `Failed to find action with type: ${action.type}. Should have already existing in the organization.`,\n );\n }\n\n logger.info(colors.magenta(`Syncing action \"${action.type}\"...`));\n try {\n await syncAction(client, {\n action,\n actionId: existing.id,\n skipPublish: !publishToPrivacyCenter,\n });\n logger.info(colors.green(`Successfully synced action \"${action.type}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(colors.red(`Failed to sync action \"${action.type}\"! - ${err.message}`));\n }\n },\n {\n concurrency: CONCURRENCY,\n },\n );\n logger.info(colors.green(`Synced \"${actions.length}\" actions!`));\n }\n\n // Sync data subjects\n if (dataSubjects) {\n // Fetch existing\n logger.info(colors.magenta(`Syncing \"${dataSubjects.length}\" data subjects...`));\n const existingDataSubjects = await fetchAllDataSubjects(client);\n await map(\n dataSubjects,\n async (dataSubject) => {\n const existing = existingDataSubjects.find((subj) => subj.type === dataSubject.type);\n if (!existing) {\n throw new Error(\n `Failed to find data subject with type: ${dataSubject.type}. Should have already existing in the organization.`,\n );\n }\n\n logger.info(colors.magenta(`Syncing data subject \"${dataSubject.type}\"...`));\n try {\n await syncDataSubject(client, {\n dataSubject,\n dataSubjectId: existing.id,\n skipPublish: !publishToPrivacyCenter,\n });\n logger.info(colors.green(`Successfully synced data subject \"${dataSubject.type}\"!`));\n } catch (err) {\n encounteredError = true;\n logger.info(\n colors.red(`Failed to sync data subject \"${dataSubject.type}\"! - ${err.message}`),\n );\n }\n },\n {\n concurrency: CONCURRENCY,\n },\n );\n logger.info(colors.green(`Synced \"${dataSubjects.length}\" data subjects!`));\n }\n\n // Sync data flows\n if (dataFlows) {\n const syncedDataFlows = await syncDataFlows(client, dataFlows, classifyService);\n encounteredError = encounteredError || !syncedDataFlows;\n }\n\n // Sync privacy center\n if (privacyCenter) {\n const privacyCenterSuccess = await syncPrivacyCenter(client, privacyCenter);\n encounteredError = encounteredError || !privacyCenterSuccess;\n }\n\n // Sync messages\n if (messages) {\n const messagesSuccess = await syncIntlMessages(client, messages);\n encounteredError = encounteredError || !messagesSuccess;\n }\n\n // Sync policies\n if (policies) {\n const policiesSuccess = await syncPolicies(client, policies);\n encounteredError = encounteredError || !policiesSuccess;\n }\n\n // Store dependency updates\n const dependencyUpdates: [string, string[]][] = [];\n // Sync data silos\n if (dataSilos) {\n const { success, dataSiloTitleToId } = await syncDataSilos(dataSilos, client, {\n dataSubjectsByName,\n apiKeysByTitle: apiKeyTitleMap,\n pageSize,\n });\n dataSilos?.forEach((dataSilo) => {\n // Queue up dependency update\n if (dataSilo['deletion-dependencies']) {\n dependencyUpdates.push([\n dataSiloTitleToId[dataSilo.title],\n dataSilo['deletion-dependencies'],\n ]);\n }\n });\n encounteredError = encounteredError || !success;\n }\n\n // Dependencies updated at the end after all data silos are created\n if (dependencyUpdates.length > 0) {\n await syncDataSiloDependencies(client, dependencyUpdates);\n }\n\n // Update processing activities\n if (processingActivities) {\n const processingActivitySuccess = await syncProcessingActivities(client, processingActivities);\n encounteredError = encounteredError || !processingActivitySuccess;\n }\n\n if (publishToPrivacyCenter) {\n // TODO: https://transcend.height.app/T-23779\n }\n\n return encounteredError;\n}\n/* eslint-enable max-lines */\n","import { getEntries } from '@transcend-io/type-utils';\n\nimport { TranscendInput } from '../codecs.js';\n\n/**\n * Combine a set of TranscendInput yaml files into a single yaml\n *\n * @param base - Base input\n * @param inputs - The list of inputs\n * @returns Merged input\n */\nexport function mergeTranscendInputs(\n base: TranscendInput,\n ...inputs: TranscendInput[]\n): TranscendInput {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cloned: any = JSON.parse(JSON.stringify(base));\n inputs.forEach((input) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getEntries(input).forEach(([key, value]: [any, any]) => {\n if (cloned[key] === undefined) {\n cloned[key] = value;\n } else if (Array.isArray(value)) {\n cloned[key] = [...cloned[key], ...value];\n } else {\n cloned[key] = value;\n }\n });\n });\n return cloned;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as e}from"./constants-CeMiHaHx.mjs";import{t}from"./logger-B-LXIf3U.mjs";import{t as n}from"./bluebird-CUitXgsY.mjs";import{t as r}from"./syncTemplates-BNu1_dmW.mjs";import{r as i}from"./request-CAsR6CMY.mjs";import{r as a,t as o}from"./makeGraphQLRequest-G078PsEL.mjs";import{r as s}from"./fetchAllRequests-DEPTEUbi.mjs";import{RequestAction as c}from"@transcend-io/privacy-types";import l from"colors";import u from"cli-progress";async function d({requestActions:d=Object.values(c),auth:f,requestIds:p,createdAtBefore:m,days:h=45,daysLeft:g=10,createdAtAfter:_,updatedAtBefore:v,updatedAtAfter:y,emailTemplate:b=`Additional Time Needed`,concurrency:x=100,transcendUrl:S=e}){let C=a(S,f),w=new Date().getTime(),T=new u.SingleBar({},u.Presets.shades_classic),E=(await r(C,b)).find(e=>e.title===b);if(!E)throw Error(`Failed to find a template with title: "${b}"`);let D=await s(C,{actions:d,createdAtBefore:m,createdAtAfter:_,updatedAtBefore:v,updatedAtAfter:y,isSilent:!1,isClosed:!1,requestIds:p});D=D.filter(e=>typeof e.daysRemaining==`number`&&e.daysRemaining<g),t.info(l.magenta(`Notifying "${D.length}" that more time is needed.`));let O=0;T.start(D.length,0),await n(D,async e=>{await o(C,i,{input:{requestId:e.id,template:E.template.defaultMessage,subject:E.subject.defaultMessage,additionalTime:h}}),O+=1,T.update(O)},{concurrency:x}),T.stop();let k=new Date().getTime()-w;return t.info(l.green(`Successfully marked ${O} requests as silent mode in "${k/1e3}" seconds!`)),D.length}export{d as t};
|
|
2
|
+
//# sourceMappingURL=notifyPrivacyRequestsAdditionalTime-BvXIXZYu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifyPrivacyRequestsAdditionalTime-BvXIXZYu.mjs","names":[],"sources":["../src/lib/requests/notifyPrivacyRequestsAdditionalTime.ts"],"sourcesContent":["import { RequestAction } from '@transcend-io/privacy-types';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { map } from '../bluebird.js';\nimport {\n NOTIFY_ADDITIONAL_TIME,\n fetchAllRequests,\n makeGraphQLRequest,\n buildTranscendGraphQLClient,\n fetchAllTemplates,\n} from '../graphql/index.js';\n\n/**\n * Mark a set of privacy requests to be in silent mode.\n * Note requests in silent mode are ignored\n *\n * @param options - Options\n * @returns The number of requests marked silent\n */\nexport async function notifyPrivacyRequestsAdditionalTime({\n requestActions = Object.values(RequestAction),\n auth,\n requestIds,\n createdAtBefore,\n days = 45,\n daysLeft = 10,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n emailTemplate = 'Additional Time Needed',\n concurrency = 100,\n transcendUrl = DEFAULT_TRANSCEND_API,\n}: {\n /** The request actions that should be restarted */\n requestActions?: RequestAction[];\n /** Filter for requests created before this date */\n createdAtBefore: Date;\n /** Filter for requests created after this date */\n createdAtAfter?: Date;\n /** Filter for requests updated before this date */\n updatedAtBefore?: Date;\n /** Filter for requests updated after this date */\n updatedAtAfter?: Date;\n /** Email template */\n emailTemplate?: string;\n /** Transcend API key authentication */\n auth: string;\n /** Number of days to extend request by */\n days?: number;\n /**\n * Only notify requests that have less than this number of days until they are considered expired.\n * This allows for re-running the command without notifying the same users multiple times\n */\n daysLeft?: number;\n /** Concurrency limit for approving */\n concurrency?: number;\n /** The set of privacy requests to notify */\n requestIds?: string[];\n /** API URL for Transcend backend */\n transcendUrl?: string;\n}): Promise<number> {\n // Find all requests made before createdAt that are in a removing data state\n const client = buildTranscendGraphQLClient(transcendUrl, auth);\n\n // Time duration\n const t0 = new Date().getTime();\n // create a new progress bar instance and use shades_classic theme\n const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n // Grab the template with that title\n const matchingTemplates = await fetchAllTemplates(client, emailTemplate);\n const exactTemplateMatch = matchingTemplates.find((template) => template.title === emailTemplate);\n if (!exactTemplateMatch) {\n throw new Error(`Failed to find a template with title: \"${emailTemplate}\"`);\n }\n\n // Pull in the requests\n let allRequests = await fetchAllRequests(client, {\n actions: requestActions,\n createdAtBefore,\n createdAtAfter,\n updatedAtBefore,\n updatedAtAfter,\n isSilent: false,\n isClosed: false,\n requestIds,\n });\n\n // Filter requests by daysLeft\n allRequests = allRequests.filter(\n (request) => typeof request.daysRemaining === 'number' && request.daysRemaining < daysLeft,\n );\n\n // Notify Transcend\n logger.info(colors.magenta(`Notifying \"${allRequests.length}\" that more time is needed.`));\n\n let total = 0;\n progressBar.start(allRequests.length, 0);\n await map(\n allRequests,\n async (requestToNotify) => {\n await makeGraphQLRequest(client, NOTIFY_ADDITIONAL_TIME, {\n input: {\n requestId: requestToNotify.id,\n template: exactTemplateMatch.template.defaultMessage,\n subject: exactTemplateMatch.subject.defaultMessage,\n additionalTime: days,\n },\n });\n\n total += 1;\n progressBar.update(total);\n },\n { concurrency },\n );\n\n progressBar.stop();\n const t1 = new Date().getTime();\n const totalTime = t1 - t0;\n\n logger.info(\n colors.green(\n `Successfully marked ${total} requests as silent mode in \"${totalTime / 1000}\" seconds!`,\n ),\n );\n return allRequests.length;\n}\n"],"mappings":"ybAsBA,eAAsB,EAAoC,CACxD,iBAAiB,OAAO,OAAO,EAAc,CAC7C,OACA,aACA,kBACA,OAAO,GACP,WAAW,GACX,iBACA,kBACA,iBACA,gBAAgB,yBAChB,cAAc,IACd,eAAe,GA6BG,CAElB,IAAM,EAAS,EAA4B,EAAc,EAAK,CAGxD,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAI/E,GADoB,MAAM,EAAkB,EAAQ,EAAc,EAC3B,KAAM,GAAa,EAAS,QAAU,EAAc,CACjG,GAAI,CAAC,EACH,MAAU,MAAM,0CAA0C,EAAc,GAAG,CAI7E,IAAI,EAAc,MAAM,EAAiB,EAAQ,CAC/C,QAAS,EACT,kBACA,iBACA,kBACA,iBACA,SAAU,GACV,SAAU,GACV,aACD,CAAC,CAGF,EAAc,EAAY,OACvB,GAAY,OAAO,EAAQ,eAAkB,UAAY,EAAQ,cAAgB,EACnF,CAGD,EAAO,KAAK,EAAO,QAAQ,cAAc,EAAY,OAAO,6BAA6B,CAAC,CAE1F,IAAI,EAAQ,EACZ,EAAY,MAAM,EAAY,OAAQ,EAAE,CACxC,MAAM,EACJ,EACA,KAAO,IAAoB,CACzB,MAAM,EAAmB,EAAQ,EAAwB,CACvD,MAAO,CACL,UAAW,EAAgB,GAC3B,SAAU,EAAmB,SAAS,eACtC,QAAS,EAAmB,QAAQ,eACpC,eAAgB,EACjB,CACF,CAAC,CAEF,GAAS,EACT,EAAY,OAAO,EAAM,EAE3B,CAAE,cAAa,CAChB,CAED,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SAAS,CACR,EAOvB,OALA,EAAO,KACL,EAAO,MACL,uBAAuB,EAAM,+BAA+B,EAAY,IAAK,YAC9E,CACF,CACM,EAAY"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-BjNQxHlz.mjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{t as e}from"./logger-B-LXIf3U.mjs";import{existsSync as t,mkdirSync as n,readdirSync as r,rmSync as i,statSync as a}from"node:fs";import{dirname as o,join as s,parse as c}from"node:path";import l from"colors";function u(t,n){t||(e.error(l.red(`A --directory must be provided.`)),n.process.exit(1));let i=[];try{i=r(t).filter(e=>e.endsWith(`.parquet`)).map(e=>s(t,e)).filter(e=>{try{return a(e).isFile()}catch{return!1}})}catch(r){e.error(l.red(`Failed to read directory: ${t}`)),e.error(l.red(r.message)),n.process.exit(1)}return i.length===0&&(e.error(l.red(`No Parquet files found in directory: ${t}`)),n.process.exit(1)),e.info(l.green(`Found: ${i.join(`, `)} parquet files`)),i}async function d(r,a){let{filePath:u,outputDir:d,clearOutputDir:h,onProgress:g}=r,_=d||o(u),{name:v}=c(u),y=s(_,`${v}.csv`);if(n(_,{recursive:!0}),h&&t(y))try{i(y,{force:!0})}catch(t){e.warn(l.yellow(`Could not remove existing output file ${y}: ${t.message}`))}let b=await a.create(`:memory:`),x=await b.connect();try{await p(x,`PRAGMA temp_directory='';`);let t=e=>`'${e.replace(/'/g,`''`)}'`;await f(x,`
|
|
2
|
+
COPY (SELECT * FROM read_parquet(${t(u)}))
|
|
3
|
+
TO ${t(y)}
|
|
4
|
+
(HEADER, DELIMITER ',', QUOTE '"', ESCAPE '"', NULL '');
|
|
5
|
+
`),g?.(0,void 0),e.info(l.green(`Wrote CSV → ${y}`))}finally{await m(x),await m(b)}}async function f(e,t){await m(await e.run(t))}async function p(e,t){try{await f(e,t)}catch{}}async function m(e){if(!(!e||typeof e.dispose!=`function`))try{await e.dispose()}catch{}}export{u as n,d as t};
|
|
6
|
+
//# sourceMappingURL=parquetToCsvOneFile-DZVKXrjn.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parquetToCsvOneFile-DZVKXrjn.mjs","names":[],"sources":["../src/lib/helpers/collectParquetFilesOrExit.ts","../src/lib/helpers/parquetToCsvOneFile.ts"],"sourcesContent":["import { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport colors from 'colors';\n\nimport type { LocalContext } from '../../context.js';\nimport { logger } from '../../logger.js';\n\n/**\n * Validate flags and collect Parquet file paths from a directory.\n * On validation error, the provided `exit` function is called.\n *\n * @param directory - the directory containing Parquet files\n * @param localContext - the context of the command, used for logging and exit\n * @returns an array of valid Parquet file paths\n */\nexport function collectParquetFilesOrExit(\n directory: string | undefined,\n localContext: LocalContext,\n): string[] {\n if (!directory) {\n logger.error(colors.red('A --directory must be provided.'));\n localContext.process.exit(1);\n }\n\n let files: string[] = [];\n try {\n const entries = readdirSync(directory);\n files = entries\n .filter((f) => f.endsWith('.parquet'))\n .map((f) => join(directory, f))\n .filter((p) => {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n });\n } catch (err) {\n logger.error(colors.red(`Failed to read directory: ${directory}`));\n logger.error(colors.red((err as Error).message));\n localContext.process.exit(1);\n }\n\n if (files.length === 0) {\n logger.error(colors.red(`No Parquet files found in directory: ${directory}`));\n localContext.process.exit(1);\n }\n logger.info(colors.green(`Found: ${files.join(', ')} parquet files`));\n return files;\n}\n","import { mkdirSync, rmSync, existsSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\n\nimport type { DuckDBConnection, DuckDBInstance } from '@duckdb/node-api';\nimport colors from 'colors';\n\nimport { logger } from '../../logger.js';\n\n/** Progress callback used by the parent runner to surface progress to the UI. */\ntype OnProgress = (processed: number, total?: number) => void;\n\n/**\n * Options for converting a single Parquet file into a single CSV file.\n */\nexport type ParquetToCsvOneFileOptions = {\n /** Absolute or relative path to the input `.parquet` file. */\n filePath: string;\n /**\n * Directory where the output CSV will be written.\n * If omitted, the CSV is written next to the input file.\n */\n outputDir?: string;\n /**\n * When true, removes a pre-existing output file with the same name before writing.\n * Useful for re-runs; ignored if the file does not exist.\n */\n clearOutputDir: boolean;\n /**\n * Optional progress hook. Called with the number of processed records.\n * `total` is not computed here; it will be `undefined`.\n */\n onProgress?: OnProgress;\n};\n\n/**\n * Convert a single Parquet file to a single CSV file (1:1) using DuckDB.\n *\n * Output naming: `${basename}.csv` in `outputDir ?? dirname(filePath)`.\n *\n * Errors:\n * - Throws on I/O failures or DuckDB execution errors.\n *\n * Why DuckDB?\n * - Robust reader for many Parquet dialects (e.g., Spark output, nested types, timestamps).\n * - Streaming COPY handles large files without loading everything into JS memory.\n *\n * What this does:\n * - Opens an in-memory DuckDB database (no `.db` file created).\n * - Optionally disables temp spilling to disk (so only your CSV is written).\n * - Executes a single `COPY (SELECT * FROM read_parquet(...)) TO ...` statement.\n * - Produces exactly one CSV per input Parquet (no chunking or rotation).\n *\n * Notes & defaults:\n * - DuckDBInstance: `:memory:` (ephemeral). No persistent DB file is created.\n * - Temp files: disabled via `PRAGMA temp_directory=''` (best-effort; ignored if unsupported).\n * - CSV format: header row, comma delimiter, double-quote quoting, empty string for NULL.\n * - Progress: DuckDB COPY doesn't expose row-level progress via the JS API; we emit a\n * best-effort final callback.\n *\n * Requirements:\n * - `@duckdb/node-api` npm package installed and available at runtime.\n * - Supported platform binary (mac arm64/x64, linux x64, windows x64).\n *\n * @param opts - Conversion options\n * @param DuckDb - DuckDB instance to use\n * @returns Promise<void> when the CSV has been written\n */\nexport async function parquetToCsvOneFile(\n opts: ParquetToCsvOneFileOptions,\n DuckDb: typeof DuckDBInstance,\n): Promise<void> {\n const { filePath, outputDir, clearOutputDir, onProgress } = opts;\n\n const baseDir = outputDir || dirname(filePath);\n const { name: baseName } = parse(filePath);\n const outPath = join(baseDir, `${baseName}.csv`);\n\n // Ensure output directory exists\n mkdirSync(baseDir, { recursive: true });\n\n // Remove any pre-existing output file if requested\n if (clearOutputDir && existsSync(outPath)) {\n try {\n rmSync(outPath, { force: true });\n } catch (err) {\n logger.warn(\n colors.yellow(\n `Could not remove existing output file ${outPath}: ${(err as Error).message}`,\n ),\n );\n }\n }\n\n // In-memory DB: no .db file created on disk\n const db = await DuckDb.create(':memory:');\n const conn = await db.connect();\n\n try {\n // Optional: prevent DuckDB from creating temp files on disk (best-effort).\n // Some versions may ignore or error; we ignore such errors safely.\n await runIgnoreError(conn, \"PRAGMA temp_directory='';\");\n\n // Optionally: cap memory to encourage in-memory execution or fail-fast\n // (commented out by default; uncomment to enforce a limit)\n // await runIgnoreError(conn, \"PRAGMA memory_limit='4GB';\");\n\n // Ensure stable CSV settings: header, comma delimiter, double quotes, empty string for NULLs.\n // Escape single quotes for SQL string literals\n const q = (p: string): string => `'${p.replace(/'/g, \"''\")}'`;\n\n // Use COPY with a subquery so DuckDB streams Parquet -> CSV efficiently.\n const sql = `\n COPY (SELECT * FROM read_parquet(${q(filePath)}))\n TO ${q(outPath)}\n (HEADER, DELIMITER ',', QUOTE '\"', ESCAPE '\"', NULL '');\n `;\n\n await run(conn, sql);\n\n // Best-effort progress notification (DuckDB JS API doesn't expose progress for COPY)\n onProgress?.(0, undefined);\n\n logger.info(colors.green(`Wrote CSV → ${outPath}`));\n } finally {\n // Close connection + db handles gracefully\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await disposeSafe(conn as any);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await disposeSafe(db as any);\n }\n}\n\n/* =============================================================================\n * DuckDB helpers\n * =============================================================================\n */\n\n/**\n * Execute a SQL statement on a DuckDB connection and dispose the result.\n *\n * @param conn - DuckDB connection\n * @param sql - SQL string to run\n * @returns Promise<void>\n */\nasync function run(conn: DuckDBConnection, sql: string): Promise<void> {\n const result = await conn.run(sql);\n // The high-level API returns a Result; ensure we dispose it to free buffers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await disposeSafe(result as any);\n}\n\n/**\n * Execute a SQL statement but ignore any error that occurs.\n * Useful for best-effort PRAGMAs that may not be supported across versions.\n *\n * @param conn - DuckDB connection\n * @param sql - SQL string to run\n * @returns Promise<void>\n */\nasync function runIgnoreError(conn: DuckDBConnection, sql: string): Promise<void> {\n try {\n await run(conn, sql);\n } catch {\n // ignore\n }\n}\n\n/**\n * Dispose a DuckDB resource (connection or instance) if present.\n *\n * @param handle - Object exposing an async `dispose()` method\n * @returns Promise<void>\n */\nasync function disposeSafe(\n handle:\n | {\n /** Dispose handler */\n dispose: () => Promise<void>;\n }\n | null\n | undefined,\n): Promise<void> {\n if (!handle || typeof handle.dispose !== 'function') return;\n try {\n await handle.dispose();\n } catch {\n // ignore\n }\n}\n"],"mappings":"wNAgBA,SAAgB,EACd,EACA,EACU,CACL,IACH,EAAO,MAAM,EAAO,IAAI,kCAAkC,CAAC,CAC3D,EAAa,QAAQ,KAAK,EAAE,EAG9B,IAAI,EAAkB,EAAE,CACxB,GAAI,CAEF,EADgB,EAAY,EAAU,CAEnC,OAAQ,GAAM,EAAE,SAAS,WAAW,CAAC,CACrC,IAAK,GAAM,EAAK,EAAW,EAAE,CAAC,CAC9B,OAAQ,GAAM,CACb,GAAI,CACF,OAAO,EAAS,EAAE,CAAC,QAAQ,MACrB,CACN,MAAO,KAET,OACG,EAAK,CACZ,EAAO,MAAM,EAAO,IAAI,6BAA6B,IAAY,CAAC,CAClE,EAAO,MAAM,EAAO,IAAK,EAAc,QAAQ,CAAC,CAChD,EAAa,QAAQ,KAAK,EAAE,CAQ9B,OALI,EAAM,SAAW,IACnB,EAAO,MAAM,EAAO,IAAI,wCAAwC,IAAY,CAAC,CAC7E,EAAa,QAAQ,KAAK,EAAE,EAE9B,EAAO,KAAK,EAAO,MAAM,UAAU,EAAM,KAAK,KAAK,CAAC,gBAAgB,CAAC,CAC9D,ECkBT,eAAsB,EACpB,EACA,EACe,CACf,GAAM,CAAE,WAAU,YAAW,iBAAgB,cAAe,EAEtD,EAAU,GAAa,EAAQ,EAAS,CACxC,CAAE,KAAM,GAAa,EAAM,EAAS,CACpC,EAAU,EAAK,EAAS,GAAG,EAAS,MAAM,CAMhD,GAHA,EAAU,EAAS,CAAE,UAAW,GAAM,CAAC,CAGnC,GAAkB,EAAW,EAAQ,CACvC,GAAI,CACF,EAAO,EAAS,CAAE,MAAO,GAAM,CAAC,OACzB,EAAK,CACZ,EAAO,KACL,EAAO,OACL,yCAAyC,EAAQ,IAAK,EAAc,UACrE,CACF,CAKL,IAAM,EAAK,MAAM,EAAO,OAAO,WAAW,CACpC,EAAO,MAAM,EAAG,SAAS,CAE/B,GAAI,CAGF,MAAM,EAAe,EAAM,4BAA4B,CAQvD,IAAM,EAAK,GAAsB,IAAI,EAAE,QAAQ,KAAM,KAAK,CAAC,GAS3D,MAAM,EAAI,EANE;yCACyB,EAAE,EAAS,CAAC;WAC1C,EAAE,EAAQ,CAAC;;MAIE,CAGpB,IAAa,EAAG,IAAA,GAAU,CAE1B,EAAO,KAAK,EAAO,MAAM,eAAe,IAAU,CAAC,QAC3C,CAGR,MAAM,EAAY,EAAY,CAE9B,MAAM,EAAY,EAAU,EAgBhC,eAAe,EAAI,EAAwB,EAA4B,CAIrE,MAAM,EAHS,MAAM,EAAK,IAAI,EAAI,CAGF,CAWlC,eAAe,EAAe,EAAwB,EAA4B,CAChF,GAAI,CACF,MAAM,EAAI,EAAM,EAAI,MACd,GAWV,eAAe,EACb,EAOe,CACX,MAAC,GAAU,OAAO,EAAO,SAAY,YACzC,GAAI,CACF,MAAM,EAAO,SAAS,MAChB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./logger-B-LXIf3U.mjs";import{l as t,n}from"./constants-lIvXgkdp.mjs";import r from"colors";import*as i from"io-ts";import a from"inquirer";import o from"fuzzysearch";function s(e,t){return o(e.toLowerCase(),t.toLowerCase())||o(t.toLowerCase(),e.toLowerCase())}function c(e,r,i,o){let c=e.filter(e=>s(r.toLowerCase(),e.toLowerCase()));return[...c,new a.Separator,...i?[]:[t],...o?[n]:[],...e.filter(e=>!c.includes(e))]}const l=i.type({key:i.string,values:i.array(i.string)});function u(t){let n=t.map(e=>{let[t,n]=e.trim().split(`:`);if(!n)throw Error(`Expected attributes in key:value1;value2,key2:value3;value4`);return{key:t,values:n.split(`;`)}});return e.info(r.magenta(`Attributes to apply to all requests:`)),e.info(r.magenta(JSON.stringify(n,null,2))),n}export{s as i,u as n,c as r,l as t};
|
|
2
|
+
//# sourceMappingURL=parseAttributesFromString-CZStzJc0.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseAttributesFromString-CZStzJc0.mjs","names":[],"sources":["../src/lib/requests/fuzzyMatchColumns.ts","../src/lib/requests/parseAttributesFromString.ts"],"sourcesContent":["import fuzzysearch from 'fuzzysearch';\nimport inquirer from 'inquirer';\n\nimport { NONE, BULK_APPLY } from './constants.js';\n\n/**\n * Check if word1 and word2 are a fuzzy match of each other.\n * Returns true if word1 is fuzzy match of word2 or vice versa.\n *\n * @param word1 - First word\n * @param word2 - Second word\n * @returns True if words are fuzzy match\n */\nexport function fuzzySearch(word1: string, word2: string): boolean {\n return (\n fuzzysearch(word1.toLowerCase(), word2.toLowerCase()) ||\n fuzzysearch(word2.toLowerCase(), word1.toLowerCase())\n );\n}\n\n/**\n * Fuzzy match column names for a particular field\n *\n * @param allColumnNames - List of all column names\n * @param fuzzyMapName - The name of field being mapped to\n * @param isRequired - When true, don't include \"NONE\" as an option\n * @param canApplyAll - When true, include an option to specify the value in bulk\n * @returns The list of suggestions for inquirer\n */\nexport function fuzzyMatchColumns(\n allColumnNames: string[],\n fuzzyMapName: string,\n isRequired: boolean,\n canApplyAll?: boolean,\n): (string | InstanceType<typeof inquirer.Separator>)[] {\n const matchingColumnNames = allColumnNames.filter((x) =>\n fuzzySearch(fuzzyMapName.toLowerCase(), x.toLowerCase()),\n );\n return [\n ...matchingColumnNames,\n new inquirer.Separator(),\n ...(isRequired ? [] : [NONE]),\n ...(canApplyAll ? [BULK_APPLY] : []),\n ...allColumnNames.filter((x) => !matchingColumnNames.includes(x)),\n ];\n}\n","import colors from 'colors';\nimport * as t from 'io-ts';\n\nimport { logger } from '../../logger.js';\n\nexport const ParsedAttributeInput = t.type({\n /** Attribute key */\n key: t.string,\n /** Attribute values */\n values: t.array(t.string),\n});\n\n/** Type override */\nexport type ParsedAttributeInput = t.TypeOf<typeof ParsedAttributeInput>;\n\n/**\n * Parse out the extra attributes to apply to all requests uploaded\n *\n * @param attributes - input as string, e.g. ['key:value1;value2','key2:value3;value4']\n * @returns The parsed attributes\n */\nexport function parseAttributesFromString(attributes: string[]): ParsedAttributeInput[] {\n // Parse out the extra attributes to apply to all requests uploaded\n const parsedAttributes = attributes.map((attribute) => {\n const [attributeKey, attributeValuesRaw] = attribute.trim().split(':');\n if (!attributeValuesRaw) {\n throw new Error('Expected attributes in key:value1;value2,key2:value3;value4');\n }\n const attributeValues = attributeValuesRaw.split(';');\n return {\n key: attributeKey,\n values: attributeValues,\n };\n });\n logger.info(colors.magenta('Attributes to apply to all requests:'));\n logger.info(colors.magenta(JSON.stringify(parsedAttributes, null, 2)));\n return parsedAttributes;\n}\n"],"mappings":"0LAaA,SAAgB,EAAY,EAAe,EAAwB,CACjE,OACE,EAAY,EAAM,aAAa,CAAE,EAAM,aAAa,CAAC,EACrD,EAAY,EAAM,aAAa,CAAE,EAAM,aAAa,CAAC,CAazD,SAAgB,EACd,EACA,EACA,EACA,EACsD,CACtD,IAAM,EAAsB,EAAe,OAAQ,GACjD,EAAY,EAAa,aAAa,CAAE,EAAE,aAAa,CAAC,CACzD,CACD,MAAO,CACL,GAAG,EACH,IAAI,EAAS,UACb,GAAI,EAAa,EAAE,CAAG,CAAC,EAAK,CAC5B,GAAI,EAAc,CAAC,EAAW,CAAG,EAAE,CACnC,GAAG,EAAe,OAAQ,GAAM,CAAC,EAAoB,SAAS,EAAE,CAAC,CAClE,CCvCH,MAAa,EAAuB,EAAE,KAAK,CAEzC,IAAK,EAAE,OAEP,OAAQ,EAAE,MAAM,EAAE,OAAO,CAC1B,CAAC,CAWF,SAAgB,EAA0B,EAA8C,CAEtF,IAAM,EAAmB,EAAW,IAAK,GAAc,CACrD,GAAM,CAAC,EAAc,GAAsB,EAAU,MAAM,CAAC,MAAM,IAAI,CACtE,GAAI,CAAC,EACH,MAAU,MAAM,8DAA8D,CAGhF,MAAO,CACL,IAAK,EACL,OAHsB,EAAmB,MAAM,IAAI,CAIpD,EACD,CAGF,OAFA,EAAO,KAAK,EAAO,QAAQ,uCAAuC,CAAC,CACnE,EAAO,KAAK,EAAO,QAAQ,KAAK,UAAU,EAAkB,KAAM,EAAE,CAAC,CAAC,CAC/D"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import{t as e}from"./logger-B-LXIf3U.mjs";import{n as t}from"./bluebird-CUitXgsY.mjs";import{i as n,o as r,u as i}from"./dataSilo-DrFetFXw.mjs";import{t as a}from"./makeGraphQLRequest-G078PsEL.mjs";import{SubDataPointDataSubCategoryGuessStatus as o}from"@transcend-io/privacy-types";import{chunk as s,keyBy as c,sortBy as l,uniq as u}from"lodash-es";import d from"colors";import{gql as f}from"graphql-request";import p from"cli-progress";async function m(t,{dataSiloIds:n=[],includeGuessedCategories:r,includeAttributes:s,parentCategories:c=[],subCategories:u=[],pageSize:m=1e3}={}){let h=[],g=new Date().getTime(),_=new p.SingleBar({},p.Presets.shades_classic),v={...c.length>0?{category:c}:{},...u.length>0?{subCategoryIds:u}:{},...c.length+u.length>0&&!r?{status:o.Approved}:{},...n.length>0?{dataSilos:n}:{}},{subDataPoints:{totalCount:y}}=await a(t,i,{filterBy:v});e.info(d.magenta(`[Step 1/3] Pulling in all subdatapoints`)),_.start(y,0);let b=0,x=!1,S,C=0;do try{let{subDataPoints:{nodes:e}}=await a(t,f`
|
|
2
|
+
query TranscendCliSubDataPointCsvExport(
|
|
3
|
+
$filterBy: SubDataPointFiltersInput
|
|
4
|
+
$first: Int!
|
|
5
|
+
$offset: Int!
|
|
6
|
+
) {
|
|
7
|
+
subDataPoints(
|
|
8
|
+
filterBy: $filterBy
|
|
9
|
+
first: $first
|
|
10
|
+
offset: $offset
|
|
11
|
+
useMaster: false
|
|
12
|
+
) {
|
|
13
|
+
nodes {
|
|
14
|
+
id
|
|
15
|
+
name
|
|
16
|
+
description
|
|
17
|
+
dataPointId
|
|
18
|
+
dataSiloId
|
|
19
|
+
purposes {
|
|
20
|
+
name
|
|
21
|
+
purpose
|
|
22
|
+
}
|
|
23
|
+
categories {
|
|
24
|
+
name
|
|
25
|
+
category
|
|
26
|
+
}
|
|
27
|
+
${r?`pendingCategoryGuesses {
|
|
28
|
+
category {
|
|
29
|
+
name
|
|
30
|
+
category
|
|
31
|
+
}
|
|
32
|
+
status
|
|
33
|
+
classifierVersion
|
|
34
|
+
}`:``}
|
|
35
|
+
${s?`attributeValues {
|
|
36
|
+
attributeKey {
|
|
37
|
+
name
|
|
38
|
+
}
|
|
39
|
+
name
|
|
40
|
+
}`:``}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`,{first:m,offset:C,filterBy:{...v}});S=e[e.length-1]?.id,h.push(...e),x=e.length===m,b+=e.length,C+=e.length,_.update(b)}catch(t){throw e.error(d.red(`An error fetching subdatapoints for cursor ${S} and offset ${C}`)),t}while(x);_.stop();let w=new Date().getTime()-g,T=l(h,`name`);return e.info(d.green(`Successfully pulled in ${T.length} subdatapoints in ${w/1e3} seconds!`)),T}async function h(n,{dataPointIds:i=[],pageSize:o=100}){let c=[],l=new Date().getTime(),u=new p.SingleBar({},p.Presets.shades_classic);e.info(d.magenta(`[Step 2/3] Fetching metadata for ${i.length} datapoints`));let f=s(i,o);u.start(i.length,0);let m=0;await t(f,async t=>{try{let{dataPoints:{nodes:e}}=await a(n,r,{first:o,filterBy:{ids:t}});c.push(...e),m+=t.length,u.update(m)}catch(n){throw e.error(d.red(`An error fetching subdatapoints for IDs ${t.join(`, `)}`)),n}}),u.stop();let h=new Date().getTime()-l;return e.info(d.green(`Successfully pulled in ${c.length} dataPoints in ${h/1e3} seconds!`)),c}async function g(r,{dataSiloIds:i=[],pageSize:o=100}){let c=[],l=new Date().getTime(),u=new p.SingleBar({},p.Presets.shades_classic);e.info(d.magenta(`[Step 3/3] Fetching metadata for ${i.length} data silos`));let f=s(i,o);u.start(i.length,0);let m=0;await t(f,async t=>{try{let{dataSilos:{nodes:e}}=await a(r,n,{first:o,filterBy:{ids:t}});c.push(...e),m+=t.length,u.update(m)}catch(n){throw e.error(d.red(`An error fetching data silos for IDs ${t.join(`, `)}`)),n}}),u.stop();let h=new Date().getTime()-l;return e.info(d.green(`Successfully pulled in ${c.length} data silos in ${h/1e3} seconds!`)),c}async function _(e,{dataSiloIds:t=[],includeGuessedCategories:n,includeAttributes:r,parentCategories:i=[],subCategories:a=[],pageSize:o=1e3}={}){let s=await m(e,{dataSiloIds:t,includeGuessedCategories:n,includeAttributes:r,parentCategories:i,subCategories:a,pageSize:o}),l=c(await h(e,{dataPointIds:u(s.map(e=>e.dataPointId))}),`id`),d=c(await g(e,{dataSiloIds:u(s.map(e=>e.dataSiloId))}),`id`);return s.map(e=>({...e,dataPoint:l[e.dataPointId],dataSilo:d[e.dataSiloId]}))}export{_ as t};
|
|
45
|
+
//# sourceMappingURL=pullAllDatapoints-DiMWp8a7.mjs.map
|