mcdev 6.0.2 → 7.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/.beautyamp.json +13 -0
- package/.eslintrc.json +7 -1
- package/.github/ISSUE_TEMPLATE/bug.yml +1 -0
- package/.github/PULL_REQUEST_TEMPLATE/pr_template_release.md +10 -3
- package/.github/workflows/close_issues_on_merge.yml +1 -1
- package/.github/workflows/code-test.yml +51 -3
- package/.github/workflows/coverage-base-update.yml +1 -1
- package/.github/workflows/coverage-develop-branch.yml +1 -1
- package/.github/workflows/coverage-main-branch.yml +1 -1
- package/.github/workflows/coverage.yml +2 -2
- package/.github/workflows/npm-publish.yml +3 -2
- package/.github/workflows/pr-labeler.yml +1 -1
- package/.husky/commit-msg +0 -2
- package/.husky/post-checkout +0 -3
- package/.husky/post-merge +2 -7
- package/.husky/pre-commit +5 -5
- package/.prettierrc +0 -8
- package/.vscode/extensions.json +2 -0
- package/.vscode/settings.json +15 -3
- package/@types/lib/Builder.d.ts +97 -0
- package/@types/lib/Builder.d.ts.map +1 -0
- package/@types/lib/Deployer.d.ts +99 -0
- package/@types/lib/Deployer.d.ts.map +1 -0
- package/@types/lib/MetadataTypeDefinitions.d.ts +80 -0
- package/@types/lib/MetadataTypeDefinitions.d.ts.map +1 -0
- package/@types/lib/MetadataTypeInfo.d.ts +78 -0
- package/@types/lib/MetadataTypeInfo.d.ts.map +1 -0
- package/@types/lib/Retriever.d.ts +66 -0
- package/@types/lib/Retriever.d.ts.map +1 -0
- package/@types/lib/cli.d.ts +3 -0
- package/@types/lib/cli.d.ts.map +1 -0
- package/@types/lib/index.d.ts +383 -0
- package/@types/lib/index.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Asset.d.ts +1082 -0
- package/@types/lib/metadataTypes/Asset.d.ts.map +1 -0
- package/@types/lib/metadataTypes/AttributeGroup.d.ts +290 -0
- package/@types/lib/metadataTypes/AttributeGroup.d.ts.map +1 -0
- package/@types/lib/metadataTypes/AttributeSet.d.ts +968 -0
- package/@types/lib/metadataTypes/AttributeSet.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Automation.d.ts +921 -0
- package/@types/lib/metadataTypes/Automation.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Campaign.d.ts +190 -0
- package/@types/lib/metadataTypes/Campaign.d.ts.map +1 -0
- package/@types/lib/metadataTypes/ContentArea.d.ts +250 -0
- package/@types/lib/metadataTypes/ContentArea.d.ts.map +1 -0
- package/@types/lib/metadataTypes/DataExtension.d.ts +571 -0
- package/@types/lib/metadataTypes/DataExtension.d.ts.map +1 -0
- package/@types/lib/metadataTypes/DataExtensionField.d.ts +236 -0
- package/@types/lib/metadataTypes/DataExtensionField.d.ts.map +1 -0
- package/@types/lib/metadataTypes/DataExtensionTemplate.d.ts +175 -0
- package/@types/lib/metadataTypes/DataExtensionTemplate.d.ts.map +1 -0
- package/@types/lib/metadataTypes/DataExtract.d.ts +217 -0
- package/@types/lib/metadataTypes/DataExtract.d.ts.map +1 -0
- package/@types/lib/metadataTypes/DataExtractType.d.ts +80 -0
- package/@types/lib/metadataTypes/DataExtractType.d.ts.map +1 -0
- package/@types/lib/metadataTypes/DeliveryProfile.d.ts +102 -0
- package/@types/lib/metadataTypes/DeliveryProfile.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Discovery.d.ts +189 -0
- package/@types/lib/metadataTypes/Discovery.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Email.d.ts +384 -0
- package/@types/lib/metadataTypes/Email.d.ts.map +1 -0
- package/@types/lib/metadataTypes/EmailSend.d.ts +652 -0
- package/@types/lib/metadataTypes/EmailSend.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Event.d.ts +958 -0
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -0
- package/@types/lib/metadataTypes/FileLocation.d.ts +101 -0
- package/@types/lib/metadataTypes/FileLocation.d.ts.map +1 -0
- package/@types/lib/metadataTypes/FileTransfer.d.ts +228 -0
- package/@types/lib/metadataTypes/FileTransfer.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Filter.d.ts +145 -0
- package/@types/lib/metadataTypes/Filter.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Folder.d.ts +287 -0
- package/@types/lib/metadataTypes/Folder.d.ts.map +1 -0
- package/@types/lib/metadataTypes/ImportFile.d.ts +409 -0
- package/@types/lib/metadataTypes/ImportFile.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Journey.d.ts +541 -0
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -0
- package/@types/lib/metadataTypes/List.d.ts +191 -0
- package/@types/lib/metadataTypes/List.d.ts.map +1 -0
- package/@types/lib/metadataTypes/MetadataType.d.ts +680 -0
- package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -0
- package/@types/lib/metadataTypes/MobileCode.d.ts +225 -0
- package/@types/lib/metadataTypes/MobileCode.d.ts.map +1 -0
- package/@types/lib/metadataTypes/MobileKeyword.d.ts +432 -0
- package/@types/lib/metadataTypes/MobileKeyword.d.ts.map +1 -0
- package/@types/lib/metadataTypes/MobileMessage.d.ts +931 -0
- package/@types/lib/metadataTypes/MobileMessage.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Query.d.ts +299 -0
- package/@types/lib/metadataTypes/Query.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Role.d.ts +164 -0
- package/@types/lib/metadataTypes/Role.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Script.d.ts +305 -0
- package/@types/lib/metadataTypes/Script.d.ts.map +1 -0
- package/@types/lib/metadataTypes/SendClassification.d.ts +221 -0
- package/@types/lib/metadataTypes/SendClassification.d.ts.map +1 -0
- package/@types/lib/metadataTypes/SenderProfile.d.ts +257 -0
- package/@types/lib/metadataTypes/SenderProfile.d.ts.map +1 -0
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts +230 -0
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts.map +1 -0
- package/@types/lib/metadataTypes/TransactionalMessage.d.ts +163 -0
- package/@types/lib/metadataTypes/TransactionalMessage.d.ts.map +1 -0
- package/@types/lib/metadataTypes/TransactionalPush.d.ts +175 -0
- package/@types/lib/metadataTypes/TransactionalPush.d.ts.map +1 -0
- package/@types/lib/metadataTypes/TransactionalSMS.d.ts +205 -0
- package/@types/lib/metadataTypes/TransactionalSMS.d.ts.map +1 -0
- package/@types/lib/metadataTypes/TriggeredSend.d.ts +671 -0
- package/@types/lib/metadataTypes/TriggeredSend.d.ts.map +1 -0
- package/@types/lib/metadataTypes/User.d.ts +677 -0
- package/@types/lib/metadataTypes/User.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Verification.d.ts +188 -0
- package/@types/lib/metadataTypes/Verification.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Asset.definition.d.ts +692 -0
- package/@types/lib/metadataTypes/definitions/Asset.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/AttributeGroup.definition.d.ts +246 -0
- package/@types/lib/metadataTypes/definitions/AttributeGroup.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/AttributeSet.definition.d.ts +893 -0
- package/@types/lib/metadataTypes/definitions/AttributeSet.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Automation.definition.d.ts +616 -0
- package/@types/lib/metadataTypes/definitions/Automation.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Campaign.definition.d.ts +126 -0
- package/@types/lib/metadataTypes/definitions/Campaign.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/ContentArea.definition.d.ts +182 -0
- package/@types/lib/metadataTypes/definitions/ContentArea.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/DataExtension.definition.d.ts +237 -0
- package/@types/lib/metadataTypes/definitions/DataExtension.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/DataExtensionField.definition.d.ts +121 -0
- package/@types/lib/metadataTypes/definitions/DataExtensionField.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/DataExtensionTemplate.definition.d.ts +133 -0
- package/@types/lib/metadataTypes/definitions/DataExtensionTemplate.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/DataExtract.definition.d.ts +156 -0
- package/@types/lib/metadataTypes/definitions/DataExtract.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/DataExtractType.definition.d.ts +34 -0
- package/@types/lib/metadataTypes/definitions/DataExtractType.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/DeliveryProfile.definition.d.ts +80 -0
- package/@types/lib/metadataTypes/definitions/DeliveryProfile.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Discovery.definition.d.ts +146 -0
- package/@types/lib/metadataTypes/definitions/Discovery.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Email.definition.d.ts +314 -0
- package/@types/lib/metadataTypes/definitions/Email.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/EmailSend.definition.d.ts +582 -0
- package/@types/lib/metadataTypes/definitions/EmailSend.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Event.definition.d.ts +867 -0
- package/@types/lib/metadataTypes/definitions/Event.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/FileLocation.definition.d.ts +68 -0
- package/@types/lib/metadataTypes/definitions/FileLocation.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/FileTransfer.definition.d.ts +191 -0
- package/@types/lib/metadataTypes/definitions/FileTransfer.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Filter.definition.d.ts +147 -0
- package/@types/lib/metadataTypes/definitions/Filter.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Folder.definition.d.ts +174 -0
- package/@types/lib/metadataTypes/definitions/Folder.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/ImportFile.definition.d.ts +306 -0
- package/@types/lib/metadataTypes/definitions/ImportFile.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +426 -0
- package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/List.definition.d.ts +118 -0
- package/@types/lib/metadataTypes/definitions/List.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/MobileCode.definition.d.ts +167 -0
- package/@types/lib/metadataTypes/definitions/MobileCode.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/MobileKeyword.definition.d.ts +276 -0
- package/@types/lib/metadataTypes/definitions/MobileKeyword.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/MobileMessage.definition.d.ts +783 -0
- package/@types/lib/metadataTypes/definitions/MobileMessage.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Query.definition.d.ts +203 -0
- package/@types/lib/metadataTypes/definitions/Query.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Role.definition.d.ts +108 -0
- package/@types/lib/metadataTypes/definitions/Role.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Script.definition.d.ts +153 -0
- package/@types/lib/metadataTypes/definitions/Script.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/SendClassification.definition.d.ts +151 -0
- package/@types/lib/metadataTypes/definitions/SendClassification.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/SenderProfile.definition.d.ts +180 -0
- package/@types/lib/metadataTypes/definitions/SenderProfile.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/TransactionalEmail.definition.d.ts +167 -0
- package/@types/lib/metadataTypes/definitions/TransactionalEmail.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/TransactionalMessage.definition.d.ts +99 -0
- package/@types/lib/metadataTypes/definitions/TransactionalMessage.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/TransactionalPush.definition.d.ts +119 -0
- package/@types/lib/metadataTypes/definitions/TransactionalPush.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/TransactionalSMS.definition.d.ts +113 -0
- package/@types/lib/metadataTypes/definitions/TransactionalSMS.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/TriggeredSend.definition.d.ts +560 -0
- package/@types/lib/metadataTypes/definitions/TriggeredSend.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/User.definition.d.ts +423 -0
- package/@types/lib/metadataTypes/definitions/User.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Verification.definition.d.ts +129 -0
- package/@types/lib/metadataTypes/definitions/Verification.definition.d.ts.map +1 -0
- package/@types/lib/retrieveChangelog.d.ts +3 -0
- package/@types/lib/retrieveChangelog.d.ts.map +1 -0
- package/@types/lib/util/auth.d.ts +41 -0
- package/@types/lib/util/auth.d.ts.map +1 -0
- package/@types/lib/util/businessUnit.d.ts +21 -0
- package/@types/lib/util/businessUnit.d.ts.map +1 -0
- package/@types/lib/util/cache.d.ts +64 -0
- package/@types/lib/util/cache.d.ts.map +1 -0
- package/@types/lib/util/cli.d.ts +125 -0
- package/@types/lib/util/cli.d.ts.map +1 -0
- package/@types/lib/util/config.d.ts +45 -0
- package/@types/lib/util/config.d.ts.map +1 -0
- package/@types/lib/util/devops.d.ts +62 -0
- package/@types/lib/util/devops.d.ts.map +1 -0
- package/@types/lib/util/file.d.ts +20 -0
- package/@types/lib/util/file.d.ts.map +1 -0
- package/@types/lib/util/init.config.d.ts +66 -0
- package/@types/lib/util/init.config.d.ts.map +1 -0
- package/@types/lib/util/init.d.ts +72 -0
- package/@types/lib/util/init.d.ts.map +1 -0
- package/@types/lib/util/init.git.d.ts +40 -0
- package/@types/lib/util/init.git.d.ts.map +1 -0
- package/@types/lib/util/init.npm.d.ts +24 -0
- package/@types/lib/util/init.npm.d.ts.map +1 -0
- package/@types/lib/util/replaceContentBlockReference.d.ts +105 -0
- package/@types/lib/util/replaceContentBlockReference.d.ts.map +1 -0
- package/@types/lib/util/util.d.ts +322 -0
- package/@types/lib/util/util.d.ts.map +1 -0
- package/@types/types/mcdev.d.d.ts +1282 -0
- package/@types/types/mcdev.d.d.ts.map +1 -0
- package/LICENSE +1 -1
- package/README.md +7 -3
- package/boilerplate/files/.beautyamp.json +13 -0
- package/boilerplate/files/.prettierrc +3 -0
- package/boilerplate/files/.vscode/extensions.json +6 -1
- package/boilerplate/files/.vscode/settings.json +16 -4
- package/boilerplate/forcedUpdates.json +9 -0
- package/jsconfig.json +7 -2
- package/lib/Builder.js +49 -45
- package/lib/Deployer.js +100 -45
- package/lib/MetadataTypeDefinitions.js +6 -0
- package/lib/MetadataTypeInfo.js +4 -0
- package/lib/Retriever.js +33 -27
- package/lib/cli.js +363 -28
- package/lib/index.js +615 -55
- package/lib/metadataTypes/Asset.js +811 -159
- package/lib/metadataTypes/AttributeGroup.js +17 -12
- package/lib/metadataTypes/AttributeSet.js +20 -15
- package/lib/metadataTypes/Automation.js +125 -93
- package/lib/metadataTypes/Campaign.js +18 -6
- package/lib/metadataTypes/ContentArea.js +21 -18
- package/lib/metadataTypes/DataExtension.js +229 -113
- package/lib/metadataTypes/DataExtensionField.js +52 -53
- package/lib/metadataTypes/DataExtensionTemplate.js +17 -5
- package/lib/metadataTypes/DataExtract.js +62 -27
- package/lib/metadataTypes/DataExtractType.js +17 -5
- package/lib/metadataTypes/DeliveryProfile.js +47 -0
- package/lib/metadataTypes/Discovery.js +15 -4
- package/lib/metadataTypes/Email.js +22 -19
- package/lib/metadataTypes/EmailSend.js +135 -35
- package/lib/metadataTypes/Event.js +95 -60
- package/lib/metadataTypes/FileLocation.js +17 -5
- package/lib/metadataTypes/FileTransfer.js +62 -26
- package/lib/metadataTypes/Filter.js +16 -4
- package/lib/metadataTypes/Folder.js +67 -39
- package/lib/metadataTypes/ImportFile.js +341 -91
- package/lib/metadataTypes/Journey.js +681 -324
- package/lib/metadataTypes/List.js +26 -14
- package/lib/metadataTypes/MetadataType.js +501 -265
- package/lib/metadataTypes/MobileCode.js +17 -5
- package/lib/metadataTypes/MobileKeyword.js +59 -43
- package/lib/metadataTypes/MobileMessage.js +67 -40
- package/lib/metadataTypes/Query.js +46 -38
- package/lib/metadataTypes/Role.js +34 -23
- package/lib/metadataTypes/Script.js +127 -39
- package/lib/metadataTypes/SendClassification.js +120 -5
- package/lib/metadataTypes/SenderProfile.js +179 -0
- package/lib/metadataTypes/TransactionalEmail.js +30 -17
- package/lib/metadataTypes/TransactionalMessage.js +25 -11
- package/lib/metadataTypes/TransactionalPush.js +24 -9
- package/lib/metadataTypes/TransactionalSMS.js +78 -46
- package/lib/metadataTypes/TriggeredSend.js +191 -43
- package/lib/metadataTypes/User.js +90 -62
- package/lib/metadataTypes/Verification.js +39 -21
- package/lib/metadataTypes/definitions/Asset.definition.js +3 -3
- package/lib/metadataTypes/definitions/AttributeGroup.definition.js +7 -1
- package/lib/metadataTypes/definitions/AttributeSet.definition.js +2 -2
- package/lib/metadataTypes/definitions/Automation.definition.js +4 -1
- package/lib/metadataTypes/definitions/Campaign.definition.js +1 -1
- package/lib/metadataTypes/definitions/ContentArea.definition.js +1 -1
- package/lib/metadataTypes/definitions/DataExtension.definition.js +17 -1
- package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +1 -1
- package/lib/metadataTypes/definitions/DataExtractType.definition.js +2 -2
- package/lib/metadataTypes/definitions/DeliveryProfile.definition.js +59 -0
- package/lib/metadataTypes/definitions/Discovery.definition.js +1 -1
- package/lib/metadataTypes/definitions/Email.definition.js +1 -1
- package/lib/metadataTypes/definitions/EmailSend.definition.js +19 -4
- package/lib/metadataTypes/definitions/Event.definition.js +140 -128
- package/lib/metadataTypes/definitions/FileLocation.definition.js +1 -1
- package/lib/metadataTypes/definitions/Filter.definition.js +1 -1
- package/lib/metadataTypes/definitions/Folder.definition.js +25 -2
- package/lib/metadataTypes/definitions/ImportFile.definition.js +52 -7
- package/lib/metadataTypes/definitions/Journey.definition.js +12 -0
- package/lib/metadataTypes/definitions/List.definition.js +1 -1
- package/lib/metadataTypes/definitions/MobileCode.definition.js +1 -1
- package/lib/metadataTypes/definitions/MobileMessage.definition.js +11 -5
- package/lib/metadataTypes/definitions/Query.definition.js +6 -0
- package/lib/metadataTypes/definitions/Script.definition.js +14 -14
- package/lib/metadataTypes/definitions/SendClassification.definition.js +60 -20
- package/lib/metadataTypes/definitions/SenderProfile.definition.js +185 -0
- package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +2 -2
- package/lib/metadataTypes/definitions/TransactionalMessage.definition.js +69 -0
- package/lib/metadataTypes/definitions/TransactionalPush.definition.js +6 -0
- package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +6 -0
- package/lib/metadataTypes/definitions/TriggeredSend.definition.js +15 -4
- package/lib/metadataTypes/definitions/Verification.definition.js +1 -1
- package/lib/retrieveChangelog.js +7 -2
- package/lib/util/auth.js +56 -21
- package/lib/util/businessUnit.js +20 -2
- package/lib/util/cache.js +37 -18
- package/lib/util/cli.js +72 -29
- package/lib/util/config.js +27 -9
- package/lib/util/devops.js +45 -24
- package/lib/util/file.js +58 -33
- package/lib/util/init.config.js +55 -24
- package/lib/util/init.git.js +6 -6
- package/lib/util/init.js +36 -14
- package/lib/util/init.npm.js +2 -2
- package/lib/util/replaceContentBlockReference.js +278 -0
- package/lib/util/util.js +152 -54
- package/package.json +33 -30
- package/test/general.test.js +1327 -4
- package/test/mockRoot/.mcdevrc.json +26 -4
- package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testExisting_dataExtensionShared.dataExtension-meta.json +3 -4
- package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testNew_dataExtensionShared.dataExtension-meta.json +1 -4
- package/test/mockRoot/deploy/testInstance/_ParentBU_/query/testNew_query.query-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/_ParentBU_/query/testNew_query.query-meta.sql +4 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset.asset-block-meta.html +12 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset.asset-block-meta.json +39 -0
- package/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +6 -6
- package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +7 -7
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-meta.json +3 -4
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testNew_dataExtension.dataExtension-meta.json +1 -4
- package/test/mockRoot/deploy/testInstance/testBU/emailSend/testExisting_emailSend.emailSend-meta.json +36 -0
- package/test/mockRoot/deploy/testInstance/testBU/emailSend/testNew_emailSend.emailSend-meta.json +36 -0
- package/test/mockRoot/deploy/testInstance/testBU/importFile/testExisting_importFile.importFile-meta.json +10 -4
- package/test/mockRoot/deploy/testInstance/testBU/importFile/testNew_importFile.importFile-meta.json +8 -4
- package/test/mockRoot/deploy/testInstance/testBU/journey/testExisting_journey_Quicksend.journey-meta.json +232 -0
- package/test/mockRoot/deploy/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.json +2 -4
- package/test/mockRoot/deploy/testInstance/testBU/mobileMessage/new.mobileMessage-meta.json +2 -4
- package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/query/testNew_query.query-meta.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/sendClassification/testExisting_sendClassification.sendClassification-meta.json +8 -0
- package/test/mockRoot/deploy/testInstance/testBU/sendClassification/testNew_sendClassification.sendClassification-meta.json +8 -0
- package/test/mockRoot/deploy/testInstance/testBU/senderProfile/testExisting_senderProfile.senderProfile-meta.json +14 -0
- package/test/mockRoot/deploy/testInstance/testBU/senderProfile/testNew_senderProfile.senderProfile-meta.json +14 -0
- package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testNew_temail.transactionalEmail-meta.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/transactionalPush/testExisting_tpush.transactionalPush-meta.json +1 -3
- package/test/mockRoot/deploy/testInstance/testBU/transactionalPush/testNew_tpush.transactionalPush-meta.json +1 -3
- package/test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testExisting_tsms.transactionalSMS-meta.json +1 -2
- package/test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testNew_tsms.transactionalSMS-meta.json +1 -2
- package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testExisting_triggeredSend.triggeredSend-meta.json +4 -5
- package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testNew_triggeredSend.triggeredSend-meta.json +4 -5
- package/test/mockRoot/deploy/testInstance/testBU/verification/testExisting_39f6a488-20eb-4ba0-b0b9.verification-meta.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/verification/testNew_39f6a488-20eb-4ba0-b0b9.verification-meta.json +1 -1
- package/test/resourceFactory.js +118 -7
- package/test/resources/1111111/automation/v1/queries/get-response.json +6 -0
- package/test/resources/1111111/automation/v1/queries/post-response.json +18 -0
- package/test/resources/1111111/dataExtension/create-expected.json +4 -7
- package/test/resources/1111111/dataExtension/retrieve-expected.json +2 -4
- package/test/resources/1111111/dataExtension/update-expected.json +7 -7
- package/test/resources/1111111/dataExtension/update-response.xml +3 -1
- package/test/resources/1111111/dataFolder/retrieve-ContentType=queryactivity-response.xml +48 -0
- package/test/resources/1111111/query/patch_keySuffix-expected.json +11 -0
- package/test/resources/1111111/query/patch_keySuffix-expected.sql +4 -0
- package/test/resources/9999999/asset/block-1157-retrieve-expected.html +4 -3
- package/test/resources/9999999/asset/build-templatebasedemail-expected.json +81 -0
- package/test/resources/9999999/asset/build-templatebasedemail-html-expected.html +20 -0
- package/test/resources/9999999/asset/build-templatebasedemail-preheader-expected.amp +1 -0
- package/test/resources/9999999/asset/create-expected.json +18 -0
- package/test/resources/9999999/asset/resolveId-1234-notFound-expected.json +1 -0
- package/test/resources/9999999/asset/resolveId-1295064-noPath-expected.json +8 -0
- package/test/resources/9999999/asset/resolveId-1295064-withPath-expected.json +8 -0
- package/test/resources/9999999/asset/retrieve-templatebasedemail-expected.json +84 -0
- package/test/resources/9999999/asset/retrieve-templatebasedemail-html-expected.html +20 -0
- package/test/resources/9999999/asset/retrieve-templatebasedemail-preheader-expected.amp +1 -0
- package/test/resources/9999999/asset/template-templatebasedemail-expected.json +81 -0
- package/test/resources/9999999/asset/template-templatebasedemail-html-expected.html +20 -0
- package/test/resources/9999999/asset/template-templatebasedemail-preheader-expected.amp +1 -0
- package/test/resources/9999999/asset/testExisting_asset_message-html-rcb-id-expected.html +33 -0
- package/test/resources/9999999/asset/testExisting_asset_message-html-rcb-key-expected.html +33 -0
- package/test/resources/9999999/asset/testExisting_asset_message-html-rcb-name-expected.html +35 -0
- package/test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-id-expected.amp +4 -0
- package/test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-key-expected.amp +4 -0
- package/test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-name-expected.amp +4 -0
- package/test/resources/9999999/asset/testExisting_asset_message-text-rcb-id-expected.amp +4 -0
- package/test/resources/9999999/asset/testExisting_asset_message-text-rcb-key-expected.amp +4 -0
- package/test/resources/9999999/asset/testExisting_asset_message-text-rcb-name-expected.amp +4 -0
- package/test/resources/9999999/asset/v1/content/assets/1295064/get-response.json +1 -1
- package/test/resources/9999999/asset/v1/content/assets/5286/get-response.json +48 -0
- package/test/resources/9999999/asset/v1/content/assets/5289/get-response.json +198 -0
- package/test/resources/9999999/asset/v1/content/assets/808714/get-response.json +4 -3
- package/test/resources/9999999/asset/v1/content/assets/950143/delete-response.txt +1 -0
- package/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json +105 -0
- package/test/resources/9999999/asset/v1/content/assets/post-response.json +59 -0
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,14.json +7 -0
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN193,194,15.json +7 -0
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN195,196,197,198,199,200,201,202,203,210,211,212,213,3.json +46 -0
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN205,206,230,232,1.json +32 -0
- package/test/resources/9999999/asset/v1/content/assets/query/{post-response.json → post-response-assetType.idIN207,208,209,5.json} +45 -47
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN214,4.json +35 -0
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN215,216,217,218,219,220,221,222,223,224,225,226,227,228.json +7 -0
- package/test/resources/9999999/asset/v1/content/assets/query/post-response-customerKey=mcdev-issue-1157.json +46 -0
- package/test/resources/9999999/attributeGroup/retrieve-expected.json +1 -1
- package/test/resources/9999999/attributeSet/retrieve-expected.json +3 -3
- package/test/resources/9999999/automation/build-expected.json +7 -7
- package/test/resources/9999999/automation/create-expected.json +7 -7
- package/test/resources/9999999/automation/patch_fixKeys-pause-expected.json +6 -6
- package/test/resources/9999999/automation/patch_fixKeys-schedule-expected.json +6 -6
- package/test/resources/9999999/automation/retrieve-expected.json +7 -7
- package/test/resources/9999999/automation/template-expected.json +7 -7
- package/test/resources/9999999/automation/update-expected.json +6 -6
- package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/delete-response.txt +1 -0
- package/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/delete-response.json +1 -0
- package/test/resources/9999999/automation/v1/imports/1ebf557b-372e-eb11-b81b-48df37d1dbd7/get-response.json +78 -0
- package/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/delete-response.txt +0 -0
- package/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/get-response.json +35 -0
- package/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/patch-response.json +14 -10
- package/test/resources/9999999/automation/v1/imports/get-response.json +78 -1
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +1 -1
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeysSuffix/get-response.json +17 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeysSuffix/patch-response.json +18 -0
- package/test/resources/9999999/automation/v1/queries/abcde-607c-4940-afef-437965094dat/get-response.json +17 -0
- package/test/resources/9999999/automation/v1/queries/get-response.json +20 -3
- package/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/delete-response.txt +1 -0
- package/test/resources/9999999/automation/v1/scripts/get-response.json +3 -3
- package/test/resources/9999999/dataExtension/build-expected.json +3 -4
- package/test/resources/9999999/dataExtension/create-expected.json +1 -4
- package/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml +4 -4
- package/test/resources/9999999/dataExtension/retrieve-expected.json +3 -4
- package/test/resources/9999999/dataExtension/retrieve-response.xml +96 -1
- package/test/resources/9999999/dataExtension/template-expected.json +3 -4
- package/test/resources/9999999/dataExtension/update-expected.json +4 -3
- package/test/resources/9999999/dataExtension/update-response.xml +5 -3
- package/test/resources/9999999/dataExtensionField/retrieve-response.xml +72 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentType=userinitiatedsends-response.xml +48 -0
- package/test/resources/9999999/deliveryProfile/get-expected.json +7 -0
- package/test/resources/9999999/emailSend/build-expected.json +43 -0
- package/test/resources/9999999/emailSend/get-expected.json +43 -0
- package/test/resources/9999999/emailSend/patch-expected.json +41 -0
- package/test/resources/9999999/emailSend/post-expected.json +41 -0
- package/test/resources/9999999/emailSend/template-expected.json +43 -0
- package/test/resources/9999999/emailSendDefinition/create-response.xml +98 -0
- package/test/resources/9999999/emailSendDefinition/delete-response.xml +36 -0
- package/test/resources/9999999/emailSendDefinition/retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml +18 -8
- package/test/resources/9999999/emailSendDefinition/update-response.xml +97 -0
- package/test/resources/9999999/importDefinition/retrieve-CustomerKey=testExisting_importFile-response.xml +30 -0
- package/test/resources/9999999/importDefinition/retrieve-Name=testExisting_importFile-response.xml +30 -0
- package/test/resources/9999999/importFile/build-expected.json +11 -6
- package/test/resources/9999999/importFile/get-expected.json +13 -7
- package/test/resources/9999999/importFile/get-sms-expected.json +79 -0
- package/test/resources/9999999/importFile/patch-expected.json +12 -7
- package/test/resources/9999999/importFile/post-expected.json +8 -5
- package/test/resources/9999999/importFile/template-expected.json +10 -5
- package/test/resources/9999999/interaction/v1/eventDefinitions/get-response.json +124 -0
- package/test/resources/9999999/interaction/v1/interactions/3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/delete-response.txt +1 -0
- package/test/resources/9999999/interaction/v1/interactions/3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/get-response.json +253 -0
- package/test/resources/9999999/interaction/v1/interactions/get-response.json +83 -779
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Multistep/get-response.json +457 -0
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Quicksend/get-response.json +253 -0
- package/test/resources/9999999/interaction/v1/interactions/{key_0b76dccf-594c-b6dc-1acf-10c4493dcb84 → key_testExisting_temail}/get-response.json +5 -5
- package/test/resources/9999999/journey/build-expected.json +105 -449
- package/test/resources/9999999/journey/get-multistep-expected.json +413 -0
- package/test/resources/9999999/journey/get-quicksend-expected.json +232 -0
- package/test/resources/9999999/journey/get-quicksend-rcb-id-expected.json +232 -0
- package/test/resources/9999999/journey/get-quicksend-rcb-key-expected.json +232 -0
- package/test/resources/9999999/journey/get-quicksend-rcb-name-expected.json +232 -0
- package/test/resources/9999999/journey/get-transactionalEmail-expected.json +211 -0
- package/test/resources/9999999/journey/template-expected.json +105 -449
- package/test/resources/9999999/legacy/v1/beta/messaging/deliverypolicy/get-response.json +15 -0
- package/test/resources/9999999/legacy/v1/beta/mobile/imports/get-response.json +112 -0
- package/test/resources/9999999/legacy/v1/beta/mobile/message/NTQ3Ojc4OjA/get-response.json +1 -1
- package/test/resources/9999999/legacy/v1/beta/object/NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow/get-response.json +12 -0
- package/test/resources/9999999/list/retrieve-response.xml +13 -0
- package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/get-response.json +1 -1
- package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/patch-response.json +1 -1
- package/test/resources/9999999/mobileMessage/build-expected.json +2 -5
- package/test/resources/9999999/mobileMessage/get-expected.json +2 -5
- package/test/resources/9999999/mobileMessage/post-create-expected.json +2 -4
- package/test/resources/9999999/mobileMessage/post-update-expected.json +2 -5
- package/test/resources/9999999/mobileMessage/template-expected.json +2 -5
- package/test/resources/9999999/query/build-expected.json +1 -1
- package/test/resources/9999999/query/build-expected.sql +2 -1
- package/test/resources/9999999/query/get-expected.json +1 -1
- package/test/resources/9999999/query/get-expected.sql +2 -1
- package/test/resources/9999999/query/get2-expected.json +1 -1
- package/test/resources/9999999/query/patch-expected.json +1 -1
- package/test/resources/9999999/query/patch_fixKeys-expected.json +1 -1
- package/test/resources/9999999/query/patch_fixKeysSuffix-expected.json +11 -0
- package/test/resources/9999999/query/patch_fixKeysSuffix-expected.sql +6 -0
- package/test/resources/9999999/query/post-expected.json +1 -1
- package/test/resources/9999999/query/template-expected.json +1 -1
- package/test/resources/9999999/query/template-expected.sql +2 -1
- package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query2ANDStatus=Active-response.xml +30 -0
- package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysSuffixANDStatus=Active-response.xml +30 -0
- package/test/resources/9999999/script/get_ampincluded-expected.html +5 -0
- package/test/resources/9999999/script/get_ampincluded-rcb-id-expected.html +5 -0
- package/test/resources/9999999/script/get_ampincluded-rcb-key-expected.html +5 -0
- package/test/resources/9999999/script/get_ampincluded-rcb-name-expected.html +5 -0
- package/test/resources/9999999/script/get_ampscript-expected.html +6 -1
- package/test/resources/9999999/script/get_ampscript-rcb-id-expected.html +8 -0
- package/test/resources/9999999/script/get_ampscript-rcb-key-expected.html +8 -0
- package/test/resources/9999999/script/get_ampscript-rcb-name-expected.html +10 -0
- package/test/resources/9999999/script/get_mixed-expected.html +5 -2
- package/test/resources/9999999/script/get_mixed-rcb-id-expected.html +12 -0
- package/test/resources/9999999/script/get_mixed-rcb-key-expected.html +12 -0
- package/test/resources/9999999/script/get_mixed-rcb-name-expected.html +14 -0
- package/test/resources/9999999/sendClassification/build-expected.json +8 -0
- package/test/resources/9999999/sendClassification/create-response.xml +51 -0
- package/test/resources/9999999/sendClassification/delete-response.xml +36 -0
- package/test/resources/9999999/sendClassification/get-expected.json +10 -0
- package/test/resources/9999999/sendClassification/patch-expected.json +8 -0
- package/test/resources/9999999/sendClassification/post-expected.json +8 -0
- package/test/resources/9999999/sendClassification/retrieve-response.xml +86 -0
- package/test/resources/9999999/sendClassification/template-expected.json +8 -0
- package/test/resources/9999999/sendClassification/update-response.xml +49 -0
- package/test/resources/9999999/senderProfile/build-expected.json +14 -0
- package/test/resources/9999999/senderProfile/create-response.xml +49 -0
- package/test/resources/9999999/senderProfile/delete-response.xml +36 -0
- package/test/resources/9999999/senderProfile/get-expected.json +16 -0
- package/test/resources/9999999/senderProfile/get-rcb-id-expected.json +16 -0
- package/test/resources/9999999/senderProfile/get-rcb-key-expected.json +16 -0
- package/test/resources/9999999/senderProfile/get-rcb-name-expected.json +16 -0
- package/test/resources/9999999/senderProfile/patch-expected.json +14 -0
- package/test/resources/9999999/senderProfile/post-expected.json +14 -0
- package/test/resources/9999999/senderProfile/retrieve-CustomerKey=Default-response.xml +44 -0
- package/test/resources/9999999/senderProfile/retrieve-CustomerKey=wrong-key-response.xml +26 -0
- package/test/resources/9999999/senderProfile/retrieve-response.xml +80 -0
- package/test/resources/9999999/senderProfile/template-expected.json +14 -0
- package/test/resources/9999999/senderProfile/update-response.xml +47 -0
- package/test/resources/9999999/transactionalEmail/build-expected.json +3 -3
- package/test/resources/9999999/transactionalEmail/get-expected.json +3 -3
- package/test/resources/9999999/transactionalEmail/patch-expected.json +3 -3
- package/test/resources/9999999/transactionalEmail/post-expected.json +2 -2
- package/test/resources/9999999/transactionalEmail/template-expected.json +3 -3
- package/test/resources/9999999/transactionalPush/build-expected.json +1 -1
- package/test/resources/9999999/transactionalPush/get-expected.json +1 -1
- package/test/resources/9999999/transactionalPush/patch-expected.json +1 -3
- package/test/resources/9999999/transactionalPush/post-expected.json +1 -3
- package/test/resources/9999999/transactionalPush/template-expected.json +1 -1
- package/test/resources/9999999/transactionalSMS/build-expected.amp +1 -1
- package/test/resources/9999999/transactionalSMS/build-expected.json +1 -2
- package/test/resources/9999999/transactionalSMS/get-expected.amp +1 -1
- package/test/resources/9999999/transactionalSMS/get-expected.json +1 -2
- package/test/resources/9999999/transactionalSMS/patch-expected.amp +1 -1
- package/test/resources/9999999/transactionalSMS/patch-expected.json +1 -2
- package/test/resources/9999999/transactionalSMS/post-expected.amp +1 -1
- package/test/resources/9999999/transactionalSMS/post-expected.json +1 -2
- package/test/resources/9999999/transactionalSMS/template-expected.amp +1 -1
- package/test/resources/9999999/transactionalSMS/template-expected.json +1 -2
- package/test/resources/9999999/triggeredSend/build-expected.json +5 -6
- package/test/resources/9999999/triggeredSend/get-expected.json +5 -6
- package/test/resources/9999999/triggeredSend/get-rcb-id-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/get-rcb-key-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/get-rcb-name-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/patch-expected.json +5 -6
- package/test/resources/9999999/triggeredSend/post-expected.json +5 -6
- package/test/resources/9999999/triggeredSend/template-expected.json +5 -6
- package/test/resources/9999999/triggeredSendDefinition/create-response.xml +6 -1
- package/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml +53 -1
- package/test/resources/9999999/triggeredSendDefinition/update-response.xml +6 -1
- package/test/resources/9999999/verification/build-expected.json +1 -1
- package/test/resources/9999999/verification/get-expected.json +1 -1
- package/test/resources/9999999/verification/patch-expected.json +1 -1
- package/test/resources/9999999/verification/post-expected.json +1 -1
- package/test/resources/9999999/verification/template-expected.json +1 -1
- package/test/type.asset.test.js +733 -17
- package/test/type.attributeGroup.test.js +6 -2
- package/test/type.attributeSet.test.js +6 -2
- package/test/type.automation.test.js +174 -162
- package/test/type.dataExtension.test.js +41 -45
- package/test/type.dataExtract.test.js +22 -29
- package/test/type.deliveryProfile.test.js +45 -0
- package/test/type.emailSend.test.js +144 -0
- package/test/type.event.test.js +62 -0
- package/test/type.fileTransfer.test.js +21 -29
- package/test/type.importFile.test.js +61 -35
- package/test/type.journey.test.js +251 -45
- package/test/type.mobileKeyword.test.js +46 -54
- package/test/type.mobileMessage.test.js +28 -27
- package/test/type.query.test.js +303 -124
- package/test/type.script.test.js +288 -69
- package/test/type.sendClassification.test.js +156 -0
- package/test/type.senderProfile.test.js +254 -0
- package/test/type.transactionalEmail.test.js +15 -11
- package/test/type.transactionalPush.test.js +15 -11
- package/test/type.transactionalSMS.test.js +30 -23
- package/test/type.triggeredSend.test.js +130 -17
- package/test/type.user.test.js +22 -14
- package/test/type.verification.test.js +13 -10
- package/test/utils.js +76 -21
- package/tsconfig.json +21 -0
- package/types/mcdev.d.js +190 -66
- package/docs/dist/documentation.md +0 -8878
- package/test/mockRoot/deploy/testInstance/testBU/journey/testExisting_interaction.interaction-meta.json +0 -576
- package/test/mockRoot/deploy/testInstance/testBU/journey/testNew_interaction.interaction-meta.json +0 -266
- package/test/resources/9999999/interaction/v1/EventDefinitions/get-response.json +0 -43
- package/test/resources/9999999/interaction/v1/interactions/233d4413-922c-4568-85a5-e5cc77efc3be/delete-response.json +0 -1
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_interaction/get-response.json +0 -592
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_interaction/put-response.json +0 -592
- package/test/resources/9999999/interaction/v1/interactions/post-response.json +0 -280
- package/test/resources/9999999/journey/get-expected.json +0 -576
- package/test/resources/9999999/script/get_ampincluded-expected.ssjs +0 -5
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
import MetadataType from './MetadataType.js';
|
|
4
|
-
import TYPE from '../../types/mcdev.d.js';
|
|
5
4
|
import { Util } from '../util/util.js';
|
|
6
5
|
import File from '../util/file.js';
|
|
7
6
|
import pLimit from 'p-limit';
|
|
8
7
|
import cliProgress from 'cli-progress';
|
|
9
8
|
import cache from '../util/cache.js';
|
|
10
9
|
import TriggeredSend from './TriggeredSend.js';
|
|
10
|
+
import Folder from './Folder.js';
|
|
11
|
+
import ReplaceCbReference from '../util/replaceContentBlockReference.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
|
|
15
|
+
* @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract
|
|
16
|
+
* @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem
|
|
17
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem
|
|
18
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff
|
|
19
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap
|
|
20
|
+
* @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams
|
|
21
|
+
* @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {import('../../types/mcdev.d.js').AssetSubType} AssetSubType
|
|
25
|
+
* @typedef {import('../../types/mcdev.d.js').AssetMap} AssetMap
|
|
26
|
+
* @typedef {import('../../types/mcdev.d.js').AssetItem} AssetItem
|
|
27
|
+
* @typedef {import('../../types/mcdev.d.js').AssetRequestParams} AssetRequestParams
|
|
28
|
+
*/
|
|
11
29
|
|
|
12
30
|
/**
|
|
13
31
|
* FileTransfer MetadataType
|
|
@@ -19,13 +37,23 @@ class Asset extends MetadataType {
|
|
|
19
37
|
* Retrieves Metadata of Asset
|
|
20
38
|
*
|
|
21
39
|
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
22
|
-
* @param {void} _
|
|
23
|
-
* @param {
|
|
40
|
+
* @param {void | string[]} _ unused parameter
|
|
41
|
+
* @param {string[]} [subTypeArr] optionally limit to a single AssetSubType
|
|
24
42
|
* @param {string} [key] customer key
|
|
25
|
-
* @
|
|
43
|
+
* @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current
|
|
44
|
+
* @returns {Promise.<{metadata: AssetMap, type: string}>} Promise
|
|
26
45
|
*/
|
|
27
|
-
static async retrieve(retrieveDir, _, subTypeArr, key) {
|
|
46
|
+
static async retrieve(retrieveDir, _, subTypeArr, key, loadShared = false) {
|
|
28
47
|
const items = [];
|
|
48
|
+
if (subTypeArr) {
|
|
49
|
+
// check if elements in subTypeArr exist in this.definition.subTypes
|
|
50
|
+
const invalidSubTypes = subTypeArr.filter(
|
|
51
|
+
(subType) => !this.definition.subTypes.includes(subType)
|
|
52
|
+
);
|
|
53
|
+
if (invalidSubTypes.length) {
|
|
54
|
+
throw new Error(`Invalid subType(s) found: ${invalidSubTypes.join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
29
57
|
subTypeArr ||= this._getSubTypes();
|
|
30
58
|
if (retrieveDir) {
|
|
31
59
|
await File.initPrettier();
|
|
@@ -34,7 +62,7 @@ class Asset extends MetadataType {
|
|
|
34
62
|
for (const subType of subTypeArr) {
|
|
35
63
|
// each subtype contains multiple different specific types (images contains jpg and png for example)
|
|
36
64
|
// we use await here to limit the risk of too many concurrent api requests at time
|
|
37
|
-
items.push(...(await this.requestSubType(subType, retrieveDir,
|
|
65
|
+
items.push(...(await this.requestSubType(subType, retrieveDir, key, null, loadShared)));
|
|
38
66
|
}
|
|
39
67
|
const metadata = this.parseResponseBody({ items: items });
|
|
40
68
|
if (retrieveDir) {
|
|
@@ -45,16 +73,55 @@ class Asset extends MetadataType {
|
|
|
45
73
|
}
|
|
46
74
|
return { metadata: metadata, type: this.definition.type };
|
|
47
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Helper for writing Metadata to disk, used for Retrieve and deploy
|
|
78
|
+
*
|
|
79
|
+
* @param {MetadataTypeMap} results metadata results from deploy
|
|
80
|
+
* @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve
|
|
81
|
+
* @param {string} [overrideType] for use when there is a subtype (such as folder-queries)
|
|
82
|
+
* @param {TemplateMap} [templateVariables] variables to be replaced in the metadata
|
|
83
|
+
* @returns {Promise.<MetadataTypeMap>} Promise of saved metadata
|
|
84
|
+
*/
|
|
85
|
+
static async saveResults(results, retrieveDir, overrideType, templateVariables) {
|
|
86
|
+
if (Object.keys(results).length) {
|
|
87
|
+
// only execute the following if records were found
|
|
88
|
+
await this._postRetrieveTasksBulk(results);
|
|
89
|
+
}
|
|
90
|
+
return super.saveResults(results, retrieveDir, overrideType, templateVariables);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* helper for Journey's {@link Asset.saveResults}. Gets executed after retreive of metadata type and
|
|
94
|
+
*
|
|
95
|
+
* @param {MetadataTypeMap} metadataMap key=customer key, value=metadata
|
|
96
|
+
*/
|
|
97
|
+
static async _postRetrieveTasksBulk(metadataMap) {
|
|
98
|
+
// Template-Based Email
|
|
99
|
+
let needTemplates = false;
|
|
100
|
+
for (const key in metadataMap) {
|
|
101
|
+
if (metadataMap[key].assetType.name == 'templatebasedemail') {
|
|
102
|
+
needTemplates = true;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (needTemplates && !cache.getCache()?.asset) {
|
|
108
|
+
// for
|
|
109
|
+
Util.logger.info(' - Caching dependent Metadata: asset-template');
|
|
110
|
+
const result = await this.retrieveForCache(undefined, ['template']);
|
|
111
|
+
cache.setMetadata('asset', result.metadata);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
48
114
|
|
|
49
115
|
/**
|
|
50
116
|
* Retrieves asset metadata for caching
|
|
51
117
|
*
|
|
52
|
-
* @param {void} _
|
|
118
|
+
* @param {void | string[]} [_] parameter not used
|
|
53
119
|
* @param {string[]} [subTypeArr] optionally limit to a single subtype
|
|
54
|
-
* @
|
|
120
|
+
* @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current
|
|
121
|
+
* @returns {Promise.<{metadata: AssetMap, type: string}>} Promise
|
|
55
122
|
*/
|
|
56
|
-
static retrieveForCache(_, subTypeArr) {
|
|
57
|
-
return this.retrieve(null, null, subTypeArr);
|
|
123
|
+
static retrieveForCache(_, subTypeArr, loadShared = false) {
|
|
124
|
+
return this.retrieve(null, null, subTypeArr, undefined, loadShared);
|
|
58
125
|
}
|
|
59
126
|
|
|
60
127
|
/**
|
|
@@ -62,9 +129,9 @@ class Asset extends MetadataType {
|
|
|
62
129
|
*
|
|
63
130
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
64
131
|
* @param {string} name name of the metadata file
|
|
65
|
-
* @param {
|
|
66
|
-
* @param {
|
|
67
|
-
* @returns {Promise.<{metadata:
|
|
132
|
+
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
133
|
+
* @param {AssetSubType} [selectedSubType] optionally limit to a single subtype
|
|
134
|
+
* @returns {Promise.<{metadata: AssetItem, type: string}>} Promise
|
|
68
135
|
*/
|
|
69
136
|
static async retrieveAsTemplate(templateDir, name, templateVariables, selectedSubType) {
|
|
70
137
|
const items = [];
|
|
@@ -75,7 +142,12 @@ class Asset extends MetadataType {
|
|
|
75
142
|
// each subtype contains multiple different specific types (images contains jpg and png for example)
|
|
76
143
|
// we use await here to limit the risk of too many concurrent api requests at time
|
|
77
144
|
items.push(
|
|
78
|
-
...(await this.requestSubType(
|
|
145
|
+
...(await this.requestSubType(
|
|
146
|
+
subType,
|
|
147
|
+
templateDir,
|
|
148
|
+
'name:' + name,
|
|
149
|
+
templateVariables
|
|
150
|
+
))
|
|
79
151
|
);
|
|
80
152
|
}
|
|
81
153
|
const metadata = this.parseResponseBody({ items: items });
|
|
@@ -90,7 +162,7 @@ class Asset extends MetadataType {
|
|
|
90
162
|
* helper for {@link Asset.retrieve} + {@link Asset.retrieveAsTemplate}
|
|
91
163
|
*
|
|
92
164
|
* @private
|
|
93
|
-
* @returns {
|
|
165
|
+
* @returns {string[]} AssetSubType array
|
|
94
166
|
*/
|
|
95
167
|
static _getSubTypes() {
|
|
96
168
|
const selectedSubTypeArr = this.properties.metaDataTypes.retrieve.filter((type) =>
|
|
@@ -112,7 +184,7 @@ class Asset extends MetadataType {
|
|
|
112
184
|
/**
|
|
113
185
|
* Creates a single asset
|
|
114
186
|
*
|
|
115
|
-
* @param {
|
|
187
|
+
* @param {AssetItem} metadata a single asset
|
|
116
188
|
* @returns {Promise} Promise
|
|
117
189
|
*/
|
|
118
190
|
static create(metadata) {
|
|
@@ -124,7 +196,7 @@ class Asset extends MetadataType {
|
|
|
124
196
|
/**
|
|
125
197
|
* Updates a single asset
|
|
126
198
|
*
|
|
127
|
-
* @param {
|
|
199
|
+
* @param {AssetItem} metadata a single asset
|
|
128
200
|
* @returns {Promise} Promise
|
|
129
201
|
*/
|
|
130
202
|
static update(metadata) {
|
|
@@ -134,25 +206,26 @@ class Asset extends MetadataType {
|
|
|
134
206
|
/**
|
|
135
207
|
* Retrieves Metadata of a specific asset type
|
|
136
208
|
*
|
|
137
|
-
* @param {
|
|
209
|
+
* @param {string} subType group of similar assets to put in a folder (ie. images)
|
|
138
210
|
* @param {string} [retrieveDir] target directory for saving assets
|
|
139
|
-
* @param {string} [
|
|
140
|
-
* @param {
|
|
141
|
-
* @param {
|
|
142
|
-
* @returns {Promise} Promise
|
|
211
|
+
* @param {string} [key] key/id/name to filter by
|
|
212
|
+
* @param {TemplateMap} [templateVariables] variables to be replaced in the metadata
|
|
213
|
+
* @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current
|
|
214
|
+
* @returns {Promise.<object[]>} Promise
|
|
143
215
|
*/
|
|
144
|
-
static async requestSubType(subType, retrieveDir,
|
|
216
|
+
static async requestSubType(subType, retrieveDir, key, templateVariables, loadShared = false) {
|
|
145
217
|
if (retrieveDir) {
|
|
146
218
|
Util.logger.info(`- Retrieving Subtype: ${subType}`);
|
|
147
219
|
} else {
|
|
148
220
|
Util.logger.info(` - Caching Subtype: ${subType}`);
|
|
149
221
|
}
|
|
150
|
-
/** @type {
|
|
222
|
+
/** @type {AssetSubType[]} */
|
|
151
223
|
const extendedSubTypeArr = this.definition.extendedSubTypes[subType];
|
|
152
224
|
const subtypeIds = extendedSubTypeArr?.map(
|
|
153
225
|
(subTypeItemName) => Asset.definition.typeMapping[subTypeItemName]
|
|
154
226
|
);
|
|
155
|
-
const uri = '/asset/v1/content/assets/query';
|
|
227
|
+
const uri = '/asset/v1/content/assets/query' + (loadShared ? '?scope=shared' : '');
|
|
228
|
+
/** @type {AssetRequestParams} */
|
|
156
229
|
const payload = {
|
|
157
230
|
page: {
|
|
158
231
|
page: 1,
|
|
@@ -162,7 +235,7 @@ class Asset extends MetadataType {
|
|
|
162
235
|
fields: ['category', 'createdDate', 'createdBy', 'modifiedDate', 'modifiedBy'], // get folder to allow duplicate name check against cache
|
|
163
236
|
};
|
|
164
237
|
|
|
165
|
-
if (
|
|
238
|
+
if (key) {
|
|
166
239
|
payload.query = {
|
|
167
240
|
leftOperand: {
|
|
168
241
|
property: 'assetType.id',
|
|
@@ -170,26 +243,26 @@ class Asset extends MetadataType {
|
|
|
170
243
|
value: subtypeIds,
|
|
171
244
|
},
|
|
172
245
|
logicalOperator: 'AND',
|
|
173
|
-
|
|
246
|
+
};
|
|
247
|
+
if (key.startsWith('id:')) {
|
|
248
|
+
payload.query.rightOperand = {
|
|
249
|
+
property: this.definition.idField,
|
|
250
|
+
simpleOperator: 'equal',
|
|
251
|
+
value: key.slice(3),
|
|
252
|
+
};
|
|
253
|
+
} else if (key.startsWith('name:')) {
|
|
254
|
+
payload.query.rightOperand = {
|
|
174
255
|
property: this.definition.nameField,
|
|
175
256
|
simpleOperator: 'equal',
|
|
176
|
-
value:
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
payload.query = {
|
|
181
|
-
leftOperand: {
|
|
182
|
-
property: 'assetType.id',
|
|
183
|
-
simpleOperator: 'in',
|
|
184
|
-
value: subtypeIds,
|
|
185
|
-
},
|
|
186
|
-
logicalOperator: 'AND',
|
|
187
|
-
rightOperand: {
|
|
257
|
+
value: key.slice(5),
|
|
258
|
+
};
|
|
259
|
+
} else {
|
|
260
|
+
payload.query.rightOperand = {
|
|
188
261
|
property: this.definition.keyField,
|
|
189
262
|
simpleOperator: 'equal',
|
|
190
263
|
value: key,
|
|
191
|
-
}
|
|
192
|
-
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
193
266
|
} else {
|
|
194
267
|
payload.query = {
|
|
195
268
|
property: 'assetType.id',
|
|
@@ -252,20 +325,21 @@ class Asset extends MetadataType {
|
|
|
252
325
|
} while (moreResults);
|
|
253
326
|
|
|
254
327
|
// only when we save results do we need the complete metadata or files. caching can skip these
|
|
255
|
-
if (retrieveDir
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
item[this.definition.
|
|
261
|
-
|
|
262
|
-
|
|
328
|
+
if (retrieveDir) {
|
|
329
|
+
if (items.length > 0) {
|
|
330
|
+
for (const item of items) {
|
|
331
|
+
if (item.customerKey.trim() !== item.customerKey) {
|
|
332
|
+
Util.logger.warn(
|
|
333
|
+
` - ${this.definition.type} ${item[this.definition.nameField]} (${
|
|
334
|
+
item[this.definition.keyField]
|
|
335
|
+
}) has leading or trailing spaces in customerKey. Please remove them in SFMC.`
|
|
336
|
+
);
|
|
337
|
+
}
|
|
263
338
|
}
|
|
339
|
+
// we have to wait on execution or it potentially causes memory reference issues when changing between BUs
|
|
340
|
+
await this.requestAndSaveExtended(items, subType, retrieveDir, templateVariables);
|
|
264
341
|
}
|
|
265
|
-
//
|
|
266
|
-
await this.requestAndSaveExtended(items, subType, retrieveDir, templateVariables);
|
|
267
|
-
Util.logger.debug(`Downloaded asset-${subType}: ${items.length}`);
|
|
268
|
-
} else if (retrieveDir && !items.length) {
|
|
342
|
+
// always show the summary even if we already had the progress bar in the console
|
|
269
343
|
Util.logger.info(` Downloaded asset-${subType}: ${items.length}`);
|
|
270
344
|
}
|
|
271
345
|
|
|
@@ -278,10 +352,10 @@ class Asset extends MetadataType {
|
|
|
278
352
|
* Retrieves extended metadata (files or extended content) of asset
|
|
279
353
|
*
|
|
280
354
|
* @param {Array} items array of items to retrieve
|
|
281
|
-
* @param {
|
|
355
|
+
* @param {string} subType group of similar assets to put in a folder (ie. images)
|
|
282
356
|
* @param {string} retrieveDir target directory for saving assets
|
|
283
|
-
* @param {
|
|
284
|
-
* @returns {Promise} Promise
|
|
357
|
+
* @param {TemplateMap} [templateVariables] variables to be replaced in the metadata
|
|
358
|
+
* @returns {Promise.<MetadataTypeMap>} Promise
|
|
285
359
|
*/
|
|
286
360
|
static async requestAndSaveExtended(items, subType, retrieveDir, templateVariables) {
|
|
287
361
|
// disable CLI logs other than error while retrieving subtype
|
|
@@ -293,7 +367,7 @@ class Asset extends MetadataType {
|
|
|
293
367
|
const extendedBar = new cliProgress.SingleBar(
|
|
294
368
|
{
|
|
295
369
|
format:
|
|
296
|
-
'
|
|
370
|
+
' Downloading [{bar}] {percentage}% | {value}/{total} | asset-' +
|
|
297
371
|
subType,
|
|
298
372
|
},
|
|
299
373
|
cliProgress.Presets.shades_classic
|
|
@@ -301,6 +375,8 @@ class Asset extends MetadataType {
|
|
|
301
375
|
|
|
302
376
|
const completed = [];
|
|
303
377
|
const failed = [];
|
|
378
|
+
const metadataMap = {};
|
|
379
|
+
|
|
304
380
|
// put in do loop to manage issues with connection timeout
|
|
305
381
|
do {
|
|
306
382
|
// use promise execution limiting to avoid rate limits on api, but speed up execution
|
|
@@ -310,9 +386,8 @@ class Asset extends MetadataType {
|
|
|
310
386
|
const rateLimit = pLimit(5);
|
|
311
387
|
|
|
312
388
|
const promiseMap = await Promise.all(
|
|
313
|
-
items.map((item) =>
|
|
389
|
+
items.map((item, index) =>
|
|
314
390
|
rateLimit(async () => {
|
|
315
|
-
const metadata = {};
|
|
316
391
|
// this is a file so extended is at another endpoint
|
|
317
392
|
if (item?.fileProperties?.extension && !completed.includes(item.id)) {
|
|
318
393
|
try {
|
|
@@ -322,7 +397,7 @@ class Asset extends MetadataType {
|
|
|
322
397
|
failed.push({ item: item, error: ex });
|
|
323
398
|
}
|
|
324
399
|
// even if the extended file failed, still save the metadata
|
|
325
|
-
|
|
400
|
+
metadataMap[item.customerKey] = item;
|
|
326
401
|
}
|
|
327
402
|
// this is a complex type which stores data in the asset itself
|
|
328
403
|
else if (!completed.includes(item.id)) {
|
|
@@ -331,15 +406,17 @@ class Asset extends MetadataType {
|
|
|
331
406
|
'asset/v1/content/assets/' + item.id
|
|
332
407
|
);
|
|
333
408
|
// only save the metadata if we have extended content
|
|
334
|
-
|
|
409
|
+
metadataMap[item.customerKey] = extendedItem;
|
|
410
|
+
// overwrite the original item with the extended content to ensure retrieve() returns it
|
|
411
|
+
items[index] = extendedItem;
|
|
335
412
|
} catch (ex) {
|
|
336
413
|
failed.push({ item: item, error: ex });
|
|
337
414
|
}
|
|
338
415
|
}
|
|
339
416
|
completed.push(item.id);
|
|
340
|
-
if (
|
|
417
|
+
if (metadataMap[item.customerKey]) {
|
|
341
418
|
await this.saveResults(
|
|
342
|
-
|
|
419
|
+
metadataMap,
|
|
343
420
|
retrieveDir,
|
|
344
421
|
'asset-' + subType,
|
|
345
422
|
templateVariables
|
|
@@ -364,6 +441,7 @@ class Asset extends MetadataType {
|
|
|
364
441
|
}
|
|
365
442
|
}
|
|
366
443
|
} while (completed.length === items.length);
|
|
444
|
+
return metadataMap;
|
|
367
445
|
}
|
|
368
446
|
|
|
369
447
|
/**
|
|
@@ -375,28 +453,26 @@ class Asset extends MetadataType {
|
|
|
375
453
|
*/
|
|
376
454
|
static _resetLogLevel(loggerLevelBak, failed) {
|
|
377
455
|
// re-enable CLI logs
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
obj = { silent: true };
|
|
396
|
-
}
|
|
456
|
+
// reset logging level
|
|
457
|
+
let obj;
|
|
458
|
+
switch (loggerLevelBak) {
|
|
459
|
+
case 'info': {
|
|
460
|
+
obj = {};
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
case 'verbose': {
|
|
464
|
+
obj = { verbose: true };
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
case 'debug': {
|
|
468
|
+
obj = { debug: true };
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
case 'error': {
|
|
472
|
+
obj = { silent: true };
|
|
397
473
|
}
|
|
398
|
-
Util.setLoggingLevel(obj);
|
|
399
474
|
}
|
|
475
|
+
Util.setLoggingLevel(obj);
|
|
400
476
|
|
|
401
477
|
if (failed.length) {
|
|
402
478
|
Util.logger.warn(
|
|
@@ -428,8 +504,8 @@ class Asset extends MetadataType {
|
|
|
428
504
|
* Some metadata types store their actual content as a separate file, e.g. images
|
|
429
505
|
* This method retrieves these and saves them alongside the metadata json
|
|
430
506
|
*
|
|
431
|
-
* @param {
|
|
432
|
-
* @param {
|
|
507
|
+
* @param {AssetItem} metadata a single asset
|
|
508
|
+
* @param {string} subType group of similar assets to put in a folder (ie. images)
|
|
433
509
|
* @param {string} retrieveDir target directory for saving assets
|
|
434
510
|
* @returns {Promise.<void>} -
|
|
435
511
|
*/
|
|
@@ -453,8 +529,8 @@ class Asset extends MetadataType {
|
|
|
453
529
|
* Some metadata types store their actual content as a separate file, e.g. images
|
|
454
530
|
* This method reads these from the local FS stores them in the metadata object allowing to deploy it
|
|
455
531
|
*
|
|
456
|
-
* @param {
|
|
457
|
-
* @param {
|
|
532
|
+
* @param {AssetItem} metadata a single asset
|
|
533
|
+
* @param {string} subType group of similar assets to put in a folder (ie. images)
|
|
458
534
|
* @param {string} deployDir directory of deploy files
|
|
459
535
|
* @param {boolean} [pathOnly] used by getFilesToCommit which does not need the binary file to be actually read
|
|
460
536
|
* @returns {Promise.<string>} if found will return the path of the binary file
|
|
@@ -488,22 +564,49 @@ class Asset extends MetadataType {
|
|
|
488
564
|
/**
|
|
489
565
|
* manages post retrieve steps
|
|
490
566
|
*
|
|
491
|
-
* @param {
|
|
492
|
-
* @returns {
|
|
567
|
+
* @param {AssetItem} metadata a single asset
|
|
568
|
+
* @returns {CodeExtractItem} metadata
|
|
493
569
|
*/
|
|
494
570
|
static postRetrieveTasks(metadata) {
|
|
495
571
|
// folder
|
|
496
572
|
this.setFolderPath(metadata);
|
|
573
|
+
|
|
574
|
+
// template-based emails
|
|
575
|
+
if (metadata.assetType.name === 'templatebasedemail') {
|
|
576
|
+
// get template
|
|
577
|
+
try {
|
|
578
|
+
if (metadata.views?.html?.template?.id) {
|
|
579
|
+
metadata.views.html.template.r__asset_key = cache.searchForField(
|
|
580
|
+
'asset',
|
|
581
|
+
metadata.views?.html?.template?.id,
|
|
582
|
+
'id',
|
|
583
|
+
'customerKey'
|
|
584
|
+
);
|
|
585
|
+
delete metadata.views.html.template.id;
|
|
586
|
+
delete metadata.views.html.template.name;
|
|
587
|
+
delete metadata.views.html.template.assetType;
|
|
588
|
+
delete metadata.views.html.template.availableViews;
|
|
589
|
+
delete metadata.views.html.template.data;
|
|
590
|
+
delete metadata.views.html.template.modelVersion;
|
|
591
|
+
}
|
|
592
|
+
} catch {
|
|
593
|
+
Util.logger.warn(
|
|
594
|
+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
|
|
595
|
+
metadata[this.definition.keyField]
|
|
596
|
+
}): Could not find email template with id (${metadata.views.html.template.id})`
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
497
601
|
// extract HTML for selected subtypes and convert payload for easier processing in MetadataType.saveResults()
|
|
498
|
-
|
|
499
|
-
return metadata;
|
|
602
|
+
return this._extractCode(metadata);
|
|
500
603
|
}
|
|
501
604
|
|
|
502
605
|
/**
|
|
503
606
|
* Gets executed after deployment of metadata type
|
|
504
607
|
*
|
|
505
|
-
* @param {
|
|
506
|
-
* @param {
|
|
608
|
+
* @param {MetadataTypeMap} metadata metadata mapped by their keyField
|
|
609
|
+
* @param {MetadataTypeMap} _ originalMetadata to be updated (contains additioanl fields)
|
|
507
610
|
* @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates
|
|
508
611
|
* @returns {Promise.<void>} -
|
|
509
612
|
*/
|
|
@@ -524,7 +627,7 @@ class Asset extends MetadataType {
|
|
|
524
627
|
* helper for {@link Asset.postDeployTasks}. triggers a refresh of active triggerredSendDefinitions associated with the updated asset-message items. Gets executed if refresh option has been set.
|
|
525
628
|
*
|
|
526
629
|
* @private
|
|
527
|
-
* @param {
|
|
630
|
+
* @param {MetadataTypeMap} metadata metadata mapped by their keyField
|
|
528
631
|
* @returns {Promise.<void>} -
|
|
529
632
|
*/
|
|
530
633
|
static async _refreshTriggeredSend(metadata) {
|
|
@@ -572,9 +675,9 @@ class Asset extends MetadataType {
|
|
|
572
675
|
/**
|
|
573
676
|
* prepares an asset definition for deployment
|
|
574
677
|
*
|
|
575
|
-
* @param {
|
|
678
|
+
* @param {AssetItem} metadata a single asset
|
|
576
679
|
* @param {string} deployDir directory of deploy files
|
|
577
|
-
* @returns {Promise.<
|
|
680
|
+
* @returns {Promise.<AssetItem>} Promise
|
|
578
681
|
*/
|
|
579
682
|
static async preDeployTasks(metadata, deployDir) {
|
|
580
683
|
// additonalattributes fail where the value is "" so we need to remove them from deploy
|
|
@@ -587,6 +690,39 @@ class Asset extends MetadataType {
|
|
|
587
690
|
// folder
|
|
588
691
|
this.setFolderId(metadata);
|
|
589
692
|
|
|
693
|
+
// template-based emails
|
|
694
|
+
if (
|
|
695
|
+
metadata.assetType.name === 'templatebasedemail' &&
|
|
696
|
+
metadata.views?.html?.template?.r__asset_key
|
|
697
|
+
) {
|
|
698
|
+
// template
|
|
699
|
+
metadata.views.html.template.id = cache.searchForField(
|
|
700
|
+
'asset',
|
|
701
|
+
metadata.views.html.template.r__asset_key,
|
|
702
|
+
'customerKey',
|
|
703
|
+
'id'
|
|
704
|
+
);
|
|
705
|
+
metadata.views.html.template.name = cache.searchForField(
|
|
706
|
+
'asset',
|
|
707
|
+
metadata.views.html.template.r__asset_key,
|
|
708
|
+
'customerKey',
|
|
709
|
+
'name'
|
|
710
|
+
);
|
|
711
|
+
metadata.views.html.template.assetType = {
|
|
712
|
+
id: 4,
|
|
713
|
+
name: 'template',
|
|
714
|
+
displayName: 'Template',
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
metadata.views.html.template.data = {
|
|
718
|
+
email: { options: { generateFrom: null } },
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
metadata.views.html.template.availableViews = [];
|
|
722
|
+
metadata.views.html.template.modelVersion = 2;
|
|
723
|
+
delete metadata.views.html.template.r__asset_key;
|
|
724
|
+
}
|
|
725
|
+
|
|
590
726
|
// restore asset type id which is needed for deploy
|
|
591
727
|
metadata.assetType.id = this.definition.typeMapping[metadata.assetType.name];
|
|
592
728
|
|
|
@@ -601,8 +737,9 @@ class Asset extends MetadataType {
|
|
|
601
737
|
|
|
602
738
|
// only execute #3 if we are deploying / copying from one BU to another, not while using mcdev as a developer tool
|
|
603
739
|
if (
|
|
740
|
+
!Util.OPTIONS.noMidSuffix &&
|
|
604
741
|
this.buObject.mid &&
|
|
605
|
-
metadata.memberId
|
|
742
|
+
metadata.memberId != this.buObject.mid && // soft comparison to accomodate for string-version of mid
|
|
606
743
|
!metadata[this.definition.keyField].endsWith(this.buObject.mid)
|
|
607
744
|
) {
|
|
608
745
|
// #3 make sure customer key is unique by suffixing it with target MID (unless we are deploying to the same MID)
|
|
@@ -618,7 +755,7 @@ class Asset extends MetadataType {
|
|
|
618
755
|
const namesInFolder = Object.keys(assetCache)
|
|
619
756
|
.filter((key) => assetCache[key].category.id === metadata.category.id)
|
|
620
757
|
.map((key) => ({
|
|
621
|
-
type: this
|
|
758
|
+
type: this.#getMainSubtype(assetCache[key].assetType.name),
|
|
622
759
|
key: key,
|
|
623
760
|
name: assetCache[key].name,
|
|
624
761
|
}));
|
|
@@ -626,7 +763,7 @@ class Asset extends MetadataType {
|
|
|
626
763
|
metadata[this.definition.nameField] = this._findUniqueName(
|
|
627
764
|
metadata[this.definition.keyField],
|
|
628
765
|
metadata[this.definition.nameField],
|
|
629
|
-
this
|
|
766
|
+
this.#getMainSubtype(metadata.assetType.name),
|
|
630
767
|
namesInFolder
|
|
631
768
|
);
|
|
632
769
|
return metadata;
|
|
@@ -637,7 +774,7 @@ class Asset extends MetadataType {
|
|
|
637
774
|
* @param {string} extendedSubType webpage, htmlblock, etc
|
|
638
775
|
* @returns {string} subType: block, message, other, etc
|
|
639
776
|
*/
|
|
640
|
-
static
|
|
777
|
+
static #getMainSubtype(extendedSubType) {
|
|
641
778
|
return Object.keys(this.definition.extendedSubTypes).find((subType) =>
|
|
642
779
|
this.definition.extendedSubTypes[subType].includes(extendedSubType)
|
|
643
780
|
);
|
|
@@ -649,7 +786,7 @@ class Asset extends MetadataType {
|
|
|
649
786
|
* @param {string} key key of the asset
|
|
650
787
|
* @param {string} name name of the asset
|
|
651
788
|
* @param {string} type assetType-name
|
|
652
|
-
* @param {string[]} namesInFolder names of the assets in the same folder
|
|
789
|
+
* @param {{ type: string; key: string; name: any; }[]} namesInFolder names of the assets in the same folder
|
|
653
790
|
* @returns {string} new name
|
|
654
791
|
*/
|
|
655
792
|
static _findUniqueName(key, name, type, namesInFolder) {
|
|
@@ -672,8 +809,8 @@ class Asset extends MetadataType {
|
|
|
672
809
|
* determines the subtype of the current asset
|
|
673
810
|
*
|
|
674
811
|
* @private
|
|
675
|
-
* @param {
|
|
676
|
-
* @returns {
|
|
812
|
+
* @param {AssetItem} metadata a single asset
|
|
813
|
+
* @returns {string} subtype
|
|
677
814
|
*/
|
|
678
815
|
static _getSubtype(metadata) {
|
|
679
816
|
for (const sub in this.definition.extendedSubTypes) {
|
|
@@ -681,6 +818,7 @@ class Asset extends MetadataType {
|
|
|
681
818
|
return sub;
|
|
682
819
|
}
|
|
683
820
|
}
|
|
821
|
+
return;
|
|
684
822
|
}
|
|
685
823
|
/**
|
|
686
824
|
* helper for {@link MetadataType.buildDefinition}
|
|
@@ -688,10 +826,10 @@ class Asset extends MetadataType {
|
|
|
688
826
|
*
|
|
689
827
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
690
828
|
* @param {string} targetDir Directory where built definitions will be saved
|
|
691
|
-
* @param {
|
|
692
|
-
* @param {
|
|
829
|
+
* @param {AssetItem} metadata main JSON file that was read from file system
|
|
830
|
+
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
693
831
|
* @param {string} templateName name of the template to be built
|
|
694
|
-
* @returns {Promise.<
|
|
832
|
+
* @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array
|
|
695
833
|
*/
|
|
696
834
|
static buildDefinitionForNested(
|
|
697
835
|
templateDir,
|
|
@@ -716,10 +854,10 @@ class Asset extends MetadataType {
|
|
|
716
854
|
* @example assets of type codesnippetblock will result in 1 json and 1 amp/html file. both files need to be run through templating
|
|
717
855
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
718
856
|
* @param {string|string[]} targetDir (List of) Directory where built definitions will be saved
|
|
719
|
-
* @param {
|
|
720
|
-
* @param {
|
|
857
|
+
* @param {AssetItem} metadata main JSON file that was read from file system
|
|
858
|
+
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
721
859
|
* @param {string} templateName name of the template to be built
|
|
722
|
-
* @returns {Promise.<
|
|
860
|
+
* @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array
|
|
723
861
|
*/
|
|
724
862
|
static buildTemplateForNested(
|
|
725
863
|
templateDir,
|
|
@@ -743,12 +881,12 @@ class Asset extends MetadataType {
|
|
|
743
881
|
* handles extracted code if any are found for complex types
|
|
744
882
|
*
|
|
745
883
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
746
|
-
* @param {string} targetDir Directory where built definitions will be saved
|
|
747
|
-
* @param {
|
|
748
|
-
* @param {
|
|
884
|
+
* @param {string|string[]} targetDir (List of) Directory where built definitions will be saved
|
|
885
|
+
* @param {AssetItem} metadata main JSON file that was read from file system
|
|
886
|
+
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
749
887
|
* @param {string} templateName name of the template to be built
|
|
750
888
|
* @param {'definition'|'template'} mode defines what we use this helper for
|
|
751
|
-
* @returns {Promise.<
|
|
889
|
+
* @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array
|
|
752
890
|
*/
|
|
753
891
|
static async _buildForNested(
|
|
754
892
|
templateDir,
|
|
@@ -759,7 +897,7 @@ class Asset extends MetadataType {
|
|
|
759
897
|
mode
|
|
760
898
|
) {
|
|
761
899
|
// * because asset's _mergeCode() is overwriting 'metadata', clone it to ensure the main file is not modified by what we do in here
|
|
762
|
-
metadata =
|
|
900
|
+
metadata = structuredClone(metadata);
|
|
763
901
|
|
|
764
902
|
// #1 text extracts
|
|
765
903
|
// define asset's subtype
|
|
@@ -789,6 +927,9 @@ class Asset extends MetadataType {
|
|
|
789
927
|
}: ${extractedFile.fileName}.${extractedFile.fileExt}.`
|
|
790
928
|
);
|
|
791
929
|
}
|
|
930
|
+
extractedFile.subFolder = extractedFile.subFolder
|
|
931
|
+
.map((el) => (el === templateName ? metadata[this.definition.keyField] : el))
|
|
932
|
+
.map((el) => this.applyTemplateValues(el, templateVariables));
|
|
792
933
|
}
|
|
793
934
|
|
|
794
935
|
// #2 binary extracts
|
|
@@ -816,6 +957,7 @@ class Asset extends MetadataType {
|
|
|
816
957
|
encoding: 'base64',
|
|
817
958
|
});
|
|
818
959
|
}
|
|
960
|
+
const nestedFilePaths = [];
|
|
819
961
|
|
|
820
962
|
// write to file (#1 + #2)
|
|
821
963
|
const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir];
|
|
@@ -828,13 +970,22 @@ class Asset extends MetadataType {
|
|
|
828
970
|
extractedFile.content,
|
|
829
971
|
extractedFile.encoding || null
|
|
830
972
|
);
|
|
973
|
+
nestedFilePaths.push([
|
|
974
|
+
File.normalizePath([targetDir, ...extractedFile.subFolder]),
|
|
975
|
+
extractedFile.fileName +
|
|
976
|
+
'.' +
|
|
977
|
+
this.definition.type +
|
|
978
|
+
'-meta.' +
|
|
979
|
+
extractedFile.fileExt,
|
|
980
|
+
]);
|
|
831
981
|
}
|
|
832
982
|
}
|
|
983
|
+
return nestedFilePaths;
|
|
833
984
|
}
|
|
834
985
|
/**
|
|
835
986
|
* generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
|
|
836
987
|
*
|
|
837
|
-
* @param {
|
|
988
|
+
* @param {MetadataTypeItem} metadata a single script activity definition
|
|
838
989
|
*/
|
|
839
990
|
static setFolderPath(metadata) {
|
|
840
991
|
try {
|
|
@@ -856,7 +1007,7 @@ class Asset extends MetadataType {
|
|
|
856
1007
|
/**
|
|
857
1008
|
* Asset-specific script that retrieves the folder ID from cache and updates the given metadata with it before deploy
|
|
858
1009
|
*
|
|
859
|
-
* @param {
|
|
1010
|
+
* @param {MetadataTypeItem} metadata a single item
|
|
860
1011
|
*/
|
|
861
1012
|
static setFolderId(metadata) {
|
|
862
1013
|
metadata.category = {
|
|
@@ -868,12 +1019,12 @@ class Asset extends MetadataType {
|
|
|
868
1019
|
/**
|
|
869
1020
|
* helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON
|
|
870
1021
|
*
|
|
871
|
-
* @param {
|
|
1022
|
+
* @param {AssetItem} metadata a single asset definition
|
|
872
1023
|
* @param {string} deployDir directory of deploy files
|
|
873
|
-
* @param {
|
|
1024
|
+
* @param {string} subType asset-subtype name; full list in AssetSubType
|
|
874
1025
|
* @param {string} [templateName] name of the template used to built defintion (prior applying templating)
|
|
875
1026
|
* @param {boolean} [fileListOnly] does not read file contents nor update metadata if true
|
|
876
|
-
* @returns {Promise.<
|
|
1027
|
+
* @returns {Promise.<CodeExtract[]>} fileList for templating (disregarded during deployment)
|
|
877
1028
|
*/
|
|
878
1029
|
static async _mergeCode(metadata, deployDir, subType, templateName, fileListOnly = false) {
|
|
879
1030
|
const subtypeExtension = `.${this.definition.type}-${subType}-meta`;
|
|
@@ -882,13 +1033,14 @@ class Asset extends MetadataType {
|
|
|
882
1033
|
let readDirArr;
|
|
883
1034
|
// unfortunately, asset's key can contain spaces at beginning/end which can break the file system when folders are created with it
|
|
884
1035
|
const customerKey = metadata.customerKey.trim();
|
|
1036
|
+
const templateFileName = templateName || customerKey;
|
|
885
1037
|
switch (metadata.assetType.name) {
|
|
886
1038
|
case 'templatebasedemail': // message
|
|
887
1039
|
case 'htmlemail': {
|
|
888
1040
|
// message
|
|
889
1041
|
// this complex type always creates its own subdir per asset
|
|
890
1042
|
subDirArr = [this.definition.type, subType];
|
|
891
|
-
readDirArr = [deployDir, ...subDirArr,
|
|
1043
|
+
readDirArr = [deployDir, ...subDirArr, templateFileName];
|
|
892
1044
|
|
|
893
1045
|
// metadata.views.html.content (mandatory)
|
|
894
1046
|
// the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs
|
|
@@ -910,13 +1062,78 @@ class Asset extends MetadataType {
|
|
|
910
1062
|
if (templateName) {
|
|
911
1063
|
// to use this method in templating, store a copy of the info in fileList
|
|
912
1064
|
fileList.push({
|
|
913
|
-
subFolder: [...subDirArr,
|
|
1065
|
+
subFolder: [...subDirArr, templateFileName],
|
|
914
1066
|
fileName: fileName,
|
|
915
1067
|
fileExt: 'html',
|
|
916
1068
|
content: metadata.views.html.content,
|
|
917
1069
|
});
|
|
918
1070
|
}
|
|
919
1071
|
}
|
|
1072
|
+
// metadata.views.html.content (optional)
|
|
1073
|
+
// the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs
|
|
1074
|
+
const fileNamePreheader = 'views.preheader.content' + subtypeExtension;
|
|
1075
|
+
if (
|
|
1076
|
+
(await File.pathExists(
|
|
1077
|
+
File.normalizePath([...readDirArr, `${fileNamePreheader}.amp`])
|
|
1078
|
+
)) &&
|
|
1079
|
+
metadata.views.preheader
|
|
1080
|
+
) {
|
|
1081
|
+
if (!fileListOnly) {
|
|
1082
|
+
metadata.views.preheader.content = await File.readFilteredFilename(
|
|
1083
|
+
readDirArr,
|
|
1084
|
+
fileNamePreheader,
|
|
1085
|
+
'amp'
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
if (templateName) {
|
|
1090
|
+
// to use this method in templating, store a copy of the info in fileList
|
|
1091
|
+
fileList.push({
|
|
1092
|
+
subFolder: [...subDirArr, templateFileName],
|
|
1093
|
+
fileName: fileNamePreheader,
|
|
1094
|
+
fileExt: 'amp',
|
|
1095
|
+
content: metadata.views.preheader.content,
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// metadata.views.text.content (optional)
|
|
1101
|
+
// the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs
|
|
1102
|
+
const fileNameText = 'views.text.content' + subtypeExtension;
|
|
1103
|
+
if (
|
|
1104
|
+
(await File.pathExists(
|
|
1105
|
+
File.normalizePath([...readDirArr, `${fileNameText}.amp`])
|
|
1106
|
+
)) &&
|
|
1107
|
+
metadata.views.text
|
|
1108
|
+
) {
|
|
1109
|
+
if (!fileListOnly) {
|
|
1110
|
+
metadata.views.text.content = await File.readFilteredFilename(
|
|
1111
|
+
readDirArr,
|
|
1112
|
+
fileNameText,
|
|
1113
|
+
'amp'
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
if (templateName) {
|
|
1118
|
+
// to use this method in templating, store a copy of the info in fileList
|
|
1119
|
+
fileList.push({
|
|
1120
|
+
subFolder: [...subDirArr, templateFileName],
|
|
1121
|
+
fileName: fileNameText,
|
|
1122
|
+
fileExt: 'amp',
|
|
1123
|
+
content: metadata.views.text.content,
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
} else if (metadata.views.text) {
|
|
1127
|
+
// ensure the text version gets generated from html
|
|
1128
|
+
metadata.views.text.data = {
|
|
1129
|
+
email: {
|
|
1130
|
+
options: {
|
|
1131
|
+
generateFrom: 'html',
|
|
1132
|
+
},
|
|
1133
|
+
},
|
|
1134
|
+
};
|
|
1135
|
+
metadata.views.text.generateFrom = 'html';
|
|
1136
|
+
}
|
|
920
1137
|
|
|
921
1138
|
// metadata.views.html.slots.<>.blocks.<>.content (optional)
|
|
922
1139
|
if (metadata?.views?.html?.slots) {
|
|
@@ -938,7 +1155,7 @@ class Asset extends MetadataType {
|
|
|
938
1155
|
// template-template
|
|
939
1156
|
// this complex type always creates its own subdir per asset
|
|
940
1157
|
subDirArr = [this.definition.type, subType];
|
|
941
|
-
readDirArr = [deployDir, ...subDirArr,
|
|
1158
|
+
readDirArr = [deployDir, ...subDirArr, templateFileName];
|
|
942
1159
|
const fileName = 'content' + subtypeExtension;
|
|
943
1160
|
|
|
944
1161
|
const fileExtArr = ['html']; // eslint-disable-line no-case-declarations
|
|
@@ -959,7 +1176,7 @@ class Asset extends MetadataType {
|
|
|
959
1176
|
if (templateName) {
|
|
960
1177
|
// to use this method in templating, store a copy of the info in fileList
|
|
961
1178
|
fileList.push({
|
|
962
|
-
subFolder: subDirArr,
|
|
1179
|
+
subFolder: [...subDirArr, templateFileName],
|
|
963
1180
|
fileName: fileName,
|
|
964
1181
|
fileExt: ext,
|
|
965
1182
|
content: metadata.content,
|
|
@@ -996,7 +1213,7 @@ class Asset extends MetadataType {
|
|
|
996
1213
|
await File.pathExists(
|
|
997
1214
|
File.normalizePath([
|
|
998
1215
|
...readDirArr,
|
|
999
|
-
`${
|
|
1216
|
+
`${templateFileName}${subtypeExtension}.amp`,
|
|
1000
1217
|
])
|
|
1001
1218
|
)
|
|
1002
1219
|
) {
|
|
@@ -1004,16 +1221,16 @@ class Asset extends MetadataType {
|
|
|
1004
1221
|
if (!fileListOnly) {
|
|
1005
1222
|
metadata.views.text.content = await File.readFilteredFilename(
|
|
1006
1223
|
readDirArr,
|
|
1007
|
-
|
|
1008
|
-
'
|
|
1224
|
+
templateFileName + subtypeExtension,
|
|
1225
|
+
'amp'
|
|
1009
1226
|
);
|
|
1010
1227
|
}
|
|
1011
1228
|
if (templateName) {
|
|
1012
1229
|
// to use this method in templating, store a copy of the info in fileList
|
|
1013
1230
|
fileList.push({
|
|
1014
1231
|
subFolder: subDirArr,
|
|
1015
|
-
fileName:
|
|
1016
|
-
fileExt: '
|
|
1232
|
+
fileName: templateFileName + subtypeExtension,
|
|
1233
|
+
fileExt: 'amp',
|
|
1017
1234
|
content: metadata.views.text.content,
|
|
1018
1235
|
});
|
|
1019
1236
|
}
|
|
@@ -1024,7 +1241,7 @@ class Asset extends MetadataType {
|
|
|
1024
1241
|
// asset
|
|
1025
1242
|
// this complex type always creates its own subdir per asset
|
|
1026
1243
|
subDirArr = [this.definition.type, subType];
|
|
1027
|
-
readDirArr = [deployDir, ...subDirArr,
|
|
1244
|
+
readDirArr = [deployDir, ...subDirArr, templateFileName];
|
|
1028
1245
|
|
|
1029
1246
|
// metadata.views.html.slots.<>.blocks.<>.content (optional) (pre & post 20222)
|
|
1030
1247
|
if (metadata?.views?.html?.slots) {
|
|
@@ -1062,7 +1279,7 @@ class Asset extends MetadataType {
|
|
|
1062
1279
|
if (templateName) {
|
|
1063
1280
|
// to use this method in templating, store a copy of the info in fileList
|
|
1064
1281
|
fileList.push({
|
|
1065
|
-
subFolder: [...subDirArr,
|
|
1282
|
+
subFolder: [...subDirArr, templateFileName],
|
|
1066
1283
|
fileName: 'views.html.content' + subtypeExtension,
|
|
1067
1284
|
fileExt: 'html',
|
|
1068
1285
|
content: metadata.views.html.content,
|
|
@@ -1088,7 +1305,7 @@ class Asset extends MetadataType {
|
|
|
1088
1305
|
if (templateName) {
|
|
1089
1306
|
// to use this method in templating, store a copy of the info in fileList
|
|
1090
1307
|
fileList.push({
|
|
1091
|
-
subFolder: [...subDirArr,
|
|
1308
|
+
subFolder: [...subDirArr, templateFileName],
|
|
1092
1309
|
fileName: 'content' + subtypeExtension,
|
|
1093
1310
|
fileExt: 'html',
|
|
1094
1311
|
content: metadata.views.html.content,
|
|
@@ -1116,7 +1333,7 @@ class Asset extends MetadataType {
|
|
|
1116
1333
|
await File.pathExists(
|
|
1117
1334
|
File.normalizePath([
|
|
1118
1335
|
...readDirArr,
|
|
1119
|
-
`${
|
|
1336
|
+
`${templateFileName}${subtypeExtension}.${ext}`,
|
|
1120
1337
|
])
|
|
1121
1338
|
)
|
|
1122
1339
|
) {
|
|
@@ -1124,7 +1341,7 @@ class Asset extends MetadataType {
|
|
|
1124
1341
|
if (!fileListOnly) {
|
|
1125
1342
|
metadata.content = await File.readFilteredFilename(
|
|
1126
1343
|
readDirArr,
|
|
1127
|
-
|
|
1344
|
+
templateFileName + subtypeExtension,
|
|
1128
1345
|
ext
|
|
1129
1346
|
);
|
|
1130
1347
|
if (ext === 'ssjs') {
|
|
@@ -1135,7 +1352,7 @@ class Asset extends MetadataType {
|
|
|
1135
1352
|
// to use this method in templating, store a copy of the info in fileList
|
|
1136
1353
|
fileList.push({
|
|
1137
1354
|
subFolder: subDirArr,
|
|
1138
|
-
fileName:
|
|
1355
|
+
fileName: templateFileName + subtypeExtension,
|
|
1139
1356
|
fileExt: ext,
|
|
1140
1357
|
content: metadata.content,
|
|
1141
1358
|
});
|
|
@@ -1174,6 +1391,8 @@ class Asset extends MetadataType {
|
|
|
1174
1391
|
templateName,
|
|
1175
1392
|
fileListOnly = false
|
|
1176
1393
|
) {
|
|
1394
|
+
const templateFileName = templateName || customerKey;
|
|
1395
|
+
|
|
1177
1396
|
for (const slot in metadataSlots) {
|
|
1178
1397
|
if (Object.prototype.hasOwnProperty.call(metadataSlots, slot)) {
|
|
1179
1398
|
const slotObj = metadataSlots[slot];
|
|
@@ -1203,7 +1422,7 @@ class Asset extends MetadataType {
|
|
|
1203
1422
|
if (templateName) {
|
|
1204
1423
|
// to use this method in templating, store a copy of the info in fileList
|
|
1205
1424
|
fileList.push({
|
|
1206
|
-
subFolder: [...subDirArr,
|
|
1425
|
+
subFolder: [...subDirArr, templateFileName, 'blocks'],
|
|
1207
1426
|
fileName: fileName,
|
|
1208
1427
|
fileExt: 'html',
|
|
1209
1428
|
content: slotObj.blocks[block].content,
|
|
@@ -1233,8 +1452,8 @@ class Asset extends MetadataType {
|
|
|
1233
1452
|
* helper for {@link Asset.postRetrieveTasks} that finds code content in JSON and extracts it
|
|
1234
1453
|
* to allow saving that separately and formatted
|
|
1235
1454
|
*
|
|
1236
|
-
* @param {
|
|
1237
|
-
* @returns {
|
|
1455
|
+
* @param {AssetItem} metadata a single asset definition
|
|
1456
|
+
* @returns {CodeExtractItem} { json: metadata, codeArr: object[], subFolder: string[] }
|
|
1238
1457
|
*/
|
|
1239
1458
|
static _extractCode(metadata) {
|
|
1240
1459
|
const codeArr = [];
|
|
@@ -1255,6 +1474,27 @@ class Asset extends MetadataType {
|
|
|
1255
1474
|
});
|
|
1256
1475
|
delete metadata.views.html.content;
|
|
1257
1476
|
}
|
|
1477
|
+
// metadata.views.preheader.content (optional)
|
|
1478
|
+
if (metadata.views?.preheader?.content?.length) {
|
|
1479
|
+
codeArr.push({
|
|
1480
|
+
subFolder: null,
|
|
1481
|
+
fileName: 'views.preheader.content',
|
|
1482
|
+
fileExt: 'amp',
|
|
1483
|
+
content: metadata.views.preheader.content,
|
|
1484
|
+
});
|
|
1485
|
+
delete metadata.views.preheader.content;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// metadata.views.text.content (optional)
|
|
1489
|
+
if (metadata.views?.text?.content?.length) {
|
|
1490
|
+
codeArr.push({
|
|
1491
|
+
subFolder: null,
|
|
1492
|
+
fileName: 'views.text.content',
|
|
1493
|
+
fileExt: 'amp',
|
|
1494
|
+
content: metadata.views.text.content,
|
|
1495
|
+
});
|
|
1496
|
+
delete metadata.views.text.content;
|
|
1497
|
+
}
|
|
1258
1498
|
|
|
1259
1499
|
// metadata.views.html.slots.<>.blocks.<>.content (optional)
|
|
1260
1500
|
if (metadata.views?.html?.slots) {
|
|
@@ -1298,7 +1538,7 @@ class Asset extends MetadataType {
|
|
|
1298
1538
|
codeArr.push({
|
|
1299
1539
|
subFolder: null,
|
|
1300
1540
|
fileName: customerKey,
|
|
1301
|
-
fileExt: '
|
|
1541
|
+
fileExt: 'amp',
|
|
1302
1542
|
content: metadata.views.text.content,
|
|
1303
1543
|
});
|
|
1304
1544
|
delete metadata.views.text.content;
|
|
@@ -1429,11 +1669,11 @@ class Asset extends MetadataType {
|
|
|
1429
1669
|
* Returns file contents mapped to their fileName without '.json' ending
|
|
1430
1670
|
*
|
|
1431
1671
|
* @param {string} dir directory that contains '.json' files to be read
|
|
1432
|
-
* @param {
|
|
1672
|
+
* @param {boolean} _ unused parameter
|
|
1433
1673
|
* @param {string[]} selectedSubType asset, message, ...
|
|
1434
|
-
* @returns {
|
|
1674
|
+
* @returns {Promise.<MetadataTypeMap>} fileName => fileContent map
|
|
1435
1675
|
*/
|
|
1436
|
-
static getJsonFromFS(dir, _, selectedSubType) {
|
|
1676
|
+
static async getJsonFromFS(dir, _, selectedSubType) {
|
|
1437
1677
|
const fileName2FileContent = {};
|
|
1438
1678
|
try {
|
|
1439
1679
|
for (const subtype of this.definition.subTypes) {
|
|
@@ -1445,8 +1685,8 @@ class Asset extends MetadataType {
|
|
|
1445
1685
|
continue;
|
|
1446
1686
|
}
|
|
1447
1687
|
const currentdir = File.normalizePath([dir, subtype]);
|
|
1448
|
-
if (File.
|
|
1449
|
-
const files = File.
|
|
1688
|
+
if (await File.pathExists(currentdir)) {
|
|
1689
|
+
const files = await File.readdir(currentdir, { withFileTypes: true });
|
|
1450
1690
|
|
|
1451
1691
|
for (const dirent of files) {
|
|
1452
1692
|
try {
|
|
@@ -1456,7 +1696,7 @@ class Asset extends MetadataType {
|
|
|
1456
1696
|
// complex types with more than one extracted piece of code are saved in their
|
|
1457
1697
|
// own subfolder (with folder name = CustomerKey)
|
|
1458
1698
|
// this section aims to find that json in the subfolder
|
|
1459
|
-
const subfolderFiles = File.
|
|
1699
|
+
const subfolderFiles = await File.readdir(
|
|
1460
1700
|
File.normalizePath([currentdir, dirent.name])
|
|
1461
1701
|
);
|
|
1462
1702
|
for (const subFileName of subfolderFiles) {
|
|
@@ -1467,10 +1707,9 @@ class Asset extends MetadataType {
|
|
|
1467
1707
|
}
|
|
1468
1708
|
}
|
|
1469
1709
|
if (fileName.endsWith('-meta.json')) {
|
|
1470
|
-
const fileContent = File.readJSONFile(
|
|
1710
|
+
const fileContent = await File.readJSONFile(
|
|
1471
1711
|
thisDir,
|
|
1472
1712
|
fileName,
|
|
1473
|
-
true,
|
|
1474
1713
|
false
|
|
1475
1714
|
);
|
|
1476
1715
|
// subtype will change the metadata suffix length
|
|
@@ -1488,7 +1727,7 @@ class Asset extends MetadataType {
|
|
|
1488
1727
|
}
|
|
1489
1728
|
}
|
|
1490
1729
|
} catch (ex) {
|
|
1491
|
-
// this will catch issues with
|
|
1730
|
+
// this will catch issues with readdir
|
|
1492
1731
|
Util.metadataLogger('debug', this.definition.type, 'getJsonFromFS', ex);
|
|
1493
1732
|
throw new Error(ex);
|
|
1494
1733
|
}
|
|
@@ -1499,7 +1738,7 @@ class Asset extends MetadataType {
|
|
|
1499
1738
|
*
|
|
1500
1739
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
1501
1740
|
* @param {string} templateName name of the metadata file
|
|
1502
|
-
* @returns {Promise.<
|
|
1741
|
+
* @returns {Promise.<string>} AssetSubType name
|
|
1503
1742
|
*/
|
|
1504
1743
|
static async findSubType(templateDir, templateName) {
|
|
1505
1744
|
const typeDirArr = [this.definition.type];
|
|
@@ -1518,14 +1757,6 @@ class Asset extends MetadataType {
|
|
|
1518
1757
|
break;
|
|
1519
1758
|
}
|
|
1520
1759
|
}
|
|
1521
|
-
if (!subType) {
|
|
1522
|
-
throw new Error(
|
|
1523
|
-
`Could not find asset with name ${templateName} in ${File.normalizePath([
|
|
1524
|
-
templateDir,
|
|
1525
|
-
...typeDirArr,
|
|
1526
|
-
])}`
|
|
1527
|
-
);
|
|
1528
|
-
}
|
|
1529
1760
|
return subType;
|
|
1530
1761
|
}
|
|
1531
1762
|
/**
|
|
@@ -1535,7 +1766,7 @@ class Asset extends MetadataType {
|
|
|
1535
1766
|
* @param {string[]} typeDirArr current subdir for this type
|
|
1536
1767
|
* @param {string} templateName name of the metadata template
|
|
1537
1768
|
* @param {string} fileName name of the metadata template file w/o extension
|
|
1538
|
-
* @returns {
|
|
1769
|
+
* @returns {Promise.<string>} metadata in string form
|
|
1539
1770
|
*/
|
|
1540
1771
|
static async readSecondaryFolder(templateDir, typeDirArr, templateName, fileName) {
|
|
1541
1772
|
// handles subtypes that create 1 folder per asset -> currently causes the below File.ReadFile to error out
|
|
@@ -1547,7 +1778,7 @@ class Asset extends MetadataType {
|
|
|
1547
1778
|
* additionally, the documentation for dataExtension and automation should be returned
|
|
1548
1779
|
*
|
|
1549
1780
|
* @param {string[]} keyArr customerkey of the metadata
|
|
1550
|
-
* @returns {string[]} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext']
|
|
1781
|
+
* @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext']
|
|
1551
1782
|
*/
|
|
1552
1783
|
static async getFilesToCommit(keyArr) {
|
|
1553
1784
|
const basePath = File.normalizePath([
|
|
@@ -1594,7 +1825,7 @@ class Asset extends MetadataType {
|
|
|
1594
1825
|
(await File.pathExists(File.normalizePath([...filePath, fileName])))
|
|
1595
1826
|
) {
|
|
1596
1827
|
// #1 load json to be able to find extracted text files & binary files
|
|
1597
|
-
const metadata = File.readJSONFile(filePath, fileName,
|
|
1828
|
+
const metadata = await File.readJSONFile(filePath, fileName, false);
|
|
1598
1829
|
// #2 find all extracted text files
|
|
1599
1830
|
const fileListNested = (
|
|
1600
1831
|
await this._mergeCode(metadata, basePath, subType, metadata.customerKey)
|
|
@@ -1629,6 +1860,427 @@ class Asset extends MetadataType {
|
|
|
1629
1860
|
).flat();
|
|
1630
1861
|
return fileList;
|
|
1631
1862
|
}
|
|
1863
|
+
/**
|
|
1864
|
+
* helper to allow us to select single metadata entries via REST
|
|
1865
|
+
*
|
|
1866
|
+
* @private
|
|
1867
|
+
* @param {string} key customer key
|
|
1868
|
+
* @returns {Promise.<string>} id value or null
|
|
1869
|
+
*/
|
|
1870
|
+
static async _getIdForSingleRetrieve(key) {
|
|
1871
|
+
const name = key.startsWith('name:') ? key.slice(5) : null;
|
|
1872
|
+
const filter = name
|
|
1873
|
+
? '?$filter=name%20eq%20' + encodeURIComponent(name)
|
|
1874
|
+
: '?$filter=customerKey%20eq%20' + encodeURIComponent(key);
|
|
1875
|
+
|
|
1876
|
+
const results = await this.client.rest.get('/asset/v1/content/assets/' + filter);
|
|
1877
|
+
const items = results?.items || [];
|
|
1878
|
+
const found = items.find((item) =>
|
|
1879
|
+
name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key
|
|
1880
|
+
);
|
|
1881
|
+
return found?.id || null;
|
|
1882
|
+
}
|
|
1883
|
+
/**
|
|
1884
|
+
* helper to allow us to select single metadata entries via REST
|
|
1885
|
+
*
|
|
1886
|
+
* @private
|
|
1887
|
+
* @param {string} id id field
|
|
1888
|
+
* @returns {Promise.<string>} key value or null
|
|
1889
|
+
*/
|
|
1890
|
+
static async _getKeyForSingleRetrieve(id) {
|
|
1891
|
+
const results = await this.client.rest.get('/asset/v1/content/assets/' + id);
|
|
1892
|
+
return results?.customerKey || null;
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
/**
|
|
1896
|
+
* Delete a metadata item from the specified business unit
|
|
1897
|
+
*
|
|
1898
|
+
* @param {string} key Identifier of item
|
|
1899
|
+
* @returns {Promise.<boolean>} deletion success flag
|
|
1900
|
+
*/
|
|
1901
|
+
static async deleteByKey(key) {
|
|
1902
|
+
// delete only works with the query's object id
|
|
1903
|
+
let id;
|
|
1904
|
+
if (key?.startsWith('id:')) {
|
|
1905
|
+
id = key.slice(3);
|
|
1906
|
+
// we need to get the actual key so that postDeletetTasks know what to do
|
|
1907
|
+
key = await this._getKeyForSingleRetrieve(id);
|
|
1908
|
+
} else {
|
|
1909
|
+
id = key ? await this._getIdForSingleRetrieve(key) : null;
|
|
1910
|
+
}
|
|
1911
|
+
if (!id) {
|
|
1912
|
+
Util.logger.error(` - ${this.definition.type} not found`);
|
|
1913
|
+
return false;
|
|
1914
|
+
}
|
|
1915
|
+
return super.deleteByKeyREST('/asset/v1/content/assets/' + id, key);
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
/**
|
|
1919
|
+
* clean up after deleting a metadata item
|
|
1920
|
+
* cannot use the generic method due to the complexity of how assets are saved to disk
|
|
1921
|
+
*
|
|
1922
|
+
* @param {string} key Identifier of metadata item
|
|
1923
|
+
* @returns {Promise.<void>} -
|
|
1924
|
+
*/
|
|
1925
|
+
static async postDeleteTasks(key) {
|
|
1926
|
+
if (key?.startsWith('id:')) {
|
|
1927
|
+
// sad
|
|
1928
|
+
}
|
|
1929
|
+
const fileArr = await this.getFilesToCommit([key]);
|
|
1930
|
+
|
|
1931
|
+
// check if asset sits in its own folder
|
|
1932
|
+
const ownFolderIndex =
|
|
1933
|
+
fileArr[0].indexOf(key + '\\') > 0
|
|
1934
|
+
? fileArr[0].indexOf(key + '\\')
|
|
1935
|
+
: fileArr[0].indexOf(key + '/');
|
|
1936
|
+
if (ownFolderIndex > 0) {
|
|
1937
|
+
fileArr.push(fileArr[0].slice(0, ownFolderIndex + key.length));
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
for (const filePath of fileArr) {
|
|
1941
|
+
await File.remove(filePath);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
/**
|
|
1945
|
+
* get name & key for provided id
|
|
1946
|
+
*
|
|
1947
|
+
* @param {string} id Identifier of metadata
|
|
1948
|
+
* @returns {Promise.<{key:string, name:string, path:string, folder:string, mid:number, error:string, isShared:boolean}>} key, name and path of metadata; null if not found
|
|
1949
|
+
*/
|
|
1950
|
+
static async resolveId(id) {
|
|
1951
|
+
let response;
|
|
1952
|
+
const json = {
|
|
1953
|
+
key: '',
|
|
1954
|
+
isShared: false,
|
|
1955
|
+
name: '',
|
|
1956
|
+
path: '',
|
|
1957
|
+
folder: '',
|
|
1958
|
+
mid: 0,
|
|
1959
|
+
legacyId: 0,
|
|
1960
|
+
error: '',
|
|
1961
|
+
sharedWith: [],
|
|
1962
|
+
};
|
|
1963
|
+
try {
|
|
1964
|
+
response = await this.client.rest.get(
|
|
1965
|
+
'asset/v1/content/assets/' +
|
|
1966
|
+
id +
|
|
1967
|
+
'?$fields=id,customerKey,name,memberId,legacyData,sharingProperties'
|
|
1968
|
+
);
|
|
1969
|
+
} catch (ex) {
|
|
1970
|
+
if (ex.response?.status !== 404) {
|
|
1971
|
+
throw ex;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
if (response?.id) {
|
|
1975
|
+
const item = response;
|
|
1976
|
+
const subType = this.#getMainSubtype(item.assetType.name);
|
|
1977
|
+
|
|
1978
|
+
// prep response object
|
|
1979
|
+
json.key = item[this.definition.keyField];
|
|
1980
|
+
json.name = item[this.definition.nameField];
|
|
1981
|
+
json.mid = item.memberId;
|
|
1982
|
+
json.isShared = item.memberId != this.buObject.mid;
|
|
1983
|
+
json.sharedWith = item.sharingProperties?.sharedWith || null;
|
|
1984
|
+
json.legacyId = item.legacyData?.legacyId;
|
|
1985
|
+
|
|
1986
|
+
const ownerBUName = json.isShared
|
|
1987
|
+
? Util.inverseGet(
|
|
1988
|
+
this.properties.credentials[this.buObject.credential].businessUnits,
|
|
1989
|
+
json.mid
|
|
1990
|
+
)
|
|
1991
|
+
: this.buObject.businessUnit;
|
|
1992
|
+
|
|
1993
|
+
// find path for code of content block, fall back to json if not found; undefined if not even the json exists
|
|
1994
|
+
let path = await this.#getPath(subType, item, ownerBUName);
|
|
1995
|
+
|
|
1996
|
+
if (!json.sharedWith) {
|
|
1997
|
+
delete json.sharedWith;
|
|
1998
|
+
}
|
|
1999
|
+
if (!json.isShared && !path) {
|
|
2000
|
+
// if not shared, we should have the file on disk; attempt download
|
|
2001
|
+
if (!cache.getCache()?.folder) {
|
|
2002
|
+
// folders not cached yet but required to fill json.path
|
|
2003
|
+
Folder.client = this.client;
|
|
2004
|
+
Folder.buObject = this.buObject;
|
|
2005
|
+
Folder.properties = this.properties;
|
|
2006
|
+
const result = await Folder.retrieveForCache(null, ['asset', 'asset-shared']);
|
|
2007
|
+
if (!cache.getCache()) {
|
|
2008
|
+
cache.initCache(this.buObject);
|
|
2009
|
+
}
|
|
2010
|
+
cache.setMetadata('folder', result.metadata);
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
await this.retrieve(
|
|
2014
|
+
File.normalizePath([
|
|
2015
|
+
this.properties.directories.retrieve,
|
|
2016
|
+
this.buObject.credential,
|
|
2017
|
+
this.buObject.businessUnit,
|
|
2018
|
+
]),
|
|
2019
|
+
null,
|
|
2020
|
+
[subType],
|
|
2021
|
+
json.key
|
|
2022
|
+
);
|
|
2023
|
+
// try again
|
|
2024
|
+
path = await this.#getPath(subType, item, this.buObject.businessUnit);
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
if (path) {
|
|
2028
|
+
json.path = path;
|
|
2029
|
+
delete json.error;
|
|
2030
|
+
} else {
|
|
2031
|
+
json.error = 'file not found on local disk';
|
|
2032
|
+
delete json.path;
|
|
2033
|
+
}
|
|
2034
|
+
const fileContent = await this.#getJson(subType, item);
|
|
2035
|
+
if (fileContent?.r__folder_Path) {
|
|
2036
|
+
json.folder = fileContent.r__folder_Path;
|
|
2037
|
+
}
|
|
2038
|
+
if (!json.legacyId) {
|
|
2039
|
+
delete json.legacyId;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
if (Util.OPTIONS.json) {
|
|
2043
|
+
// for automated processing by VSCode extension, optionally print the json
|
|
2044
|
+
console.log(JSON.stringify(json, null, 2)); // eslint-disable-line no-console
|
|
2045
|
+
} else {
|
|
2046
|
+
Util.logger.info(` - ID: ${id}`);
|
|
2047
|
+
Util.logger.info(` - Key: ${item[this.definition.keyField]}`);
|
|
2048
|
+
Util.logger.info(` - Name: ${item[this.definition.nameField]}`);
|
|
2049
|
+
|
|
2050
|
+
if (json.isShared) {
|
|
2051
|
+
Util.logger.warn(' - Shared from: ' + ownerBUName + ' (' + json.mid + ')');
|
|
2052
|
+
}
|
|
2053
|
+
if (json.sharedWith && Array.isArray(json.sharedWith)) {
|
|
2054
|
+
Util.logger.warn(
|
|
2055
|
+
` with: ${json.sharedWith
|
|
2056
|
+
.map(
|
|
2057
|
+
(mid) =>
|
|
2058
|
+
Util.inverseGet(
|
|
2059
|
+
this.properties.credentials[this.buObject.credential]
|
|
2060
|
+
.businessUnits,
|
|
2061
|
+
mid
|
|
2062
|
+
) +
|
|
2063
|
+
' (' +
|
|
2064
|
+
mid +
|
|
2065
|
+
')'
|
|
2066
|
+
)
|
|
2067
|
+
.sort()
|
|
2068
|
+
.join(', ')}`
|
|
2069
|
+
);
|
|
2070
|
+
}
|
|
2071
|
+
if (json.legacyId) {
|
|
2072
|
+
Util.logger.info(` - Legacy ID: ${json.legacyId}`);
|
|
2073
|
+
}
|
|
2074
|
+
Util.logger.info(` - How to use:`);
|
|
2075
|
+
Util.logger.info(` %%= ContentBlockByKey("${json.key}") =%%`);
|
|
2076
|
+
|
|
2077
|
+
if (json.folder) {
|
|
2078
|
+
Util.logger.info(
|
|
2079
|
+
` %%= ContentBlockByName("${json.folder.split('/').join('\\') + '\\' + json.name}") =%%`
|
|
2080
|
+
);
|
|
2081
|
+
if (json.folder.includes('&') || json.name.includes('&')) {
|
|
2082
|
+
Util.logger.warn(
|
|
2083
|
+
` - ContentBlockByName will fail because your path or name contains the & or & symbol. Please replace it with 'and' or remove it.`
|
|
2084
|
+
);
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
Util.logger.info(
|
|
2088
|
+
' - local link: ' +
|
|
2089
|
+
(path ||
|
|
2090
|
+
`404. Try running mcdev r ${this.buObject.credential}/${ownerBUName} ${this.definition.type}-${subType} ${item[this.definition.keyField]}`)
|
|
2091
|
+
);
|
|
2092
|
+
}
|
|
2093
|
+
return json;
|
|
2094
|
+
} else {
|
|
2095
|
+
json.error = 'id not found';
|
|
2096
|
+
delete json.key;
|
|
2097
|
+
delete json.mid;
|
|
2098
|
+
delete json.name;
|
|
2099
|
+
delete json.path;
|
|
2100
|
+
delete json.folder;
|
|
2101
|
+
delete json.isShared;
|
|
2102
|
+
delete json.legacyId;
|
|
2103
|
+
delete json.sharedWith;
|
|
2104
|
+
if (Util.OPTIONS.json) {
|
|
2105
|
+
console.log(JSON.stringify(json, null, 2)); // eslint-disable-line no-console
|
|
2106
|
+
return json;
|
|
2107
|
+
}
|
|
2108
|
+
Util.logger.error(` - ${this.definition.type} with id ${id} not found on BU`);
|
|
2109
|
+
return json;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
/**
|
|
2114
|
+
* helper for {@link Asset.resolveId} that finds the path to the asset's code
|
|
2115
|
+
*
|
|
2116
|
+
* @param {string} subType asset subtype
|
|
2117
|
+
* @param {object} item api response for metadata
|
|
2118
|
+
* @param {string} buName owner business unit name
|
|
2119
|
+
* @returns {string} path to the asset's code
|
|
2120
|
+
*/
|
|
2121
|
+
static async #getPath(subType, item, buName) {
|
|
2122
|
+
const pathBase1 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`;
|
|
2123
|
+
const pathBase2 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`;
|
|
2124
|
+
const paths = [];
|
|
2125
|
+
for (const ext of ['html', 'ssjs', 'amp', 'json']) {
|
|
2126
|
+
paths.push(pathBase1 + ext, pathBase2 + ext);
|
|
2127
|
+
}
|
|
2128
|
+
const path = await Util.findAsync(paths, async (p) => await File.pathExists(p));
|
|
2129
|
+
return path;
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* helper for {@link Asset.resolveId} that loads the JSON file for the asset
|
|
2133
|
+
*
|
|
2134
|
+
* @param {string} subType asset subtype
|
|
2135
|
+
* @param {object} item api response for metadata
|
|
2136
|
+
* @returns {Promise.<object>} JS object of the asset we loaded from disk
|
|
2137
|
+
*/
|
|
2138
|
+
static async #getJson(subType, item) {
|
|
2139
|
+
const mid = item.memberId;
|
|
2140
|
+
const buName =
|
|
2141
|
+
mid === this.buObject.mid
|
|
2142
|
+
? this.buObject.businessUnit
|
|
2143
|
+
: Object.keys(
|
|
2144
|
+
this.properties.credentials[this.buObject.credential].businessUnits
|
|
2145
|
+
).find(
|
|
2146
|
+
(buName) =>
|
|
2147
|
+
this.properties.credentials[this.buObject.credential].businessUnits[
|
|
2148
|
+
buName
|
|
2149
|
+
] == mid
|
|
2150
|
+
);
|
|
2151
|
+
const pathBase1 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`;
|
|
2152
|
+
const pathBase2 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`;
|
|
2153
|
+
const paths = [];
|
|
2154
|
+
paths.push(pathBase1 + 'json', pathBase2 + 'json');
|
|
2155
|
+
|
|
2156
|
+
const path = await Util.findAsync(paths, async (p) => await File.pathExists(p));
|
|
2157
|
+
const pathArr = path.split('/');
|
|
2158
|
+
const fileName = pathArr.pop().slice(0, -5);
|
|
2159
|
+
const fileContent = await File.readJSONFile(pathArr.join('/'), fileName, false);
|
|
2160
|
+
return fileContent;
|
|
2161
|
+
}
|
|
2162
|
+
/**
|
|
2163
|
+
*
|
|
2164
|
+
* @param {MetadataTypeItem} item single metadata item
|
|
2165
|
+
* @param {string} retrieveDir directory where metadata is saved
|
|
2166
|
+
* @returns {Promise.<MetadataTypeItem>} key of the item that was updated
|
|
2167
|
+
*/
|
|
2168
|
+
static async replaceCbReference(item, retrieveDir) {
|
|
2169
|
+
const responseItem = structuredClone(item);
|
|
2170
|
+
const parentName = `${this.definition.type} ${item[this.definition.keyField]}`;
|
|
2171
|
+
let changes = false;
|
|
2172
|
+
let error;
|
|
2173
|
+
|
|
2174
|
+
// *** type specific logic ***
|
|
2175
|
+
const subType = this.#getMainSubtype(item.assetType.name);
|
|
2176
|
+
/** @type {CodeExtract[]} */
|
|
2177
|
+
const fileList = await this._mergeCode(
|
|
2178
|
+
item,
|
|
2179
|
+
retrieveDir,
|
|
2180
|
+
subType,
|
|
2181
|
+
item[this.definition.keyField],
|
|
2182
|
+
false
|
|
2183
|
+
);
|
|
2184
|
+
const fileListChanged = [];
|
|
2185
|
+
for (const file of fileList) {
|
|
2186
|
+
try {
|
|
2187
|
+
file.content = ReplaceCbReference.replaceReference(file.content, parentName);
|
|
2188
|
+
changes = true;
|
|
2189
|
+
fileListChanged.push(file);
|
|
2190
|
+
} catch (ex) {
|
|
2191
|
+
if (ex.code !== 200) {
|
|
2192
|
+
error = ex;
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
// save what was changed regardless of other errors
|
|
2198
|
+
for (const extractedFile of fileListChanged) {
|
|
2199
|
+
File.writeToFile(
|
|
2200
|
+
[retrieveDir, ...extractedFile.subFolder],
|
|
2201
|
+
extractedFile.fileName,
|
|
2202
|
+
extractedFile.fileExt,
|
|
2203
|
+
extractedFile.content,
|
|
2204
|
+
extractedFile.encoding || null
|
|
2205
|
+
);
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
if (error) {
|
|
2209
|
+
throw error;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
if (!changes) {
|
|
2213
|
+
const ex = new Error('No changes made to the code.');
|
|
2214
|
+
ex.code = 200;
|
|
2215
|
+
throw ex;
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
// *** finish ***
|
|
2219
|
+
// replaceReference will throw an error if nothing was updated which will end execution here
|
|
2220
|
+
// no error means we have a new item to deploy and need to update the item in our retrieve folder
|
|
2221
|
+
return responseItem;
|
|
2222
|
+
}
|
|
2223
|
+
/**
|
|
2224
|
+
* this iterates over all items found in the retrieve folder and executes the type-specific method for replacing references
|
|
2225
|
+
*
|
|
2226
|
+
* @param {MetadataTypeMap} metadataMap list of metadata (keyField => metadata)
|
|
2227
|
+
* @param {string} retrieveDir retrieve dir including cred and bu
|
|
2228
|
+
* @returns {Promise.<string[]>} Returns list of keys for which references were replaced
|
|
2229
|
+
*/
|
|
2230
|
+
static async replaceCbReferenceLoop(metadataMap, retrieveDir) {
|
|
2231
|
+
const keysForDeploy = [];
|
|
2232
|
+
if (!metadataMap) {
|
|
2233
|
+
// if a type was skipped e.g. because it shall only be looked at on the parent then we would expect metadataMap to be undefined
|
|
2234
|
+
return keysForDeploy;
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
const fromDescription = Util.OPTIONS.referenceFrom
|
|
2238
|
+
.map((from) => 'ContentBlockBy' + Util.capitalizeFirstLetter(from))
|
|
2239
|
+
.join(' and ');
|
|
2240
|
+
|
|
2241
|
+
if (Object.keys(metadataMap).length) {
|
|
2242
|
+
Util.logger.info(`Searching ${this.definition.type} for ${fromDescription}:`);
|
|
2243
|
+
// const baseDir = [retrieveDir, ...this.definition.type.split('-')];
|
|
2244
|
+
const deployMap = {};
|
|
2245
|
+
|
|
2246
|
+
for (const key in metadataMap) {
|
|
2247
|
+
const item = metadataMap[key];
|
|
2248
|
+
if (this.isFiltered(item, true) || this.isFiltered(item, false)) {
|
|
2249
|
+
// we would not have saved these items to disk but they exist in the cache and hence need to be skipped here
|
|
2250
|
+
|
|
2251
|
+
continue;
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
try {
|
|
2255
|
+
// add key but make sure to turn it into string or else numeric keys will be filtered later
|
|
2256
|
+
deployMap[key] = await this.replaceCbReference(item, retrieveDir);
|
|
2257
|
+
|
|
2258
|
+
// ! this method is equal to the super version except that it does not run saveToDisk here
|
|
2259
|
+
// await this.saveToDisk(deployMap, key, baseDir);
|
|
2260
|
+
|
|
2261
|
+
keysForDeploy.push(key + '');
|
|
2262
|
+
Util.logger.info(` - added ${this.definition.type} to update queue: ${key}`);
|
|
2263
|
+
} catch (ex) {
|
|
2264
|
+
if (ex.code !== 200) {
|
|
2265
|
+
// dont print error if we simply did not find relevant content blocks
|
|
2266
|
+
Util.logger.errorStack(ex, ex.message);
|
|
2267
|
+
}
|
|
2268
|
+
Util.logger.info(
|
|
2269
|
+
Util.getGrayMsg(
|
|
2270
|
+
` ☇ skipping ${this.definition.type} ${
|
|
2271
|
+
item[this.definition.keyField]
|
|
2272
|
+
}: no ${fromDescription} found`
|
|
2273
|
+
)
|
|
2274
|
+
);
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
Util.logger.info(
|
|
2279
|
+
`Found ${keysForDeploy.length} ${this.definition.type}${keysForDeploy.length === 1 ? '' : 's'} to update`
|
|
2280
|
+
);
|
|
2281
|
+
}
|
|
2282
|
+
return keysForDeploy;
|
|
2283
|
+
}
|
|
1632
2284
|
}
|
|
1633
2285
|
|
|
1634
2286
|
// Assign definition to static attributes
|