Repository: Accenture/sfmc-devtools Branch: main Commit: 76970577de5f Files: 1071 Total size: 6.8 MB Directory structure: gitextract_bi7k1rji/ ├── .beautyamp.json ├── .bitbucket/ │ └── PULL_REQUEST_TEMPLATE.md ├── .coverage-comment-template.svelte ├── .editorconfig ├── .fork/ │ ├── .prettierrc │ └── custom-commands.json ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.yml │ │ ├── feature_request.md │ │ └── task.md │ ├── PULL_REQUEST_TEMPLATE/ │ │ └── pr_template_release.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── copilot-instructions.md │ ├── dependabot.yml │ ├── pr-labeler.yml │ └── workflows/ │ ├── close_issues_on_merge.yml │ ├── code-test.yml │ ├── coverage-base-update.yml │ ├── coverage-develop-branch.yml │ ├── coverage-main-branch.yml │ ├── coverage.yml │ ├── npm-publish.yml │ ├── pr-labeler.yml │ └── sync-milestone.yml ├── .gitignore ├── .husky/ │ ├── .gitignore │ ├── commit-msg │ ├── post-checkout │ ├── post-merge │ └── pre-commit ├── .issuetracker ├── .markdownlint.json ├── .markdownlint.md ├── .mcdev-validations.js ├── .npmrc ├── .nycrc.json ├── .prettierignore ├── .prettierrc ├── .vscode/ │ ├── extensions.json │ ├── launch.json │ └── settings.json ├── .vsls.json ├── @types/ │ ├── lib/ │ │ ├── Builder.d.ts │ │ ├── Deployer.d.ts │ │ ├── MetadataTypeDefinitions.d.ts │ │ ├── MetadataTypeInfo.d.ts │ │ ├── Retriever.d.ts │ │ ├── cli.d.ts │ │ ├── index.d.ts │ │ ├── metadataTypes/ │ │ │ ├── Asset.d.ts │ │ │ ├── AttributeGroup.d.ts │ │ │ ├── AttributeSet.d.ts │ │ │ ├── Automation.d.ts │ │ │ ├── Campaign.d.ts │ │ │ ├── ContentArea.d.ts │ │ │ ├── DataExtension.d.ts │ │ │ ├── DataExtensionField.d.ts │ │ │ ├── DataExtensionTemplate.d.ts │ │ │ ├── DataExtract.d.ts │ │ │ ├── DataExtractType.d.ts │ │ │ ├── DataFilter.d.ts │ │ │ ├── DataFilterHidden.d.ts │ │ │ ├── DeliveryProfile.d.ts │ │ │ ├── Discovery.d.ts │ │ │ ├── DomainVerification.d.ts │ │ │ ├── Email.d.ts │ │ │ ├── EmailSend.d.ts │ │ │ ├── Event.d.ts │ │ │ ├── FileLocation.d.ts │ │ │ ├── FileTransfer.d.ts │ │ │ ├── Filter.d.ts │ │ │ ├── FilterDefinition.d.ts │ │ │ ├── FilterDefinitionHidden.d.ts │ │ │ ├── Folder.d.ts │ │ │ ├── ImportFile.d.ts │ │ │ ├── Journey.d.ts │ │ │ ├── List.d.ts │ │ │ ├── MetadataType.d.ts │ │ │ ├── MobileCode.d.ts │ │ │ ├── MobileKeyword.d.ts │ │ │ ├── MobileMessage.d.ts │ │ │ ├── Query.d.ts │ │ │ ├── Role.d.ts │ │ │ ├── Script.d.ts │ │ │ ├── SendClassification.d.ts │ │ │ ├── SenderProfile.d.ts │ │ │ ├── TransactionalEmail.d.ts │ │ │ ├── TransactionalMessage.d.ts │ │ │ ├── TransactionalPush.d.ts │ │ │ ├── TransactionalSMS.d.ts │ │ │ ├── TriggeredSend.d.ts │ │ │ ├── TriggeredSendSummary.d.ts │ │ │ ├── User.d.ts │ │ │ ├── Verification.d.ts │ │ │ └── definitions/ │ │ │ ├── Asset.definition.d.ts │ │ │ ├── AttributeGroup.definition.d.ts │ │ │ ├── AttributeSet.definition.d.ts │ │ │ ├── Automation.definition.d.ts │ │ │ ├── Campaign.definition.d.ts │ │ │ ├── ContentArea.definition.d.ts │ │ │ ├── DataExtension.definition.d.ts │ │ │ ├── DataExtensionField.definition.d.ts │ │ │ ├── DataExtensionTemplate.definition.d.ts │ │ │ ├── DataExtract.definition.d.ts │ │ │ ├── DataExtractType.definition.d.ts │ │ │ ├── DataFilter.definition.d.ts │ │ │ ├── DataFilterHidden.definition.d.ts │ │ │ ├── DeliveryProfile.definition.d.ts │ │ │ ├── Discovery.definition.d.ts │ │ │ ├── DomainVerification.definition.d.ts │ │ │ ├── Email.definition.d.ts │ │ │ ├── EmailSend.definition.d.ts │ │ │ ├── Event.definition.d.ts │ │ │ ├── FileLocation.definition.d.ts │ │ │ ├── FileTransfer.definition.d.ts │ │ │ ├── Filter.definition.d.ts │ │ │ ├── FilterDefinition.definition.d.ts │ │ │ ├── FilterDefinitionHidden.definition.d.ts │ │ │ ├── Folder.definition.d.ts │ │ │ ├── ImportFile.definition.d.ts │ │ │ ├── Journey.definition.d.ts │ │ │ ├── List.definition.d.ts │ │ │ ├── MobileCode.definition.d.ts │ │ │ ├── MobileKeyword.definition.d.ts │ │ │ ├── MobileMessage.definition.d.ts │ │ │ ├── Query.definition.d.ts │ │ │ ├── Role.definition.d.ts │ │ │ ├── Script.definition.d.ts │ │ │ ├── SendClassification.definition.d.ts │ │ │ ├── SenderProfile.definition.d.ts │ │ │ ├── TransactionalEmail.definition.d.ts │ │ │ ├── TransactionalMessage.definition.d.ts │ │ │ ├── TransactionalPush.definition.d.ts │ │ │ ├── TransactionalSMS.definition.d.ts │ │ │ ├── TriggeredSend.definition.d.ts │ │ │ ├── TriggeredSendSummary.definition.d.ts │ │ │ ├── User.definition.d.ts │ │ │ └── Verification.definition.d.ts │ │ ├── retrieveChangelog.d.ts │ │ └── util/ │ │ ├── auth.d.ts │ │ ├── businessUnit.d.ts │ │ ├── cache.d.ts │ │ ├── cli.d.ts │ │ ├── config.d.ts │ │ ├── devops.d.ts │ │ ├── file.d.ts │ │ ├── init.config.d.ts │ │ ├── init.d.ts │ │ ├── init.git.d.ts │ │ ├── init.npm.d.ts │ │ ├── replaceContentBlockReference.d.ts │ │ ├── util.d.ts │ │ └── validations.d.ts │ └── types/ │ └── mcdev.d.d.ts ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── boilerplate/ │ ├── config.json │ ├── files/ │ │ ├── .beautyamp.json │ │ ├── .editorconfig │ │ ├── .gitattributes │ │ ├── .npmrc │ │ ├── .prettierrc │ │ ├── .vscode/ │ │ │ ├── extensions.json │ │ │ └── settings.json │ │ ├── README.md │ │ └── eslint.config.js │ ├── forcedUpdates.json │ ├── gitignore-template │ └── npm-dependencies.json ├── docs/ │ └── dist/ │ └── considerations.md ├── eslint.config.js ├── lib/ │ ├── Builder.js │ ├── Deployer.js │ ├── MetadataTypeDefinitions.js │ ├── MetadataTypeInfo.js │ ├── Retriever.js │ ├── cli.js │ ├── index.js │ ├── metadataTypes/ │ │ ├── Asset.js │ │ ├── AttributeGroup.js │ │ ├── AttributeSet.js │ │ ├── Automation.js │ │ ├── Campaign.js │ │ ├── ContentArea.js │ │ ├── DataExtension.js │ │ ├── DataExtensionField.js │ │ ├── DataExtensionTemplate.js │ │ ├── DataExtract.js │ │ ├── DataExtractType.js │ │ ├── DataFilter.js │ │ ├── DataFilterHidden.js │ │ ├── DeliveryProfile.js │ │ ├── Discovery.js │ │ ├── DomainVerification.js │ │ ├── Email.js │ │ ├── EmailSend.js │ │ ├── Event.js │ │ ├── FileLocation.js │ │ ├── FileTransfer.js │ │ ├── Filter.js │ │ ├── Folder.js │ │ ├── ImportFile.js │ │ ├── Journey.js │ │ ├── List.js │ │ ├── MetadataType.js │ │ ├── MobileCode.js │ │ ├── MobileKeyword.js │ │ ├── MobileMessage.js │ │ ├── Query.js │ │ ├── Role.js │ │ ├── Script.js │ │ ├── SendClassification.js │ │ ├── SenderProfile.js │ │ ├── TransactionalEmail.js │ │ ├── TransactionalMessage.js │ │ ├── TransactionalPush.js │ │ ├── TransactionalSMS.js │ │ ├── TriggeredSend.js │ │ ├── TriggeredSendSummary.js │ │ ├── User.js │ │ ├── Verification.js │ │ └── definitions/ │ │ ├── Asset.definition.js │ │ ├── AttributeGroup.definition.js │ │ ├── AttributeSet.definition.js │ │ ├── Automation.definition.js │ │ ├── Campaign.definition.js │ │ ├── ContentArea.definition.js │ │ ├── DataExtension.definition.js │ │ ├── DataExtensionField.definition.js │ │ ├── DataExtensionTemplate.definition.js │ │ ├── DataExtract.definition.js │ │ ├── DataExtractType.definition.js │ │ ├── DataFilter.definition.js │ │ ├── DataFilterHidden.definition.js │ │ ├── DeliveryProfile.definition.js │ │ ├── Discovery.definition.js │ │ ├── DomainVerification.definition.js │ │ ├── Email.definition.js │ │ ├── EmailSend.definition.js │ │ ├── Event.definition.js │ │ ├── FileLocation.definition.js │ │ ├── FileTransfer.definition.js │ │ ├── Filter.definition.js │ │ ├── Folder.definition.js │ │ ├── ImportFile.definition.js │ │ ├── Journey.definition.js │ │ ├── List.definition.js │ │ ├── MobileCode.definition.js │ │ ├── MobileKeyword.definition.js │ │ ├── MobileMessage.definition.js │ │ ├── Query.definition.js │ │ ├── Role.definition.js │ │ ├── Script.definition.js │ │ ├── SendClassification.definition.js │ │ ├── SenderProfile.definition.js │ │ ├── TransactionalEmail.definition.js │ │ ├── TransactionalMessage.definition.js │ │ ├── TransactionalPush.definition.js │ │ ├── TransactionalSMS.definition.js │ │ ├── TriggeredSend.definition.js │ │ ├── TriggeredSendSummary.definition.js │ │ ├── User.definition.js │ │ └── Verification.definition.js │ ├── retrieveChangelog.js │ └── util/ │ ├── auth.js │ ├── businessUnit.js │ ├── cache.js │ ├── cli.js │ ├── config.js │ ├── devops.js │ ├── file.js │ ├── init.config.js │ ├── init.git.js │ ├── init.js │ ├── init.npm.js │ ├── replaceContentBlockReference.js │ ├── util.js │ └── validations.js ├── package.json ├── prepare-release.js ├── test/ │ ├── general.test.js │ ├── mockRoot/ │ │ ├── .mcdev-auth.json │ │ ├── .mcdev-validations.js │ │ ├── .mcdevrc.json │ │ └── deploy/ │ │ └── testInstance/ │ │ ├── _ParentBU_/ │ │ │ ├── dataExtension/ │ │ │ │ ├── testExisting_dataExtensionShared.dataExtension-meta.json │ │ │ │ └── testNew_dataExtensionShared.dataExtension-meta.json │ │ │ ├── query/ │ │ │ │ ├── testNew_query.query-meta.json │ │ │ │ └── testNew_query.query-meta.sql │ │ │ └── user/ │ │ │ ├── testBlocked_user.user-meta.json │ │ │ ├── testExisting_user.user-meta.json │ │ │ └── testNew_user.user-meta.json │ │ └── testBU/ │ │ ├── asset/ │ │ │ ├── block/ │ │ │ │ ├── testExisting_asset_html-matchNamFail.asset-block-meta.html │ │ │ │ ├── testExisting_asset_html-matchNamFail.asset-block-meta.json │ │ │ │ ├── testExisting_asset_html-matchName.asset-block-meta.html │ │ │ │ ├── testExisting_asset_html-matchName.asset-block-meta.json │ │ │ │ ├── testExisting_asset_html-matchNameAdd.asset-block-meta.html │ │ │ │ ├── testExisting_asset_html-matchNameAdd.asset-block-meta.json │ │ │ │ ├── testNew_asset.asset-block-meta.html │ │ │ │ ├── testNew_asset.asset-block-meta.json │ │ │ │ ├── testNew_asset_htmlblock.asset-block-meta.html │ │ │ │ ├── testNew_asset_htmlblock.asset-block-meta.json │ │ │ │ ├── testNew_asset_withCBBK_notexisting.asset-block-meta.html │ │ │ │ ├── testNew_asset_withCBBK_notexisting.asset-block-meta.json │ │ │ │ ├── testNew_asset_withCBBK_preexisting.asset-block-meta.html │ │ │ │ ├── testNew_asset_withCBBK_preexisting.asset-block-meta.json │ │ │ │ ├── test_slash.asset-block-meta.html │ │ │ │ └── test_slash.asset-block-meta.json │ │ │ ├── message/ │ │ │ │ ├── testNew_assetMessage/ │ │ │ │ │ ├── testNew_assetMessage.asset-message-meta.json │ │ │ │ │ └── views.html.content.asset-message-meta.html │ │ │ │ └── testNew_asset_templatebasedemail/ │ │ │ │ ├── testNew_asset_templatebasedemail.asset-message-meta.json │ │ │ │ └── views.html.content.asset-message-meta.html │ │ │ └── template/ │ │ │ └── testNew_asset_template/ │ │ │ ├── content.asset-template-meta.html │ │ │ └── testNew_asset_template.asset-template-meta.json │ │ ├── automation/ │ │ │ ├── testExisting_automation.automation-meta.json │ │ │ └── testNew_automation.automation-meta.json │ │ ├── dataExtension/ │ │ │ ├── testExisting_dataExtension.dataExtension-meta.json │ │ │ └── testNew_dataExtension.dataExtension-meta.json │ │ ├── dataExtract/ │ │ │ ├── testExisting_dataExtract.dataExtract-meta.json │ │ │ └── testNew_dataExtract.dataExtract-meta.json │ │ ├── dataFilter/ │ │ │ ├── testExisting_dataFilter.dataFilter-meta.json │ │ │ └── testNew_dataFilter.dataFilter-meta.json │ │ ├── domainVerification/ │ │ │ ├── joern.berkefeld.New@accenture.com.domainVerification-meta.json │ │ │ ├── joern.berkefeld@accenture.com.domainVerification-meta.json │ │ │ └── mcdev.accenture.com.domainVerification-meta.json │ │ ├── emailSend/ │ │ │ ├── testExisting_emailSend.emailSend-meta.json │ │ │ └── testNew_emailSend.emailSend-meta.json │ │ ├── event/ │ │ │ ├── testExisting_event.event-meta.json │ │ │ ├── testNew_event_withExistingDE.event-meta.json │ │ │ └── testNew_event_withSchema.event-meta.json │ │ ├── fileLocation/ │ │ │ ├── ExactTarget Enhanced FTP.fileLocation-meta.json │ │ │ ├── testExisting_fileLocation_aws.fileLocation-meta.json │ │ │ └── testExisting_fileLocation_exsftp.fileLocation-meta.json │ │ ├── fileTransfer/ │ │ │ ├── testExisting_fileTransfer.fileTransfer-meta.json │ │ │ └── testNew_fileTransfer.fileTransfer-meta.json │ │ ├── filter/ │ │ │ ├── testExisting_filter.filter-meta.json │ │ │ └── testNew_filter.filter-meta.json │ │ ├── importFile/ │ │ │ ├── testExisting_importFile.importFile-meta.json │ │ │ └── testNew_importFile.importFile-meta.json │ │ ├── journey/ │ │ │ ├── testExisting_journey_Multistep.journey-meta.json │ │ │ ├── testExisting_journey_Quicksend.journey-meta.json │ │ │ ├── testExisting_journey_updatecontact.journey-meta.json │ │ │ ├── testExisting_journey_updatecontact_sharedDE.journey-meta.json │ │ │ ├── testExisting_temail.journey-meta.json │ │ │ ├── testExisting_temail_notPublished.journey-meta.json │ │ │ └── testNew_temail_notPublished.journey-meta.json │ │ ├── mobileKeyword/ │ │ │ ├── 4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.amp │ │ │ ├── 4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.json │ │ │ ├── 4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.amp │ │ │ └── 4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.json │ │ ├── mobileMessage/ │ │ │ ├── NTIzOjc4OjA.mobileMessage-meta.amp │ │ │ ├── NTIzOjc4OjA.mobileMessage-meta.json │ │ │ ├── new.mobileMessage-meta.amp │ │ │ └── new.mobileMessage-meta.json │ │ ├── query/ │ │ │ ├── testExisting_query.query-meta.json │ │ │ ├── testExisting_query.query-meta.sql │ │ │ ├── testExisting_query_fixKeys.query-meta.json │ │ │ ├── testExisting_query_fixKeys.query-meta.sql │ │ │ ├── testNew_query.query-meta.json │ │ │ └── testNew_query.query-meta.sql │ │ ├── script/ │ │ │ ├── testExisting_script.script-meta.json │ │ │ ├── testExisting_script.script-meta.ssjs │ │ │ ├── testNew_script.script-meta.json │ │ │ └── testNew_script.script-meta.ssjs │ │ ├── sendClassification/ │ │ │ ├── testExisting_sendClassification.sendClassification-meta.json │ │ │ └── testNew_sendClassification.sendClassification-meta.json │ │ ├── senderProfile/ │ │ │ ├── testExisting_senderProfile.senderProfile-meta.json │ │ │ └── testNew_senderProfile.senderProfile-meta.json │ │ ├── transactionalEmail/ │ │ │ ├── testExisting_temail.transactionalEmail-meta.json │ │ │ └── testNew_temail.transactionalEmail-meta.json │ │ ├── transactionalPush/ │ │ │ ├── testExisting_tpush.transactionalPush-meta.json │ │ │ └── testNew_tpush.transactionalPush-meta.json │ │ ├── transactionalSMS/ │ │ │ ├── testExisting_tsms.transactionalSMS-meta.amp │ │ │ ├── testExisting_tsms.transactionalSMS-meta.json │ │ │ ├── testNew_tsms.transactionalSMS-meta.amp │ │ │ └── testNew_tsms.transactionalSMS-meta.json │ │ ├── triggeredSend/ │ │ │ ├── testExisting_triggeredSend.triggeredSend-meta.json │ │ │ └── testNew_triggeredSend.triggeredSend-meta.json │ │ └── verification/ │ │ ├── testExisting_automation__s1.7.verification-meta.json │ │ └── testNew_automation__s1.7.verification-meta.json │ ├── resourceFactory.js │ ├── resources/ │ │ ├── 1111111/ │ │ │ ├── accountUser/ │ │ │ │ ├── configure-response.xml │ │ │ │ ├── create-response.xml │ │ │ │ ├── retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-QAA-response.xml │ │ │ │ ├── retrieve-ActiveFlag=falseANDEmaillike@-QAA-response.xml │ │ │ │ ├── retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-QAA-response.xml │ │ │ │ ├── retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-QAA-response.xml │ │ │ │ ├── retrieve-ActiveFlag=trueANDEmaillike@-QAA-response.xml │ │ │ │ └── update-response.xml │ │ │ ├── accountUserAccount/ │ │ │ │ ├── retrieve-AccountUser.AccountUserID=700301950-response.xml │ │ │ │ └── retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml │ │ │ ├── automation/ │ │ │ │ └── v1/ │ │ │ │ └── queries/ │ │ │ │ ├── get-response.json │ │ │ │ └── post-response.json │ │ │ ├── businessUnit/ │ │ │ │ └── retrieve-ID=1111111-QAA-response.xml │ │ │ ├── data/ │ │ │ │ └── v1/ │ │ │ │ └── customobjectdata/ │ │ │ │ └── key/ │ │ │ │ └── testExisting_dataExtensionShared/ │ │ │ │ └── rowset/ │ │ │ │ └── get-response.json │ │ │ ├── dataExtension/ │ │ │ │ ├── create-expected.json │ │ │ │ ├── create-response.xml │ │ │ │ ├── retrieve-expected.json │ │ │ │ ├── retrieve-expected.md │ │ │ │ ├── retrieve-response.xml │ │ │ │ ├── template_sharedDE-expected.json │ │ │ │ ├── update-expected.json │ │ │ │ └── update-response.xml │ │ │ ├── dataExtensionField/ │ │ │ │ ├── retrieve-CustomerKey=[testExisting_dataExtensionShared].[TriggerUpdate_randomNumber_]-response.xml │ │ │ │ ├── retrieve-DataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml │ │ │ │ ├── retrieve-DataExtension.CustomerKey=testNew_dataExtensionSharedORDataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml │ │ │ │ └── retrieve-response.xml │ │ │ ├── dataExtensionTemplate/ │ │ │ │ └── retrieve-response.xml │ │ │ ├── dataFolder/ │ │ │ │ ├── retrieve-ContentType=queryactivity-response.xml │ │ │ │ ├── retrieve-ContentTypeINdataextension,hidden,queryactivity,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ ├── retrieve-ContentTypeINdataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ ├── retrieve-ContentTypeINshared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ └── retrieve-response-.xml │ │ │ ├── list/ │ │ │ │ └── retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml │ │ │ ├── platform/ │ │ │ │ └── v1/ │ │ │ │ └── setup/ │ │ │ │ └── quickflow/ │ │ │ │ └── data/ │ │ │ │ └── get-response.json │ │ │ ├── query/ │ │ │ │ ├── patch_keySuffix-expected.json │ │ │ │ └── patch_keySuffix-expected.sql │ │ │ ├── role/ │ │ │ │ └── retrieve-IsPrivate=false-response.xml │ │ │ └── user/ │ │ │ ├── build-expected.json │ │ │ ├── create-expected.json │ │ │ ├── retrieve-expected.json │ │ │ ├── retrieve-expected.md │ │ │ ├── template-expected.json │ │ │ └── update-expected.json │ │ ├── 9999999/ │ │ │ ├── accountUser/ │ │ │ │ └── retrieve-response.xml │ │ │ ├── asset/ │ │ │ │ ├── build-asset_htmlblock-expected.html │ │ │ │ ├── build-asset_htmlblock-expected.json │ │ │ │ ├── build-templatebasedemail-expected.json │ │ │ │ ├── build-templatebasedemail-html-expected.html │ │ │ │ ├── build-templatebasedemail-preheader-expected.amp │ │ │ │ ├── create-expected.json │ │ │ │ ├── resolveId-1234-notFound-expected.json │ │ │ │ ├── resolveId-1295064-noPath-expected.json │ │ │ │ ├── resolveId-1295064-withPath-expected.json │ │ │ │ ├── retrieve-templatebasedemail-expected.json │ │ │ │ ├── retrieve-templatebasedemail-html-expected.html │ │ │ │ ├── retrieve-templatebasedemail-preheader-expected.amp │ │ │ │ ├── template-emailTemplate-expected.json │ │ │ │ ├── template-templatebasedemail-expected.json │ │ │ │ ├── template-templatebasedemail-html-expected.html │ │ │ │ ├── template-templatebasedemail-preheader-expected.amp │ │ │ │ ├── template-testExisting_asset_htmlblock-expected.json │ │ │ │ ├── testExisting_asset_htmlblock-retrieve-expected.html │ │ │ │ ├── testExisting_asset_htmlblock-retrieve-expected.json │ │ │ │ ├── testExisting_asset_message-html-rcb-id-expected.html │ │ │ │ ├── testExisting_asset_message-html-rcb-key-expected.html │ │ │ │ ├── testExisting_asset_message-html-rcb-name-expected.html │ │ │ │ ├── testExisting_asset_message-preheader-rcb-id-expected.amp │ │ │ │ ├── testExisting_asset_message-preheader-rcb-key-expected.amp │ │ │ │ ├── testExisting_asset_message-preheader-rcb-name-expected.amp │ │ │ │ ├── testExisting_asset_message-text-rcb-id-expected.amp │ │ │ │ ├── testExisting_asset_message-text-rcb-key-expected.amp │ │ │ │ ├── testExisting_asset_message-text-rcb-name-expected.amp │ │ │ │ ├── test_coderesource_js-retrieve-expected.js │ │ │ │ ├── test_coderesource_js-retrieve-expected.json │ │ │ │ ├── test_coderesource_json-retrieve-expected.json │ │ │ │ ├── test_coderesource_json-retrieve-expected.jsonc │ │ │ │ ├── test_coderesource_xml-retrieve-expected.json │ │ │ │ ├── test_coderesource_xml-retrieve-expected.xml │ │ │ │ ├── test_interactivecontent-retrieve-expected.json │ │ │ │ ├── test_landingpage-retrieve-expected.json │ │ │ │ ├── test_microsite-retrieve-expected.json │ │ │ │ └── v1/ │ │ │ │ └── content/ │ │ │ │ ├── assets/ │ │ │ │ │ ├── 1209971/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 1295064/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 1295065/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 1295066/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 1295067/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 16992/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 5286/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 5289/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 808714/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9451/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9456/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9458/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9460/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9463/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9465/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 950143/ │ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── get-response-customerKey=testExisting_asset.json │ │ │ │ │ ├── post-response-key=testNew_assetMessage.json │ │ │ │ │ ├── post-response-key=testNew_asset_htmlblock.json │ │ │ │ │ ├── post-response-key=testNew_asset_template.json │ │ │ │ │ ├── post-response-key=testNew_asset_templatebasedemail.json │ │ │ │ │ ├── post-response-key=testNew_asset_withCBBK_notexisting.json │ │ │ │ │ ├── post-response-key=testNew_asset_withCBBK_preexisting.json │ │ │ │ │ ├── post-response-key=test_slash.json │ │ │ │ │ ├── post-response.json │ │ │ │ │ └── query/ │ │ │ │ │ ├── +post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213-slashfolder.json │ │ │ │ │ ├── post-response-assetType.idIN1,205,206,230,232.json │ │ │ │ │ ├── post-response-assetType.idIN1,3,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,210,211,212,213,215,216,217,218,219,220,221,222,223,224.json │ │ │ │ │ ├── post-response-assetType.idIN1,3,4,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,210,211,212,213,214,215,216,217,218,219,220,221,222.json │ │ │ │ │ ├── post-response-assetType.idIN1,3,4,5,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,207,208,209,210,211,212,213,214,215,216,217,218.json │ │ │ │ │ ├── post-response-assetType.idIN1,5,205,206,207,208,209,230,232.json │ │ │ │ │ ├── post-response-assetType.idIN14,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192.json │ │ │ │ │ ├── post-response-assetType.idIN15,193,194.json │ │ │ │ │ ├── post-response-assetType.idIN215,216,217,218,219,220,221,222,223,224,225,226,227,228.json │ │ │ │ │ ├── post-response-assetType.idIN219,220,221,222,223,224,225,226,227,228,230,232,240,241,242,243,244,245.json │ │ │ │ │ ├── post-response-assetType.idIN223,224,225,226,227,228,230,232.json │ │ │ │ │ ├── post-response-assetType.idIN225,226,227,228,230,232.json │ │ │ │ │ ├── post-response-assetType.idIN240,241,242,243,244,245.json │ │ │ │ │ ├── post-response-assetType.idIN246,247,248,249.json │ │ │ │ │ ├── post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213.json │ │ │ │ │ ├── post-response-assetType.idIN4,214.json │ │ │ │ │ ├── post-response-assetType.idIN5,207,208,209.json │ │ │ │ │ └── post-response-customerKey=testExisting_asset_htmlblock.json │ │ │ │ └── categories/ │ │ │ │ └── post-response.json │ │ │ ├── asset-deploy/ │ │ │ │ └── block/ │ │ │ │ ├── testNew_asset_badExtension.bad-type-extension.json │ │ │ │ └── testNew_asset_badName_bad.asset-block-meta.json │ │ │ ├── asset-deploy2/ │ │ │ │ └── block/ │ │ │ │ ├── testBlacklist_asset_htmlblock.asset-block-meta.html │ │ │ │ └── testBlacklist_asset_htmlblock.asset-block-meta.json │ │ │ ├── asset-slashfolder-deploy/ │ │ │ │ └── block/ │ │ │ │ ├── test_slash.asset-block-meta.html │ │ │ │ └── test_slash.asset-block-meta.json │ │ │ ├── attributeGroup/ │ │ │ │ └── retrieve-expected.json │ │ │ ├── attributeSet/ │ │ │ │ └── retrieve-expected.json │ │ │ ├── automation/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── clone-expected.json │ │ │ │ ├── create-callout-expected.json │ │ │ │ ├── create-expected.json │ │ │ │ ├── create-testNew_automation-expected.md │ │ │ │ ├── delete-response.xml │ │ │ │ ├── patch_fixKeys-pause-expected.json │ │ │ │ ├── patch_fixKeys-schedule-expected.json │ │ │ │ ├── perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml │ │ │ │ ├── perform-08afb0e2-b00a-4c88-fixKey_pause-response.xml │ │ │ │ ├── perform-08afb0e2-b00a-4c88-fixKey_schedule-response.xml │ │ │ │ ├── perform-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml │ │ │ │ ├── retrieve-expected.json │ │ │ │ ├── retrieve-testExisting_automation-expected.md │ │ │ │ ├── retrieve-wait-expected.json │ │ │ │ ├── retrieve-wait-expected.md │ │ │ │ ├── template-expected.json │ │ │ │ ├── update-callout-expected.json │ │ │ │ ├── update-expected.json │ │ │ │ ├── update-testExisting_automation-expected.md │ │ │ │ └── v1/ │ │ │ │ ├── automations/ │ │ │ │ │ ├── 08afb0e2-b00a-4c88-ad2e-1f7f8788c560/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 08afb0e2-b00a-4c88-ad2e-pause/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 08afb0e2-b00a-4c88-fixKey_pause/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 08afb0e2-b00a-4c88-fixKey_schedule/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 0fc2ac96-14ba-495a-8db9-3ddd4f8ac444-wait/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 8f82c2a7-0bae-45a9-bdee-e631ab25c0d5/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ └── post-response.json │ │ │ │ ├── dataextracts/ │ │ │ │ │ ├── 56c5370a-f988-4f36-b0ee-0f876573f6d7/ │ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── post-response.json │ │ │ │ ├── dataextracttypes/ │ │ │ │ │ └── get-response.json │ │ │ │ ├── dataverifications/ │ │ │ │ │ ├── post-response.json │ │ │ │ │ └── testExisting_39f6a488-20eb-4ba0-b0b9/ │ │ │ │ │ ├── delete-response.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── patch-response.json │ │ │ │ ├── filetransfers/ │ │ │ │ │ ├── 72c328ac-f5b0-4e37-91d3-a775666f15a6/ │ │ │ │ │ │ ├── delete-response.json │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── post-response.json │ │ │ │ ├── filters/ │ │ │ │ │ ├── a0f1a1bc-4ea1-44b3-8fe1-ce40ef35c1c0/ │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── f018f237-f7ef-40b0-afc8-39ea2e5dcca4/ │ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ └── get-response.json │ │ │ │ ├── ftplocations/ │ │ │ │ │ └── get-response.json │ │ │ │ ├── imports/ │ │ │ │ │ ├── 1ebf557b-372e-eb11-b81b-48df37d1dbd7/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 9d16f42c-2260-ed11-b849-48df37d1de8b/ │ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── d2474efb-a449-ef11-b876-f40343c95928/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── post-response.json │ │ │ │ ├── queries/ │ │ │ │ │ ├── 549f0568-607c-4940-afef-437965094dae/ │ │ │ │ │ │ └── actions/ │ │ │ │ │ │ └── start/ │ │ │ │ │ │ └── post-response.txt │ │ │ │ │ ├── 549f0568-607c-4940-afef-437965094dat/ │ │ │ │ │ │ ├── actions/ │ │ │ │ │ │ │ └── start/ │ │ │ │ │ │ │ └── post-response.txt │ │ │ │ │ │ ├── delete-response.json │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 549f0568-607c-4940-afef-437965094dat_fixKeys/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── 549f0568-607c-4940-afef-437965094dat_fixKeysSuffix/ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── abcde-607c-4940-afef-437965094dat/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── get-response-Name=testExisting_query.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── post-response.json │ │ │ │ └── scripts/ │ │ │ │ ├── 39f6a488-20eb-4ba0-b0b9-023725b574e4/ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── patch-response.json │ │ │ │ ├── get-response-name=testExisting_script.json │ │ │ │ ├── get-response.json │ │ │ │ └── post-response.json │ │ │ ├── data/ │ │ │ │ └── v1/ │ │ │ │ ├── customobjectdata/ │ │ │ │ │ └── key/ │ │ │ │ │ └── testExisting_dataExtension/ │ │ │ │ │ └── rowset/ │ │ │ │ │ └── get-response.json │ │ │ │ ├── filetransferlocation/ │ │ │ │ │ ├── Salesforce%20Objects%20%26%20Reports/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── testExisting_fileLocation_aws/ │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── testExisting_fileLocation_azure/ │ │ │ │ │ │ ├── delete-response.json │ │ │ │ │ │ └── get-response.json │ │ │ │ │ └── testExisting_fileLocation_exsftp/ │ │ │ │ │ └── patch-response.json │ │ │ │ └── filetransferlocations/ │ │ │ │ └── get-response.json │ │ │ ├── dataExtension/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── create-expected.json │ │ │ │ ├── create-response.xml │ │ │ │ ├── delete-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_dataExtension-response.xml │ │ │ │ ├── retrieve-CustomerKey=testNew_event_withSchema-response.xml │ │ │ │ ├── retrieve-Name=testExisting_dataExtension-response.xml │ │ │ │ ├── retrieve-createdViaEvent-response.xml │ │ │ │ ├── retrieve-expected.json │ │ │ │ ├── retrieve-expected.md │ │ │ │ ├── retrieve-response.xml │ │ │ │ ├── retrieve_event_withSchema-expected.json │ │ │ │ ├── template-expected.json │ │ │ │ ├── update-afterCreatedViaEvent-response.xml │ │ │ │ ├── update-callout-afterCreatedViaEvent-expected.xml │ │ │ │ ├── update-expected.json │ │ │ │ └── update-response.xml │ │ │ ├── dataExtension-deploy/ │ │ │ │ └── testBlacklist_dataExtension.dataExtension-meta.json │ │ │ ├── dataExtensionField/ │ │ │ │ ├── retrieve-CustomerKey=[testExisting_dataExtension].[LastName]-response.xml │ │ │ │ ├── retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml │ │ │ │ ├── retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml │ │ │ │ ├── retrieve-DataExtension.CustomerKey=testNew_event_withSchema-response.xml │ │ │ │ ├── retrieve-DataExtension.CustomerKeyINtestExisting_dataExtension,testNew_dataExtension-response.xml │ │ │ │ ├── retrieve-Name=FirstName-response.xml │ │ │ │ ├── retrieve-Name=LastName-response.xml │ │ │ │ └── retrieve-response.xml │ │ │ ├── dataExtensionTemplate/ │ │ │ │ └── retrieve-response.xml │ │ │ ├── dataExtract/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── dataFilter/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── dataFolder/ │ │ │ │ ├── +retrieve-ContentTypeINasset,asset-shared,cloudpages-slashfolder-response.xml │ │ │ │ ├── create-ContentType=asset,Name=testFolder_samePath,ParentFolderID=89397-response.xml │ │ │ │ ├── create-ContentType=dataextension,Name=my,ParentFolderID=2-response.xml │ │ │ │ ├── create-ContentType=dataextension,Name=path,ParentFolderID=862002-response.xml │ │ │ │ ├── create-ContentType=dataextension,Name=sub,ParentFolderID=862001-response.xml │ │ │ │ ├── create-ContentType=dataextension,Name=subpath,ParentFolderID=862003-response.xml │ │ │ │ ├── create-response.xml │ │ │ │ ├── retrieve-ContentType=asset-shared-QAA-response.xml │ │ │ │ ├── retrieve-ContentType=asset-shared-response.xml │ │ │ │ ├── retrieve-ContentType=automations-response.xml │ │ │ │ ├── retrieve-ContentType=journey-response.xml │ │ │ │ ├── retrieve-ContentType=queryactivity-response.xml │ │ │ │ ├── retrieve-ContentType=ssjsactivity-response.xml │ │ │ │ ├── retrieve-ContentType=userinitiatedsends-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-sha,automatio,cloudpage,dataexten,filteract,filterdef,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,useriniti-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-sha,automatio,cloudpage,dataexten,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,triggered,triggered,useriniti-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-sha,automatio,cloudpage,dataexten,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,useriniti-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-sha,dataexten,salesforc,shared_da,shared_da,shared_sa,synchroni,automatio,useriniti,journey,mysubs,list,publicati,queryacti,ssjsactiv,triggered,triggered-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared,cloudpages,dataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared,cloudpages,journey-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared,cloudpages,ssjsactivity-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared,cloudpages-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared-QAA-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset,asset-shared-response.xml │ │ │ │ ├── retrieve-ContentTypeINasset-shared,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml │ │ │ │ ├── retrieve-ContentTypeINautomations,queryactivity-response.xml │ │ │ │ ├── retrieve-ContentTypeINcontextual_suppression_list,hidden,list,mysubs,publication,suppression_list,triggered_send,triggered_send_journeybuilder-response.xml │ │ │ │ ├── retrieve-ContentTypeINcontextual_suppression_list,list,mysubs,publication,suppression_list-response.xml │ │ │ │ ├── retrieve-ContentTypeINdataextension,hidden,queryactivity,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ ├── retrieve-ContentTypeINdataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ ├── retrieve-ContentTypeINdataextension,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml │ │ │ │ ├── retrieve-ContentTypeINfilteractivity,hidden-response.xml │ │ │ │ ├── retrieve-ContentTypeINfilterdefinition,hidden-response.xml │ │ │ │ ├── retrieve-ContentTypeINhidden,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml │ │ │ │ ├── retrieve-ContentTypeINhidden,triggered_send,triggered_send_journeybuilder-response.xml │ │ │ │ ├── retrieve-ContentTypeINshared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml │ │ │ │ ├── retrieve-QAA-response.xml │ │ │ │ ├── retrieve-response.xml │ │ │ │ ├── retrieve-samePathOtherBU-response.xml │ │ │ │ └── update-response.xml │ │ │ ├── deliveryProfile/ │ │ │ │ └── get-expected.json │ │ │ ├── domainVerification/ │ │ │ │ ├── create-expected.json │ │ │ │ ├── get-sap-expected.json │ │ │ │ └── update-expected.json │ │ │ ├── email/ │ │ │ │ ├── retrieve-response.xml │ │ │ │ └── v1/ │ │ │ │ ├── category/ │ │ │ │ │ ├── post-response-parentCatId=290937,name=my,catType=automations.json │ │ │ │ │ ├── post-response-parentCatId=862100,name=sub,catType=automations.json │ │ │ │ │ ├── post-response-parentCatId=862101,name=path,catType=automations.json │ │ │ │ │ └── post-response-parentCatId=862102,name=subpath,catType=automations.json │ │ │ │ └── filters/ │ │ │ │ └── filterdefinition/ │ │ │ │ ├── 10ef27dd-4be8-4bf6-970a-8acf8e281e55/ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── patch-response.json │ │ │ │ ├── category/ │ │ │ │ │ ├── 5318/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── 8502/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ └── 8503/ │ │ │ │ │ └── get-response.json │ │ │ │ └── post-response.json │ │ │ ├── emailSend/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── emailSendDefinition/ │ │ │ │ ├── create-response.xml │ │ │ │ ├── delete-response.xml │ │ │ │ ├── retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml │ │ │ │ └── update-response.xml │ │ │ ├── event/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-automation-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-published-expected.json │ │ │ │ ├── post_withExistingDE-callout-expected.json │ │ │ │ ├── post_withExistingDE-expected.json │ │ │ │ ├── post_withSchema-callout-expected.json │ │ │ │ ├── post_withSchema-expected.json │ │ │ │ ├── put-callout-expected.json │ │ │ │ ├── put-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── event-deploy/ │ │ │ │ ├── testNew_event_badExtension.bad-type-extension.json │ │ │ │ └── testNew_event_badName_bad.event-meta.json │ │ │ ├── eventDefinition/ │ │ │ │ └── get-expected.json │ │ │ ├── fileLocation/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-aws-expected.json │ │ │ │ ├── get-azure-expected.json │ │ │ │ ├── get-eftp-expected.json │ │ │ │ ├── get-exsftp-expected.json │ │ │ │ ├── get-gcp-expected.json │ │ │ │ ├── get-sor-expected.json │ │ │ │ ├── patch-aws-expected.json │ │ │ │ ├── patch-exsftp-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── fileTransfer/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── filter/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── filterActivity/ │ │ │ │ ├── create-response.xml │ │ │ │ └── retrieve-CustomerKey=testExisting_filter-response.xml │ │ │ ├── filterDefinition/ │ │ │ │ └── retrieve-CustomerKey=testExisting_dataFilter-response.xml │ │ │ ├── folder-deploy/ │ │ │ │ ├── Data Extensions/ │ │ │ │ │ ├── my/ │ │ │ │ │ │ ├── sub/ │ │ │ │ │ │ │ ├── path/ │ │ │ │ │ │ │ │ └── subpath.folder-meta.json │ │ │ │ │ │ │ └── path.folder-meta.json │ │ │ │ │ │ └── sub.folder-meta.json │ │ │ │ │ ├── my.folder-meta.json │ │ │ │ │ └── testExisting_folder.folder-meta.json │ │ │ │ └── my automations/ │ │ │ │ ├── my/ │ │ │ │ │ ├── sub/ │ │ │ │ │ │ ├── path/ │ │ │ │ │ │ │ └── subpath.folder-meta.json │ │ │ │ │ │ └── path.folder-meta.json │ │ │ │ │ └── sub.folder-meta.json │ │ │ │ └── my.folder-meta.json │ │ │ ├── folder-deploy-samepath/ │ │ │ │ └── Content Builder/ │ │ │ │ └── testFolder_samePath.folder-meta.json │ │ │ ├── folder-deploy-slash/ │ │ │ │ └── Content Builder/ │ │ │ │ └── Headers%2FFolders.folder-meta.json │ │ │ ├── hub/ │ │ │ │ └── v1/ │ │ │ │ └── contacts/ │ │ │ │ └── schema/ │ │ │ │ ├── attributeGroups/ │ │ │ │ │ └── get-response.json │ │ │ │ └── setDefinitions/ │ │ │ │ └── get-response.json │ │ │ ├── importDefinition/ │ │ │ │ ├── retrieve-CustomerKey=testExisting_importFile-response.xml │ │ │ │ └── retrieve-Name=testExisting_importFile-response.xml │ │ │ ├── importFile/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-dataImport-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-sms-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── interaction/ │ │ │ │ └── v1/ │ │ │ │ ├── eventDefinitions/ │ │ │ │ │ ├── get-response.json │ │ │ │ │ ├── key_DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── key_testExisting_event/ │ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ │ └── put-response.json │ │ │ │ │ ├── key_testExisting_event_automation/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── post_withExistingDE-response.json │ │ │ │ │ └── post_withSchema-response.json │ │ │ │ └── interactions/ │ │ │ │ ├── 0175b971-71a3-4d8e-98ac-48121f3fbf4f/ │ │ │ │ │ ├── audit/ │ │ │ │ │ │ └── all/ │ │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ │ ├── get-response-versionNumber=2.json │ │ │ │ │ │ └── get-response-versionNumber=3.json │ │ │ │ │ ├── delete-response-versionNumber=1.txt │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ ├── get-response-versionNumber=3.json │ │ │ │ │ └── get-response.json │ │ │ │ ├── 3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/ │ │ │ │ │ ├── delete-response.txt │ │ │ │ │ └── get-response.json │ │ │ │ ├── dsfdsafdsa-922c-4568-85a5-e5cc77efc3be/ │ │ │ │ │ ├── audit/ │ │ │ │ │ │ └── all/ │ │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ │ └── get-response-versionNumber=2.json │ │ │ │ │ └── delete-response.txt │ │ │ │ ├── get-response-status=Published.json │ │ │ │ ├── get-response.json │ │ │ │ ├── key_testExisting_journey_Multistep/ │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── put-response.json │ │ │ │ ├── key_testExisting_journey_Quicksend/ │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ └── get-response.json │ │ │ │ ├── key_testExisting_journey_updatecontact/ │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── put-response.json │ │ │ │ ├── key_testExisting_journey_updatecontact_sharedDE/ │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── put-response.json │ │ │ │ ├── key_testExisting_temail/ │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ ├── put-response-paused.json │ │ │ │ │ └── put-response.json │ │ │ │ ├── key_testExisting_temail_notPublished/ │ │ │ │ │ ├── get-response-versionNumber=1.json │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── put-response.json │ │ │ │ ├── key_testNew_temail_notPublished/ │ │ │ │ │ └── get-response.json │ │ │ │ ├── post-response.json │ │ │ │ ├── publishAsync/ │ │ │ │ │ └── 0175b971-71a3-4d8e-98ac-48121f3fbf4f/ │ │ │ │ │ ├── post-response-versionNumber=1.json │ │ │ │ │ └── post-response-versionNumber=3.json │ │ │ │ ├── publishStatus/ │ │ │ │ │ └── 45f06c0a-3ed2-48b2-a6a8-b5119253f01c/ │ │ │ │ │ ├── get-response-failed.json │ │ │ │ │ ├── get-response-success.json │ │ │ │ │ └── get-response-successWarnings.json │ │ │ │ ├── transactional/ │ │ │ │ │ ├── create/ │ │ │ │ │ │ └── post-response.json │ │ │ │ │ ├── pause/ │ │ │ │ │ │ └── post-response.json │ │ │ │ │ └── resume/ │ │ │ │ │ └── post-response.json │ │ │ │ ├── validateAsync/ │ │ │ │ │ └── 0175b971-71a3-4d8e-98ac-48121f3fbf4f/ │ │ │ │ │ └── post-response.json │ │ │ │ └── validateStatus/ │ │ │ │ └── 45f06c0a-3ed2-48b2-a6a8-b5119253f01c/ │ │ │ │ ├── get-response-failed.json │ │ │ │ ├── get-response-success.json │ │ │ │ ├── get-response-successWarnings.json │ │ │ │ └── get-response.json │ │ │ ├── journey/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── create-transactionaEmail-publish-expected.json │ │ │ │ ├── get-multistep-expected.json │ │ │ │ ├── get-published-expected.json │ │ │ │ ├── get-quicksend-expected.json │ │ │ │ ├── get-quicksend-rcb-id-expected.json │ │ │ │ ├── get-quicksend-rcb-key-expected.json │ │ │ │ ├── get-quicksend-rcb-name-expected.json │ │ │ │ ├── get-transactionalEmail-expected.json │ │ │ │ ├── get-updatecontact-expected.json │ │ │ │ ├── get-updatecontact-sharedDE-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ ├── publish-callout-expected.json │ │ │ │ ├── put-expected.json │ │ │ │ ├── put-updatecontact-expected.json │ │ │ │ ├── put-updatecontact-sharedDE-expected.json │ │ │ │ ├── template-expected.json │ │ │ │ └── validate-callout-expected.json │ │ │ ├── legacy/ │ │ │ │ └── v1/ │ │ │ │ ├── beta/ │ │ │ │ │ ├── automations/ │ │ │ │ │ │ └── notifications/ │ │ │ │ │ │ ├── RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/ │ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ │ └── post-response.json │ │ │ │ │ │ ├── RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToyNTow/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ └── cDhLQ2o2NExxVVc5N3VZeHF5WEExUToyNTow/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── bulk/ │ │ │ │ │ │ └── automations/ │ │ │ │ │ │ └── automation/ │ │ │ │ │ │ └── definition/ │ │ │ │ │ │ ├── NewRkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToyNTow/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── cDhLQ2o2NExxVVc5N3VZeHF5WEExUToyNTow/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ ├── post-response-pauseSchedule.json │ │ │ │ │ │ └── post-response-schedule.json │ │ │ │ │ ├── messaging/ │ │ │ │ │ │ └── deliverypolicy/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ ├── mobile/ │ │ │ │ │ │ ├── code/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── imports/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── keyword/ │ │ │ │ │ │ │ ├── NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow/ │ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ │ ├── cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow/ │ │ │ │ │ │ │ │ └── delete-response.json │ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ │ └── post-response.json │ │ │ │ │ │ └── message/ │ │ │ │ │ │ ├── NTIzOjc4OjA/ │ │ │ │ │ │ │ ├── delete-response.json │ │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ │ └── post-response.json │ │ │ │ │ │ ├── NTQ3Ojc4OjA/ │ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── post-response.json │ │ │ │ │ └── object/ │ │ │ │ │ └── NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow/ │ │ │ │ │ └── get-response.json │ │ │ │ └── beta2/ │ │ │ │ └── data/ │ │ │ │ └── campaign/ │ │ │ │ └── get-response.json │ │ │ ├── list/ │ │ │ │ └── retrieve-response.xml │ │ │ ├── messaging/ │ │ │ │ └── v1/ │ │ │ │ ├── domainverification/ │ │ │ │ │ ├── delete/ │ │ │ │ │ │ └── post-response.txt │ │ │ │ │ ├── get-response.json │ │ │ │ │ ├── post-response.txt │ │ │ │ │ └── update/ │ │ │ │ │ └── post-response.txt │ │ │ │ ├── email/ │ │ │ │ │ └── definitions/ │ │ │ │ │ ├── get-response.json │ │ │ │ │ ├── post-response.json │ │ │ │ │ ├── testExisting_temail/ │ │ │ │ │ │ ├── delete-response.json │ │ │ │ │ │ ├── get-response.json │ │ │ │ │ │ └── patch-response.json │ │ │ │ │ ├── testExisting_temail_notPublished/ │ │ │ │ │ │ └── get-response.json │ │ │ │ │ └── testNew_temail_notPublished/ │ │ │ │ │ └── get-response.json │ │ │ │ ├── push/ │ │ │ │ │ └── definitions/ │ │ │ │ │ ├── get-response.json │ │ │ │ │ ├── post-response.json │ │ │ │ │ └── testExisting_tpush/ │ │ │ │ │ ├── get-response.json │ │ │ │ │ └── patch-response.json │ │ │ │ └── sms/ │ │ │ │ └── definitions/ │ │ │ │ ├── get-response.json │ │ │ │ ├── post-response.json │ │ │ │ └── testExisting_tsms/ │ │ │ │ ├── get-response.json │ │ │ │ └── patch-response.json │ │ │ ├── mobileKeyword/ │ │ │ │ ├── build-expected.amp │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.amp │ │ │ │ ├── get-expected.json │ │ │ │ ├── post-create-expected.amp │ │ │ │ ├── post-create-expected.json │ │ │ │ ├── template-expected.amp │ │ │ │ └── template-expected.json │ │ │ ├── mobileMessage/ │ │ │ │ ├── build-expected.amp │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.amp │ │ │ │ ├── get-expected.json │ │ │ │ ├── post-create-expected.amp │ │ │ │ ├── post-create-expected.json │ │ │ │ ├── post-update-expected.amp │ │ │ │ ├── post-update-expected.json │ │ │ │ ├── template-expected.amp │ │ │ │ └── template-expected.json │ │ │ ├── program/ │ │ │ │ ├── retrieve-CustomerKey=testExisting_automation-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_automation_fixKey_pause-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_automation_fixKey_schedule-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_automation_fixedKey_paused-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_automation_fixedKey_scheduled-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_automation_pause-response.xml │ │ │ │ ├── retrieve-CustomerKey=testNew_automation-response.xml │ │ │ │ ├── retrieve-Name=testExisting_automation-response.xml │ │ │ │ └── retrieve-response.xml │ │ │ ├── query/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── build-expected.sql │ │ │ │ ├── clone-expected.json │ │ │ │ ├── clone-expected.sql │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-expected.sql │ │ │ │ ├── get2-expected.json │ │ │ │ ├── get_sharedDE-expected.json │ │ │ │ ├── get_sharedDE-expected.sql │ │ │ │ ├── patch-expected.json │ │ │ │ ├── patch-expected.sql │ │ │ │ ├── patch_fixKeys-expected.json │ │ │ │ ├── patch_fixKeys-expected.sql │ │ │ │ ├── patch_fixKeysSuffix-expected.json │ │ │ │ ├── patch_fixKeysSuffix-expected.sql │ │ │ │ ├── post-expected.json │ │ │ │ ├── post-expected.sql │ │ │ │ ├── template-expected.json │ │ │ │ ├── template-expected.sql │ │ │ │ ├── template_sharedDE-expected.json │ │ │ │ └── template_sharedDE-expected.sql │ │ │ ├── queryDefinition/ │ │ │ │ ├── retrieve-CustomerKey=badANDStatus=Active-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_query2ANDStatus=Active-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_query_fixKeysSuffixANDStatus=Active-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_query_fixedKeysANDStatus=Active-response.xml │ │ │ │ └── retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml │ │ │ ├── script/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── build-expected.ssjs │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-expected.ssjs │ │ │ │ ├── get_ampincluded-expected.html │ │ │ │ ├── get_ampincluded-expected.json │ │ │ │ ├── get_ampincluded-rcb-id-expected.html │ │ │ │ ├── get_ampincluded-rcb-key-expected.html │ │ │ │ ├── get_ampincluded-rcb-name-expected.html │ │ │ │ ├── get_ampscript-expected.html │ │ │ │ ├── get_ampscript-expected.json │ │ │ │ ├── get_ampscript-rcb-id-expected.html │ │ │ │ ├── get_ampscript-rcb-key-expected.html │ │ │ │ ├── get_ampscript-rcb-name-expected.html │ │ │ │ ├── get_mixed-expected.html │ │ │ │ ├── get_mixed-expected.json │ │ │ │ ├── get_mixed-rcb-id-expected.html │ │ │ │ ├── get_mixed-rcb-key-expected.html │ │ │ │ ├── get_mixed-rcb-name-expected.html │ │ │ │ ├── get_noScriptTag-expected.html │ │ │ │ ├── get_noScriptTag-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── patch-expected.ssjs │ │ │ │ ├── post-expected.json │ │ │ │ ├── post-expected.ssjs │ │ │ │ ├── template-expected.json │ │ │ │ └── template-expected.ssjs │ │ │ ├── sendClassification/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── create-response.xml │ │ │ │ ├── delete-response.xml │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ ├── retrieve-response.xml │ │ │ │ ├── template-expected.json │ │ │ │ └── update-response.xml │ │ │ ├── senderProfile/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── create-response.xml │ │ │ │ ├── delete-response.xml │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-rcb-id-expected.json │ │ │ │ ├── get-rcb-key-expected.json │ │ │ │ ├── get-rcb-name-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ ├── retrieve-CustomerKey=Default-response.xml │ │ │ │ ├── retrieve-CustomerKey=wrong-key-response.xml │ │ │ │ ├── retrieve-response.xml │ │ │ │ ├── template-expected.json │ │ │ │ └── update-response.xml │ │ │ ├── transactionalEmail/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── create-publish-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-published-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── transactionalPush/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── transactionalSMS/ │ │ │ │ ├── build-expected.amp │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.amp │ │ │ │ ├── get-expected.json │ │ │ │ ├── patch-expected.amp │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.amp │ │ │ │ ├── post-expected.json │ │ │ │ ├── template-expected.amp │ │ │ │ └── template-expected.json │ │ │ ├── triggeredSend/ │ │ │ │ ├── build-expected.json │ │ │ │ ├── get-expected.json │ │ │ │ ├── get-rcb-id-expected.json │ │ │ │ ├── get-rcb-key-expected.json │ │ │ │ ├── get-rcb-name-expected.json │ │ │ │ ├── patch-expected.json │ │ │ │ ├── post-expected.json │ │ │ │ └── template-expected.json │ │ │ ├── triggeredSendDefinition/ │ │ │ │ ├── create-response.xml │ │ │ │ ├── delete-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_triggeredSend-response.xml │ │ │ │ ├── retrieve-CustomerKey=testExisting_triggeredSend_rcb-response.xml │ │ │ │ ├── retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml │ │ │ │ ├── retrieve-TriggeredSendStatusINdummy,Active-response.xml │ │ │ │ └── update-response.xml │ │ │ ├── triggeredSendSummary/ │ │ │ │ ├── get-expected.json │ │ │ │ └── retrieve-response.xml │ │ │ └── verification/ │ │ │ ├── build-expected.json │ │ │ ├── get-expected.json │ │ │ ├── patch-expected.json │ │ │ ├── post-expected.json │ │ │ └── template-expected.json │ │ ├── auth.json │ │ ├── rest404-response.json │ │ └── retrieve-response.xml │ ├── type.asset.test.js │ ├── type.attributeGroup.test.js │ ├── type.attributeSet.test.js │ ├── type.automation.test.js │ ├── type.dataExtension.test.js │ ├── type.dataExtensionField.test.js │ ├── type.dataExtract.test.js │ ├── type.dataFilter.test.js │ ├── type.deliveryProfile.test.js │ ├── type.domainVerification.test.js │ ├── type.emailSend.test.js │ ├── type.event.test.js │ ├── type.fileLocation.test.js │ ├── type.fileTransfer.test.js │ ├── type.filter.test.js │ ├── type.folder.test.js │ ├── type.importFile.test.js │ ├── type.journey.test.js │ ├── type.mobileKeyword.test.js │ ├── type.mobileMessage.test.js │ ├── type.query.test.js │ ├── type.script.test.js │ ├── type.sendClassification.test.js │ ├── type.senderProfile.test.js │ ├── type.transactionalEmail.test.js │ ├── type.transactionalPush.test.js │ ├── type.transactionalSMS.test.js │ ├── type.triggeredSend.test.js │ ├── type.triggeredSendSummary.test.js │ ├── type.user.test.js │ ├── type.verification.test.js │ └── utils.js ├── tsconfig.json ├── tsconfig.npmScripts.json ├── tsconfig.precommit.json └── types/ └── mcdev.d.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .beautyamp.json ================================================ { "ampscript": { "capitalizeAndOrNot": true, "capitalizeIfFor": true, "capitalizeSet": true, "capitalizeVar": true, "maxParametersPerLine": 4 }, "editor": { "insertSpaces": true, "tabSize": 4 } } ================================================ FILE: .bitbucket/PULL_REQUEST_TEMPLATE.md ================================================ # PR details ## What is the purpose of this pull request? (put an "X" next to an item) - [ ] Documentation update - [ ] Bug fix - [ ] New metadata support - [ ] Enhanced metadata - [ ] Add a CLI option - [ ] Add something to the core - [ ] Other, please explain: ## What changes did you make? (Give an overview) ... ## Is there anything you'd like reviewers to focus on? ... ================================================ FILE: .coverage-comment-template.svelte ================================================

Coverage Report

Commit:{short_commit_sha}
Base: {base_ref}@{base_short_commit_sha}

{#if has_base_data} {/if} {#each summary_list as { type, percent }} {#if has_base_data} {/if} {/each}
TypeBaseThis PR
{type} {#if Number.isFinite(percent.base)}  {percent.base}% {:else} - {/if} {#if Number.isFinite(percent.total)}  {percent.total}% {#if has_base_data}  ({formatPercentDiff(percent.diff)}) {/if} {:else} - {/if}
Details (changed files):
{#each changed_files_coverage_data as [file, data]} {@const percents = [ data.statements.pct, data.branches.pct, data.functions.pct, data.lines.pct, ]} {#each percents as percent} {/each} {/each}
File Statements Branches Functions Lines
{file} {#if Number.isFinite(percent)}  {percent}% {:else} - {/if}
================================================ FILE: .editorconfig ================================================ root = true [*] end_of_line = lf indent_style = space indent_size = 4 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true ================================================ FILE: .fork/.prettierrc ================================================ { "useTabs": false, "tabWidth": 2, "printWidth": 40, "trailingComma": "none" } ================================================ FILE: .fork/custom-commands.json ================================================ [ { "version" : 1 }, { "action" : { "type" : "url", "url" : "https://github.com/Accenture/sfmc-devtools/compare/main...${ref:short}?expand=1&template=pr_template_release.md" }, "name" : "Create PR/Release-PR to master branch", "refTargets" : [ "localbranch", "remotebranch" ], "target" : "ref" }, { "action" : { "type" : "url", "url" : "https://github.com/Accenture/sfmc-devtools/compare/develop...${ref:short}?expand=1" }, "name" : "Create PR/To develop branch", "refTargets" : [ "localbranch", "remotebranch" ], "target" : "ref" }, { "action" : { "type" : "url", "url" : "https://github.com/Accenture/sfmc-devtools/compare/hotfix...${ref:short}?expand=1" }, "name" : "Create PR/To hotfix branch", "refTargets" : [ "localbranch", "remotebranch" ], "target" : "ref" }, { "action" : { "script" : "SKIP_HOOKS=1 git switch ${ref}", "showOutput" : false, "type" : "sh", "waitForExit" : true }, "name" : "Skip Hooks/Checkout", "refTargets" : [ "localbranch" ], "target" : "ref" }, { "action" : { "script" : "SKIP_HOOKS=1 git switch ${ref:short} && SKIP_HOOKS=2 git pull", "showOutput" : false, "type" : "sh", "waitForExit" : true }, "name" : "Skip Hooks/Checkout & Pull", "refTargets" : [ "remotebranch" ], "target" : "ref" }, { "name" : "Skip Hooks/Commit", "refTargets" : [ "localbranch", "remotebranch" ], "target" : "ref", "ui" : { "buttons" : [ { "action" : { "args" : "commit -n -m \"$1{text}\" -m \" $2{text}\"", "path" : "${git}", "showOutput" : false, "type" : "process", "waitForExit" : true }, "title" : "Commit without Hooks" }, { "action" : { "type" : "cancel" }, "title" : "Cancel" } ], "controls" : [ { "placeholder" : "", "text" : "", "textBoxType" : "generic", "title" : "Commit subject", "type" : "textBox" }, { "placeholder" : "", "text" : "", "textBoxType" : "generic", "title" : "Description", "type" : "textBox" } ], "description" : "This will create a commit but not run pre-commit hooks", "title" : "Commit skipping Hooks" } }, { "action" : { "script" : "SKIP_HOOKS=4 git merge ${ref:short}", "showOutput" : false, "type" : "sh", "waitForExit" : true }, "name" : "Skip Hooks/Merge into current branch", "refTargets" : [ "localbranch" ], "target" : "ref" }, { "action" : { "script" : "SKIP_HOOKS=3 git pull", "showOutput" : false, "type" : "sh", "waitForExit" : true }, "name" : "Skip Hooks/Pull", "refTargets" : [ "localbranch", "remotebranch" ], "target" : "ref" } ] ================================================ FILE: .gitattributes ================================================ # Set the default behavior, in case people don't have core.autocrlf set. * text=auto eol=lf # Declare files that will always have LF line endings on checkout. *.ssjs text eol=lf @types/** linguist-generated ================================================ FILE: .github/ISSUE_TEMPLATE/bug.yml ================================================ name: 🐞 Bug description: File a bug/issue title: '[BUG] ' labels: [bug, NEW] body: - type: checkboxes attributes: label: Is there an existing issue for this? description: Please [search here](https://github.com/Accenture/sfmc-devtools/issues) to see if an issue already exists for your problem. options: - label: I have searched the existing issues required: true - type: textarea attributes: label: Current Behavior description: A clear & concise description of what you're experiencing. validations: required: false - type: textarea attributes: label: Expected Behavior description: A clear & concise description of what you expected to happen. validations: required: false - type: textarea attributes: label: Steps To Reproduce description: Steps to reproduce the behavior. value: | 1. Go to '...' 2. Click on '....' 3. Run '...' 4. See error... validations: required: false - type: dropdown id: version attributes: label: Version description: What version of our software are you running? (mcdev --version) options: - 9.0.3 - 9.0.2 - 9.0.1 - 9.0.0 - 8.4.0 - 8.3.1 - 8.3.0 - 8.2.1 - 8.2.0 - 8.1.0 - 8.0.2 - 8.0.1 - 8.0.0 - 7.10.1 - 7.10.0 - 7.9.0 - 7.8.0 - 7.7.2 - 7.7.1 - 7.7.0 - 7.6.3 - 7.6.2 - 7.6.1 - 7.6.0 - 7.5.0 - 7.4.4 - 7.4.3 - 7.4.2 - 7.4.1 - 7.4.0 - 7.3.1 - 7.3.0 - 7.2.0 - 7.1.4 - 7.1.3 - 7.1.2 - 7.1.1 - 7.1.0 - 7.0.4 - 7.0.3 - 7.0.2 - 7.0.1 - 7.0.0 - 6.0.2 - 6.0.1 - 6.0.0 - 5.3.0 - 5.2.0 - 5.1.0 - 5.0.2 - 5.0.1 - 5.0.0 - 4.3.4 - 4.3.3 - 4.3.2 - 4.3.1 - 4.3.0 - 4.2.1 - 4.2.0 - 4.1.12 - 4.1.11 - 4.1.10 - 4.1.9 - 4.1.8 - 4.1.7 - 4.1.6 - 4.1.5 - 4.1.4 - 4.1.3 - 4.1.2 - 4.1.1 - 4.1.0 - 4.0.2 - 4.0.1 - 4.0.0 - 3.1.3 - 3.1.2 - 3.1.1 - 3.1.0 - 3.0.3 - 3.0.2 - 3.0.1 - develop-branch validations: required: true - type: textarea attributes: label: Environment description: | examples: - **Operating system (Windows/Mac/Linux/...)**: Windows 10 - **Node (node --version)**: 13.14.0 - **npm (npm --version)**: 7.6.3 value: | - OS: - Node: - npm: validations: required: false - type: checkboxes attributes: label: Participation options: - label: I am willing to submit a pull request for this issue. required: false - type: textarea attributes: label: Additional comments description: Is there anything else that's important for the team to know? ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: "[FEATURE] " labels: NEW, enhancement assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/ISSUE_TEMPLATE/task.md ================================================ --- name: Task about: Technical improvements without functional impact / changes to the Documentation title: "[TASK] " labels: NEW, chore assignees: '' issueType: task --- ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/pr_template_release.md ================================================ # Release details ## Checklist ### Before merge - [ ] Wiki updated with info in ticket listed under **Documentation** - [ ] ran `npm run prepare-release` (which runs `npm audit fix`, `npm run lint-ts`, `npm run lint:fix`, `git add`, `git commit`) - [ ] pushed potential changes made by prepare-release ### After merge - [ ] merged all dependabot PRs that target main branch - [ ] updated [bug template](/.github/ISSUE_TEMPLATE/bug.yml) to include the new version - [ ] updated [.mcdevrc](/test/mockRoot/.mcdevrc.json) for tests to the new version - [ ] ran `npm run version:major/minor/patch` - [ ] pushed version-prep commits - [ ] merged main branch into develop branch - [ ] closed GitHub milestone - [ ] created [new GitHub Release](https://github.com/Accenture/sfmc-devtools/releases/new) ## Documentation ... insert updated documentation here ... ## Issues - closes #1234567 ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ # PR details ## What changes did you make? (Give an overview) - closes #1234 ## Further details (optional) ... ## Checklist - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] test scripts updated - [ ] Wiki updated (if applicable) ================================================ FILE: .github/copilot-instructions.md ================================================ # GitHub Copilot Instructions for sfmc-devtools Always assume a bug-ticket might be outdated and first try to verify if the described issue is still occurring. ## Commit Messages Prefix every commit message with the issue number it was created for: ``` #1234: <commit message> ``` Example: `#1234: fix journey deployment error` ## Branch Naming Branch names must follow this pattern, where the type is derived from the issue type: ``` copilot/task/1234-issue-title copilot/bug/1234-issue-title copilot/feature/1234-issue-title ``` - Use `task` for task/chore issues - Use `bug` for bug report issues - Use `feature` for feature request/enhancement issues - Replace spaces in the issue title with hyphens and use lowercase ## Pull Request Title The PR title should be derived from the branch name: ``` Branch: copilot/task/1234-issue-title PR title: task/1234 issue title ``` Format: `<type>/<issue-number> <issue title with spaces>` ## Pull Request Description Follow the structure defined in [PULL_REQUEST_TEMPLATE.md](./PULL_REQUEST_TEMPLATE.md): ```markdown # PR details ## What changes did you make? (Give an overview) - closes #1234 ## Further details (optional) ... ## Checklist - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] test scripts updated - [ ] Wiki updated (if applicable) ``` Replace `#1234` with the actual issue number the PR is created for. ## Issue Relationship Always link the PR to the issue it was created for by including `closes #<issue-number>` in the PR description. ## Labels The repository has component labels prefixed with `c/` based on the class names in `lib/metadataTypes/`. When files in that directory are changed, assign the matching pre-existing `c/` label(s) to the PR. Examples: - Changes to `lib/metadataTypes/Journey.js` → assign label `c/journey` - Changes to `lib/metadataTypes/Automation.js` → assign label `c/automation` - Changes to `lib/metadataTypes/DataExtension.js` → assign label `c/dataextension` The label name is `c/` followed by the lower camel-cased class name (filename without extension). Only assign labels that already exist in the repository. ## Milestone Assign the same milestone to the PR that the issue has assigned. ================================================ FILE: .github/dependabot.yml ================================================ # To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: 'npm' # See documentation for possible values directory: '/' # Location of package manifests schedule: interval: 'weekly' target-branch: 'develop' open-pull-requests-limit: 10 labels: - 'dependencies' - package-ecosystem: 'github-actions' directory: '/' schedule: interval: 'weekly' target-branch: 'main' labels: - 'dependencies' - 'github-action' ================================================ FILE: .github/pr-labeler.yml ================================================ enhancement: ['feature/*', 'feat/*', 'copilot/feature/*'] bug: ['bugfix/*', 'bug/*', 'fix/*', 'hotfix/*', 'copilot/bug/*'] chore: ['chore/*', 'task/*', 'copilot/task/*'] ================================================ FILE: .github/workflows/close_issues_on_merge.yml ================================================ name: Close issues related to a merged pull request based on master branch. on: pull_request: types: [closed] branches: - develop - hotfix jobs: closeIssueOnPrMergeTrigger: permissions: contents: read pull-requests: read issues: write runs-on: ubuntu-latest steps: - name: Closes issues related to a merged pull request. uses: ldez/gha-mjolnir@v1.5.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/code-test.yml ================================================ # Custom tests for mcdev # name: "Code Testing" on: push: branches: [main, develop, hotfix] pull_request: # The branches below must be a subset of the branches above branches: [main, develop, hotfix] jobs: lintandTesting: runs-on: ubuntu-latest strategy: fail-fast: false matrix: node: ["20.19", 21, 22, 23, 24, 25] name: lint & test w/ node v${{ matrix.node }} permissions: actions: read contents: read security-events: write steps: - name: Checkout repository uses: actions/checkout@v6 - name: Setup node uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} registry-url: https://registry.npmjs.org/ - run: npm ci --ignore-scripts - run: npm run lint # Assuming code passes, run tests - name: Run mcdev-tests run: npm run test ================================================ FILE: .github/workflows/coverage-base-update.yml ================================================ name: Update coverage comment # base-update.yml on: pull_request: types: [edited] permissions: # allow dependabot to execute this workflow pull-requests: write jobs: hello_world_job: runs-on: ubuntu-latest name: Test and report steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 1000 - name: Prepare for Report Coverage (without nyc run) run: | npm i svelte-to-html@1.0.9 git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1000 - name: Download artifact for base branch uses: dawidd6/action-download-artifact@v19 continue-on-error: true with: workflow: ${{ github.event.pull_request.base.ref == 'main' && 'coverage-main-branch.yml' || github.event.pull_request.base.ref == 'develop' && 'coverage-develop-branch.yml' || 'coverage.yml' }} workflow_conclusion: success commit: ${{github.event.pull_request.base.sha}} name: 'test-coverage-output' path: base-artifacts search_artifacts: true - name: Download artifact for to be merged branch uses: dawidd6/action-download-artifact@v19 continue-on-error: true with: workflow: 'coverage.yml' workflow_conclusion: success commit: ${{github.event.pull_request.head.sha}} name: 'test-coverage-output' path: artifacts search_artifacts: true - name: Check file existence id: check_files uses: andstor/file-existence-action@v3 with: files: 'base-artifacts/coverage-summary.json, artifacts/coverage-summary.json' - name: Update Coverage comment uses: sidx1024/report-nyc-coverage-github-action@v1.2.7 if: steps.check_files.outputs.files_exists == 'true' # Only runs if all of the files exists with: coverage_file: 'artifacts/coverage-summary.json' base_coverage_file: 'base-artifacts/coverage-summary.json' comment_template_file: '.coverage-comment-template.svelte' ================================================ FILE: .github/workflows/coverage-develop-branch.yml ================================================ name: Test coverage for develop branch # default-branch.yml on: push: branches: - develop permissions: # allow dependabot to execute this workflow pull-requests: write jobs: hello_world_job: runs-on: ubuntu-latest name: Test and upload coverage steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ github.event.ref }} fetch-depth: 1000 - uses: actions/setup-node@v6 with: node-version-file: ./package.json - run: npm ci --ignore-scripts - name: Run mcdev-tests with coverage run: npm run coverage - name: Prepare for Report Coverage (mini) run: | npx c8 report --reporter json-summary --exclude-after-remap false - name: Upload coverage artifact uses: actions/upload-artifact@v7 with: name: test-coverage-output path: coverage overwrite: true retention-days: 90 ================================================ FILE: .github/workflows/coverage-main-branch.yml ================================================ name: Test coverage for main branch # default-branch.yml on: push: branches: - main permissions: # allow dependabot to execute this workflow pull-requests: write jobs: hello_world_job: runs-on: ubuntu-latest name: Test and upload coverage steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ github.event.ref }} fetch-depth: 1000 - uses: actions/setup-node@v6 with: node-version-file: ./package.json - run: npm ci --ignore-scripts - name: Run mcdev-tests with coverage run: npm run coverage - name: Prepare for Report Coverage (mini) run: | npx c8 report --reporter json-summary --exclude-after-remap false - name: Upload coverage artifact uses: actions/upload-artifact@v7 with: name: test-coverage-output path: coverage overwrite: true retention-days: 90 ================================================ FILE: .github/workflows/coverage.yml ================================================ on: [pull_request] name: Test coverage report # main.yml permissions: # allow dependabot to execute this workflow pull-requests: write jobs: hello_world_job: runs-on: ubuntu-latest name: Test and report steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 1000 - uses: actions/setup-node@v6 with: node-version-file: ./package.json - run: npm ci --ignore-scripts - name: Run mcdev-tests with coverage run: npm run coverage - name: Prepare for Report Coverage run: | npx c8 report --reporter json-summary --exclude-after-remap false npm i svelte-to-html@1.0.9 git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1000 - name: Upload coverage artifact uses: actions/upload-artifact@v7 with: name: test-coverage-output path: coverage overwrite: true retention-days: 90 - name: Download coverage artifact uses: actions/download-artifact@v8 with: path: artifacts/test-coverage-output - name: Get Run ID id: get_run_id run: | echo "name=run_id::$(\ gh run list \ --workflow "${{ github.event.pull_request.base.ref == 'main' && 'coverage-main-branch.yml' || github.event.pull_request.base.ref == 'develop' && 'coverage-develop-branch.yml' || 'coverage.yml' }}" \ --json conclusion,headSha,status,databaseId \ --jq ".[] | select( .conclusion == \"success\" and .headSha == \"${{github.event.pull_request.base.sha}}\") | .databaseId" \ )" >> $GITHUB_OUTPUT env: GITHUB_TOKEN: ${{ github.token }} - name: Download artifact for base branch if available, previous uses: dawidd6/action-download-artifact@v19 continue-on-error: true with: workflow: ${{ github.event.pull_request.base.ref == 'main' && 'coverage-main-branch.yml' || github.event.pull_request.base.ref == 'develop' && 'coverage-develop-branch.yml' || 'coverage.yml' }} run_id: ${{steps.get_run_id.outputs.run_id}} name: 'test-coverage-output' path: base-artifacts search_artifacts: true - name: Check file existence id: check_files uses: andstor/file-existence-action@v3 with: files: 'base-artifacts/coverage-summary.json, artifacts/test-coverage-output/coverage-summary.json' - name: Report coverage uses: sidx1024/report-nyc-coverage-github-action@v1.2.7 id: report with: coverage_file: 'artifacts/test-coverage-output/coverage-summary.json' base_coverage_file: ${{steps.check_files.outputs.files_exists == 'true' && 'base-artifacts/coverage-summary.json' || ''}} comment_template_file: '.coverage-comment-template.svelte' ================================================ FILE: .github/workflows/npm-publish.yml ================================================ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages name: Publish NPM on Release on: release: types: [published] permissions: id-token: write # Required for OIDC contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version-file: ./package.json - run: npm ci - run: npm test publish-npm: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version-file: ./package.json registry-url: https://registry.npmjs.org/ - run: npm publish - name: Close release milestone if empty env: GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} RELEASE_TAG: ${{ github.event.release.tag_name }} run: | set -euo pipefail owner="${REPO%%/*}" repo="${REPO##*/}" milestone_title="${RELEASE_TAG#v}" if [ -z "${milestone_title}" ]; then echo "Could not parse milestone version from release tag (tag=${RELEASE_TAG})." exit 0 fi milestones_json="$(gh api "repos/${owner}/${repo}/milestones?state=open&per_page=100")" milestone_number="$(echo "$milestones_json" | jq -r \ --arg milestone_title "$milestone_title" \ '.[] | select(.title == $milestone_title) | .number' \ | head -n1)" if [ -z "${milestone_number}" ] || [ "${milestone_number}" = "null" ]; then echo "No matching open milestone found for parsed version '${milestone_title}'." exit 0 fi milestone="$(gh api "repos/${owner}/${repo}/milestones/${milestone_number}")" state="$(echo "$milestone" | jq -r '.state')" open_issues="$(echo "$milestone" | jq -r '.open_issues')" title="$(echo "$milestone" | jq -r '.title')" echo "Matched milestone #${milestone_number} '${title}' (state=${state}, open_issues=${open_issues})." if [ "$state" != "open" ]; then echo "Milestone is already closed. Nothing to do." exit 0 fi if [ "$open_issues" -ne 0 ]; then echo "Milestone has open items. Skipping close." exit 0 fi gh api -X PATCH "repos/${owner}/${repo}/milestones/${milestone_number}" -f state="closed" >/dev/null echo "Milestone #${milestone_number} closed." ================================================ FILE: .github/workflows/pr-labeler.yml ================================================ name: PR Labeler on: pull_request: types: [opened] permissions: contents: read jobs: pr-labeler: permissions: contents: read # for TimonVS/pr-labeler-action to read config file pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR runs-on: ubuntu-latest steps: - uses: TimonVS/pr-labeler-action@v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/pr-labeler.yml # optional, .github/pr-labeler.yml is the default value ================================================ FILE: .github/workflows/sync-milestone.yml ================================================ name: Sync Milestone from Issue on: pull_request: types: [opened, edited, reopened] jobs: sync-milestone: runs-on: ubuntu-latest permissions: issues: read pull-requests: write steps: - name: Sync Milestone env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} OWNER: ${{ github.repository_owner }} run: | # 1. Get the milestone of the officially linked issues and the PR's current milestone via GraphQL # This catches issues linked via "Fixes #123" and similar in the body or the UI sidebar. API_RESPONSE=$(gh api graphql -f query=' query($owner: String!, $name: String!, $pr: Int!) { repository(owner: $owner, name: $name) { pullRequest(number: $pr) { milestone { number } closingIssuesReferences(first: 1) { nodes { milestone { number title } } } } } }' -F owner="$OWNER" -F name="${REPO#*/}" -F pr=$PR_NUMBER) MILESTONE_NUMBER=$(echo "$API_RESPONSE" | jq -r '.data.repository.pullRequest.closingIssuesReferences.nodes[0].milestone.number // "null"') MILESTONE_TITLE=$(echo "$API_RESPONSE" | jq -r '.data.repository.pullRequest.closingIssuesReferences.nodes[0].milestone.title // "null"') CURRENT_PR_MILESTONE=$(echo "$API_RESPONSE" | jq -r '.data.repository.pullRequest.milestone.number // "null"') # 2. Check if a milestone was found if [ "$MILESTONE_NUMBER" != "null" ] && [ -n "$MILESTONE_NUMBER" ]; then if [ "$MILESTONE_NUMBER" = "$CURRENT_PR_MILESTONE" ]; then echo "PR already has milestone '$MILESTONE_TITLE' set. No update needed." else echo "Found milestone '$MILESTONE_TITLE' from linked issue. Assigning to PR..." gh pr edit $PR_NUMBER --milestone "$MILESTONE_TITLE" --repo "$REPO" fi else echo "No milestone found on linked issues or no issues linked." fi ================================================ FILE: .gitignore ================================================ /.nyc_output/ /businessUnits/ /coverage/ /deploy/ /logs/ /retrieve/ /roles/ /template/ /tmp/ node_modules/ .mcdev-auth.json .mcdevrc.json .vscode/tasks.json !test/mockRoot/* ================================================ FILE: .husky/.gitignore ================================================ _ ================================================ FILE: .husky/commit-msg ================================================ INPUT_FILE=$1 START_LINE=`head -n1 $INPUT_FILE` PATTERN="^(#[[:digit:]]|Merge|Revert)" if ! echo "$START_LINE" | grep -qE "$PATTERN" ; then echo "Bad commit message, see example: \"#431 commit message\", you provided: \"$START_LINE\"" exit 1 fi ================================================ FILE: .husky/post-checkout ================================================ #!/bin/sh # ### git commit message template ### git config commit.template .git/templatemessage TICKETID=`git rev-parse --abbrev-ref HEAD | LC_ALL=en_US.utf8 grep -oP '^((copilot\/)?(feature|bug|bugfix|fix|hotfix|task|chore)\/)?\K\d{1,7}' || true` if [ -z "$TICKETID" ] then TICKETID="0" fi TEMPLATE="#$TICKETID: " echo "[POST-CHECKOUT] Setting template commit to '$TEMPLATE'" # wrap $TEMPLATE in quotes or else it is trimmed automatically echo "$TEMPLATE" > ".git/templatemessage" if [ "${SKIP_HOOKS:-0}" -gt 0 ] 2>/dev/null; then echo "[POST-CHECKOUT] skipping hooks ($SKIP_HOOKS)" exit 0 fi # ### run npm install ### echo "[POST-CHECKOUT] 📦 Checking for changes to dependencies" # $1 is the new HEAD pointer NEWHEAD=$1 # $2 is the previous HEAD pointer OLDHEAD=$2 # extract all paths to package-lock.json files PACKAGES=$(git diff --name-only "$OLDHEAD" "$NEWHEAD" | grep -E "^package-lock\.json" || true) if [ -n "$PACKAGES" ]; then for package in $PACKAGES; do echo "📦 $package was changed." done echo "📦 Running npm install to update your dependencies..." npm install npm run lint:fix else echo "📦 All packages up-to-date. No need to run npm install." fi ================================================ FILE: .husky/post-merge ================================================ if [[ $SKIP_HOOKS>0 ]]; then echo "[POST-MERGE] skipping hooks ($SKIP_HOOKS)" exit 0 fi # ### run npm install ### echo "[POST-MERGE] 📦 Checking for changes to dependencies" # define how to split strings into array elements IFS=$'\n' # extract all paths to package-lock.json files PACKAGE_LOCK_REGEX="(^package-lock\.json)" echo "[POST-MERGE] running git diff --name-only HEAD^1 HEAD" PACKAGES=$(git diff --name-only HEAD^1 HEAD | grep -E $PACKAGE_LOCK_REGEX || true) if [[ ${PACKAGES[@]} ]]; then for package in $PACKAGES; do echo "📦 $package was changed." done echo "📦 Running npm install to update your dependencies..." npm install npm run lint:fix else echo "📦 All packages up-to-date. No need to run npm install." fi ================================================ FILE: .husky/pre-commit ================================================ # run lint-staged hooks echo "[PRE-COMMIT] Run lint-staged" lint-staged # update typescript type declarations echo "[PRE-COMMIT] Run typescript validation and create/update d.ts files" tsc -p tsconfig.precommit.json git add @types ================================================ FILE: .issuetracker ================================================ # Integration with Issue Tracker # # (note that '\' need to be escaped). [issuetracker "Accenture Jira Rule"] regex = "(CSCLSROZ)-(\\d+)" url = "https://alm.accenture.com/jira/browse/$1-$2" [issuetracker "GitHub Pull Request Rule"] regex = "pull request #(\\d+)" url = "https://github.com/Accenture/sfmc-devtools/pull/$1" [issuetracker "GitHub Issue Rule"] regex = "#(\\d+)" url = "https://github.com/Accenture/sfmc-devtools/issues/$1" ================================================ FILE: .markdownlint.json ================================================ { "default": true, "line-length": false, "no-duplicate-header": false, "no-trailing-punctuation": false, "no-inline-html": false, "no-bare-urls": false, "list-marker-space": { "ul_single": 1, "ol_single": 1, "ul_multi": 1, "ol_multi": 1 }, "ul-indent": { "indent": 2 }, "ol-prefix": { "style": "ordered" } } ================================================ FILE: .markdownlint.md ================================================ # How to set up markdownlint rules - [list of rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md) - [how to configure in vscode](https://github.com/DavidAnson/vscode-markdownlint#configure) ================================================ FILE: .mcdev-validations.js ================================================ ================================================ FILE: .npmrc ================================================ save-prefix='' ================================================ FILE: .nycrc.json ================================================ { "all": true, "include": ["lib/**"], "exclude": ["lib/metadataTypes/definitions/*.js", "test/**", "types/**"] } ================================================ FILE: .prettierignore ================================================ docs node_modules retrieve ================================================ FILE: .prettierrc ================================================ { "tabWidth": 4, "printWidth": 100, "singleQuote": true, "trailingComma": "es5", "overrides": [ { "files": "*.json", "options": { "parser": "json" } }, { "files": "package.json|package-lock.json", "options": { "printWidth": 40 } }, { "files": "*.ssjs", "options": { "parser": "babel", "trailingComma": "none" } }, { "files": "*.md", "options": { "tabWidth": 2 } } ] } ================================================ FILE: .vscode/extensions.json ================================================ { // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp // List of extensions which should be recommended for users of this workspace. "recommendations": [ // collaboration "aaron-bond.better-comments", "github.vscode-pull-request-github", "johnpapa.vscode-peacock", // Linters "dbaeumer.vscode-eslint", // Formatting & colors "editorconfig.editorconfig", "esbenp.prettier-vscode", "xnerd.ampscript-language", "FiB.beautyAmp", // mcdev tests "hbenl.vscode-mocha-test-adapter", "IBM.output-colorizer", // Markdown / Readme.md "joernberkefeld.markdown-preview-bitbucket-innersource" ] } ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceFolder}\\lib\\index.js", "args": ["retrieve", "Dev"] } ] } ================================================ FILE: .vscode/settings.json ================================================ { "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit", "source.fixAll.markdownlint": "explicit" }, "editor.formatOnSave": true, "files.associations": { "*.ssjs": "javascript", "*.html": "ampscript" }, "files.eol": "\n", "js/ts.implicitProjectConfig.checkJs": true, "javascript.validate.enable": true, "markdown.extension.italic.indicator": "_", "markdown.extension.list.indentationSize": "adaptive", "markdown.extension.toc.levels": "2..6", "markdown.extension.toc.orderedList": false, "markdown.extension.toc.slugifyMode": "github", "markdown.extension.tableFormatter.enabled": false, "sql-formatter.indent": " ", "sql-formatter.uppercase": true, "[html]": { "editor.defaultFormatter": "FiB.beautyAmp" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "markdown-toc.orderedList": true, "markdown-toc.insertAnchor": true, "outline.showProperties": false, "outline.showVariables": false, "breadcrumbs.showVariables": false, "breadcrumbs.showProperties": false, "githubIssues.issueBranchTitle": "feature/${issueNumber}-${sanitizedIssueTitle}", "githubIssues.queries": [ { "label": "My Issues", "query": "default" }, { "label": "New Issues", "query": "no:assignee state:open repo:${owner}/${repository} sort:created-desc" }, { "label": "Created By Me", "query": "author:${user} state:open repo:${owner}/${repository} sort:created-desc" } ], "vsicons.associations.files": [ { "icon": "apex", "languages": [ { "ids": "ampscript", "defaultExtension": "amp" }, { "ids": "AMPscript", "defaultExtension": "amp" } ], "light": true, "format": "FileFormat.svg" } ], "workbench.colorCustomizations": { "activityBar.activeBackground": "#fbed80", "activityBar.background": "#fbed80", "activityBar.foreground": "#15202b", "activityBar.inactiveForeground": "#15202b99", "activityBarBadge.background": "#06b9a5", "activityBarBadge.foreground": "#15202b", "commandCenter.border": "#15202b99", "sash.hoverBorder": "#fbed80", "statusBar.background": "#f9e64f", "statusBar.foreground": "#15202b", "statusBarItem.hoverBackground": "#f7df1e", "statusBarItem.remoteBackground": "#f9e64f", "statusBarItem.remoteForeground": "#15202b", "titleBar.activeBackground": "#f9e64f", "titleBar.activeForeground": "#15202b", "titleBar.inactiveBackground": "#f9e64f99", "titleBar.inactiveForeground": "#15202b99" }, "peacock.color": "#f9e64f" } ================================================ FILE: .vsls.json ================================================ { "$schema": "http://json.schemastore.org/vsls", "gitignore": "none", "excludeFiles": ["*.p12", "*.cer", "token", ".gitignore"], "hideFiles": ["bin", "obj"] } ================================================ FILE: @types/lib/Builder.d.ts ================================================ export default Builder; export type BuObject = import("../types/mcdev.d.js").BuObject; export type CodeExtract = import("../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../types/mcdev.d.js").CodeExtractItem; export type Mcdevrc = import("../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../types/mcdev.d.js").MultiMetadataTypeList; export type SoapRequestParams = import("../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * Builds metadata from a template using market specific customisation */ declare class Builder { /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} keyArr customerkey of the metadata * @param {string[]} marketArr market localizations * @returns {Promise.<MultiMetadataTypeList>} - */ static buildTemplate(businessUnit: string, selectedType: string, keyArr: string[], marketArr: string[]): Promise<MultiMetadataTypeList>; /** * Build a specific metadata file based on a template. * * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} nameArr name of the metadata * @param {string[]} marketArr market localizations * @returns {Promise.<MultiMetadataTypeList>} - */ static buildDefinition(businessUnit: string, selectedType: string, nameArr: string[], marketArr: string[]): Promise<MultiMetadataTypeList>; /** * Build a specific metadata file based on a template using a list of bu-market combos * * @param {string} listName name of list of BU-market combos * @param {string} type supported metadata type * @param {string[]} nameArr name of the metadata * @returns {Promise.<object>} - */ static buildDefinitionBulk(listName: string, type: string, nameArr: string[]): Promise<object>; /** * helper for buildDefinitionBulk, createDeltaPkg * * @param {string} listName market list name * @returns {Promise.<void>} - */ static purgeDeployFolderList(listName: string): Promise<void>; /** * helper for buildDefiniton, purgeDeployFolderList * * @param {string} businessUnit cred/bu combo * @returns {Promise.<void>} - */ static purgeDeployFolder(businessUnit: string): Promise<void>; /** * Creates a Builder, uses v2 auth if v2AuthOptions are passed. * * @param {Mcdevrc} properties properties for auth saved * @param {BuObject} buObject properties for auth */ constructor(properties: Mcdevrc, buObject: BuObject); properties: import("../types/mcdev.d.js").Mcdevrc; templateDir: string; retrieveDir: string; buObject: import("../types/mcdev.d.js").BuObject; targetDir: string[]; /** * @type {MultiMetadataTypeList} */ metadata: MultiMetadataTypeList; /** * Builds a specific metadata file by name * * @param {string} metadataType metadata type to build * @param {string[]} nameArr name of metadata to build * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MultiMetadataTypeList>} Promise */ _buildDefinition(metadataType: string, nameArr: string[], templateVariables: TemplateMap): Promise<MultiMetadataTypeList>; /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} metadataType metadata type to create a template of * @param {string[]} keyArr customerkey of metadata to create a template of * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MultiMetadataTypeList>} Promise */ _buildTemplate(metadataType: string, keyArr: string[], templateVariables: TemplateMap): Promise<MultiMetadataTypeList>; } //# sourceMappingURL=Builder.d.ts.map ================================================ FILE: @types/lib/Deployer.d.ts ================================================ export default Deployer; export type BuObject = import("../types/mcdev.d.js").BuObject; export type CodeExtract = import("../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../types/mcdev.d.js").CodeExtractItem; export type Mcdevrc = import("../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../types/mcdev.d.js").MultiMetadataTypeList; export type SoapRequestParams = import("../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../types/mcdev.d.js").TemplateMap; export type MultiMetadataTypeMap = import("../types/mcdev.d.js").MultiMetadataTypeMap; export type TypeKeyCombo = import("../types/mcdev.d.js").TypeKeyCombo; export type ListMap = import("../types/mcdev.d.js").ListMap; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * * @typedef {import('../types/mcdev.d.js').ListMap} ListMap */ /** * Reads metadata from local directory and deploys it to specified target business unit. * Source and target business units are also compared before the deployment to apply metadata specific patches. */ declare class Deployer { /** * Deploys all metadata located in the 'deploy' directory to the specified business unit * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<Object.<string, MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type) */ static deploy(businessUnit: string, selectedTypesArr?: string[] | TypeKeyCombo, keyArr?: string[]): Promise<{ [x: string]: MultiMetadataTypeMap; }>; /** * helper for {@link Deployer.deploy} * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {Mcdevrc} properties General configuration to be used in retrieve * @param {string[] | TypeKeyCombo} [typeArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<MultiMetadataTypeMap>} ensure that BUs are worked on sequentially */ static _deployBU(cred: string, bu: string, properties: Mcdevrc, typeArr?: string[] | TypeKeyCombo, keyArr?: string[]): Promise<MultiMetadataTypeMap>; /** * Returns metadata of a business unit that is saved locally * * @param {string} deployDir root directory of metadata. * @param {string[]} [typeArr] limit deployment to given metadata type * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {Promise.<MultiMetadataTypeMap>} Metadata of BU in local directory */ static readBUMetadata(deployDir: string, typeArr?: string[], listBadKeys?: boolean): Promise<MultiMetadataTypeMap>; /** * parses asset metadata to auto-create folders in target folder * * @param {string} deployDir root directory of metadata. * @param {MultiMetadataTypeMap} metadata list of metadata * @param {string[]} metadataTypeArr list of metadata types * @returns {Promise.<object>} folder metadata */ static createFolderDefinitions(deployDir: string, metadata: MultiMetadataTypeMap, metadataTypeArr: string[]): Promise<object>; /** * Creates a Deployer, uses v2 auth if v2AuthOptions are passed. * * @param {Mcdevrc} properties General configuration to be used in retrieve * @param {BuObject} buObject properties for auth */ constructor(properties: Mcdevrc, buObject: BuObject); buObject: import("../types/mcdev.d.js").BuObject; properties: import("../types/mcdev.d.js").Mcdevrc; deployDir: string; retrieveDir: string; /** * Deploy all metadata that is located in the deployDir * * @param {string[] | TypeKeyCombo} [types] limit deployment to given metadata type (can include subtype) * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<MultiMetadataTypeMap>} Promise of all deployed metadata */ _deploy(types?: string[] | TypeKeyCombo, keyArr?: string[]): Promise<MultiMetadataTypeMap>; /** @type {MultiMetadataTypeMap} */ metadata: MultiMetadataTypeMap; } //# sourceMappingURL=Deployer.d.ts.map ================================================ FILE: @types/lib/MetadataTypeDefinitions.d.ts ================================================ declare namespace _default { export { asset }; export { attributeGroup }; export { attributeSet }; export { automation }; export { campaign }; export { contentArea }; export { dataFilter }; export { dataFilterHidden }; export { dataExtension }; export { dataExtensionField }; export { dataExtensionTemplate }; export { dataExtract }; export { dataExtractType }; export { deliveryProfile }; export { discovery }; export { domainVerification }; export { email }; export { emailSend }; export { event }; export { fileLocation }; export { fileTransfer }; export { filter }; export { folder }; export { importFile }; export { journey }; export { list }; export { mobileCode }; export { mobileKeyword }; export { mobileMessage }; export { query }; export { role }; export { script }; export { sendClassification }; export { senderProfile }; export { transactionalMessage }; export { transactionalEmail }; export { transactionalPush }; export { transactionalSMS }; export { triggeredSend }; export { triggeredSendSummary }; export { user }; export { verification }; } export default _default; import asset from './metadataTypes/definitions/Asset.definition.js'; import attributeGroup from './metadataTypes/definitions/AttributeGroup.definition.js'; import attributeSet from './metadataTypes/definitions/AttributeSet.definition.js'; import automation from './metadataTypes/definitions/Automation.definition.js'; import campaign from './metadataTypes/definitions/Campaign.definition.js'; import contentArea from './metadataTypes/definitions/ContentArea.definition.js'; import dataFilter from './metadataTypes/definitions/DataFilter.definition.js'; import dataFilterHidden from './metadataTypes/definitions/DataFilterHidden.definition.js'; import dataExtension from './metadataTypes/definitions/DataExtension.definition.js'; import dataExtensionField from './metadataTypes/definitions/DataExtensionField.definition.js'; import dataExtensionTemplate from './metadataTypes/definitions/DataExtensionTemplate.definition.js'; import dataExtract from './metadataTypes/definitions/DataExtract.definition.js'; import dataExtractType from './metadataTypes/definitions/DataExtractType.definition.js'; import deliveryProfile from './metadataTypes/definitions/DeliveryProfile.definition.js'; import discovery from './metadataTypes/definitions/Discovery.definition.js'; import domainVerification from './metadataTypes/definitions/DomainVerification.definition.js'; import email from './metadataTypes/definitions/Email.definition.js'; import emailSend from './metadataTypes/definitions/EmailSend.definition.js'; import event from './metadataTypes/definitions/Event.definition.js'; import fileLocation from './metadataTypes/definitions/FileLocation.definition.js'; import fileTransfer from './metadataTypes/definitions/FileTransfer.definition.js'; import filter from './metadataTypes/definitions/Filter.definition.js'; import folder from './metadataTypes/definitions/Folder.definition.js'; import importFile from './metadataTypes/definitions/ImportFile.definition.js'; import journey from './metadataTypes/definitions/Journey.definition.js'; import list from './metadataTypes/definitions/List.definition.js'; import mobileCode from './metadataTypes/definitions/MobileCode.definition.js'; import mobileKeyword from './metadataTypes/definitions/MobileKeyword.definition.js'; import mobileMessage from './metadataTypes/definitions/MobileMessage.definition.js'; import query from './metadataTypes/definitions/Query.definition.js'; import role from './metadataTypes/definitions/Role.definition.js'; import script from './metadataTypes/definitions/Script.definition.js'; import sendClassification from './metadataTypes/definitions/SendClassification.definition.js'; import senderProfile from './metadataTypes/definitions/SenderProfile.definition.js'; import transactionalMessage from './metadataTypes/definitions/TransactionalMessage.definition.js'; import transactionalEmail from './metadataTypes/definitions/TransactionalEmail.definition.js'; import transactionalPush from './metadataTypes/definitions/TransactionalPush.definition.js'; import transactionalSMS from './metadataTypes/definitions/TransactionalSMS.definition.js'; import triggeredSend from './metadataTypes/definitions/TriggeredSend.definition.js'; import triggeredSendSummary from './metadataTypes/definitions/TriggeredSendSummary.definition.js'; import user from './metadataTypes/definitions/User.definition.js'; import verification from './metadataTypes/definitions/Verification.definition.js'; //# sourceMappingURL=MetadataTypeDefinitions.d.ts.map ================================================ FILE: @types/lib/MetadataTypeInfo.d.ts ================================================ declare namespace _default { export { asset }; export { attributeGroup }; export { attributeSet }; export { automation }; export { campaign }; export { contentArea }; export { dataExtension }; export { dataExtensionField }; export { dataExtensionTemplate }; export { dataExtract }; export { dataExtractType }; export { dataFilter }; export { dataFilterHidden }; export { deliveryProfile }; export { discovery }; export { domainVerification }; export { email }; export { emailSend }; export { event }; export { fileLocation }; export { fileTransfer }; export { filter }; export { folder }; export { importFile }; export { journey }; export { list }; export { mobileCode }; export { mobileKeyword }; export { mobileMessage }; export { query }; export { role }; export { script }; export { sendClassification }; export { senderProfile }; export { transactionalEmail }; export { transactionalPush }; export { transactionalSMS }; export { triggeredSend }; export { triggeredSendSummary }; export { user }; export { verification }; } export default _default; import asset from './metadataTypes/Asset.js'; import attributeGroup from './metadataTypes/AttributeGroup.js'; import attributeSet from './metadataTypes/AttributeSet.js'; import automation from './metadataTypes/Automation.js'; import campaign from './metadataTypes/Campaign.js'; import contentArea from './metadataTypes/ContentArea.js'; import dataExtension from './metadataTypes/DataExtension.js'; import dataExtensionField from './metadataTypes/DataExtensionField.js'; import dataExtensionTemplate from './metadataTypes/DataExtensionTemplate.js'; import dataExtract from './metadataTypes/DataExtract.js'; import dataExtractType from './metadataTypes/DataExtractType.js'; import dataFilter from './metadataTypes/DataFilter.js'; import dataFilterHidden from './metadataTypes/DataFilterHidden.js'; import deliveryProfile from './metadataTypes/DeliveryProfile.js'; import discovery from './metadataTypes/Discovery.js'; import domainVerification from './metadataTypes/DomainVerification.js'; import email from './metadataTypes/Email.js'; import emailSend from './metadataTypes/EmailSend.js'; import event from './metadataTypes/Event.js'; import fileLocation from './metadataTypes/FileLocation.js'; import fileTransfer from './metadataTypes/FileTransfer.js'; import filter from './metadataTypes/Filter.js'; import folder from './metadataTypes/Folder.js'; import importFile from './metadataTypes/ImportFile.js'; import journey from './metadataTypes/Journey.js'; import list from './metadataTypes/List.js'; import mobileCode from './metadataTypes/MobileCode.js'; import mobileKeyword from './metadataTypes/MobileKeyword.js'; import mobileMessage from './metadataTypes/MobileMessage.js'; import query from './metadataTypes/Query.js'; import role from './metadataTypes/Role.js'; import script from './metadataTypes/Script.js'; import sendClassification from './metadataTypes/SendClassification.js'; import senderProfile from './metadataTypes/SenderProfile.js'; import transactionalEmail from './metadataTypes/TransactionalEmail.js'; import transactionalPush from './metadataTypes/TransactionalPush.js'; import transactionalSMS from './metadataTypes/TransactionalSMS.js'; import triggeredSend from './metadataTypes/TriggeredSend.js'; import triggeredSendSummary from './metadataTypes/TriggeredSendSummary.js'; import user from './metadataTypes/User.js'; import verification from './metadataTypes/Verification.js'; //# sourceMappingURL=MetadataTypeInfo.d.ts.map ================================================ FILE: @types/lib/Retriever.d.ts ================================================ export default Retriever; export type BuObject = import("../types/mcdev.d.js").BuObject; export type CodeExtract = import("../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../types/mcdev.d.js").CodeExtractItem; export type Mcdevrc = import("../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../types/mcdev.d.js").TypeKeyCombo; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * Retrieves metadata from a business unit and saves it to the local filesystem. */ declare class Retriever { /** * Creates a Retriever, uses v2 auth if v2AuthOptions are passed. * * @param {Mcdevrc} properties General configuration to be used in retrieve * @param {BuObject} buObject properties for auth */ constructor(properties: Mcdevrc, buObject: BuObject); buObject: import("../types/mcdev.d.js").BuObject; properties: import("../types/mcdev.d.js").Mcdevrc; retrieveDir: string; templateDir: string; savePath: string; /** * Retrieve metadata of specified types into local file system and Retriever.metadata * * @param {string[]} metadataTypes list of metadata types to retrieve; can include subtypes! * @param {string[] | TypeKeyCombo} [namesOrKeys] name of Metadata to retrieveAsTemplate or list of keys for normal retrieval * @param {TemplateMap} [templateVariables] Object of values which can be replaced (in case of templating) * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.<MultiMetadataTypeList>} Promise of a list of retrieved items grouped by type {automation:[...], query:[...]} */ retrieve(metadataTypes: string[], namesOrKeys?: string[] | TypeKeyCombo, templateVariables?: TemplateMap, changelogOnly?: boolean): Promise<MultiMetadataTypeList>; /** * helper for Retriever.retrieve to get all dependencies of the given types * * @param {string[]} metadataTypes list of metadata types to retrieve; can include subtypes! * @returns {string[]} unique list dependent metadata types */ _getTypeDependencies(metadataTypes: string[]): string[]; } //# sourceMappingURL=Retriever.d.ts.map ================================================ FILE: @types/lib/cli.d.ts ================================================ #!/usr/bin/env node export type TypeKeyCombo = import("../types/mcdev.d.js").TypeKeyCombo; //# sourceMappingURL=cli.d.ts.map ================================================ FILE: @types/lib/index.d.ts ================================================ export default Mcdev; export type BuObject = import("../types/mcdev.d.js").BuObject; export type CodeExtract = import("../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../types/mcdev.d.js").MultiMetadataTypeMap; export type SkipInteraction = import("../types/mcdev.d.js").SkipInteraction; export type SoapRequestParams = import("../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../types/mcdev.d.js").TypeKeyCombo; export type ExplainType = import("../types/mcdev.d.js").ExplainType; export type ContentBlockConversionTypes = import("../types/mcdev.d.js").ContentBlockConversionTypes; export type BuildFilter = import("../types/mcdev.d.js").BuildFilter; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../types/mcdev.d.js').SkipInteraction} SkipInteraction * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../types/mcdev.d.js').ExplainType} ExplainType * @typedef {import('../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes * @typedef {import('../types/mcdev.d.js').BuildFilter} BuildFilter */ /** * main class */ declare class Mcdev { /** * @returns {string} current version of mcdev */ static version(): string; /** * helper method to use unattended mode when including mcdev as a package * * @param {SkipInteraction} [skipInteraction] signals what to insert automatically for things usually asked via wizard * @returns {void} */ static setSkipInteraction(skipInteraction?: SkipInteraction): void; /** * configures what is displayed in the console * * @param {object} argv list of command line parameters given by user * @param {boolean} [argv.silent] only errors printed to CLI * @param {boolean} [argv.verbose] chatty user CLI output * @param {boolean} [argv.debug] enables developer output & features * @returns {void} */ static setLoggingLevel(argv: { silent?: boolean; verbose?: boolean; debug?: boolean; }): void; static knownOptions: string[]; /** * allows setting system wide / command related options * * @param {object} argv list of command line parameters given by user * @returns {void} */ static setOptions(argv: object): void; /** * handler for 'mcdev createDeltaPkg * * @param {object} argv yargs parameters * @param {string} [argv.commitrange] git commit range via positional * @param {string} [argv.range] git commit range via option * @param {string} [argv.filter] filter file paths that start with any * @param {number} [argv.commitHistory] filter file paths that start with any * @param {DeltaPkgItem[]} [argv.diffArr] list of files to include in delta package (skips git diff when provided) * @returns {Promise.<DeltaPkgItem[]>} list of changed items */ static createDeltaPkg(argv: { commitrange?: string; range?: string; filter?: string; commitHistory?: number; diffArr?: DeltaPkgItem[]; }): Promise<DeltaPkgItem[]>; /** * @returns {Promise} . */ static selectTypes(): Promise<any>; /** * @returns {ExplainType[]} list of supported types with their apiNames */ static explainTypes(): ExplainType[]; /** * @returns {Promise.<boolean>} success flag */ static upgrade(): Promise<boolean>; /** * helper to show an off-the-logs message to users */ static "__#private@#welcomeMessage"(): void; /** * Retrieve all metadata from the specified business unit into the local file system. * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit retrieval to given metadata type * @param {string[]} [keys] limit retrieval to given metadata key * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.<object>} - */ static retrieve(businessUnit: string, selectedTypesArr?: string[] | TypeKeyCombo, keys?: string[], changelogOnly?: boolean): Promise<object>; /** * helper for {@link Mcdev.retrieve} * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit retrieval to given metadata type/subtype * @param {string[]} [keys] limit retrieval to given metadata key * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.<object>} ensure that BUs are worked on sequentially */ static "__#private@#retrieveBU"(cred: string, bu: string, selectedTypesArr?: string[] | TypeKeyCombo, keys?: string[], changelogOnly?: boolean): Promise<object>; /** * Deploys all metadata located in the 'deploy' directory to the specified business unit * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<Object.<string, MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type) */ static deploy(businessUnit: string, selectedTypesArr?: string[] | TypeKeyCombo, keyArr?: string[]): Promise<{ [x: string]: MultiMetadataTypeMap; }>; /** * Creates template file for properties.json * * @param {string} [credentialsName] identifying name of the installed package / project * @returns {Promise.<void>} - */ static initProject(credentialsName?: string): Promise<void>; /** * Clones an existing project from git repository and installs it * * @returns {Promise.<void>} - */ static joinProject(): Promise<void>; /** * Refreshes BU names and ID's from MC instance * * @param {string} credentialsName identifying name of the installed package / project * @returns {Promise.<void>} - */ static findBUs(credentialsName: string): Promise<void>; /** * Creates docs for supported metadata types in Markdown and/or HTML format * * @param {string} businessUnit references credentials from properties.json * @param {string} type metadata type * @returns {Promise.<void>} - */ static document(businessUnit: string, type: string): Promise<void>; /** * deletes metadata from MC instance by key * * @param {string} businessUnit references credentials from properties.json * @param {string | TypeKeyCombo} selectedTypes supported metadata type (single) or complex object * @param {string[] | string} [keys] Identifier of metadata * @returns {Promise.<boolean>} true if successful, false otherwise */ static deleteByKey(businessUnit: string, selectedTypes: string | TypeKeyCombo, keys?: string[] | string): Promise<boolean>; /** * get name & key for provided id * * @param {string} businessUnit references credentials from properties.json * @param {string} type supported metadata type * @param {string} id Identifier of metadata * @returns {Promise.<{key:string, name:string, path:string}>} key, name and path of metadata; null if not found */ static resolveId(businessUnit: string, type: string, id: string): Promise<{ key: string; name: string; path: string; }>; /** * ensures triggered sends are restarted to ensure they pick up on changes of the underlying emails * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static refresh(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * method for contributors to get details on SOAP objects * * @param {string} type references credentials from properties.json * @param {string} [businessUnit] defaults to first credential's ParentBU * @returns {Promise.<void>} - */ static describeSoap(type: string, businessUnit?: string): Promise<void>; /** * Converts metadata to legacy format. Output is saved in 'converted' directory * * @param {string} businessUnit references credentials from properties.json * @returns {Promise.<void>} - */ static badKeys(businessUnit: string): Promise<void>; /** * Retrieve a specific metadata file and templatise. * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} name name of the metadata * @param {string} market market which should be used to revert template * @returns {Promise.<MultiMetadataTypeList>} - */ static retrieveAsTemplate(businessUnit: string, selectedType: string, name: string[], market: string): Promise<MultiMetadataTypeList>; /** * @param {string} businessUnit references credentials from properties.json * @param {TypeKeyCombo} typeKeyList limit retrieval to given metadata type * @returns {Promise.<TypeKeyCombo>} selected types including dependencies */ static addDependentCbReferences(businessUnit: string, typeKeyList: TypeKeyCombo): Promise<TypeKeyCombo>; /** * * @param {string} businessUnit references credentials from properties.json * @param {TypeKeyCombo} typeKeyList limit retrieval to given metadata type * @returns {Promise.<TypeKeyCombo>} dependencies */ static addDependencies(businessUnit: string, typeKeyList: TypeKeyCombo): Promise<TypeKeyCombo>; /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnitTemplate references credentials from properties.json * @param {string} businessUnitDefinition references credentials from properties.json * @param {TypeKeyCombo} typeKeyCombo limit retrieval to given metadata type * @returns {Promise.<MultiMetadataTypeList | object>} response from buildDefinition */ static clone(businessUnitTemplate: string, businessUnitDefinition: string, typeKeyCombo: TypeKeyCombo): Promise<MultiMetadataTypeList | object>; /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnitTemplate references credentials from properties.json * @param {string} businessUnitDefinition references credentials from properties.json * @param {TypeKeyCombo} typeKeyCombo limit retrieval to given metadata type * @param {string[]} marketTemplate market localizations * @param {string[]} marketDefinition market localizations * @param {boolean} [bulk] runs buildDefinitionBulk instead of buildDefinition; requires marketList to be defined and given via marketDefinition * @param {BuildFilter} [filter] market list specific filter for buildTemplate * @returns {Promise.<MultiMetadataTypeList | object>} response from buildDefinition */ static build(businessUnitTemplate: string, businessUnitDefinition: string, typeKeyCombo: TypeKeyCombo, marketTemplate: string[], marketDefinition: string[], bulk?: boolean, filter?: BuildFilter): Promise<MultiMetadataTypeList | object>; /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnit references credentials from properties.json * @param {string | TypeKeyCombo} selectedTypes limit retrieval to given metadata type * @param {string[] | undefined} keyArr customerkey of the metadata * @param {string[]} marketArr market localizations * @param {BuildFilter} [filter] market list specific filter * @returns {Promise.<MultiMetadataTypeList>} - */ static buildTemplate(businessUnit: string, selectedTypes: string | TypeKeyCombo, keyArr: string[] | undefined, marketArr: string[], filter?: BuildFilter): Promise<MultiMetadataTypeList>; /** * helper for {@link buildTemplate} to apply include/exclude key filters * * @param {TypeKeyCombo | undefined} typeKeyList supported metadata type * @param {BuildFilter} filter market list specific filter for buildTemplate */ static applyKeyFilters(typeKeyList: TypeKeyCombo | undefined, filter: BuildFilter): void; /** * Build a specific metadata file based on a template. * * @param {string} businessUnit references credentials from properties.json * @param {boolean} [alwaysAsk] by default this code only runs if --retrieve is set; this flag allows to always ask * @param {TypeKeyCombo} [selectedTypes] limit retrieval to given metadata type * @param {TypeKeyCombo} [defaultPlusTheseTypes] if we run build for a non-standard type we need to tell it what to download on top * @returns {Promise.<void>} - */ static _reRetrieve(businessUnit: string, alwaysAsk?: boolean, selectedTypes?: TypeKeyCombo, defaultPlusTheseTypes?: TypeKeyCombo): Promise<void>; /** * Build a specific metadata file based on a template. * * @param {string} businessUnit references credentials from properties.json * @param {string | TypeKeyCombo} selectedTypes limit retrieval to given metadata type * @param {string[] | undefined} nameArr name of the metadata * @param {string[]} marketArr market localizations * @returns {Promise.<MultiMetadataTypeList>} - */ static buildDefinition(businessUnit: string, selectedTypes: string | TypeKeyCombo, nameArr: string[] | undefined, marketArr: string[]): Promise<MultiMetadataTypeList>; /** * Build a specific metadata file based on a template using a list of bu-market combos * * @param {string} listName name of list of BU-market combos * @param {string | TypeKeyCombo} selectedTypes supported metadata type * @param {string[]} [nameArr] name of the metadata * @returns {Promise.<object>} - */ static buildDefinitionBulk(listName: string, selectedTypes: string | TypeKeyCombo, nameArr?: string[]): Promise<object>; /** * * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static getFilesToCommit(businessUnit: string, selectedType: string, keyArr: string[]): Promise<string[]>; /** * Publish an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static publish(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * Publish an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static validate(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * Start/execute an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static execute(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * Schedule an item (shortcut for execute --schedule) * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static schedule(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * pause an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static pause(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * stop an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static stop(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * stop an item * * @param {string} businessUnit name of BU * @param {TypeKeyCombo} selectedTypes limit to given metadata types * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static audit(businessUnit: string, selectedTypes: TypeKeyCombo): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * Updates the key to match the name field * * @param {string} businessUnit name of BU * @param {TypeKeyCombo | undefined} selectedTypesObj limit retrieval to given metadata type * @param {string} to what to replace with * @param {string[]} [fromList] what to replace * @returns {Promise.<Object.<string, object>>} key1: business unit name, key2:type value: list of fixed item keys */ static replaceCbReference(businessUnit: string, selectedTypesObj: TypeKeyCombo | undefined, to: string, fromList?: string[]): Promise<{ [x: string]: object; }>; /** * Updates the key to match the name field * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit retrieval to given metadata type * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, object>>} key1: business unit name, key2:type value: list of fixed item keys */ static fixKeys(businessUnit: string, selectedTypes: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: object; }>; /** * run a method across BUs * * @param {'schedule'|'execute'|'pause'|'stop'|'publish'|'validate'|'fixKeys'|'replaceCbReference'|'refresh'|'audit'} methodName what to run * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static "__#private@#runMethod"(methodName: "schedule" | "execute" | "pause" | "stop" | "publish" | "validate" | "fixKeys" | "replaceCbReference" | "refresh" | "audit", businessUnit: string, selectedTypes?: string[] | TypeKeyCombo, keys?: string[]): Promise<{ [x: string]: { [x: string]: string[]; }; }>; /** * helper for Mcdev.#runMethod * * @param {'schedule'|'execute'|'pause'|'stop'|'publish'|'validate'|'fixKeys'|'replaceCbReference'|'refresh'|'audit'} methodName what to run * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string} [type] limit execution to given metadata type * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.<string[]>} list of keys that were affected */ static "__#private@#runOnBU"(methodName: "schedule" | "execute" | "pause" | "stop" | "publish" | "validate" | "fixKeys" | "replaceCbReference" | "refresh" | "audit", cred: string, bu: string, type?: string, keyArr?: string[]): Promise<string[]>; /** * helper for Mcdev.#runOnBU * * @param {string} selectedType limit execution to given metadata type * @param {BuObject} buObject properties for auth * @returns {Promise.<string[]>} keyArr */ static "__#private@#retrieveKeysWithLike"(selectedType: string, buObject: BuObject): Promise<string[]>; /** * Updates the key to match the name field * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string} type limit execution to given metadata type * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.<string[]>} list of keys that were affected */ static "__#private@#fixKeys"(cred: string, bu: string, type: string, keyArr?: string[]): Promise<string[]>; /** * Updates the key to match the name field * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string} type limit execution to given metadata type * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.<string[]>} list of keys that were affected */ static "__#private@#replaceCbReference"(cred: string, bu: string, type: string, keyArr?: string[]): Promise<string[]>; /** * helper to convert CSVs into an array. if only one value was given, it's also returned as an array * * @param {string|string[]|undefined} metadataOption potentially comma-separated value or null * @param {string[]} [allowedIdentifiers] 'key', 'id', 'name' * @param {boolean} [firstOnly] removes all but the first entry if enabled * @returns {TypeKeyCombo} values split into an array. */ static metadataToTypeKey(metadataOption: string | string[] | undefined, allowedIdentifiers?: string[], firstOnly?: boolean): TypeKeyCombo; } //# sourceMappingURL=index.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Asset.d.ts ================================================ export default Asset; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type AssetSubType = import("../../types/mcdev.d.js").AssetSubType; export type AssetMap = import("../../types/mcdev.d.js").AssetMap; export type AssetItem = import("../../types/mcdev.d.js").AssetItem; export type AssetRequestParams = import("../../types/mcdev.d.js").AssetRequestParams; export type ContentBlockConversionTypes = import("../../types/mcdev.d.js").ContentBlockConversionTypes; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * @typedef {import('../../types/mcdev.d.js').AssetSubType} AssetSubType * @typedef {import('../../types/mcdev.d.js').AssetMap} AssetMap * @typedef {import('../../types/mcdev.d.js').AssetItem} AssetItem * @typedef {import('../../types/mcdev.d.js').AssetRequestParams} AssetRequestParams * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * FileTransfer MetadataType * * @augments MetadataType */ declare class Asset extends MetadataType { /** * Retrieves Metadata of Asset * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} _ unused parameter * @param {string[]} [subTypeArr] optionally limit to a single AssetSubType * @param {string} [key] customer key * @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current * @returns {Promise.<{metadata: AssetMap, type: string}>} Promise */ static retrieve(retrieveDir: string, _: void | string[], subTypeArr?: string[], key?: string, loadShared?: boolean): Promise<{ metadata: AssetMap; type: string; }>; /** * Retrieves asset metadata for caching * * @param {void | string[]} [_] parameter not used * @param {string[]} [subTypeArr] optionally limit to a single subtype * @param {void | string} [__] parameter not used * @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current * @returns {Promise.<{metadata: AssetMap, type: string}>} Promise */ static retrieveForCache(_?: void | string[], subTypeArr?: string[], __?: void | string, loadShared?: boolean): Promise<{ metadata: AssetMap; type: string; }>; /** * Retrieves asset metadata for templating * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {AssetSubType} [selectedSubType] optionally limit to a single subtype * @returns {Promise.<{metadata: AssetItem, type: string}>} Promise */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap, selectedSubType?: AssetSubType): Promise<{ metadata: AssetItem; type: string; }>; /** * helper for {@link Asset.retrieve} + {@link Asset.retrieveAsTemplate} * * @private * @returns {string[]} AssetSubType array */ private static _getSubTypes; /** * Returns Order in which metadata needs to be retrieved/deployed and skips components with missing components * * @param {AssetMap} metadataMap metadata thats about to be deployed * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<AssetMap>} keyField => metadata map but sorted to ensure dependencies are deployed in correct order */ static _getUpsertOrderAndSkipMissing(metadataMap: AssetMap, deployDir: string): Promise<AssetMap>; /** * MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. * * @param {AssetMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<AssetMap>} keyField => metadata map */ static upsert(metadataMap: AssetMap, deployDir: string): Promise<AssetMap>; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * Creates a single asset * * @param {AssetItem} metadata a single asset * @returns {Promise} Promise */ static create(metadata: AssetItem): Promise<any>; /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postCreateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * Updates a single asset * * @param {AssetItem} metadata a single asset * @returns {Promise} Promise */ static update(metadata: AssetItem): Promise<any>; /** * Retrieves Metadata of a specific asset type * * @param {string|string[]} subType group of similar assets to put in a folder (ie. images) * @param {string} [retrieveDir] target directory for saving assets * @param {string} [key] key/id/name to filter by * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current * @returns {Promise.<object[]>} Promise */ static requestSubType(subType: string | string[], retrieveDir?: string, key?: string, templateVariables?: TemplateMap, loadShared?: boolean): Promise<object[]>; /** * Retrieves extended metadata (files or extended content) of asset * * @param {Array} items array of items to retrieve * @param {string} subType group of similar assets to put in a folder (ie. images) * @param {string} retrieveDir target directory for saving assets * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMap>} Promise */ static requestAndSaveExtended(items: any[], subType: string, retrieveDir: string, templateVariables?: TemplateMap): Promise<MetadataTypeMap>; /** * helper that reset the log level and prints errors * * @private * @param {'info'|'verbose'|'debug'|'error'} loggerLevelBak original logger level * @param {object[]} failed array of failed items */ private static _resetLogLevel; /** * Some metadata types store their actual content as a separate file, e.g. images * This method retrieves these and saves them alongside the metadata json * * @param {AssetItem} metadata a single asset * @param {string} subType group of similar assets to put in a folder (ie. images) * @param {string} retrieveDir target directory for saving assets * @returns {Promise.<void>} - */ static _retrieveExtendedFile(metadata: AssetItem, subType: string, retrieveDir: string): Promise<void>; /** * helper for {@link Asset.preDeployTasks} * Some metadata types store their actual content as a separate file, e.g. images * This method reads these from the local FS stores them in the metadata object allowing to deploy it * * @param {AssetItem} metadata a single asset * @param {string} subType group of similar assets to put in a folder (ie. images) * @param {string} deployDir directory of deploy files * @param {boolean} [pathOnly] used by getFilesToCommit which does not need the binary file to be actually read * @returns {Promise.<string>} if found will return the path of the binary file */ static _readExtendedFileFromFS(metadata: AssetItem, subType: string, deployDir: string, pathOnly?: boolean): Promise<string>; /** * manages post retrieve steps * * @param {AssetItem} metadata a single asset * @returns {CodeExtractItem} metadata */ static postRetrieveTasks(metadata: AssetItem): CodeExtractItem; /** * 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. * * @private * @param {MetadataTypeMap} metadata metadata mapped by their keyField * @returns {Promise.<void>} - */ private static _refreshTriggeredSend; /** * prepares an asset definition for deployment * * @param {AssetItem} metadata a single asset * @param {string} deployDir directory of deploy files * @returns {Promise.<AssetItem>} Promise */ static preDeployTasks(metadata: AssetItem, deployDir: string): Promise<AssetItem>; /** * find the subType matching the extendedSubType * * @param {string} extendedSubType webpage, htmlblock, etc * @returns {string} subType: block, message, other, etc */ static "__#private@#getMainSubtype"(extendedSubType: string): string; /** * determines the subtype of the current asset * * @private * @param {AssetItem} metadata a single asset * @returns {string} subtype */ private static _getSubtype; /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string} targetDir Directory where built definitions will be saved * @param {AssetItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested(templateDir: string, targetDir: string, metadata: AssetItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example assets of type codesnippetblock will result in 1 json and 1 amp/html file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {AssetItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested(templateDir: string, targetDir: string | string[], metadata: AssetItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {AssetItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static _buildForNested(templateDir: string, targetDir: string | string[], metadata: AssetItem, templateVariables: TemplateMap, templateName: string, mode: "definition" | "template"): Promise<string[][]>; /** * generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single script activity definition * @param {boolean} [hideWarning] when checking content blocks we do want to set the folder path but if we cant, lets not cludder the log with warnings about it */ static setFolderPath(metadata: MetadataTypeItem, hideWarning?: boolean): void; /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {AssetItem} metadata a single asset definition * @returns {Promise.<void>} fileList for templating (disregarded during deployment) */ static _preDeployTasksBocks(metadata: AssetItem): Promise<void>; /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @returns {Promise.<void>} - */ static _preDeployTasksBocks_slots(metadataSlots: object): Promise<void>; /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {AssetItem} metadata a single asset definition * @param {string} deployDir directory of deploy files * @param {string} subType asset-subtype name; full list in AssetSubType * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @param {boolean} [fileListOnly] does not read file contents nor update metadata if true * @returns {Promise.<CodeExtract[]>} fileList for templating (disregarded during deployment) */ static _mergeCode(metadata: AssetItem, deployDir: string, subType: string, templateName?: string, fileListOnly?: boolean): Promise<CodeExtract[]>; /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {string} prefix usually the customerkey * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @param {string[]} readDirArr directory of deploy files * @param {string} subtypeExtension asset-subtype name ending on -meta * @param {string[]} subDirArr directory of files w/o leading deploy dir * @param {object[]} fileList directory of files w/o leading deploy dir * @param {string} customerKey external key of template (could have been changed if used during templating) * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @param {boolean} [fileListOnly] does not read file contents nor update metadata if true * @returns {Promise.<void>} - */ static _mergeCode_slots(prefix: string, metadataSlots: object, readDirArr: string[], subtypeExtension: string, subDirArr: string[], fileList: object[], customerKey: string, templateName?: string, fileListOnly?: boolean): Promise<void>; /** * helper for {@link Asset.postRetrieveTasks} that finds code content in JSON and extracts it * to allow saving that separately and formatted * * @param {AssetItem} metadata a single asset definition * @returns {CodeExtractItem} { json: metadata, codeArr: object[], subFolder: string[] } */ static _extractCode(metadata: AssetItem): CodeExtractItem; /** * helper for {@link Asset.postRetrieveTasks} via {@link Asset._extractCode} * * @param {string} prefix usually the customerkey * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @param {object[]} codeArr to be extended array for extracted code * @returns {void} */ static _extractCode_slots(prefix: string, metadataSlots: object, codeArr: object[]): void; /** * helper for {@link Asset.getJsonFromFS} that reads the file system for metadata files * * @param {string} currentdir directory to scan * @param {string} subtype single subtype of asset * @param {MetadataTypeMap} fileName2FileContent fileName => fileContent map */ static _getJsonFromFS(currentdir: string, subtype: string, fileName2FileContent: MetadataTypeMap): Promise<void>; /** * optional method used for some types to try a different folder structure * * @param {string} templateDir Directory where metadata templates are stored * @param {string[]} typeDirArr current subdir for this type * @param {string} templateName name of the metadata template * @param {string} fileName name of the metadata template file w/o extension * @returns {Promise.<string>} metadata in string form */ static readSecondaryFolder(templateDir: string, typeDirArr: string[], templateName: string, fileName: string): Promise<string>; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} id value or null */ private static _getIdForSingleRetrieve; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} id id field * @returns {Promise.<string>} key value or null */ private static _getKeyForSingleRetrieve; /** * clean up after deleting a metadata item * cannot use the generic method due to the complexity of how assets are saved to disk * * @param {string} key Identifier of metadata item * @returns {Promise.<void>} - */ static postDeleteTasks(key: string): Promise<void>; /** * get name & key for provided id * * @param {string} id Identifier of metadata * @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 */ static resolveId(id: string): Promise<{ key: string; name: string; path: string; folder: string; mid: number; error: string; isShared: boolean; }>; /** * helper for {@link Asset.resolveId} that finds the path to the asset's code * * @param {string} subType asset subtype * @param {object} item api response for metadata * @param {string} buName owner business unit name * @returns {Promise.<string>} path to the asset's code */ static "__#private@#getPath"(subType: string, item: object, buName: string): Promise<string>; /** * helper for {@link Asset.resolveId} that loads the JSON file for the asset * * @param {string} subType asset subtype * @param {object} item api response for metadata * @returns {Promise.<object>} JS object of the asset we loaded from disk */ static "__#private@#getJson"(subType: string, item: object): Promise<object>; /** * * @param {MetadataTypeItem} item single metadata item * @param {string} retrieveDir directory where metadata is saved * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem>} key of the item that was updated */ static replaceCbReference(item: MetadataTypeItem, retrieveDir: string, findAssetKeys?: Set<string>): Promise<MetadataTypeItem>; /** * * @param {string[]} keyArr limit retrieval to given metadata type * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} findAssetKeys list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<Set.<string>>} found asset keys */ static getCbReferenceKeys(keyArr: string[], retrieveDir: string, findAssetKeys: Set<string>): Promise<Set<string>>; /** * @param {object} slots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @param {string[]} dependentKeyArr list of found keys */ static _getDependentFilesExtra(slots: object, dependentKeyArr: string[]): void; } declare namespace Asset { let getJsonFromFSCache: { [x: string]: any; }; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { asset: string[]; }; folderType: string; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: string[]; typeCdpByDefault: boolean; typeName: string; stringifyFieldsBeforeTemplate: string[]; allowMatchingByName: boolean; fields: { activeDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; allowedBlocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; assetType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'assetType.displayName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'assetType.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'assetType.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; availableViews: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modelVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; blocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; businessUnitAvailability: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.view': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.update': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.delete': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.memberId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.transferOwnership': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; category: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'category.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'category.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'category.parentId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; channels: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; content: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.url': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; contentType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.userId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customFields: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.campaigns': { skipValidation: boolean; }; 'data.approvals': { skipValidation: boolean; }; 'data.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.email.attributes': { skipValidation: boolean; }; 'data.email.legacy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.email.options': { skipValidation: boolean; }; 'data.portfolio': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.site': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.site.content': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.site.content.url': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; design: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; enterpriseId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; file: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.fileName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.extension': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.externalUrl': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.fileSize': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.fileCreatedDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.width': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.height': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.publishedURL': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; legacyData: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; locked: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxBlocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; memberId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; meta: { skipValidation: boolean; }; minBlocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.userId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; objectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.userId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sharingProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.localAssets': { skipValidation: boolean; }; 'sharingProperties.sharedWith': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.sharedFrom': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.sharedFromMID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.sharingType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; slots: { skipValidation: boolean; }; 'status.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'status.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; superContent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; tags: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; template: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; thumbnail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; version: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; views: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; subTypes: string[]; crosslinkedSubTypes: string[]; selflinkedSubTypes: string[]; binarySubtypes: string[]; extendedSubTypes: { archive: string[]; asset: string[]; audio: string[]; block: string[]; cloudpage: string[]; code: string[]; coderesource: string[]; document: string[]; image: string[]; message: string[]; other: string[]; rawimage: string[]; template: string[]; textfile: string[]; video: string[]; }; typeMapping: { asset: number; file: number; block: number; template: number; message: number; custom: number; default: number; image: number; rawimage: number; video: number; document: number; audio: number; archive: number; code: number; textfile: number; ai: number; psd: number; pdd: number; eps: number; gif: number; jpe: number; jpeg: number; jpg: number; jp2: number; jpx: number; pict: number; pct: number; png: number; tif: number; tiff: number; tga: number; bmp: number; wmf: number; vsd: number; pnm: number; pgm: number; pbm: number; ppm: number; svg: number; '3fr': number; ari: number; arw: number; bay: number; cap: number; crw: number; cr2: number; dcr: number; dcs: number; dng: number; drf: number; eip: number; erf: number; fff: number; iiq: number; k25: number; kdc: number; mef: number; mos: number; mrw: number; nef: number; nrw: number; orf: number; pef: number; ptx: number; pxn: number; raf: number; raw: number; rw2: number; rwl: number; rwz: number; srf: number; sr2: number; srw: number; x3f: number; '3gp': number; '3gpp': number; '3g2': number; '3gp2': number; asf: number; avi: number; m2ts: number; mts: number; dif: number; dv: number; mkv: number; mpg: number; f4v: number; flv: number; mjpg: number; mjpeg: number; mxf: number; mpeg: number; mp4: number; m4v: number; mp4v: number; mov: number; swf: number; wmv: number; rm: number; ogv: number; indd: number; indt: number; incx: number; wwcx: number; doc: number; docx: number; dot: number; dotx: number; mdb: number; mpp: number; ics: number; xls: number; xlsx: number; xlk: number; xlsm: number; xlt: number; xltm: number; csv: number; tsv: number; tab: number; pps: number; ppsx: number; ppt: number; pptx: number; pot: number; thmx: number; pdf: number; ps: number; qxd: number; rtf: number; sxc: number; sxi: number; sxw: number; odt: number; ods: number; ots: number; odp: number; otp: number; epub: number; dvi: number; key: number; keynote: number; pez: number; aac: number; m4a: number; au: number; aif: number; aiff: number; aifc: number; mp3: number; wav: number; wma: number; midi: number; oga: number; ogg: number; ra: number; vox: number; voc: number; '7z': number; arj: number; bz2: number; cab: number; gz: number; gzip: number; iso: number; lha: number; sit: number; tgz: number; jar: number; rar: number; tar: number; zip: number; gpg: number; htm: number; html: number; xhtml: number; xht: number; css: number; less: number; sass: number; js: number; json: number; atom: number; rss: number; xml: number; xsl: number; xslt: number; md: number; markdown: number; as: number; fla: number; eml: number; text: number; txt: number; freeformblock: number; textblock: number; htmlblock: number; textplusimageblock: number; imageblock: number; abtestblock: number; dynamicblock: number; stylingblock: number; einsteincontentblock: number; webpage: number; webtemplate: number; templatebasedemail: number; htmlemail: number; textonlyemail: number; socialshareblock: number; socialfollowblock: number; buttonblock: number; layoutblock: number; defaulttemplate: number; smartcaptureblock: number; smartcaptureformfieldblock: number; smartcapturesubmitoptionsblock: number; slotpropertiesblock: number; externalcontentblock: number; codesnippetblock: number; rssfeedblock: number; formstylingblock: number; referenceblock: number; imagecarouselblock: number; customblock: number; liveimageblock: number; livesettingblock: number; contentmap: number; jsonmessage: number; icemailformblock: number; coderesource: number; jscoderesource: number; csscoderesource: number; jsoncoderesource: number; rsscoderesource: number; textcoderesource: number; xmlcoderesource: number; cloudpages: number; landingpage: number; microsite: number; interactivecontent: number; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Asset.d.ts.map ================================================ FILE: @types/lib/metadataTypes/AttributeGroup.d.ts ================================================ export default AttributeGroup; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; /** * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj */ /** * AttributeGroup MetadataType * * @augments MetadataType */ declare class AttributeGroup extends MetadataType { /** * Retrieves Metadata of schema attribute groups. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata of schema attribute groups for caching. * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single metadata * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace AttributeGroup { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { attributeSet: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { applicationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; applicationKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeCount: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeGroupIconKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeGroupType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeSetIdentifiers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].definitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].definitionName.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].namespace': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; canAddProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canAddRelationships: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canChangeProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canModify: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canRemove: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; connectingID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'connectingID.identifierType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; containsSchemaAttributes: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'definitionName.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; displayOrder: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fullyQualifiedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isHidden: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isOwner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isPrimary: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSystemDefined: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; localizedDescription: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceSetKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceValueKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'localizedDescription.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; mID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; namespace: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; objectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requiredRelationships: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__attributeSet_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=AttributeGroup.d.ts.map ================================================ FILE: @types/lib/metadataTypes/AttributeSet.d.ts ================================================ export default AttributeSet; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; /** * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj */ /** * AttributeSet MetadataType * * @augments MetadataType */ declare class AttributeSet extends MetadataType { static systemValueDefinitions: any; /** * Retrieves Metadata of schema set Definitions. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata of schema set definitions for caching. * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * used to identify updated shared data extensions that are used in attributeSets. * helper for DataExtension.#fixShared_onBU * * @param {Object.<string, string>} sharedDataExtensionMap ID-Key relationship of shared data extensions * @param {object} fixShared_fields DataExtensionField.fixShared_fields * @returns {Promise.<string[]>} Promise of list of shared dataExtension IDs */ static fixShared_retrieve(sharedDataExtensionMap: { [x: string]: string; }, fixShared_fields: object): Promise<string[]>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single metadata * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * helper for {@link AttributeSet.postRetrieveTasks} * * @returns {object[]} all system value definitions */ static _getSystemValueDefinitions(): object[]; } declare namespace AttributeSet { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; attributeSet: string[]; attributeGroup: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: any; lastmodNameField: any; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { applicationID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; applicationKey: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; attributeCount: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canAddValues: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canChangeValues: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canModify: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canRemove: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; categoryID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'connectingID.identifierType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createDate: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; createdBy: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; customObjectOwnerMID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.isDeleteAtEndOfRetentionPeriod': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.isResetRetentionPeriodOnImport': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.isRowBasedRetention': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.periodUnitOfMeasure': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.setDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.periodLength': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; definitionID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; definitionKey: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; definitionName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'definitionName.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fullyQualifiedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isCustomObjectBacked: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isEvent: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isHidden: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isReadOnly: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isRoot: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isSendable: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isShared: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isSystemDefined: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isTestaable: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftConnectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.cardinality ': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.identifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; localizedDescription: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceSetKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceValueKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; nonStandardAttributeGroupReferences: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'nonStandardAttributeGroupReferences[].attributeGroupType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'nonStandardAttributeGroupReferences[].attributeGroupID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'nonStandardAttributeGroupReferences[].definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.maskType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.maskTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.storageType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.storageTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.valueDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.definitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.definitionName.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; parentID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; relationshipCount: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; relationships: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].canModify': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].canRemove': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].isGroupToSetRelationship': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].isHidden': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].isSystemDefined': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipIDs': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.r__attributeSet_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.r__attributeGroup_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.r__attributeSet_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.r__attributeGroup_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipIDs[].type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipIDs[].value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipReferenceType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].leftAttributeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].rightAttributeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].c__leftFullyQualifiedName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].c__rightFullyQualifiedName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightConnectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.identifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; sendAttributeStorageName: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; sendContactKeyStorageName: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; setDefinitionID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; setDefinitionKey: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'setDefinitionName.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageFieldReferenceID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageFieldReferenceID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; storageLogicalType: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; storageName: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalIsRowIdentifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalObjectFieldAPIName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalObjectFieldDataTypeName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalObjectFieldLength': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; storageObjectIDs: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectInformation.externalObjectAPIName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageReferenceID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageReferenceID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; valueDefinitions: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].baseType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].customerDataID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].connectingID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].dataSourceID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].dataSourceName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].dataType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].defaultValue': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].definitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].definitionName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].description': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].displayOrder': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].fullyQualifiedName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isHidden': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isIdentityValue': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isNullable': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isPrimaryKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isReadOnly': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isSystemDefined': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isUpdateable': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].length': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].localizedDescription': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].name': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.maskType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.maskTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.storageType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.storageTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.valueDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].ordinal': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].parentDefinition': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].parentIdentifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].parentType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].restrictionLookupListID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].scale': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].setDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].setDefinitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].setDefinitionName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldReferenceID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldReferenceID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldReferenceID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldValueID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldValueID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageObjectFieldInformation': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldAPIName': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldDataTypeName': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldLength': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalIsRowIdentifier': { skipValidation: boolean; }; 'valueDefinitions[].valueDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].valueDefinitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; r__folder_Path: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; r__dataExtension_key: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=AttributeSet.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Automation.d.ts ================================================ export default Automation; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SDKError = import("../../types/mcdev.d.js").SDKError; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type AutomationItem = import("../../types/mcdev.d.js").AutomationItem; export type AutomationItemObj = import("../../types/mcdev.d.js").AutomationItemObj; export type AutomationMap = import("../../types/mcdev.d.js").AutomationMap; export type AutomationMapObj = import("../../types/mcdev.d.js").AutomationMapObj; export type AutomationSchedule = import("../../types/mcdev.d.js").AutomationSchedule; export type AutomationScheduleSoap = import("../../types/mcdev.d.js").AutomationScheduleSoap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * @typedef {import('../../types/mcdev.d.js').AutomationItem} AutomationItem * @typedef {import('../../types/mcdev.d.js').AutomationItemObj} AutomationItemObj * @typedef {import('../../types/mcdev.d.js').AutomationMap} AutomationMap * @typedef {import('../../types/mcdev.d.js').AutomationMapObj} AutomationMapObj * @typedef {import('../../types/mcdev.d.js').AutomationSchedule} AutomationSchedule * @typedef {import('../../types/mcdev.d.js').AutomationScheduleSoap} AutomationScheduleSoap */ /** * Automation MetadataType * * @augments MetadataType */ declare class Automation extends MetadataType { static notificationUpdates: {}; static createdKeyMap: any; static _skipNotificationRetrieve: boolean; /** @type {AutomationMap} */ static _cachedMetadataMap: AutomationMap; /** * Retrieves Metadata of Automation * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<AutomationMapObj>} Promise of metadata */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<AutomationMapObj>; /** * helper for {@link this.retrieveRESTcollection} * * @param {SDKError} ex exception * @param {string} key id or key of item * @param {string} url url to call for retry * @returns {Promise.<any>} can return retry-result */ static handleRESTErrors(ex: SDKError, key: string, url: string): Promise<any>; /** * helper for {@link Automation.retrieve} to get Automation Notifications * * @param {MetadataTypeMap} metadataMap keyField => metadata map * @param {boolean} [skipNotification] skip notification retrieval * @returns {Promise.<object>} Promise of automation legacy api response */ static "__#private@#getAutomationLegacyREST"(metadataMap: MetadataTypeMap, skipNotification?: boolean): Promise<object>; /** * Retrieves Metadata of Automation * * @returns {Promise.<AutomationMapObj>} Promise of metadata */ static retrieveChangelog(): Promise<AutomationMapObj>; /** * Retrieves automation metadata for caching * * @returns {Promise.<AutomationMapObj>} Promise of metadata */ static retrieveForCache(): Promise<AutomationMapObj>; /** * Retrieve a specific Automation Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<AutomationItemObj>} Promise of metadata */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<AutomationItemObj>; /** * helper for {@link Automation.postRetrieveTasks} and {@link Automation.execute} * * @param {AutomationItem} metadata a single automation * @returns {boolean} true if the automation schedule is valid */ static "__#private@#isValidSchedule"(metadata: AutomationItem): boolean; /** * manages post retrieve steps * * @param {AutomationItem} metadata a single automation * @returns {AutomationItem | void} parsed item */ static postRetrieveTasks(metadata: AutomationItem): AutomationItem | void; /** * a function to active the schedule of an automation * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static schedule(keyArr: string[]): Promise<string[]>; /** * a function to pause the schedule of an automation * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static pause(keyArr: string[]): Promise<string[]>; /** * a function to active the schedule of an automation * * @param {'schedule'|'pause'} mode what to do * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static "__#private@#schedulePause"(mode: "schedule" | "pause", keyArr: string[]): Promise<string[]>; /** * helper for {@link Automation.schedule} * * @param {'schedule'|'pause'} mode what to do * @param {string} key automation key * @param {string} automationLegacyId automation id * @param {string} [scheduleLegacyId] schedule id * @param {string} [description] schedule description * @returns {Promise.<{key:string, response:object}>} metadata key and API response */ static "__#private@#schedulePauseItem"(mode: "schedule" | "pause", key: string, automationLegacyId: string, scheduleLegacyId?: string, description?: string): Promise<{ key: string; response: object; }>; /** * a function to start query execution via API * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static execute(keyArr: string[]): Promise<string[]>; /** * Creates a single automation * * @param {AutomationItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata: AutomationItem): Promise<any>; /** * Updates a single automation * * @param {AutomationItem} metadata single metadata entry * @param {AutomationItem} metadataBefore metadata mapped by their keyField * @returns {Promise} Promise */ static update(metadata: AutomationItem, metadataBefore: AutomationItem): Promise<any>; /** * helper for {@link Automation.preDeployTasks} and {@link Automation.execute} * * @param {AutomationItem} metadata metadata mapped by their keyField */ static "__#private@#preDeploySchedule"(metadata: AutomationItem): void; /** * Gets executed before deploying metadata * * @param {AutomationItem} metadata metadata mapped by their keyField * @returns {Promise.<AutomationItem>} Promise */ static preDeployTasks(metadata: AutomationItem): Promise<AutomationItem>; /** * Validates the automation to be sure it can be deployed. * Whitelisted Activites are deployed but require configuration * * @param {AutomationItem} metadata single automation record * @returns {boolean} result if automation can be deployed based on steps */ static validateDeployMetadata(metadata: AutomationItem): boolean; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @returns {Promise.<void>} - */ static _postChangeKeyTasks(metadataEntry: MetadataTypeItem): Promise<void>; /** * Gets executed after deployment of metadata type * * @param {AutomationMap} metadataMap metadata mapped by their keyField * @returns {Promise.<void>} - */ static postDeployTasks(metadataMap: AutomationMap): Promise<void>; /** * helper for {@link Automation.postDeployTasks} * * @param {AutomationMap} metadataMap metadata mapped by their keyField * @param {string} key current customer key * @returns {Promise.<void>} - */ static "__#private@#updateNotificationInfoREST"(metadataMap: AutomationMap, key: string): Promise<void>; /** * Builds a schedule object to be used for scheduling an automation * based on combination of ical string and start/end dates. * * @param {AutomationSchedule} scheduleObject child of automation metadata used for scheduling * @param {boolean} [errorOnNotSchedulable] used if run for schedule command * @returns {void} throws and error in case of problems */ static _checkSchedule(scheduleObject: AutomationSchedule, errorOnNotSchedulable?: boolean): void; /** * used to convert dates to the system timezone required for startDate * * @param {number} offsetServer stack4: US Mountain time (UTC-7); other stacks: US Central (UTC-6) * @param {string|Date} dateInput date in ISO format (2021-12-05T20:00:00.983) * @param {string} [offsetInput] timzone difference (+02:00) * @returns {string} date in server */ static _calcTime(offsetServer: number, dateInput: string | Date, offsetInput?: string): string; /** * Experimental: Only working for DataExtensions: * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {AutomationItem} json dataextension * @param {object[][]} tabled prepped array for output in tabular format * @returns {string} file content */ private static _generateDocMd; /** * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {string} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {AutomationItem} json dataextension.columns * @param {'html'|'md'} mode html or md * @returns {Promise.<void>} Promise of success of saving the file */ private static _writeDoc; /** * Parses metadata into a readable Markdown/HTML format then saves it * * @param {AutomationMap} [metadata] a list of dataExtension definitions * @returns {Promise.<void>} - */ static document(metadata?: AutomationMap): Promise<void>; /** * helper to allow us to select single metadata entries via REST * * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static "__#private@#getObjectIdForSingleRetrieve"(key: string): Promise<string>; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static postDeleteTasks(customerKey: string): Promise<void>; } declare namespace Automation { let retrieveDir: string; let definition: { activityTypeMapping: { dataExtract: number; dataFactoryUtility: number; emailSend: number; fileTransfer: number; filter: number; fireEvent: number; importFile: number; journeyEntry: number; journeyEntryOld: number; query: number; script: number; verification: number; wait: number; push: number; sms: number; reportDefinition: number; refreshMobileFilteredList: number; refreshGroup: number; interactions: number; interactionStudioData: number; importMobileContact: number; }; bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtract: string[]; emailSend: string[]; fileTransfer: string[]; importFile: string[]; query: string[]; script: string[]; verification: string[]; }; folderType: string; hasExtended: boolean; filter: { description: string[]; }; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; maxKeyLength: number; scheduleTypeMapping: { MINUTELY: number; HOURLY: number; DAILY: number; WEEKLY: number; MONTHLY: number; }; statusMapping: { AwaitingTrigger: number; Building: number; BuildingError: number; Error: number; InactiveTrigger: number; PausedSchedule: number; Ready: number; Running: number; Scheduled: number; Stopped: number; }; fileNameOperatorMapping: { Equals: number; Contains: number; 'Begins with': number; 'Ends with': number; }; timeZoneMapping: { 'Afghanistan Standard Time': number; 'Alaskan Standard Time': number; 'Arab Standard Time': number; 'Arabian Standard Time': number; 'Arabic Standard Time': number; 'Argentina Standard Time': number; 'Atlantic Standard Time': number; 'AUS Central Standard Time': number; 'AUS Eastern Standard Time': number; 'Azerbaijan Standard Time': number; 'Azores Standard Time': number; 'Canada Central Standard Time': number; 'Cape Verde Standard Time': number; 'Caucasus Standard Time': number; 'Cen. Australia Standard Time': number; 'Central America Standard Time': number; 'Central Asia Standard Time': number; 'Central Brazilian Standard Time': number; 'Central Europe Standard Time': number; 'Central European Standard Time': number; 'Central Pacific Standard Time': number; 'Central Standard Time': number; 'Central Standard Time (Mexico)': number; 'Central Standard Time (no DST)': number; 'China Standard Time': number; 'Dateline Standard Time': number; 'E. Africa Standard Time': number; 'E. Australia Standard Time': number; 'E. Europe Standard Time': number; 'E. South America Standard Time': number; 'Eastern Standard Time': number; 'Egypt Standard Time': number; 'Ekaterinburg Standard Time': number; 'Fiji Standard Time': number; 'FLE Standard Time': number; 'Georgian Standard Time': number; 'GMT Standard Time': number; 'Greenland Standard Time': number; 'Greenwich Standard Time': number; 'GTB Standard Time': number; 'Hawaiian Standard Time': number; 'India Standard Time': number; 'Iran Standard Time': number; 'Israel Standard Time': number; 'Jordan Standard Time': number; 'Korea Standard Time': number; 'Mauritius Standard Time': number; 'Mid-Atlantic Standard Time': number; 'Middle East Standard Time': number; 'Montevideo Standard Time': number; 'Morocco Standard Time': number; 'Mountain Standard Time': number; 'Mountain Standard Time (Mexico)': number; 'Myanmar Standard Time': number; 'N. Central Asia Standard Time': number; 'Namibia Standard Time': number; 'Nepal Standard Time': number; 'New Zealand Standard Time': number; 'Newfoundland Standard Time': number; 'North Asia East Standard Time': number; 'North Asia Standard Time': number; 'Pacific SA Standard Time': number; 'Pacific Standard Time': number; 'Pacific Standard Time (Mexico)': number; 'Pakistan Standard Time': number; 'Romance Standard Time': number; 'Russian Standard Time': number; 'SA Pacific Standard Time': number; 'SA Western Standard Time': number; 'Samoa Standard Time': number; 'SE Asia Standard Time': number; 'Singapore Standard Time': number; 'South Africa Standard Time': number; 'Sri Lanka Standard Time': number; 'Taipei Standard Time': number; 'Tasmania Standard Time': number; 'Tokyo Standard Time': number; 'Tonga Standard Time': number; 'US Eastern Standard Time': number; 'US Mountain Standard Time': number; 'Venezuela Standard Time': number; 'Vladivostok Standard Time': number; 'W. Australia Standard Time': number; 'W. Central Africa Standard Time': number; 'W. Europe Standard Time': number; 'West Asia Standard Time': number; 'West Pacific Standard Time': number; 'Yakutsk Standard Time': number; }; timeZoneDifference: { 1: string; 2: string; 3: string; 4: string; 5: string; 6: string; 7: string; 8: string; 9: string; 10: string; 11: string; 12: string; 13: string; 14: string; 15: string; 16: string; 17: string; 18: string; 19: string; 20: string; 21: string; 22: string; 23: string; 24: string; 25: string; 26: string; 27: string; 28: string; 29: string; 30: string; 31: string; 32: string; 33: string; 34: string; 35: string; 36: string; 37: string; 38: string; 39: string; 40: string; 41: string; 42: string; 43: string; 44: string; 45: string; 46: string; 47: string; 48: string; 49: string; 50: string; 51: string; 52: string; 53: string; 54: string; 55: string; 56: string; 57: string; 58: string; 59: string; 60: string; 61: string; 62: string; 63: string; 64: string; 65: string; 66: string; 67: string; 68: string; 69: string; 70: string; 71: string; 72: string; 73: string; 74: string; 75: string; 76: string; 77: string; 78: string; 79: string; 80: string; 81: string; 82: string; 83: string; 84: string; 85: string; 86: string; 87: string; 88: string; 89: string; 90: string; 91: string; 92: string; }; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; customDeployTypes: string[]; manualDeployTypes: any[]; fields: { categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.fileNamePatternTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.fileNamingPattern': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.folderLocationText': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.isPublished': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.queueFiles': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.triggerActive': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: any; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastRunInstanceId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastRunTime: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; legacyId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastSavedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastSavedByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; pausedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; pausedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; updateInProgress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; notifications: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].message': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].channelType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].notificationType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startSource: { skipValidation: boolean; }; 'schedule.endDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.icalRecur': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.occurrences': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.pattern': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.rangeTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduleStatus': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.statusId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.timezoneId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.timezoneName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.typeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduleTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; statusId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; steps: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].activityObjectId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].displayOrder': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].objectTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].targetDataExtensions': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].serializedObject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].r__type': { skipValidation: boolean; }; 'steps[].activities[].r__key': { skipValidation: boolean; }; 'steps[].activities[].timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].annotation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].step': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].stepNumber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; typeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Automation.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Campaign.d.ts ================================================ export default Campaign; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * Campaign MetadataType * * @augments MetadataType */ declare class Campaign extends MetadataType { /** * Retrieves Metadata of campaigns. Afterwards, starts metadata retrieval for their campaign assets * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Parses campaign asset response body and returns metadata entries mapped to their id * * @param {string} retrieveDir folder where to save * @param {string} campaignId of camapaign to retrieve * @param {string} name of camapaign for saving * @returns {Promise.<MetadataTypeMapObj>} Campaign Asset Object */ static getAssetTags(retrieveDir: string, campaignId: string, name: string): Promise<MetadataTypeMapObj>; } declare namespace Campaign { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ownerId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; externalKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignCode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'display.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'display.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; isFavorite: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignOwnerName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignOwner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignStatus: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Campaign.d.ts.map ================================================ FILE: @types/lib/metadataTypes/ContentArea.d.ts ================================================ export default ContentArea; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ContentArea MetadataType * * @augments MetadataType */ declare class ContentArea extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed item */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace ContentArea { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: any; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; restPagination: any; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { BackgroundColor: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BorderColor: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BorderWidth: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Cellpadding: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Cellspacing: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Content: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FontFamily: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HasFontSize: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsBlank: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsDynamicContent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsLocked: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSurvey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Layout: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Width: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=ContentArea.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataExtension.d.ts ================================================ export default DataExtension; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type DataExtensionFieldItem = import("../../types/mcdev.d.js").DataExtensionFieldItem; export type DataExtensionFieldMap = import("../../types/mcdev.d.js").DataExtensionFieldMap; export type DataExtensionItem = import("../../types/mcdev.d.js").DataExtensionItem; export type DataExtensionMap = import("../../types/mcdev.d.js").DataExtensionMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldItem} DataExtensionFieldItem * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldMap} DataExtensionFieldMap * @typedef {import('../../types/mcdev.d.js').DataExtensionItem} DataExtensionItem * @typedef {import('../../types/mcdev.d.js').DataExtensionMap} DataExtensionMap */ /** * DataExtension MetadataType * * @augments MetadataType */ declare class DataExtension extends MetadataType { /** @type {Object.<string, DataExtensionFieldMap>} key: deKey, value: deFieldMap */ static oldFields: { [x: string]: { [x: string]: import("../../types/mcdev.d.js").DataExtensionFieldItem; }; }; /** * Upserts dataExtensions after retrieving them from source and target to compare * if create or update operation is needed. * * @param {DataExtensionMap} metadataMap dataExtensions mapped by their customerKey * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<MetadataTypeMap>} keyField => metadata map */ static upsert(metadataMap: DataExtensionMap, deployDir: string): Promise<MetadataTypeMap>; /** * helper for {@link DataExtension.upsert} * * @param {object} res - * @returns {boolean} true: keep, false: discard */ static "__#private@#filterUpsertResults"(res: object): boolean; /** * Create a single dataExtension. Also creates their columns in 'dataExtension.columns' * * @param {DataExtensionItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata: DataExtensionItem): Promise<any>; /** * SFMC saves a date in "RetainUntil" under certain circumstances even * if that field duplicates whats in the period fields * during deployment, that extra value is not accepted by the APIs which is why it needs to be removed * * @param {DataExtensionItem} metadata single metadata entry * @returns {void} */ static "__#private@#cleanupRetentionPolicyFields"(metadata: DataExtensionItem): void; /** * Updates a single dataExtension. Also updates their columns in 'dataExtension.columns' * * @param {DataExtensionItem} metadata single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise} Promise */ static update(metadata: DataExtensionItem, handleOutside?: boolean): Promise<any>; /** * Gets executed after deployment of metadata type * * @param {DataExtensionMap} upsertedMetadata metadata mapped by their keyField * @param {DataExtensionMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static postDeployTasks(upsertedMetadata: DataExtensionMap, originalMetadata: DataExtensionMap, createdUpdated: { created: number; updated: number; }): Promise<void>; /** * takes care of updating attribute groups on child BUs after an update to Shared DataExtensions * helper for {@link DataExtension.postDeployTasks} * fixes an issue where shared data extensions are not visible in data designer on child BU; SF known issue: https://issues.salesforce.com/#q=W-11031095 * * @param {DataExtensionMap} upsertedMetadata metadata mapped by their keyField * @param {DataExtensionMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static "__#private@#fixShared"(upsertedMetadata: DataExtensionMap, originalMetadata: DataExtensionMap, createdUpdated: { created: number; updated: number; }): Promise<void>; /** * helper for {@link DataExtension.#fixShared} * * @returns {Promise.<string[]>} list of selected BU names */ static "__#private@#fixShared_getBUs"(): Promise<string[]>; /** * helper for {@link DataExtension.#fixShared} * * @param {string} childBuName name of child BU to fix * @param {BuObject} buObjectParent bu object for parent BU * @param {object} clientParent SDK for parent BU * @param {Object.<string, string>} sharedDataExtensionMap ID-Key relationship of shared data extensions * @returns {Promise.<string[]>} updated shared DE keys on BU */ static "__#private@#fixShared_onBU"(childBuName: string, buObjectParent: BuObject, clientParent: object, sharedDataExtensionMap: { [x: string]: string; }): Promise<string[]>; /** * method that actually takes care of triggering the update for a particular BU-sharedDe combo * helper for {@link DataExtension.#fixShared_onBU} * * @param {string} deId data extension ObjectID * @param {string} deKey dataExtension key * @param {BuObject} buObjectChildBu BU object for Child BU * @param {object} clientChildBu SDK for child BU * @param {BuObject} buObjectParent BU object for Parent BU * @param {object} clientParent SDK for parent BU * @returns {Promise.<boolean>} flag that signals if the fix was successful */ static "__#private@#fixShared_item"(deId: string, deKey: string, buObjectChildBu: BuObject, clientChildBu: object, buObjectParent: BuObject, clientParent: object): Promise<boolean>; /** * add a new field to the shared DE to trigger an update to the data model * helper for {@link DataExtension.#fixShared_item} * * @param {BuObject} buObjectChildBu BU object for Child BU * @param {object} clientChildBu SDK for child BU * @param {string} deKey dataExtension key * @param {string} deId dataExtension ObjectID * @returns {Promise.<string>} randomSuffix */ static "__#private@#fixShared_item_addField"(buObjectChildBu: BuObject, clientChildBu: object, deKey: string, deId: string): Promise<string>; /** * get ID of the field added by {@link DataExtension.#fixShared_item_addField} on the shared DE via parent BU * helper for {@link DataExtension.#fixShared_item} * * @param {string} randomSuffix - * @param {BuObject} buObjectParent BU object for Parent BU * @param {object} clientParent SDK for parent BU * @param {string} deKey dataExtension key * @returns {Promise.<string>} fieldObjectID */ static "__#private@#fixShared_item_getFieldId"(randomSuffix: string, buObjectParent: BuObject, clientParent: object, deKey: string): Promise<string>; /** * delete the field added by {@link DataExtension.#fixShared_item_addField} * helper for {@link DataExtension.#fixShared_item} * * @param {string} randomSuffix - * @param {BuObject} buObjectChildBu BU object for Child BU * @param {object} clientChildBu SDK for child BU * @param {string} deKey dataExtension key * @param {string} fieldObjectID field ObjectID * @returns {Promise} - */ static "__#private@#fixShared_item_deleteField"(randomSuffix: string, buObjectChildBu: BuObject, clientChildBu: object, deKey: string, fieldObjectID: string): Promise<any>; /** * Retrieves dataExtension metadata. Afterwards starts retrieval of dataExtensionColumn metadata retrieval * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {void | string[]} [_] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: DataExtensionMap, type: string}>} Promise of item map */ static retrieve(retrieveDir: string, additionalFields?: string[], _?: void | string[], key?: string): Promise<{ metadata: DataExtensionMap; type: string; }>; /** * get shared dataExtensions from parent BU and merge them into the cache * helper for {@link DataExtension.retrieve} and for AttributeSet.fixShared_retrieve * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<DataExtensionMap>} keyField => metadata map */ static retrieveSharedForCache(additionalFields?: string[]): Promise<DataExtensionMap>; /** * helper to retrieve all dataExtension fields and attach them to the dataExtension metadata * * @param {DataExtensionMap} metadata already cached dataExtension metadata * @param {SoapRequestParams} [fieldOptions] optionally filter results * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<void>} - */ static attachFields(metadata: DataExtensionMap, fieldOptions?: SoapRequestParams, additionalFields?: string[]): Promise<void>; /** * Retrieves dataExtension metadata. Afterwards starts retrieval of dataExtensionColumn metadata retrieval * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<{metadata: DataExtensionMap, type: string}>} Promise of item map */ static retrieveChangelog(additionalFields?: string[]): Promise<{ metadata: DataExtensionMap; type: string; }>; /** * manages post retrieve steps * * @param {DataExtensionItem} metadata a single dataExtension * @returns {Promise.<DataExtensionItem>} metadata */ static postRetrieveTasks(metadata: DataExtensionItem): Promise<DataExtensionItem>; /** * Helper to retrieve Data Extension Fields * * @private * @param {SoapRequestParams} [options] options (e.g. continueRequest) * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<DataExtensionFieldMap>} Promise of items */ private static _retrieveFields; /** * helps retrieving fields during templating and deploy where we dont want the full list * * @private * @param {DataExtensionMap} metadata list of DEs * @param {string} customerKey external key of single DE * @returns {Promise.<void>} - */ private static _retrieveFieldsForSingleDe; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @returns {Promise.<void>} - */ static _postChangeKeyTasks(metadataEntry: MetadataTypeItem): Promise<void>; /** * prepares a DataExtension for deployment * * @param {DataExtensionItem} metadata a single data Extension * @returns {Promise.<DataExtensionItem>} Promise of updated single DE */ static preDeployTasks(metadata: DataExtensionItem): Promise<DataExtensionItem>; /** * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {DataExtensionItem} json single dataextension * @param {object[][]} tabled prepped array for output in tabular format * @returns {string} file content */ private static _generateDocHtml; /** * Experimental: Only working for DataExtensions: * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {DataExtensionItem} json dataextension * @param {object[][]} tabled prepped array for output in tabular format * @returns {string} file content */ private static _generateDocMd; /** * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {string} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {DataExtensionItem} json dataextension.columns * @param {'html'|'md'} mode html or md * @param {string[]} [fieldsToKeep] list of keys(columns) to show. This will also specify * @returns {Promise.<void>} Promise of success of saving the file */ private static _writeDoc; /** * Parses metadata into a readable Markdown/HTML format then saves it * * @param {DataExtensionMap} [metadataMap] a list of dataExtension definitions * @returns {Promise.<any>} - */ static document(metadataMap?: DataExtensionMap): Promise<any>; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - promise */ static postDeleteTasks(customerKey: string): Promise<void>; /** * Retrieves folder metadata into local filesystem. Also creates a uniquePath attribute for each folder. * * @returns {Promise.<{metadata: DataExtensionMap, type: string}>} Promise */ static retrieveForCache(): Promise<{ metadata: DataExtensionMap; type: string; }>; /** * Retrieves dataExtension metadata in template format. * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata item * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<{metadata: DataExtensionItem, type: string}>} Promise of items */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<{ metadata: DataExtensionItem; type: string; }>; /** * Retrieves dataExtension metadata and cleans it * * @private * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {SoapRequestParams} [options] e.g. filter * @returns {Promise.<DataExtensionMap>} keyField => metadata map */ private static _retrieveAll; } declare namespace DataExtension { let deployedSharedKeys: any; let buObject: import("../../types/mcdev.d.js").BuObject; let client: any; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: any; folderType: string; filter: { CustomerKey: string[]; Name: string[]; }; templateFields: { AudienceBuilderResult: string[]; CONTEXTUAL_SUPPRESSION_LISTS: string[]; DomainExclusion: string[]; 'Event DE Template': string[]; PushSendLog: string[]; SendLog: string[]; 'SmartCapture - Contacts Template Extension': string[]; SmsSendLog: string[]; SMSMessageTracking: any; SMSSubscriptionLog: any; TriggeredSendDataExtension: string[]; }; dataRetentionPeriodUnitOfMeasureMapping: { Days: number; Weeks: number; Months: number; Years: number; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { CategoryID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriod: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodUnitOfMeasure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DeleteAtEndOfRetentionPeriod: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Fields: { skipValidation: boolean; }; folderContentType: { skipValidation: boolean; }; IsPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsTestable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ResetRetentionPeriodOnImport: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RetainUntil: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RowBasedRetention: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SendableDataExtensionField.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SendableDataExtensionField.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SendableDataExtensionField.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendableSubscriberField: { skipValidation: boolean; }; 'SendableSubscriberField.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Template.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Template.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Template.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_ContentType: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; r__dataExtensionTemplate_name: { skipValidation: boolean; }; c__retentionPolicy: { skipValidation: boolean; }; c__retainUntil: { skipValidation: boolean; }; c__dataRetentionPeriodUnitOfMeasure: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DataExtension.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataExtensionField.d.ts ================================================ export default DataExtensionField; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type DataExtensionFieldMap = import("../../types/mcdev.d.js").DataExtensionFieldMap; export type DataExtensionFieldItem = import("../../types/mcdev.d.js").DataExtensionFieldItem; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldMap} DataExtensionFieldMap * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldItem} DataExtensionFieldItem */ /** * DataExtensionField MetadataType * * @augments MetadataType */ declare class DataExtensionField extends MetadataType { static fixShared_fields: any; /** * Retrieves all records and saves it to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<{metadata: DataExtensionFieldMap, type: string}>} Promise of items */ static retrieve(retrieveDir: string, additionalFields?: string[]): Promise<{ metadata: DataExtensionFieldMap; type: string; }>; /** * Retrieves all records and saves it to disk * * @returns {Promise.<MetadataTypeMapObj>} Promise of items */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * helps retrieving fields for a single DE. Use when needing field data for one DE only. * * @param {string} customerKey external key of single DE * @returns {Promise.<object>} Promise of items */ static retrieveFieldsForSingleDe(customerKey: string): Promise<object>; /** * determines if a dataExtension is shared (from parent BU) by checking its folder's ContentType in the parent BU folder cache * * @param {string} customerKey external key of single DE * @returns {boolean} true if the DE is shared (stored on parent BU) */ static isSharedDe(customerKey: string): boolean; /** * helps retrieving fields for a single DE from parent BU. * Use when the DE is shared (stored on parent BU) and its fields are not in the current BU's cache. * * @param {string} customerKey external key of single DE * @returns {Promise.<object>} Promise of items */ static retrieveFieldsForSingleSharedDe(customerKey: string): Promise<object>; /** * Routes field retrieval to the correct method depending on whether the DE is local or shared. * Use this instead of duplicating the isSharedDe() check at each call site. * * @param {string} customerKey external key of single DE * @returns {Promise.<object>} Promise of items */ static retrieveFieldsForSingleDeAuto(customerKey: string): Promise<object>; /** * Retrieves all records for caching * * @param {SoapRequestParams} [requestParams] required for the specific request (filter for example) * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<{metadata: DataExtensionFieldMap, type: string}>} Promise of items */ static retrieveForCacheDE(requestParams?: SoapRequestParams, additionalFields?: string[]): Promise<{ metadata: DataExtensionFieldMap; type: string; }>; /** * helper for DataExtension.retrieveFieldsForSingleDe that sorts the fields into an array * * @param {DataExtensionFieldMap} fieldsObj customerKey-based list of fields for one dataExtension * @returns {DataExtensionFieldItem[]} sorted array of field objects */ static convertToSortedArray(fieldsObj: DataExtensionFieldMap): DataExtensionFieldItem[]; /** * sorting method to ensure `Ordinal` is respected * * @param {DataExtensionFieldItem} a - * @param {DataExtensionFieldItem} b - * @returns {number} sorting based on Ordinal */ static sortDeFields(a: DataExtensionFieldItem, b: DataExtensionFieldItem): number; /** * manages post retrieve steps; only used by DataExtension class * * @param {DataExtensionFieldItem} metadata a single item * @returns {DataExtensionFieldItem} metadata */ static postRetrieveTasksDE(metadata: DataExtensionFieldItem): DataExtensionFieldItem; /** * Mofifies passed deployColumns for update by mapping ObjectID to their target column's values. * Removes FieldType field if its the same in deploy and target column, because it results in an error even if its of the same type * * @param {DataExtensionFieldItem[]} deployColumns Columns of data extension that will be deployed * @param {string} deKey external/customer key of Data Extension * @returns {Promise.<DataExtensionFieldMap>} existing fields by their original name to allow re-adding FieldType after update */ static prepareDeployColumnsOnUpdate(deployColumns: DataExtensionFieldItem[], deKey: string): Promise<DataExtensionFieldMap>; /** * Delete a data extension from the specified business unit * * @param {string} customerKey Identifier of metadata * @param {string} [fieldId] for programmatic deletes only one can pass in the ID directly * @returns {Promise.<boolean>} deletion success flag */ static deleteByKeySOAP(customerKey: string, fieldId?: string): Promise<boolean>; } declare namespace DataExtensionField { let buObject: import("../../types/mcdev.d.js").BuObject; let client: import("sfmc-sdk").default; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: any; filter: {}; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; deleteSynchronously: boolean; fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DataExtension.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DataExtension.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DataExtension.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultValue: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FieldType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsPrimaryKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsRequired: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; MaxLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Ordinal: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Scale: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DataExtensionField.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataExtensionTemplate.d.ts ================================================ export default DataExtensionTemplate; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DataExtensionTemplate MetadataType * * @augments MetadataType */ declare class DataExtensionTemplate extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; } declare namespace DataExtensionTemplate { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; filter: {}; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsTestable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendableCustomObjectField: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendableSubscriberField: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodUnitOfMeasure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RowBasedRetention: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ResetRetentionPeriodOnImport: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DeleteAtEndOfRetentionPeriod: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RetainUntil: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DataExtensionTemplate.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataExtract.d.ts ================================================ export default DataExtract; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DataExtract MetadataType * * @augments MetadataType */ declare class DataExtract extends MetadataType { /** * Retrieves Metadata of Data Extract Activity. * Endpoint /automation/v1/dataextracts/ returns all Data Extracts * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata of Data Extract Activity for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Retrieve a specific dataExtract Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise of metadata */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<MetadataTypeItemObj>; /** * Creates a single Data Extract * * @param {MetadataTypeItem} dataExtract a single Data Extract * @returns {Promise} Promise */ static create(dataExtract: MetadataTypeItem): Promise<any>; /** * Updates a single Data Extract * * @param {MetadataTypeItem} dataExtract a single Data Extract * @returns {Promise} Promise */ static update(dataExtract: MetadataTypeItem): Promise<any>; /** * prepares a dataExtract for deployment * * @param {MetadataTypeItem} metadata a single dataExtract activity definition * @returns {MetadataTypeItem} metadata object */ static preDeployTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static postDeployTasks(upsertResults: MetadataTypeMap): Promise<void>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ private static _getObjectIdForSingleRetrieve; } declare namespace DataExtract { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; nameField: string; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataExtractDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataExtractTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataFields: { skipValidation: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; endDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileSpec: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; intervalType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataExtractType_name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DataExtract.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataExtractType.d.ts ================================================ export default DataExtractType; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DataExtractType MetadataType * Only for Caching No retrieve/upsert is required * as this is a configuration in the EID * * @augments MetadataType */ declare class DataExtractType extends MetadataType { /** * Retrieves Metadata of Data Extract Type. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata of Data Extract Type for caching. * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; } declare namespace DataExtractType { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; extractId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DataExtractType.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataFilter.d.ts ================================================ export default DataFilter; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type DataFilterItem = import("../../types/mcdev.d.js").DataFilterItem; export type DataExtensionFieldMap = import("../../types/mcdev.d.js").DataExtensionFieldMap; export type DataExtensionFieldItem = import("../../types/mcdev.d.js").DataExtensionFieldItem; export type DataFilterMap = import("../../types/mcdev.d.js").DataFilterMap; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type FilterConditionSet = import("../../types/mcdev.d.js").FilterConditionSet; export type FilterCondition = import("../../types/mcdev.d.js").FilterCondition; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').DataFilterItem} DataFilterItem * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldMap} DataExtensionFieldMap * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldItem} DataExtensionFieldItem * @typedef {import('../../types/mcdev.d.js').DataFilterMap} DataFilterMap * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').FilterConditionSet} FilterConditionSet * @typedef {import('../../types/mcdev.d.js').FilterCondition} FilterCondition */ /** * DataFilter (FilterDefinition) MetadataType * * @augments MetadataType */ declare class DataFilter extends MetadataType { static cache: {}; static deIdKeyMap: any; static hidden: boolean; /** * Retrieves all records and saves it to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [_] unused parameter * @param {string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: DataFilterMap, type: string}>} Promise of items */ static retrieve(retrieveDir: string, _?: string[], __?: string[], key?: string): Promise<{ metadata: DataFilterMap; type: string; }>; /** * helper for {@link DataFilter.retrieve} * * @param {boolean} [recached] indicates if this is a recursive call after cache refresh * @returns {Promise.<number[]>} Array of folder IDs */ static _getFilterFolderIds(recached?: boolean): Promise<number[]>; /** * helper for {@link DataFilter._cacheMeasures} * * @returns {Promise.<number[]>} Array of folder IDs */ static _getMeasureFolderIds(): Promise<number[]>; /** * helper for {@link DataFilter.retrieve}. uses cached dataExtensions to resolve dataExtensionFields * * @param {DataFilterMap} metadataTypeMap - * @param {'retrieve'|'deploy'} [mode] - */ static _cacheDeFields(metadataTypeMap: DataFilterMap, mode?: "retrieve" | "deploy"): Promise<void>; /** * helper for {@link DataFilter._cacheDeFields} * * @param {DataExtensionFieldMap} deFieldCache - */ static saveDataExtensionFieldCacheToMap(deFieldCache: DataExtensionFieldMap): void; /** * helper for {@link DataFilter.retrieve} * * @param {DataFilterMap} metadataTypeMap - */ static _cacheContactAttributes(metadataTypeMap: DataFilterMap): Promise<void>; /** * helper for {@link DataFilter.retrieve} * * @param {DataFilterMap} metadataTypeMap - */ static _cacheMeasures(metadataTypeMap: DataFilterMap): Promise<void>; /** * Retrieves all records for caching * * @returns {Promise.<{metadata: DataFilterMap, type: string}>} Promise of items */ static retrieveForCache(): Promise<{ metadata: DataFilterMap; type: string; }>; /** * parses retrieved Metadata before saving * * @param {DataFilterItem} metadata a single record * @returns {Promise.<DataFilterItem>} parsed metadata definition */ static postRetrieveTasks(metadata: DataFilterItem): Promise<DataFilterItem>; /** * helper for {@link postRetrieveTasks} * * @param {DataFilterItem} metadata - * @param {'postRetrieve'|'preDeploy'} mode - * @param {DataExtensionFieldItem[]} [fieldCache] - * @param {FilterConditionSet} [filter] - * @returns {void} */ static _resolveFields(metadata: DataFilterItem, mode: "postRetrieve" | "preDeploy", fieldCache?: DataExtensionFieldItem[], filter?: FilterConditionSet): void; /** * helper for {@link _resolveFields} * * @param {DataFilterItem} metadata - * @param {FilterCondition} condition - * @param {DataExtensionFieldItem[]} fieldCache - * @returns {void} */ static _postRetrieve_resolveFieldIdsCondition(metadata: DataFilterItem, condition: FilterCondition, fieldCache: DataExtensionFieldItem[]): void; /** * helper for {@link _resolveFields} * * @param {DataFilterItem} metadata - * @param {FilterCondition} condition - * @param {DataExtensionFieldItem[]} fieldCache - * @returns {void} */ static _preDeploy_resolveFieldNamesCondition(metadata: DataFilterItem, condition: FilterCondition, fieldCache: DataExtensionFieldItem[]): void; /** * helper for {@link postRetrieveTasks} * * @param {DataFilterItem} metadata - * @param {object} [filter] - * @returns {void} */ static _postRetrieve_resolveAttributeIds(metadata: DataFilterItem, filter?: object): void; /** * prepares a item for deployment * * @param {DataFilterItem} metadata a single record * @returns {Promise.<DataFilterItem>} Promise of updated single item */ static preDeployTasks(metadata: DataFilterItem): Promise<DataFilterItem>; /** * Creates a single item * * @param {DataFilterItem} metadata a single item * @returns {Promise.<DataFilterItem>} Promise */ static create(metadata: DataFilterItem): Promise<DataFilterItem>; /** * Updates a single item * * @param {DataFilterItem} metadata a single item * @returns {Promise.<DataFilterItem>} Promise */ static update(metadata: DataFilterItem): Promise<DataFilterItem>; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or empty string */ private static _getObjectIdForSingleRetrieve; } declare namespace DataFilter { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; filter: {}; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderType: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; restPageSize: number; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionXml: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectTypeName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__source_dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__filterDefinition: { skipValidation: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DataFilter.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DataFilterHidden.d.ts ================================================ export default DataFilterHidden; /** * DataFilterHidden (FilterDefinitionHidden) MetadataType * * @augments DataFilter */ declare class DataFilterHidden extends DataFilter { } declare namespace DataFilterHidden { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; filter: {}; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderType: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; restPageSize: number; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionXml: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectTypeName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__source_dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__filterDefinition: { skipValidation: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import DataFilter from './DataFilter.js'; //# sourceMappingURL=DataFilterHidden.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DeliveryProfile.d.ts ================================================ export default DeliveryProfile; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DeliveryProfile MetadataType * * @augments MetadataType */ declare class DeliveryProfile extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] not used * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; } declare namespace DeliveryProfile { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; filter: {}; hasExtended: boolean; idField: string; keyField: string; keyIsFixed: boolean; maxKeyLength: number; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DeliveryProfile.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Discovery.d.ts ================================================ export default Discovery; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ImportFile MetadataType * * @augments MetadataType */ declare class Discovery extends MetadataType { /** * Retrieves API endpoint * documentation: https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/routes.htm * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] not used * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; } declare namespace Discovery { let definition: { bodyIteratorField: any; dependencies: any[]; dependencyGraph: any; endPointMapping: { Address: string; Asset: string; Automation: string; Contacts: string; Data: string; Device: string; Email: string; Guide: string; Hub: string; Interaction: string; 'Interaction-Experimental': string; Legacy: string; Messaging: string; 'Messaging-Experimental': string; OTT: string; 'OTT-Experimental': string; Platform: string; 'Platform-Experimental': string; Provisioning: string; Push: string; SMS: string; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { basePath: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; baseUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; discoveryVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; documentationLink: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; kind: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; methods: { skipValidation: boolean; }; metadata: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metadata.supportsResponseEncoding': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; protocol: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; resources: { skipValidation: boolean; }; rootUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; schemas: { skipValidation: boolean; }; servicePath: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; title: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; version: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Discovery.d.ts.map ================================================ FILE: @types/lib/metadataTypes/DomainVerification.d.ts ================================================ export default DomainVerification; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type DomainVerificationItem = import("../../types/mcdev.d.js").DomainVerificationItem; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').DomainVerificationItem} DomainVerificationItem */ /** * DomainVerification MetadataType * * @augments MetadataType */ declare class DomainVerification extends MetadataType { /** * Retrieves Metadata ofDomainVerification. * Endpoint /automation/v1/dataextracts/ returns all items * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata of DomainVerification for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Creates a single item * * @param {DomainVerificationItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem: DomainVerificationItem): Promise<any>; /** * Creates a multiple metadata entries via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for POST * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static createRESTBulk(metadataEntry: MetadataTypeItem, uri: string): Promise<object> | null; /** * helper for {@link MetadataType.createREST} * * @param {DomainVerificationItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<DomainVerificationItem>} apiResponse */ static postCreateTasks(metadataEntry: DomainVerificationItem, apiResponse: object): Promise<DomainVerificationItem>; /** * helper for {@link update} * * @param {DomainVerificationItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<DomainVerificationItem>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry: DomainVerificationItem, apiResponse: object): Promise<DomainVerificationItem>; /** * Updates a single item; replaces super.updateREST because we need to send metadataItem as an array for some reason and also get an array back * * @param {DomainVerificationItem} metadataItem a single item * @returns {Promise.<DomainVerificationItem>} Promise */ static update(metadataItem: DomainVerificationItem): Promise<DomainVerificationItem>; /** * manages post retrieve steps * * @param {DomainVerificationItem} metadataItem a single item * @returns {DomainVerificationItem|void} metadata */ static postRetrieveTasks(metadataItem: DomainVerificationItem): DomainVerificationItem | void; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static postDeployTasks(upsertResults: MetadataTypeMap): Promise<void>; /** * prepares a single item for deployment * * @param {DomainVerificationItem} metadata a single item * @returns {Promise.<DomainVerificationItem>} Promise */ static preDeployTasks(metadata: DomainVerificationItem): Promise<DomainVerificationItem>; /** * Gets executed before deleting a list of keys for the current type * * @returns {Promise.<void>} - */ static preDeleteTasks(): Promise<void>; } declare namespace DomainVerification { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; createdDateField: any; createdNameField: any; lastmodDateField: any; lastmodNameField: any; nameField: string; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { domain: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; emailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; enterpriseId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; memberId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; domainType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; emailSendTime: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=DomainVerification.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Email.d.ts ================================================ export default Email; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * Email MetadataType * * @augments MetadataType */ declare class Email extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single query * @returns {MetadataTypeItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace Email { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: any; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; restPagination: any; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CharacterSet: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ClonedFromID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ContentAreas: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.CategoryID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.Content': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsBlank': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsDynamicContent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsLocked': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsSurvey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.Key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].CategoryID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].Content': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsBlank': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsDynamicContent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsLocked': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsSurvey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].Key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ContentCheckStatus: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; EmailType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Folder: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HasDynamicSubjectLine: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HTMLBody: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsActive: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsHTMLPaste: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PreHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Subject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SyncTextWithHTML: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TextBody: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Email.d.ts.map ================================================ FILE: @types/lib/metadataTypes/EmailSend.d.ts ================================================ export default EmailSend; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MessageSendActivity MetadataType * * @augments MetadataType */ declare class EmailSend extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Updates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static update(metadataItem: MetadataTypeItem): Promise<any>; /** * Creates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem: MetadataTypeItem): Promise<any>; /** * prepares a single item for deployment * * @param {MetadataTypeItem} metadata a single script activity definition * @returns {Promise.<MetadataTypeItem>} Promise */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single query * @returns {MetadataTypeItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace EmailSend { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { asset: string[]; dataExtension: string[]; deliveryProfile: string[]; list: string[]; sendClassification: string[]; senderProfile: string[]; }; folderType: string; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: any; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { Additional: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; AutoBccEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BccEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CCEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DeduplicateByEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.DomainType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.FooterContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.FooterSalutationSource': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.HeaderContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.HeaderSalutationSource': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.PrivateDomain': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.PrivateIP': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.SourceAddressType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DeliveryScheduledTime: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DomainType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DynamicEmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.Subject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.Status': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; EmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ExclusionFilter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FooterContentArea: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FooterSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HeaderContentArea: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HeaderSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IntegratedTracking: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; InteractionObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsMultipart: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSeedListSend: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSendLogging: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsWrapped: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Keyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; MessageDeliveryType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PreHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PrivateDomain: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PrivateIP: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToDisplayName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SeedListOccurance: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList.CustomObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendDefinitionList: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].CustomObjectID': { skipValidation: boolean; }; 'SendDefinitionList[].SendDefinitionListType': { skipValidation: boolean; }; 'SendDefinitionList[].DataSourceTypeID': { skipValidation: boolean; }; 'SendDefinitionList[].IsTestObject': { skipValidation: boolean; }; 'SendDefinitionList[].SalesForceObjectID': { skipValidation: boolean; }; 'SendDefinitionList[].Name': { skipValidation: boolean; }; 'SendDefinitionList[].r__dataExtension_key': { skipValidation: boolean; }; 'SendDefinitionList[].List.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].List.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].r__list_PathName': { skipValidation: boolean; }; 'SenderProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.FromAddress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.FromName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendLimit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowClose: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowDelete: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowOpen: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SourceAddressType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SuppressTracking: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TestEmailAddr: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TimeZone: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TrackingUsers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; r__asset_name_readOnly: { skipValidation: boolean; }; r__asset_key: { skipValidation: boolean; }; r__email_name: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; r__senderProfile_key: { skipValidation: boolean; }; r__sendClassification_key: { skipValidation: boolean; }; r__deliveryProfile_key: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=EmailSend.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Event.d.ts ================================================ export default Event; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type ReferenceObject = import("../../types/mcdev.d.js").ReferenceObject; export type SfObjectField = import("../../types/mcdev.d.js").SfObjectField; export type configurationArguments = import("../../types/mcdev.d.js").configurationArguments; export type Conditions = import("../../types/mcdev.d.js").Conditions; export type DataExtensionItem = import("../../types/mcdev.d.js").DataExtensionItem; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * * @typedef {import('../../types/mcdev.d.js').ReferenceObject} ReferenceObject * @typedef {import('../../types/mcdev.d.js').SfObjectField} SfObjectField * @typedef {import('../../types/mcdev.d.js').configurationArguments} configurationArguments * @typedef {import('../../types/mcdev.d.js').Conditions} Conditions * @typedef {import('../../types/mcdev.d.js').DataExtensionItem} DataExtensionItem */ /** * Event MetadataType * * @augments MetadataType */ declare class Event extends MetadataType { static reCacheDataExtensions: any[]; static createdKeys: any[]; /** * Retrieves Metadata of Event Definition. * Endpoint /interaction/v1/eventDefinitions return all Event Definitions with all details. * Currently it is not needed to loop over Imports with endpoint /interaction/v1/eventDefinitions/{id} * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Retrieve a specific Event Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise of metadata */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<MetadataTypeItemObj>; /** * Creates a single Event Definition * * @param {MetadataTypeItem} metadata a single Event Definition * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * Updates a single Event Definition (using PUT method since PATCH isn't supported) * * @param {MetadataTypeItem} metadataEntry a single Event Definition * @returns {Promise} Promise */ static update(metadataEntry: MetadataTypeItem): Promise<any>; /** * prepares an event definition for deployment * * @param {MetadataTypeItem} metadata a single eventDefinition * @returns {Promise.<MetadataTypeItem>} parsed version */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * helper for {@link createOrUpdate} * * @param {string} metadataKey key of item we are looking at * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create */ static removeFromDeployment(metadataKey: string, metadataToUpdate: MetadataTypeItemDiff[], metadataToCreate: MetadataTypeItem[]): void; /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single event definition * @returns {Promise.<MetadataTypeItem>} parsed metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; static sfObjects: { /** @type {string[]} */ workflowObjects: string[]; /** @type {Object.<string, ReferenceObject[]>} object-name > object data */ referencedObjects: { [x: string]: import("../../types/mcdev.d.js").ReferenceObject[]; }; /** @type {Object.<string, Object.<string, SfObjectField>>} object-name > field-name > field data */ objectFields: { [x: string]: { [x: string]: import("../../types/mcdev.d.js").SfObjectField; }; }; /** @type {Object.<string, Promise.<any>>} */ loadingFields: { [x: string]: Promise<any>; }; /** @type {Object.<string, Promise.<any>>} */ loadingRelatedObjects: { [x: string]: Promise<any>; }; /** @type {Promise.<any>} */ loadingWorkflowObjects: Promise<any>; }; /** * helper for {@link checkSalesforceEntryEvents} that retrieves information about SF object fields * * @param {string} objectAPIName salesforce object api name */ static getSalesforceObjects(objectAPIName: string): Promise<void>; /** * helper that allows skipping to run this again in multi-key retrieval */ static _getWorkflowObjects(): Promise<void>; /** * helper that allows skipping to run this again in multi-key retrieval * * @param {string} objectAPIName SF entry object of the current event */ static _getRelatedSfObjects(objectAPIName: string): Promise<void>; /** * helper that allows skipping to run this again in multi-key retrieval * * @param {string} objectAPIName SF object for which to get the fields */ static _getSalesforceObjectFields(objectAPIName: string): Promise<void>; static defaultSalesforceFields: string[]; /** * * @param {configurationArguments} ca trigger[0].configurationArguments * @param {boolean} isPublished if the current item is published it means we do not need to do contact vs common checks * @returns {string} warnings or null */ static checkSalesforceEntryEvents(ca: configurationArguments, isPublished: boolean): string; /** * * @param {object[]} conditions - * @param {string[]} errors list of errors * @param {'primaryObjectFilterCriteria'|'relatedObjectFilterCriteria'} context used to improve error logs */ static checkSfFilterFieldsExist(conditions: object[], errors: string[], context: "primaryObjectFilterCriteria" | "relatedObjectFilterCriteria"): void; static requiredConfigurationArguments: string[]; /** * * @param {string} triggerType e.g. SalesforceObjectTriggerV2, APIEvent, ... * @param {configurationArguments} ca trigger[0].configurationArguments * @param {string} key of event / journey * @param {boolean} isPublished if the current item is published it means we do not need to do contact vs common checks * @param {string} [type] optionally provide metadatype for error on missing configurationArguments attributes * @returns {Promise.<void>} - */ static postRetrieveTasks_SalesforceEntryEvents(triggerType: string, ca: configurationArguments, key: string, isPublished: boolean, type?: string): Promise<void>; /** * * @param {string} triggerType e.g. SalesforceObjectTriggerV2, APIEvent, ... * @param {string[]} eventDataSummary eventDataConfig in simplified string-form * @param {string} deKey key of associated dataExtension * @returns {Promise.<void>} - */ static compareSalesforceEntryEvents_dataExtension(triggerType: string, eventDataSummary: string[], deKey: string): Promise<void>; /** * * @param {string} triggerType e.g. SalesforceObjectTriggerV2, APIEvent, ... * @param {configurationArguments} ca trigger[0].configurationArguments * @returns {Promise.<string>} - */ static preDeployTasks_SalesforceEntryEvents(triggerType: string, ca: configurationArguments): Promise<string>; } declare namespace Event { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { automation: string[]; dataExtension: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; validTypes: string[]; fields: { 'arguments.audienceCount': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.audienceDefinitionID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.audienceDescription': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.audienceSource': { skipValidation: boolean; }; 'arguments.audienceName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.automationId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.buildAudienceDefinitionID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.contactAttributeGroup': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.contactAttributeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.contactAttributeName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.criteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dataExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dataTargetName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.formName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dateOffset': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dateOffsetUnit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dateType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.eid': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.eventDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.eventDefinitionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.mid': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.resetHighWatermark': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.serializedObjectType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.transactionKeyDataExtension': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.transactionKeyEvent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.useHighWatermark': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; automationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; category: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; configurationArguments: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.applicationExtensionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.relationshipIdName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.relationshipName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.isPolymorphic': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.referenceObjectName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactPersonType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.dataExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.evaluationCriteriaSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.eventDataConfig': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.eventDataConfig.objects': { skipValidation: boolean; }; 'configurationArguments.eventDataSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.objectAPIName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument.fields': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument.fields.ContactKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument.fields.Email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.primaryObjectFilterCriteria': { skipValidation: boolean; }; 'configurationArguments.primaryObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.relatedObjectFilterCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.relatedObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.salesforceTriggerCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.unconfigured': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.whoToInject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataExtensionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataExtensionName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; disableDEDataLogging: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; eventDefinitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionTemplate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; iconUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; interactionCount: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isVisibleInPicker: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.attributeName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.automationType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.categoryId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.folderPath': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.guidId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.isPlatformObject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastRunInstance': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastRunTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSaveDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSavedBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSavedBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSavedBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.memberId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.modifiedDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.notifications': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.processes': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.schedule': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.createdBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.iCalRecur': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.lastUpdatedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.scheduleState': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.scheduleStatus': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.timeZoneId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduledTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.selectedCategoryId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.selectedCategoryId[]': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.status': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.updateInProgress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.criteriaDescription': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.customAttributeName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.formattedDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.formattedTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.icon': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.original_icon': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.isConfigured': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.runOnceScheduleMode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.scheduleFlowMode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.scheduleState': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys.0': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys.0.from': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys.0.to': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; mode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; publishedInteractionCount: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledDayOfWeek': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledWeek': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.endDateTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.endType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.frequency': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.interval': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.occurrences': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.recurrencePattern': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledDay': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.startDateTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.monday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.tuesday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.wednesday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.thursday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.friday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.saturday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.sunday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].dataType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].defaultValue': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].isDevicePreference': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].isNullable': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].isPrimaryKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].maxLength': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.sendableCustomObjectField': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.sendableSubscriberField': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.isPlatformObject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceApplicationExtensionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; entrySourceGroupConfigUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__automation_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Event.d.ts.map ================================================ FILE: @types/lib/metadataTypes/FileLocation.d.ts ================================================ export default FileLocation; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ImportFile MetadataType * * @augments MetadataType */ declare class FileLocation extends MetadataType { static cache: {}; /** * Retrieves Metadata of FileLocation * Endpoint /automation/v1/ftplocations/ return all FileLocations * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves folder metadata into local filesystem. Also creates a uniquePath attribute for each folder. * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} Promise */ static create(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} Promise */ static update(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} _ a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postCreateTasks(_: MetadataTypeItem, apiResponse: object): Promise<object>; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} _ a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(_: MetadataTypeItem, apiResponse: object): Promise<object>; /** * prepares a import definition for deployment * * @param {MetadataTypeItem} metadata a single importDef * @returns {Promise.<MetadataTypeItem>} Promise */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace FileLocation { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: any; createdNameField: any; lastmodDateField: any; lastmodNameField: any; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; locationTypeMapping: { 'Enhanced FTP Site Import Directory': number; 'External FTP Site': number; 'External SFTP Site': number; 'External FTPS Site': number; 'Salesforce Objects and Reports': number; Safehouse: number; 'Enhanced FTP Site Export Directory': number; 'Legacy Import Directory': number; 'Relative location under FTP Site': number; 'Amazon Simple Storage Service': number; 'Azure Blob Storage': number; 'Google Cloud Storage': number; }; locationTypeMappingDeployable: { 'External SFTP Site': string; 'Amazon Simple Storage Service': string; 'Azure Blob Storage': string; 'Google Cloud Storage': string; }; locationTypeIdMappingDeployable: { 2: string; 13: string; 15: string; 16: string; }; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; locationTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; locationType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; locationUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; relPath: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; awsFileTransferLocation: { skipValidation: boolean; }; azureFileTransferLocation: { skipValidation: boolean; }; gcpFileTransferLocation: { skipValidation: boolean; }; sFtpFileTransferLocation: { skipValidation: boolean; }; c__locationType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=FileLocation.d.ts.map ================================================ FILE: @types/lib/metadataTypes/FileTransfer.d.ts ================================================ export default FileTransfer; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * FileTransfer MetadataType * * @augments MetadataType */ declare class FileTransfer extends MetadataType { /** * Retrieves Metadata of FileTransfer Activity. * Endpoint /automation/v1/filetransfers/ returns all File Transfers * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata of FileTransfer Activity for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Retrieve a specific File Transfer Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<MetadataTypeItemObj>; /** * Creates a single File Transfer * * @param {MetadataTypeItem} fileTransfer a single File Transfer * @returns {Promise} Promise */ static create(fileTransfer: MetadataTypeItem): Promise<any>; /** * Updates a single File Transfer * * @param {MetadataTypeItem} fileTransfer a single File Transfer * @returns {Promise} Promise */ static update(fileTransfer: MetadataTypeItem): Promise<any>; /** * prepares a fileTransfer for deployment * * @param {MetadataTypeItem} metadata a single fileTransfer activity definition * @returns {Promise} Promise */ static preDeployTasks(metadata: MetadataTypeItem): Promise<any>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single fileTransfer activity definition * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ private static _getObjectIdForSingleRetrieve; } declare namespace FileTransfer { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: {}; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileSpec: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isCompressed: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isEncrypted: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isFileSpecLocalized: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isPgp: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isUpload: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxFileAge: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxFileAgeScheduleOffset: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxImportFrequency: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; publicKeyManagementId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__fileLocation_name: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=FileTransfer.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Filter.d.ts ================================================ export default Filter; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type FilterItem = import("../../types/mcdev.d.js").FilterItem; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').FilterItem} FilterItem */ /** * Filter MetadataType * * @augments MetadataType */ declare class Filter extends MetadataType { /** * Retrieves Metadata of Filter. * Endpoint /automation/v1/filters/ returns all Filters, * but only with some of the fields. So it is needed to loop over * Filters with the endpoint /automation/v1/filters/{id} * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * parses retrieved Metadata before saving * * @param {FilterItem} metadata a single record * @returns {FilterItem} parsed metadata definition */ static postRetrieveTasks(metadata: FilterItem): FilterItem; /** * helper for postRetrieveTasks to map data types * * @param {'source'|'destination'} target we are processing source and destinations * @param {FilterItem} metadata single record */ static _postRetrieve_dataTypeMapping(target: "source" | "destination", metadata: FilterItem): void; /** * helper for preDeployTasks to map data types * * @param {'source'|'destination'} target we are processing source and destinations * @param {FilterItem} metadata single record * @param {FilterItem} cachedVersion cached version of the metadata */ static _preDeploy_dataTypeMapping(target: "source" | "destination", metadata: FilterItem, cachedVersion: FilterItem): void; /** * Creates a single item * this uses soap API because the rest api does not allow hotlinking to an existing target DE * * @param {FilterItem} item a single item * @returns {Promise} Promise */ static create(item: FilterItem): Promise<any>; /** * helper that converts the rest item into a soap item * * @param {FilterItem} item a single item * @returns {object} SOAP formatted filter item */ static preCreateSOAPItem(item: FilterItem): object; /** * helper that runs update on all create calls to ensure all fields are set * * @param {FilterItem} restItem original rest item * @param {object} response SOAP response * @returns {Promise.<FilterItem>} created item */ static postCreateTasks(restItem: FilterItem, response: object): Promise<FilterItem>; /** * Updates a single item * * @param {MetadataTypeItem} item a single item * @returns {Promise} Promise */ static update(item: MetadataTypeItem): Promise<any>; /** * prepares a record for deployment * * @param {FilterItem} metadata a single record * @returns {Promise.<FilterItem>} Promise of updated single record */ static preDeployTasks(metadata: FilterItem): Promise<FilterItem>; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or empty string */ private static _getObjectIdForSingleRetrieve; } declare namespace Filter { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataFilter: string[]; dataExtension: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderType: string; folderIdField: string; filter: { statusId: number; }; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DestinationObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DestinationTypeID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterActivityId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FilterDefinitionID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SourceObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SourceTypeID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionSourceTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; statusId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; resultDEName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; resultDEKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; resultDEDescription: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataFilter_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__source_dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__destination_dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Filter.d.ts.map ================================================ FILE: @types/lib/metadataTypes/FilterDefinition.d.ts ================================================ export default FilterDefinition; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type FilterDefinitionItem = import("../../types/mcdev.d.js").FilterDefinitionItem; export type FilterDefinitionMap = import("../../types/mcdev.d.js").FilterDefinitionMap; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type FilterConditionSet = import("../../types/mcdev.d.js").FilterConditionSet; export type FilterCondition = import("../../types/mcdev.d.js").FilterCondition; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').FilterDefinitionItem} FilterDefinitionItem * @typedef {import('../../types/mcdev.d.js').FilterDefinitionMap} FilterDefinitionMap * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').FilterConditionSet} FilterConditionSet * @typedef {import('../../types/mcdev.d.js').FilterCondition} FilterCondition */ /** * FilterDefinition MetadataType * * @augments MetadataType */ declare class FilterDefinition extends MetadataType { static cache: {}; static deIdKeyMap: any; static hidden: boolean; /** * Retrieves all records and saves it to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [_] unused parameter * @param {string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: FilterDefinitionMap, type: string}>} Promise of items */ static retrieve(retrieveDir: string, _?: string[], __?: string[], key?: string): Promise<{ metadata: FilterDefinitionMap; type: string; }>; /** * helper for {@link FilterDefinition.retrieve} * * @param {boolean} [recached] indicates if this is a recursive call after cache refresh * @returns {Promise.<number[]>} Array of folder IDs */ static _getFilterFolderIds(recached?: boolean): Promise<number[]>; /** * helper for {@link FilterDefinition._cacheMeasures} * * @returns {Promise.<number[]>} Array of folder IDs */ static _getMeasureFolderIds(): Promise<number[]>; /** * helper for {@link FilterDefinition.retrieve}. uses cached dataExtensions to resolve dataExtensionFields * * @param {FilterDefinitionMap} metadataTypeMap - * @param {'retrieve'|'deploy'} [mode] - */ static _cacheDeFields(metadataTypeMap: FilterDefinitionMap, mode?: "retrieve" | "deploy"): Promise<void>; /** * helper for {@link FilterDefinition.retrieve} * * @param {FilterDefinitionMap} metadataTypeMap - */ static _cacheContactAttributes(metadataTypeMap: FilterDefinitionMap): Promise<void>; /** * helper for {@link FilterDefinition.retrieve} * * @param {FilterDefinitionMap} metadataTypeMap - */ static _cacheMeasures(metadataTypeMap: FilterDefinitionMap): Promise<void>; /** * Retrieves all records for caching * * @returns {Promise.<{metadata: FilterDefinitionMap, type: string}>} Promise of items */ static retrieveForCache(): Promise<{ metadata: FilterDefinitionMap; type: string; }>; /** * parses retrieved Metadata before saving * * @param {FilterDefinitionItem} metadata a single record * @returns {Promise.<FilterDefinitionItem>} parsed metadata definition */ static postRetrieveTasks(metadata: FilterDefinitionItem): Promise<FilterDefinitionItem>; /** * helper for {@link postRetrieveTasks} * * @param {FilterDefinitionItem} metadata - * @param {'postRetrieve'|'preDeploy'} mode - * @param {object[]} [fieldCache] - * @param {FilterConditionSet} [filter] - * @returns {void} */ static _resolveFields(metadata: FilterDefinitionItem, mode: "postRetrieve" | "preDeploy", fieldCache?: object[], filter?: FilterConditionSet): void; /** * helper for {@link _resolveFields} * * @param {FilterCondition} condition - * @param {object[]} fieldCache - * @returns {void} */ static _postRetrieve_resolveFieldIdsCondition(condition: FilterCondition, fieldCache: object[]): void; /** * helper for {@link _resolveFields} * * @param {FilterCondition} condition - * @param {object[]} fieldCache - * @returns {void} */ static _preDeploy_resolveFieldNamesCondition(condition: FilterCondition, fieldCache: object[]): void; /** * helper for {@link postRetrieveTasks} * * @param {FilterDefinitionItem} metadata - * @param {object} [filter] - * @returns {void} */ static _postRetrieve_resolveAttributeIds(metadata: FilterDefinitionItem, filter?: object): void; /** * prepares a item for deployment * * @param {FilterDefinitionItem} metadata a single record * @returns {Promise.<FilterDefinitionItem>} Promise of updated single item */ static preDeployTasks(metadata: FilterDefinitionItem): Promise<FilterDefinitionItem>; /** * Creates a single item * * @param {FilterDefinitionItem} metadata a single item * @returns {Promise.<FilterDefinitionItem>} Promise */ static create(metadata: FilterDefinitionItem): Promise<FilterDefinitionItem>; /** * Updates a single item * * @param {FilterDefinitionItem} metadata a single item * @returns {Promise.<FilterDefinitionItem>} Promise */ static update(metadata: FilterDefinitionItem): Promise<FilterDefinitionItem>; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ private static _getObjectIdForSingleRetrieve; } declare namespace FilterDefinition { let dataExtensionFieldCache: { [x: string]: import("../../types/mcdev.d.js").DataExtensionFieldItem; }; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; filter: {}; hasExtended: boolean; idField: string; keyField: string; nameField: string; folderType: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; restPageSize: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionXml: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectTypeName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__source_dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__filterDefinition: { skipValidation: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=FilterDefinition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/FilterDefinitionHidden.d.ts ================================================ export default FilterDefinitionHidden; /** * FilterDefinitionHidden MetadataType * * @augments FilterDefinition */ declare class FilterDefinitionHidden extends FilterDefinition { } declare namespace FilterDefinitionHidden { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; filter: {}; hasExtended: boolean; idField: string; keyField: string; nameField: string; folderType: string; folderIdField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; restPageSize: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdatedByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionXml: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectTypeName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; derivedFromObjectName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__source_dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__filterDefinition: { skipValidation: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import FilterDefinition from './FilterDefinition.js'; //# sourceMappingURL=FilterDefinitionHidden.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Folder.d.ts ================================================ export default Folder; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type ListItem = import("../../types/mcdev.d.js").ListItem; export type ListMap = import("../../types/mcdev.d.js").ListMap; export type ListIdMap = import("../../types/mcdev.d.js").ListIdMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * * @typedef {import('../../types/mcdev.d.js').ListItem} ListItem * @typedef {import('../../types/mcdev.d.js').ListMap} ListMap * @typedef {import('../../types/mcdev.d.js').ListIdMap} ListIdMap */ /** * Folder MetadataType * * @augments MetadataType */ declare class Folder extends MetadataType { /** * Retrieves metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] content type of folder * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: ListMap, type: string}>} Promise */ static retrieve(retrieveDir: string, additionalFields?: string[], subTypeArr?: string[], key?: string): Promise<{ metadata: ListMap; type: string; }>; /** * Retrieves folder metadata for caching * * @param {void | string[]} [_] parameter not used * @param {string[]} [subTypeArr] content type of folder * @returns {Promise.<{metadata: ListMap, type: string}>} Promise */ static retrieveForCache(_?: void | string[], subTypeArr?: string[]): Promise<{ metadata: ListMap; type: string; }>; /** * Folder upsert (copied from Metadata Upsert), after retrieving from target * and comparing to check if create or update operation is needed. * Copied due to having a dependency on itself, meaning the created need to be serial * * @param {ListMap} metadata metadata mapped by their keyField * @returns {Promise.<ListMap>} Promise of saved metadata */ static upsert(metadata: ListMap): Promise<ListMap>; /** * creates a folder based on metatadata * * @param {ListItem} metadataEntry metadata of the folder * @returns {Promise.<any>} Promise of api response */ static create(metadataEntry: ListItem): Promise<any>; /** * Updates a single Folder. * * @param {MetadataTypeItem} metadataEntry single metadata entry * @returns {Promise.<any>} Promise of api response */ static update(metadataEntry: MetadataTypeItem): Promise<any>; /** * prepares a folder for deployment * * @param {ListItem} metadata a single folder definition * @returns {Promise.<ListItem>} Promise of parsed folder metadata */ static preDeployTasks(metadata: ListItem): Promise<ListItem>; /** * Returns file contents mapped to their filename without '.json' ending * * @param {string} dir directory with json files, e.g. /retrieve/cred/bu/folder, /deploy/cred/bu/folder, /template/folder * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {Promise.<ListMap>} fileName => fileContent map */ static getJsonFromFS(dir: string, listBadKeys?: boolean): Promise<ListMap>; /** * Helper to retrieve the folders as promise * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {boolean} [queryAllAccounts] which queryAllAccounts setting to use * @param {string[]} [contentTypeList] content type of folder * @returns {Promise.<ListItem[]>} soap object */ static retrieveHelper(additionalFields?: string[], queryAllAccounts?: boolean, contentTypeList?: string[]): Promise<ListItem[]>; /** * Gets executed after retreive of metadata type * * @param {ListItem} metadata metadata mapped by their keyField * @returns {ListItem} cloned metadata */ static postRetrieveTasks(metadata: ListItem): ListItem; /** * Helper for writing Metadata to disk, used for Retrieve and deploy * * @param {ListMap} results metadata results from deploy * @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve * @returns {Promise.<ListMap>} Promise of saved metadata */ static saveResults(results: ListMap, retrieveDir: string): Promise<ListMap>; } declare namespace Folder { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; subTypes: string[]; deployFolderTypes: string[]; deployFolderTypesEmailRest: string[]; deployFolderTypesAssetRest: string[]; deployFolderBlacklist: string[]; folderTypesFromParent: string[]; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: boolean; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { $: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; '@_xsi:type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ContentType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; catType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsActive: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsEditable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; editable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AllowChildren: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; extendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; objectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; parentCatId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; parentId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.Path': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; _generated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Folder.d.ts.map ================================================ FILE: @types/lib/metadataTypes/ImportFile.d.ts ================================================ export default ImportFile; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type SDKError = import("../../types/mcdev.d.js").SDKError; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError */ /** * ImportFile MetadataType * * @augments MetadataType */ declare class ImportFile extends MetadataType { /** * Retrieves Metadata of Import File. * Endpoint /automation/v1/imports/ return all Import Files with all details. * Currently it is not needed to loop over Imports with endpoint /automation/v1/imports/{id} * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * helper for {@link MetadataType.retrieveRESTcollection} * * @param {SDKError} ex exception * @param {string} key id or key of item * @param {string} url url to call for retry * @returns {Promise.<any>} can return retry-result */ static handleRESTErrors(ex: SDKError, key: string, url: string): Promise<any>; /** * Retrieves import definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache(_?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieve a specific Import Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<MetadataTypeItemObj>; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ private static _getObjectIdForSingleRetrieve; /** * Creates a single Import File * * @param {MetadataTypeItem} importFile a single Import File * @returns {Promise} Promise */ static create(importFile: MetadataTypeItem): Promise<any>; /** * Updates a single Import File * * @param {MetadataTypeItem} importFile a single Import File * @returns {Promise} Promise */ static update(importFile: MetadataTypeItem): Promise<any>; /** * prepares a import definition for deployment * * @param {MetadataTypeItem} metadata a single importDef * @returns {Promise.<MetadataTypeItem>} Promise */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace ImportFile { let smsImports: {}; let dataExtensionsLegacy: {}; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; list: string[]; mobileKeyword: string[]; }; destinationObjectTypeMapping: { unknown: number; DataExtension: number; List: number; SMS: number; Push: number; WhatsApp: number; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; restConcurrentLimit: number; subscriberImportTypeMapping: { DataExtension: number; Email: number; }; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; updateTypeMapping: { Add: number; AddUpdate: number; Overwrite: number; Update: number; }; blankFileProcessingTypeMapping: { Fail: number; Process: number; Skip: number; }; fields: { allowErrors: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; blankFileProcessingType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dateFormatLocale: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; deleteFile: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationObjectTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; encodingName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fieldMappingType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fieldMappings: { skipValidation: boolean; }; fileNamingPattern: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileSpec: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; hasColumnHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; importDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isOrderedImport: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSequential: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxFileAgeHours: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxFileAgeScheduleOffsetHours: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxImportFrequencyHours: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; }; notificationEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; otherDelimiter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sendEmailNotification: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; standardQuotedStrings: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; subscriberImportTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; updateTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceCustomObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceDataExtensionName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__dataAction: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'source.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'source.c__type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.c__type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.r__list_PathName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'source.r__fileLocation_name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__subscriberImportType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__blankFileProcessing: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=ImportFile.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Journey.d.ts ================================================ export default Journey; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * Journey MetadataType * id: A unique id of the journey assigned by the journey’s API during its creation * key: A unique id of the journey within the MID. Can be generated by the developer * definitionId: A unique UUID provided by Salesforce Marketing Cloud. Each version of a journey has a unique DefinitionID while the Id and Key remain the same. Version 1 will have id == definitionId * * @augments MetadataType */ declare class Journey extends MetadataType { /** * Retrieves Metadata of Journey * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * helper for Journey's {@link Journey.saveResults}. Gets executed after retreive of metadata type and * * @param {MetadataTypeMap} metadataMap key=customer key, value=metadata */ static _postRetrieveTasksBulk(metadataMap: MetadataTypeMap): Promise<void>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} Array with one metadata object */ static postRetrieveTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * helper for {@link Journey.postRetrieveTasks} * * @private * @param {MetadataTypeItem} metadata a single item */ private static _postRetrieveTasks_activities; /** * prepares a TSD for deployment * ! BETA RELEASE of journey support (v4.3.0); it so far only resolves a limited amount of dependencies and will likely break during cross-BU deployments! * * @param {MetadataTypeItem} metadata of a single TSD * @returns {Promise.<MetadataTypeItem>} metadata object */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * helper for {@link Journey.preDeployTasks} * * @private * @param {MetadataTypeItem} metadata a single item */ private static _preDeployTasks_activities; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create */ static postDeployTasks(upsertResults: MetadataTypeMap): Promise<void>; /** * a function to publish the journey via API * * @param {string[]} keyArr keys or ids of the metadata * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField as returned by update/create; needs to be refreshed after publish * @returns {Promise.<string[]>} Returns list of updated keys/ids that were published. Success could only be seen with a delay in the UI because the publish-endpoint is async */ static publish(keyArr: string[], upsertResults?: MetadataTypeMap): Promise<string[]>; /** * * @param {string[]} executedKeyArr list of journey keys * @param {number} transactionalCounter how many transactiona-send journeys did we expect to refresh * @param {number} multiStepCounter how many multi-step journeys did we expect to refresh * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField returned by update/create; needs to be refreshed after publish * @returns {Promise.<void>} - */ static _reRetrieve(executedKeyArr: string[], transactionalCounter: number, multiStepCounter: number, upsertResults?: MetadataTypeMap): Promise<void>; /** * helper for {@link Journey.publish} and {@link Journey.validate} * * @param {string} statusUrl URL to check the status of the publish request * @param {string} key journey-key or id for log messages * @param {string} name journey-name for log messages * @param {import('yocto-spinner').Spinner} spinner reference to spinner to allow stopping it when done * @param {number} [tries] number of tries used to check the status * @returns {Promise.<string>} key of the item that was published successfully */ static _checkPublishStatus(statusUrl: string, key: string, name: string, spinner: import("yocto-spinner").Spinner, tries?: number): Promise<string>; /** * helper for {@link Journey._checkPublishStatus} * * @param {{status:string, errors:Array, warnings:Array}} response publishStatus response */ static _showPublishStatusDetails(response: { status: string; errors: any[]; warnings: any[]; }): void; /** * a function to validate the journey via API * * @param {string[]} keyArr keys or ids of the metadata * @returns {Promise.<string[]>} Returns list of updated keys/ids that were published. Success could only be seen with a delay in the UI because the publish-endpoint is async */ static validate(keyArr: string[]): Promise<string[]>; /** * audit latest or given journey version * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were paused */ static audit(keyArr: string[]): Promise<string[]>; /** * TSD-specific refresh method that finds active TSDs and refreshes them * * @param {string[]} keyArr metadata keys * @param {boolean} [_] whether to check if the key is valid * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField as returned by update/create; needs to be refreshed after publish * @returns {Promise.<string[]>} Returns list of keys that were refreshed */ static refresh(keyArr: string[], _?: boolean, upsertResults?: MetadataTypeMap): Promise<string[]>; /** * helper for {@link Journey.refresh} that pauses, publishes and starts a triggered send * * @param {string} key external key of triggered send item * @param {MetadataTypeMapObj} journeyCache metadata cache * @returns {Promise.<boolean>} true if refresh was successful */ static _refreshItem(key: string, journeyCache: MetadataTypeMapObj): Promise<boolean>; } declare namespace Journey { let definition: { folderType: string; bodyIteratorField: string; dependencies: string[]; dependencyGraph: { event: string[]; dataExtension: string[]; deliveryProfile: string[]; list: string[]; senderProfile: string[]; sendClassification: string[]; asset: string[]; mobileMessage: string[]; mobileKeyword: string[]; mobileCode: string[]; }; folderIdField: string; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; priorityMapping: { High: number; Medium: number; Low: number; }; fields: { activities: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].outcomes': { skipValidation: boolean; }; 'activities[].arguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitEndDateAttributeDataBound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitForEventId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.executionMode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.startActivityKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitQueueId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.definitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.emailSubjectDataBound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.contactId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.contactKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.emailAddress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.sourceCustomObjectId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.sourceCustomObjectKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.fieldType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.eventData': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.obfuscationProperties': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.customObjectKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.definitionInstanceId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.filterResult': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.requestObjectId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityData': { skipValidation: boolean; }; 'activities[].arguments.objectMap': { skipValidation: boolean; }; 'activities[].configurationArguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isReconcilable': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isActivityBatchValidated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSendKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSendId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.campaigns': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.suppressionLists': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.autoAddSubscribers': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.autoUpdateSubscribers': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.bccEmail': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.categoryId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.ccEmail': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.created': { skipValidation: boolean; }; 'activities[].configurationArguments.triggeredSend.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.domainExclusions': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.dynamicEmailSubject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.emailSubject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.exclusionFilter': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isSalesforceTracking': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isMultipart': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isSendLogging': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isStoppedOnJobError': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.keyword': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.modified': { skipValidation: boolean; }; 'activities[].configurationArguments.triggeredSend.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.preHeader': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.replyToAddress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.replyToDisplayName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.suppressTracking': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.triggeredSendStatus': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.throttleOpens': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.throttleCloses': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.throttleLimit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isTrackingClicks': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.emailId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__triggeredSend_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.senderProfileId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.deliveryProfileId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__senderProfile_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.sendClassificationId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__deliveryProfile_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__sendClassification_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__list_PathName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.publicationListId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__list_PathName.publicationList': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__list_PathName.suppressionLists': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__dataExtension_key.domainExclusions': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.priority': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.c__priority': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__asset_name_readOnly': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__asset_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.updateSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.applicationExtensionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.r__transactionalEmail_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.applicationExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isModified': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isSimulation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.googleAnalyticsCampaignName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.useLLTS': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.fuelAgentRequested': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.r__triggeredSend_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitDuration': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitUnit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.specifiedTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitEndDateAttributeExpression': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.specificDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitForEventKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.schemaVersionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.criteria': { skipValidation: boolean; }; 'activities[].configurationArguments.eventDataConfig': { skipValidation: boolean; }; 'activities[].metaData': { skipValidation: boolean; }; 'activities[].schema': { skipValidation: boolean; }; 'activities[].arguments.activityData.updateContactFields[].r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityData.updateContactFields[].r__dataExtensionField_name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityData.updateContactFields[].field': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; channel: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'defaults.email': { skipValidation: boolean; }; 'defaults.mobileNumber': { skipValidation: boolean; }; 'defaults.properties.analyticsTracking.enabled': { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; 'defaults.properties': { skipValidation: boolean; }; 'defaults.properties.analyticsTracking.analyticsType': { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; 'defaults.properties.analyticsTracking.urlDomainsToTrack': { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; entryMode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; executionMode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; exits: { skipValidation: boolean; }; goals: { skipValidation: boolean; }; healthStats: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastPublishedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.templateId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; scheduledStatus: { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; stats: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; triggers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].outcomes': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.startActivityKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.dequeueReason': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.lastExecutedActivityKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.filterResult': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.serializedObjectType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.eventDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.eventDefinitionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.dataExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.automationId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.r__event_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.eventDataConfig': { skipValidation: boolean; }; 'triggers[].configurationArguments.primaryObjectFilterCriteria': { skipValidation: boolean; }; 'triggers[].configurationArguments.relatedObjectFilterCriteria': { skipValidation: boolean; }; 'triggers[].configurationArguments.salesforceTriggerCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.objectApiName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.objectAPIName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.contactKey': { skipValidation: boolean; }; 'triggers[].configurationArguments.contactPersonType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.primaryObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.relatedObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.eventDataSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.evaluationCriteriaSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.applicationExtensionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.passThroughArgument': { skipValidation: boolean; }; 'triggers[].configurationArguments.filterDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.criteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.schemaVersionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.whoToInject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.additionalObjectFilterCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.sourceInteractionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.entrySourceGroupConfigUrl': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.r__event_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.category': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.eventDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.eventDefinitionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.chainType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.configurationRequired': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.iconUrl': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.title': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.scheduleState': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; version: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; workflowApiVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; campaigns: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; metaData: { skipValidation: boolean; }; notifiers: { skipValidation: boolean; }; tags: { skipValidation: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Journey.d.ts.map ================================================ FILE: @types/lib/metadataTypes/List.d.ts ================================================ export default List; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * List MetadataType * * @augments MetadataType */ declare class List extends MetadataType { /** * Retrieves Metadata of Lists * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Gets metadata cache with limited fields and does not store value to disk * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * helper for {@link retrieveForCache} and {@link retrieve} * * @private * @param {MetadataTypeMapObj} results metadata from retrieve for current BU * @returns {Promise.<MetadataTypeMapObj>} Promise */ private static _retrieveParentAllSubs; /** * manages post retrieve steps * * @param {MetadataTypeItem} list a single list * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(list: MetadataTypeItem): MetadataTypeItem; /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single list definition * @param {boolean} [parseForCache] if set to true, the Category ID is kept * @returns {MetadataTypeItem} Array with one metadata object and one sql string */ static parseMetadata(metadata: MetadataTypeItem, parseForCache?: boolean): MetadataTypeItem; } declare namespace List { let client: import("sfmc-sdk").default; let buObject: import("../../types/mcdev.d.js").BuObject; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: any; folderType: string; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; restPagination: any; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { 'AutomatedEmail.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutomatedEmail.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutomatedEmail.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Category: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ListClassification: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ListName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=List.d.ts.map ================================================ FILE: @types/lib/metadataTypes/MetadataType.d.ts ================================================ export default MetadataType; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type SDK = import("sfmc-sdk").default; export type SDKError = import("../../types/mcdev.d.js").SDKError; export type SOAPError = import("../../types/mcdev.d.js").SOAPError; export type RestError = import("../../types/mcdev.d.js").RestError; export type ContentBlockConversionTypes = import("../../types/mcdev.d.js").ContentBlockConversionTypes; /** * MetadataType class that gets extended by their specific metadata type class. * Provides default functionality that can be overwritten by child metadata type classes * */ declare class MetadataType { /** * Returns file contents mapped to their filename without '.json' ending * * @param {string} dir directory with json files, e.g. /retrieve/cred/bu/event, /deploy/cred/bu/event, /template/event * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @param {string[]} [selectedSubType] asset, message, ... * @returns {Promise.<MetadataTypeMap>} fileName => fileContent map */ static getJsonFromFS(dir: string, listBadKeys?: boolean, selectedSubType?: string[]): Promise<MetadataTypeMap>; /** * Returns fieldnames of Metadata Type. 'this.definition.fields' variable only set in child classes. * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {boolean} [isCaching] if true, then check if field should be skipped for caching * @returns {string[]} Fieldnames */ static getFieldNamesToRetrieve(additionalFields?: string[], isCaching?: boolean): string[]; /** * Deploys metadata * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved, ending on cred/bu * @param {string} retrieveDir directory where metadata after deploy should be saved, ending on cred/bu * @returns {Promise.<MetadataTypeMap>} Promise of keyField => metadata map */ static deploy(metadataMap: MetadataTypeMap, deployDir: string, retrieveDir: string): Promise<MetadataTypeMap>; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @param {MetadataTypeMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static postDeployTasks(upsertResults: MetadataTypeMap, originalMetadata: MetadataTypeMap, createdUpdated: { created: number; updated: number; }): Promise<void>; /** * Gets executed before deleting a list of keys for the current type * * @param {string} keyArr metadata keys * @returns {Promise.<void>} - */ static preDeleteTasks(keyArr: string): Promise<void>; /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @param {MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped * @returns {Promise.<object>} apiResponse, potentially modified */ static postCreateTasks(metadataEntry: MetadataTypeItem, apiResponse: object, metadataEntryWithAllFields: MetadataTypeItem): Promise<object>; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @param {MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry: MetadataTypeItem, apiResponse: object, metadataEntryWithAllFields: MetadataTypeItem): Promise<object>; /** * helper for {@link MetadataType.createREST} when legacy API endpoints as these do not return the created item but only their new id * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<void>} - */ static postDeployTasks_legacyApi(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<void>; /** * Gets executed after retreive of metadata type * * @param {MetadataTypeItem} metadata a single item * @param {string} targetDir folder where retrieves should be saved * @param {boolean} [isTemplating] signals that we are retrieving templates * @returns {MetadataTypeItem} cloned metadata */ static postRetrieveTasks(metadata: MetadataTypeItem, targetDir: string, isTemplating?: boolean): MetadataTypeItem; /** * generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single item */ static setFolderPath(metadata: MetadataTypeItem): void; /** * generic script that retrieves the folder ID from cache and updates the given metadata with it before deploy * * @param {MetadataTypeItem} metadata a single item */ static setFolderId(metadata: MetadataTypeItem): void; /** * Gets metadata from Marketing Cloud * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] optionally limit to a single subtype * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} metadata */ static retrieve(retrieveDir: string, additionalFields?: string[], subTypeArr?: string[], key?: string): Promise<MetadataTypeMapObj>; /** * Gets metadata from Marketing Cloud * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] optionally limit to a single subtype * @returns {Promise.<MetadataTypeMapObj>} metadata */ static retrieveChangelog(additionalFields?: string[], subTypeArr?: string[]): Promise<MetadataTypeMapObj>; /** * Gets metadata cache with limited fields and does not store value to disk * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] optionally limit to a single subtype * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} metadata */ static retrieveForCache(additionalFields?: string[], subTypeArr?: string[], key?: string): Promise<MetadataTypeMapObj>; /** * Gets metadata cache with limited fields and does not store value to disk * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} [subType] optionally limit to a single subtype * @returns {Promise.<MetadataTypeItemObj>} metadata */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap, subType?: string): Promise<MetadataTypeItemObj>; /** * Retrieve a specific Script by Name * * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} uri rest endpoint for GET * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} name name (not key) of the metadata item * @returns {Promise.<{metadata: MetadataTypeItem, type: string}>} Promise */ static retrieveTemplateREST(templateDir: string, uri: string, templateVariables: TemplateMap, name: string): Promise<{ metadata: MetadataTypeItem; type: string; }>; /** * Gets metadata cache with limited fields and does not store value to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string} templateDir (List of) Directory where built definitions will be saved * @param {string} key name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} single metadata */ static buildTemplate(retrieveDir: string, templateDir: string, key: string, templateVariables: TemplateMap): Promise<MetadataTypeItemObj>; /** * Gets executed before deploying metadata * * @param {MetadataTypeItem} metadata a single metadata item * @param {string} deployDir folder where files for deployment are stored * @returns {Promise.<MetadataTypeItem>} Promise of a single metadata item */ static preDeployTasks(metadata: MetadataTypeItem, deployDir: string): Promise<MetadataTypeItem>; /** * helper to find a new unique name during item creation * * @param {string} key key of the item * @param {string} name name of the item * @param {{ type: string; key: string; name: any; }[]} namesInFolder names of the items in the same folder * @param {string} [subtype] itemType-name * @returns {string} new name */ static findUniqueName(key: string, name: string, namesInFolder: { type: string; key: string; name: any; }[], subtype?: string): string; /** * Abstract create method that needs to be implemented in child metadata type * * @param {MetadataTypeItem} metadata single metadata entry * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static create(metadata: MetadataTypeItem, deployDir: string): Promise<object> | null; /** * Abstract update method that needs to be implemented in child metadata type * * @param {MetadataTypeItem} metadata single metadata entry * @param {MetadataTypeItem} [metadataBefore] metadata mapped by their keyField * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static update(metadata: MetadataTypeItem, metadataBefore?: MetadataTypeItem): Promise<object> | null; /** * Abstract refresh method that needs to be implemented in child metadata type * * @param {string[]} [keyArr] metadata keys * @param {boolean} [checkKey] whether to check if the key is valid * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField as returned by update/create; needs to be refreshed after publish * @returns {Promise.<string[]>} Returns list of keys that were refreshed */ static refresh(keyArr?: string[], checkKey?: boolean, upsertResults?: MetadataTypeMap): Promise<string[]>; /** * * @param {string[]} keyArr limit retrieval to given metadata type * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<Set.<string>>} found asset keys */ static getCbReferenceKeys(keyArr: string[], retrieveDir: string, findAssetKeys?: Set<string>): Promise<Set<string>>; /** * this iterates over all items found in the retrieve folder and executes the type-specific method for replacing references * * @param {MetadataTypeMap} metadataMap list of metadata (keyField => metadata) * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<string[]>} Returns list of keys for which references were replaced */ static replaceCbReferenceLoop(metadataMap: MetadataTypeMap, retrieveDir: string, findAssetKeys?: Set<string>): Promise<string[]>; /** * Abstract execute method that needs to be implemented in child metadata type * * @param {MetadataTypeItem} item single metadata item * @param {string} [retrieveDir] directory where metadata is saved * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem | CodeExtractItem>} key of the item that was updated */ static replaceCbReference(item: MetadataTypeItem, retrieveDir?: string, findAssetKeys?: Set<string>): Promise<MetadataTypeItem | CodeExtractItem>; /** * Abstract execute method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were executed */ static execute(keyArr: string[], cache?: MetadataTypeMapObj): Promise<string[]>; /** * Abstract schedule method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were executed */ static schedule(keyArr: string[], cache?: MetadataTypeMapObj): Promise<string[]>; /** * Abstract pause method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were paused */ static pause(keyArr: string[], cache?: MetadataTypeMapObj): Promise<string[]>; /** * Abstract stop method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were stopped */ static stop(keyArr: string[]): Promise<string[]>; /** * test if metadata was actually changed or not to potentially skip it during deployment * * @param {MetadataTypeItem} cachedVersion cached version from the server * @param {MetadataTypeItem} metadata item to upload * @param {string} [fieldName] optional field name to use for identifying the record in logs * @returns {boolean} true if metadata was changed */ static hasChanged(cachedVersion: MetadataTypeItem, metadata: MetadataTypeItem, fieldName?: string): boolean; /** * test if metadata was actually changed or not to potentially skip it during deployment * * @param {MetadataTypeItem} cachedVersion cached version from the server * @param {MetadataTypeItem} metadataItem item to upload * @param {string} [fieldName] optional field name to use for identifying the record in logs * @param {boolean} [silent] optionally suppress logging * @returns {boolean} true on first identified deviation or false if none are found */ static hasChangedGeneric(cachedVersion: MetadataTypeItem, metadataItem: MetadataTypeItem, fieldName?: string, silent?: boolean): boolean; /** * helper for {@link MetadataType.upsert} to enforce max key length * * @param {string} metadataKey key of metadata */ static enforceMaxKeyLength(metadataKey: string): void; /** * MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {boolean} [runUpsertSequentially] when a type has self-dependencies creates need to run one at a time and created/changed keys need to be cached to ensure following creates/updates have thoses keys available * @returns {Promise.<MetadataTypeMap>} keyField => metadata map */ static upsert(metadataMap: MetadataTypeMap, deployDir: string, runUpsertSequentially?: boolean): Promise<MetadataTypeMap>; /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadataMap list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create * @returns {Promise.<'create' | 'update' | 'skip'>} action to take */ static createOrUpdate(metadataMap: MetadataTypeMap, metadataKey: string, hasError: boolean, metadataToUpdate: MetadataTypeItemDiff[], metadataToCreate: MetadataTypeItem[]): Promise<"create" | "update" | "skip">; /** * helper for {@link MetadataType.createOrUpdate} * * @param {MetadataTypeItem} metadataItem to be deployed item * @returns {MetadataTypeItem} cached item or undefined */ static getCacheMatchedByName(metadataItem: MetadataTypeItem): MetadataTypeItem; /** * Creates a single metadata entry via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for POST * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static createREST(metadataEntry: MetadataTypeItem, uri: string, handleOutside?: boolean): Promise<object> | null; /** * Creates a single metadata entry via fuel-soap (generic lib not wrapper) * * @param {MetadataTypeItem} metadataEntry single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static createSOAP(metadataEntry: MetadataTypeItem, handleOutside?: boolean): Promise<object> | null; /** * Updates a single metadata entry via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for PATCH * @param {'patch'|'post'|'put'} [httpMethod] defaults to 'patch'; some update requests require PUT instead of PATCH * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static updateREST(metadataEntry: MetadataTypeItem, uri: string, httpMethod?: "patch" | "post" | "put", handleOutside?: boolean): Promise<object> | null; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {boolean} [keepMap] some types require to check the old-key new-key relationship in their postDeployTasks; currently used by dataExtension only * @returns {Promise.<void>} - */ static _postChangeKeyTasks(metadataEntry: MetadataTypeItem, keepMap?: boolean): Promise<void>; /** * Updates a single metadata entry via fuel-soap (generic lib not wrapper) * * @param {MetadataTypeItem} metadataEntry single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static updateSOAP(metadataEntry: MetadataTypeItem, handleOutside?: boolean): Promise<object> | null; /** * * @param {SOAPError} ex error that occured * @param {'creating'|'updating'|'retrieving'|'executing'|'pausing'} msg what to print in the log * @param {MetadataTypeItem} [metadataEntry] single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @param {string} [nameAttribute] name attribute to use in the error message instead of keyField */ static _handleSOAPErrors(ex: SOAPError, msg: "creating" | "updating" | "retrieving" | "executing" | "pausing", metadataEntry?: MetadataTypeItem, handleOutside?: boolean, nameAttribute?: string): void; /** * helper for {@link MetadataType._handleSOAPErrors} * * @param {SOAPError} ex error that occured * @returns {string} error message */ static getSOAPErrorMsg(ex: SOAPError): string; /** * Retrieves SOAP via generic fuel-soap wrapper based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {SoapRequestParams} [requestParams] required for the specific request (filter for example) * @param {string} [singleRetrieve] key of single item to filter by * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<MetadataTypeMapObj>} Promise of item map */ static retrieveSOAP(retrieveDir?: string, requestParams?: SoapRequestParams, singleRetrieve?: string, additionalFields?: string[]): Promise<MetadataTypeMapObj>; /** * Retrieves Metadata for Rest Types * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string} uri rest endpoint for GET * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @param {string} [singleRetrieve] key of single item to filter by * @returns {Promise.<{metadata: (MetadataTypeMap | MetadataTypeItem), type: string}>} Promise of item map (single item for templated result) */ static retrieveREST(retrieveDir: string, uri: string, templateVariables?: TemplateMap, singleRetrieve?: string): Promise<{ metadata: (MetadataTypeMap | MetadataTypeItem); type: string; }>; /** * * @param {object[]} urlArray {uri: string, id: string} combo of URL and ID/key of metadata * @param {number} [concurrentRequests] optionally set a different amount of concurrent requests * @param {boolean} [logAmountOfUrls] if true, prints an info message about to-be loaded amount of metadata * @returns {Promise.<{metadata: (MetadataTypeMap | MetadataTypeItem), type: string}>} Promise of item map (single item for templated result) */ static retrieveRESTcollection(urlArray: object[], concurrentRequests?: number, logAmountOfUrls?: boolean): Promise<{ metadata: (MetadataTypeMap | MetadataTypeItem); type: string; }>; /** * helper for {@link this.retrieveRESTcollection} * * @param {RestError} ex exception * @param {string} key id or key of item * @param {string} url url to call for retry * @returns {Promise.<any>} - */ static handleRESTErrors(ex: RestError, key: string, url: string): Promise<any>; /** * Used to execute a query/automation etc. * * @param {string} uri REST endpoint where the POST request should be sent * @param {string} key item key * @returns {Promise.<{key:string, response:string}>} metadata key and API response (OK or error) */ static executeREST(uri: string, key: string): Promise<{ key: string; response: string; }>; /** * Used to execute a query/automation etc. * * @param {MetadataTypeItem} [metadataEntry] single metadata entry * @returns {Promise.<{key:string, response:object}>} metadata key and API response */ static executeSOAP(metadataEntry?: MetadataTypeItem): Promise<{ key: string; response: object; }>; /** * helper for {@link MetadataType.retrieveREST} and {@link MetadataType.retrieveSOAP} * * @param {string|number} singleRetrieve key of single item to filter by * @param {MetadataTypeMap} metadataMap saved metadata * @returns {Promise.<void>} - */ static runDocumentOnRetrieve(singleRetrieve: string | number, metadataMap: MetadataTypeMap): Promise<void>; /** * helper for {@link parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword * * @param {MetadataTypeItem} metadata single item */ static createCustomKeyField(metadata: MetadataTypeItem): void; /** * Builds map of metadata entries mapped to their keyfields * * @param {object} body json of response body * @param {string} [singleRetrieve] key of single item to filter by * @returns {MetadataTypeMap} keyField => metadata map */ static parseResponseBody(body: object, singleRetrieve?: string): MetadataTypeMap; /** * Deletes a field in a metadata entry if the selected definition property equals false. * * @example * Removes field (or nested fields childs) that are not updateable * deleteFieldByDefinition(metadataEntry, 'CustomerKey', 'isUpdateable'); * @param {MetadataTypeItem} metadataEntry One entry of a metadataType * @param {string} fieldPath field path to be checked if it conforms to the definition (dot seperated if nested): 'fuu.bar' * @param {'isCreateable'|'isUpdateable'|'retrieving'|'template'} definitionProperty delete field if definitionProperty equals false for specified field. Options: [isCreateable | isUpdateable] * @param {string} origin string of parent object, required when using arrays as these are parsed slightly differently. * @returns {void} */ static deleteFieldByDefinition(metadataEntry: MetadataTypeItem, fieldPath: string, definitionProperty: "isCreateable" | "isUpdateable" | "retrieving" | "template", origin: string): void; /** * Remove fields from metadata entry that are not createable * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static removeNotCreateableFields(metadataEntry: MetadataTypeItem): void; /** * Remove fields from metadata entry that are not updateable * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static removeNotUpdateableFields(metadataEntry: MetadataTypeItem): void; /** * Remove fields from metadata entry that are not needed in the template * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static keepTemplateFields(metadataEntry: MetadataTypeItem): void; /** * Remove fields from metadata entry that are not needed in the stored metadata * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static keepRetrieveFields(metadataEntry: MetadataTypeItem): void; /** * checks if the current metadata entry should be saved on retrieve or not * * @static * @param {MetadataTypeItem} metadataEntry metadata entry * @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude * @returns {boolean} true: skip saving == filtered; false: continue with saving * @memberof MetadataType */ static isFiltered(metadataEntry: MetadataTypeItem, include?: boolean): boolean; /** * optionally filter by what folder something is in * * @static * @param {object} metadataEntry metadata entry * @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude * @returns {boolean} true: filtered == do NOT save; false: not filtered == do save * @memberof MetadataType */ static isFilteredFolder(metadataEntry: object, include?: boolean): boolean; /** * internal helper * * @private * @param {object} myFilter include/exclude filter object * @param {string} r__folder_Path already determined folder path * @returns {?boolean} true: filter value found; false: filter value not found; null: no filter defined */ private static _filterFolder; /** * internal helper * * @private * @param {object} myFilter include/exclude filter object * @param {object} metadataEntry metadata entry * @returns {?boolean} true: filter value found; false: filter value not found; null: no filter defined */ private static _filterOther; /** * Helper for writing Metadata to disk, used for Retrieve and deploy * * @param {MetadataTypeMap} results metadata results from deploy * @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve * @param {string} [overrideType] for use when there is a subtype (such as folder-queries) * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMap>} Promise of saved metadata */ static saveResults(results: MetadataTypeMap, retrieveDir: string, overrideType?: string, templateVariables?: TemplateMap): Promise<MetadataTypeMap>; /** * * @param {MetadataTypeMap} results metadata results from deploy * @param {string} originalKey key of metadata * @param {string[]} baseDir [retrieveDir, ...overrideType.split('-')] * @param {string} [subtypeExtension] e.g. ".asset-meta" or ".query-meta" * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItem>} saved metadata */ static saveToDisk(results: MetadataTypeMap, originalKey: string, baseDir: string[], subtypeExtension?: string, templateVariables?: TemplateMap): Promise<MetadataTypeItem>; /** * helper for {@link MetadataType.buildDefinitionForNested} * searches extracted file for template variable names and applies the market values * * @param {string} code code from extracted code * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {string} code with markets applied */ static applyTemplateValues(code: string, templateVariables: TemplateMap): string; /** * helper for {@link MetadataType.buildTemplateForNested} * searches extracted file for template variable values and applies the market variable names * * @param {string} code code from extracted code * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {string} code with markets applied */ static applyTemplateNames(code: string, templateVariables: TemplateMap): string; /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types (e.g script, asset, query) * * @param {string} templateDir Directory where metadata templates are stored * @param {string | string[]} targetDir Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} variables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested(templateDir: string, targetDir: string | string[], metadata: MetadataTypeItem, variables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested(templateDir: string, targetDir: string | string[], metadata: MetadataTypeItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * check template directory for complex types that open subfolders for their subtypes * * @param {string} templateDir Directory where metadata templates are stored * @param {string} templateName name of the metadata file * @returns {Promise.<string>} subtype name */ static findSubType(templateDir: string, templateName: string): Promise<string>; /** * optional method used for some types to try a different folder structure * * @param {string} templateDir Directory where metadata templates are stored * @param {string[]} typeDirArr current subdir for this type * @param {string} templateName name of the metadata template * @param {string} fileName name of the metadata template file w/o extension * @param {Error} ex error from first attempt * @returns {Promise.<string>} metadata in string form */ static readSecondaryFolder(templateDir: string, typeDirArr: string[], templateName: string, fileName: string, ex: Error): Promise<string>; /** * Builds definition based on template * NOTE: Most metadata files should use this generic method, unless custom * parsing is required (for example scripts & queries) * * @param {string} templateDir Directory where metadata templates are stored * @param {string | string[]} targetDir (List of) Directory where built definitions will be saved * @param {string} templateName name of the metadata file * @param {TemplateMap} variables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMapObj>} Promise of item map */ static buildDefinition(templateDir: string, targetDir: string | string[], templateName: string, variables: TemplateMap): Promise<MetadataTypeMapObj>; /** * Standardizes a check for multiple messages * * @param {object} ex response payload from REST API * @returns {string[]} formatted Error Message */ static getErrorsREST(ex: object): string[]; /** * Gets metadata cache with limited fields and does not store value to disk * * @param {MetadataTypeMap} [metadata] a list of type definitions * @param {boolean} [isDeploy] used to skip non-supported message during deploy * @returns {void} */ static document(metadata?: MetadataTypeMap, isDeploy?: boolean): void; /** * get name & key for provided id * * @param {string} id Identifier of metadata * @returns {Promise.<{key:string, name:string}>} key, name and path of metadata; null if not found */ static resolveId(id: string): Promise<{ key: string; name: string; }>; /** * Delete a metadata item from the specified business unit * * @param {string} customerKey Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(customerKey: string): Promise<boolean>; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @param {string[]} [additionalExtensions] additional file extensions to delete on top of `${this.definition.type}-meta.json` * @returns {Promise.<void>} - Promise */ static postDeleteTasks(customerKey: string, additionalExtensions?: string[]): Promise<void>; /** * Delete a data extension from the specified business unit * * @param {string} key Identifier of metadata * @param {string} [overrideKeyField] optionally change the name of the key field if the api uses a different name * @param {number} [codeNotFound] error code that is responded with if the item was not found * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<boolean>} deletion success flag */ static deleteByKeySOAP(key: string, overrideKeyField?: string, codeNotFound?: number, handleOutside?: boolean): Promise<boolean>; /** * Delete a data extension from the specified business unit * * @param {string} url endpoint * @param {string} key Identifier of metadata * @param {number} [codeNotFound] error code that is responded with if the item was not found * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<boolean>} deletion success flag */ static deleteByKeyREST(url: string, key: string, codeNotFound?: number, handleOutside?: boolean): Promise<boolean>; /** * helper for {@link deleteByKey}, {@link deleteByKeyREST}, {@link deleteByKeySOAP} * * @param {string} key Identifier of metadata */ static deleteNotFound(key: string): Promise<void>; /** * Returns metadata of a business unit that is saved locally * * @param {string} readDir root directory of metadata. * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @param {object} [buMetadata] Metadata of BU in local directory * @returns {Promise.<object>} Metadata of BU in local directory */ static readBUMetadataForType(readDir: string, listBadKeys?: boolean, buMetadata?: object): Promise<object>; /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static getFilesToCommit(keyArr: string[]): Promise<string[]>; /** * * @param {string[]} keyArr customerkey of the metadata * @param {TypeKeyCombo} multiTypeKeyList list of all keys that need to be deployed * @param {TypeKeyCombo} notFoundList list of all keys that were not found * @param {boolean} isFirstCall will not gray out the log message for type/keys that you initially selected but only for their dependencies * @returns {Promise.<TypeKeyCombo>} list of all keys that need to be deployed */ static getDependentFiles(keyArr: string[], multiTypeKeyList?: TypeKeyCombo, notFoundList?: TypeKeyCombo, isFirstCall?: boolean): Promise<TypeKeyCombo>; /** * optional helper for {@link this.getDependentTypes} * * @param {object} metadataItem metadata json read from filesystem * @param {TypeKeyCombo} dependentTypeKeyCombo list started in this.getDependentTypes */ static getDependentFilesExtra(metadataItem: object, dependentTypeKeyCombo: TypeKeyCombo): void; /** * Hook called when dependency keys were not found in the primary retrieve folder. * Override in subtypes to show type-specific warnings (e.g. shared/synchronized dataExtensions). * Keys returned by this method still receive the generic "not found" warning. * Used by {@link MetadataType.getDependentFiles}. * * @param {string[]} notFound keys that could not be found in the retrieve folder * @returns {Promise.<string[]>} keys that should still trigger the default "not found" warning */ static handleNotFoundDependencies(notFound: string[]): Promise<string[]>; /** * helper for {@link MetadataType.getDependentFiles} * * @param {MetadataTypeItem} obj the metadataItem to search in * @param {string} nestedKey e.g "my.field.here" * @param {string} dependentType used for types that need custom handling * @returns {(string)[]} result array or null if nothing was found */ static getNestedValue(obj: MetadataTypeItem, nestedKey: string, dependentType: string): (string)[]; /** * helper for {@link MetadataType.getNestedValue} * * @param {any} obj the metadataItem to search in (or the result) * @param {string[]} nestedKeyParts key in dot-notation split into parts * @param {string} dependentType used for types that need custom handling * @returns {(string) | (string)[]} result */ static getNestedValueHelper(obj: any, nestedKeyParts: string[], dependentType: string): (string) | (string)[]; /** * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @returns {string[]} list of keys */ static getKeysForFixing(metadataMap: MetadataTypeMap): string[]; /** * helper for getKeysForFixing and createOrUpdate * * @param {string} baseField name of the field to start the new key with * @param {MetadataTypeItem} metadataItem - * @param {number} maxKeyLength - * @returns {string} newKey */ static getNewKey(baseField: string, metadataItem: MetadataTypeItem, maxKeyLength: number): string; /** * @typedef {'off'|'warn'|'error'} ValidationLevel */ /** * @typedef {object} ValidationRules * @property {ValidationLevel} [noGuidKeys] flags metadata that did not get a proper key * @property {ValidationLevel} [noRootFolder] flags metadata that did not get a proper key * @property {{type:string[], options: ValidationRules}[]} [overrides] flags metadata that did not get a proper key */ /** * Gets executed before deploying metadata * * @param {'retrieve'|'buildDefinition'|'deploy'} method used to select the right config * @param {MetadataTypeItem | CodeExtractItem} originalItem a single metadata item * @param {string} targetDir folder where files for deployment are stored * @returns {Promise.<MetadataTypeItem | CodeExtractItem>} Promise of a single metadata item */ static validation(method: "retrieve" | "buildDefinition" | "deploy", originalItem: MetadataTypeItem | CodeExtractItem, targetDir: string): Promise<MetadataTypeItem | CodeExtractItem>; } declare namespace MetadataType { namespace definition { let bodyIteratorField: string; let dependencies: any[]; let fields: any; let hasExtended: any; let idField: string; let keyField: string; let nameField: string; let type: string; } let client: SDK; let properties: Mcdevrc; let subType: string; let buObject: BuObject; } //# sourceMappingURL=MetadataType.d.ts.map ================================================ FILE: @types/lib/metadataTypes/MobileCode.d.ts ================================================ export default MobileCode; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MobileCode MetadataType * * @augments MetadataType */ declare class MobileCode extends MetadataType { /** * Retrieves Metadata of Mobile Keywords * Endpoint /legacy/v1/beta/mobile/code/ return all Mobile Codes with all details. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; } declare namespace MobileCode { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; endDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordLimit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordsUsed: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; code: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; codeType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isShortCode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordsUsedOther: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isGsmCharacterSetOnly: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isMms: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isStackIndependant: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; supportsConcatenation: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isClientOwned: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isOwner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dipSwitches: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sendableCountries: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sendableCountries[].countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sendableCountries[].vendor': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sendableCountries[].fromNameSupported': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; countryCode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; moEngineVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=MobileCode.d.ts.map ================================================ FILE: @types/lib/metadataTypes/MobileKeyword.d.ts ================================================ export default MobileKeyword; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MobileKeyword MetadataType * * @augments MetadataType */ declare class MobileKeyword extends MetadataType { /** * Retrieves Metadata of Mobile Keywords * Endpoint /legacy/v1/beta/mobile/keyword/ return all Mobile Keywords with all details. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * helper for {@link MobileKeyword.preDeployTasks} and {@link MobileKeyword.createOrUpdate} to ensure we have code & keyword properly set * * @param {MetadataTypeItem} metadata single item */ static "__#private@#setCodeAndKeyword"(metadata: MetadataTypeItem): void; /** * Retrieves event definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(_?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * retrieve an item and create a template from it * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} key name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise of metadata */ static retrieveAsTemplate(templateDir: string, key: string, templateVariables: TemplateMap): Promise<MetadataTypeItemObj>; /** * helper for {@link MobileKeyword.retrieve} and {@link MobileKeyword.retrieveAsTemplate} * * @param {string} key customer key of single item to retrieve / name of the metadata file * @returns {Array} key, queryParams */ static "__#private@#getRetrieveKeyAndUrl"(key: string): any[]; /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {CodeExtractItem | MetadataTypeItem | void} Array with one metadata object and one ssjs string; or single metadata object; nothing if filtered */ static postRetrieveTasks(metadata: MetadataTypeItem): CodeExtractItem | MetadataTypeItem | void; /** * helper for {@link MobileKeyword.postRetrieveTasks} and {@link MobileKeyword._buildForNested} * * @param {string} metadataScript the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content */ static prepExtractedCode(metadataScript: string): { fileExt: string; code: string; }; /** * helper for {@link MobileKeyword.buildTemplateForNested} / {@link MobileKeyword.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static _buildForNested(templateDir: string, targetDir: string | string[], metadata: MetadataTypeItem, templateVariables: TemplateMap, templateName: string, mode: "definition" | "template"): Promise<string[][]>; /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse */ static postCreateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * helper for {@link MetadataType.updateREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * helper for {@link MobileKeyword.preDeployTasks} that loads extracted code content back into JSON * * @param {MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} content for metadata.script */ static _mergeCode(metadata: MetadataTypeItem, deployDir: string, templateName?: string): Promise<string>; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static postDeleteTasks(customerKey: string): Promise<void>; } declare namespace MobileKeyword { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { mobileCode: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__codeKeyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__mobileCode_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; endDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dipSwitches: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isInherited: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; decodedId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; restriction: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; companyName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; responseMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; messages: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; code: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.code': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.endDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordLimit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsed': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.codeType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isShortCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsedOther': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isGsmCharacterSetOnly': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isMms': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isStackIndependant': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.supportsConcatenation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isClientOwned': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isOwner': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.dipSwitches': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.moEngineVersion': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=MobileKeyword.d.ts.map ================================================ FILE: @types/lib/metadataTypes/MobileMessage.d.ts ================================================ export default MobileMessage; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MobileMessage MetadataType * * @augments MetadataType */ declare class MobileMessage extends MetadataType { /** * Retrieves Metadata of Mobile Keywords * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves event definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(_?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * helper for {@link MobileMessage.preDeployTasks} that loads extracted code content back into JSON * * @param {MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} code */ static _mergeCode(metadata: MetadataTypeItem, deployDir: string, templateName?: string): Promise<string>; /** * helper for {@link MobileMessage.postRetrieveTasks} and {@link MobileMessage._buildForNested} * * @param {string} code the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content */ static prepExtractedCode(code: string): { fileExt: string; code: string; }; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single query * @returns {CodeExtractItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata: MetadataTypeItem): CodeExtractItem; /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse */ static postCreateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * helper for {@link MetadataType.updateREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * helper for {@link MobileMessage.buildTemplateForNested} / {@link MobileMessage.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static _buildForNested(templateDir: string, targetDir: string | string[], metadata: MetadataTypeItem, templateVariables: TemplateMap, templateName: string, mode: "definition" | "template"): Promise<string[][]>; } declare namespace MobileMessage { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { mobileCode: string[]; mobileKeyword: string[]; }; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: any; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { allowSingleOptin: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; audience: { skipValidation: boolean; }; 'audience[]': { skipValidation: boolean; }; campaigns: { skipValidation: boolean; }; 'campaigns[]': { skipValidation: boolean; }; r__mobileCode_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.code': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.codeType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.dipSwitches': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.endDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isClientOwned': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isGsmCharacterSetOnly': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isMms': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isOwner': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isShortCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isStackIndependant': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordLimit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsed': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsedOther': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.moEngineVersion': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[]': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[].countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[].vendor': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[].fromNameSupported': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.supportsConcatenation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; concatenateMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; currentEditStep: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; doubleOptinConfirmMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; doubleOptinInitialMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; doubleOptinValidResponses: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; duplicateOptInResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; expireHours: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; fromName: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; invalidMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isCertified: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isDuplicationAllowed: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isExpireSet: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isFromNameCertificationAccepted: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isSentImmediately: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isSubscriberResponseToAnySubscriptionForShortCode: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isSuppressMt: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isTest: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isTimeZoneBased: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'keyword.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.isInherited': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.keyword': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.keywordType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.restriction': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; messageObjectId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; messagesPerPeriod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; minutesPerPeriod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; moStartDate: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; moEndDate: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'moTimezone.name': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'moTimezone.offset': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.key': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.createdDate': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.createdBy': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.lastUpdated': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.lastUpdatedBy': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.name': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.description': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.startDate': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.iCalRecur': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.timeZone': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.timeZoneId': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; mtSendDate: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; nextJob: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; nextKeyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; numberMessagesPerPeriod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinErrorMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinInvalidAgeMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinMinimumAge: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinType: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; origin: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; outboundSendBehaviorFlag: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; outboundSendTypeFlag: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; periodType: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; programId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; publishedMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; responseMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sendMethod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; smsTriggeredSendDefinitionId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; statistics: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.sent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.delivered': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.undelivered': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.unknown': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; statusId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.keyword': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.restriction': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.isInherited': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.keyword': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.restriction': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.isInherited': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; subscriberResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyCorrectResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyIncorrectResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyResponsesAllowed: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyTooManyEntriesMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyType: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.description': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.icon': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.lastUpdated': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.name': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; text: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; triggeredSendId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; triggeredSendName: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__campaign_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'r__campaign_key[]': { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=MobileMessage.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Query.d.ts ================================================ export default Query; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type QueryItem = import("../../types/mcdev.d.js").QueryItem; export type QueryMap = import("../../types/mcdev.d.js").QueryMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * @typedef {import('../../types/mcdev.d.js').QueryItem} QueryItem * @typedef {import('../../types/mcdev.d.js').QueryMap} QueryMap */ /** * Query MetadataType * * @augments MetadataType */ declare class Query extends MetadataType { /** * Retrieves Metadata of queries * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: QueryMap, type: string}>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<{ metadata: QueryMap; type: string; }>; /** * a function to start query execution via API * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed successfully */ static execute(keyArr: string[]): Promise<string[]>; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ private static _getObjectIdForSingleRetrieve; /** * Retrieves query metadata for caching * * @returns {Promise.<{metadata: QueryMap, type: string}>} Promise of metadata */ static retrieveForCache(): Promise<{ metadata: QueryMap; type: string; }>; /** * Retrieve a specific Query by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<{metadata: Query, type: string}>} Promise of metadata */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<{ metadata: Query; type: string; }>; /** * manages post retrieve steps * * @param {QueryItem} metadata a single query * @returns {CodeExtractItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata: QueryItem): CodeExtractItem; /** * Creates a single query * * @param {QueryItem} query a single query * @returns {Promise} Promise */ static create(query: QueryItem): Promise<any>; /** * Updates a single query * * @param {QueryItem} query a single query * @returns {Promise} Promise */ static update(query: QueryItem): Promise<any>; /** * prepares a Query for deployment * * @param {QueryItem} metadata a single query activity * @param {string} deployDir directory of deploy files * @returns {Promise.<QueryItem>} Promise */ static preDeployTasks(metadata: QueryItem, deployDir: string): Promise<QueryItem>; /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {QueryItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested(templateDir: string, targetDir: string | string[], metadata: QueryItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example queries are saved as 1 json and 1 sql file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {QueryItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested(templateDir: string, targetDir: string | string[], metadata: QueryItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link Query.buildTemplateForNested} / {@link Query.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @private * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {QueryItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ private static _buildForNested; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static postDeleteTasks(customerKey: string): Promise<void>; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create */ static postDeployTasks(upsertResults: MetadataTypeMap): Promise<void>; } declare namespace Query { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; folderType: string; filter: { description: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; targetUpdateTypeMapping: { Append: number; Overwrite: number; Update: number; }; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isFrozen: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; queryDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; queryText: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetDescription: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetUpdateTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetUpdateTypeName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; validatedQueryText: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Query.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Role.d.ts ================================================ export default Role; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type SoapSDKFilterSimple = import("../../types/mcdev.d.js").SoapSDKFilterSimple; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').SoapSDKFilterSimple} SoapSDKFilterSimple * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ImportFile MetadataType * * @augments MetadataType */ declare class Role extends MetadataType { /** * Gets metadata from Marketing Cloud * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] Returns specified fields even if their retrieve definition is not set to true * @param {void | string[]} [___] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Metadata store object */ static retrieve(retrieveDir: string, _?: void | string[], ___?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * adds default roles to the list of retrieved roles for proper caching (but not storing) * also caches available timezones for retrieve-user * * @param {MetadataTypeMap} parsed list or previously retrieved items as reference */ static cacheDefaultRolesAndTimezones(parsed: MetadataTypeMap): Promise<void>; /** * Gets executed before deploying metadata * * @param {MetadataTypeItem} metadata a single metadata item * @returns {MetadataTypeItem} Promise of a single metadata item */ static preDeployTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * Create a single Role. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * Updates a single Role. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * Creates markdown documentation of all roles * * @param {MetadataTypeMap} [metadata] role definitions * @returns {Promise.<void>} - */ static document(metadata?: MetadataTypeMap): Promise<void>; /** * iterates through permissions to output proper row-names for nested permissionss * * @static * @param {string} role name of the user role * @param {object} element data of the permission * @param {string} [permission] name of the permission * @param {string} [isAllowed] "true" / "false" from the parent * @memberof Role * @returns {void} */ static _traverseRoles(role: string, element: object, permission?: string, isAllowed?: string): void; } declare namespace Role { let allPermissions: {}; let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; deployBlacklist: string[]; documentInOneFile: boolean; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: any; isUpdateable: any; retrieving: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsSystemDefined: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PermissionSets: { retrieving: boolean; skipCache: boolean; skipValidation: boolean; }; c__notAssignable: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Role.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Script.d.ts ================================================ export default Script; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type ContentBlockConversionTypes = import("../../types/mcdev.d.js").ContentBlockConversionTypes; export type ScriptItem = import("../../types/mcdev.d.js").ScriptItem; export type ScriptMap = import("../../types/mcdev.d.js").ScriptMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * @typedef {import('../../types/mcdev.d.js').ScriptItem} ScriptItem * @typedef {import('../../types/mcdev.d.js').ScriptMap} ScriptMap */ /** * Script MetadataType * * @augments MetadataType */ declare class Script extends MetadataType { /** * Retrieves Metadata of Script * Endpoint /automation/v1/scripts/ return all Scripts with all details. * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: ScriptMap, type: string}>} Promise */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<{ metadata: ScriptMap; type: string; }>; /** * Retrieves script metadata for caching * * @returns {Promise.<{metadata: ScriptMap, type: string}>} Promise */ static retrieveForCache(): Promise<{ metadata: ScriptMap; type: string; }>; /** * Retrieve a specific Script by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<{metadata: ScriptItem, type: string}>} Promise */ static retrieveAsTemplate(templateDir: string, name: string, templateVariables: TemplateMap): Promise<{ metadata: ScriptItem; type: string; }>; /** * Updates a single Script * * @param {MetadataTypeItem} script a single Script * @returns {Promise} Promise */ static update(script: MetadataTypeItem): Promise<any>; /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry: MetadataTypeItem, apiResponse: object): Promise<object>; /** * Creates a single Script * * @param {MetadataTypeItem} script a single Script * @returns {Promise} Promise */ static create(script: MetadataTypeItem): Promise<any>; /** * helper for {@link Script.preDeployTasks} that loads extracted code content back into JSON * * @param {ScriptItem} metadata a single asset definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} content for metadata.script */ static _mergeCode(metadata: ScriptItem, deployDir: string, templateName?: string): Promise<string>; /** * prepares a Script for deployment * * @param {ScriptItem} metadata a single script activity definition * @param {string} dir directory of deploy files * @returns {Promise.<ScriptItem>} Promise */ static preDeployTasks(metadata: ScriptItem, dir: string): Promise<ScriptItem>; /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {ScriptItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested(templateDir: string, targetDir: string | string[], metadata: ScriptItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {ScriptItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested(templateDir: string, targetDir: string | string[], metadata: ScriptItem, templateVariables: TemplateMap, templateName: string): Promise<string[][]>; /** * helper for {@link Script.buildTemplateForNested} / {@link Script.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {ScriptItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static _buildForNested(templateDir: string, targetDir: string | string[], metadata: ScriptItem, templateVariables: TemplateMap, templateName: string, mode: "definition" | "template"): Promise<string[][]>; /** * manages post retrieve steps * * @param {ScriptItem} metadata a single item * @returns {CodeExtractItem} a single item with code parts extracted */ static postRetrieveTasks(metadata: ScriptItem): CodeExtractItem; /** * manages post retrieve steps * * @param {ScriptItem} metadata a single item * @returns {CodeExtractItem} a single item with code parts extracted */ static getCodeExtractItem(metadata: ScriptItem): CodeExtractItem; /** * helper for {@link Script.postRetrieveTasks} and {@link Script._buildForNested} * * @param {string} metadataScript the code of the file * @param {string} metadataName the name of the metadata * @returns {{fileExt:string,code:string}} returns found extension and file content */ static prepExtractedCode(metadataScript: string, metadataName: string): { fileExt: string; code: string; }; /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ private static _getObjectIdForSingleRetrieve; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static postDeleteTasks(customerKey: string): Promise<void>; /** * * @param {MetadataTypeItem} item single metadata item * @param {string} retrieveDir directory where metadata is saved * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<CodeExtractItem>} key of the item that was updated */ static replaceCbReference(item: MetadataTypeItem, retrieveDir: string, findAssetKeys?: Set<string>): Promise<CodeExtractItem>; } declare namespace Script { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: any; folderType: string; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; folderLocationText: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; script: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ssjsActivityId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; statusId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; parentCategoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Script.d.ts.map ================================================ FILE: @types/lib/metadataTypes/SendClassification.d.ts ================================================ export default SendClassification; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * SendClassification MetadataType * * @augments MetadataType */ declare class SendClassification extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Updates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static update(metadataItem: MetadataTypeItem): Promise<any>; /** * Creates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem: MetadataTypeItem): Promise<any>; /** * prepares a import definition for deployment * * @param {MetadataTypeItem} metadata a single importDef * @returns {Promise.<MetadataTypeItem>} Promise */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static postDeployTasks(upsertResults: MetadataTypeMap): Promise<void>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * this is the only known way to get the object ID for a deliveryProfile * * @param {MetadataTypeItem} metadata a single sendClassification item */ static updateDeliveryProfileIdInCache(metadata: MetadataTypeItem): void; } declare namespace SendClassification { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { senderProfile: string[]; }; filter: {}; hasExtended: boolean; idField: string; keyField: string; keyIsFixed: boolean; maxKeyLength: number; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; sendClassificationTypeMapping: { Commercial: string; Transactional: string; }; fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ArchiveEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DeliveryProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DeliveryProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DeliveryProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; HonorPublicationListOptOutsForTransactionalSends: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendClassificationType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SenderProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SenderProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SenderProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendPriority: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__classification: { skipValidation: boolean; }; r__deliveryProfile_key: { skipValidation: boolean; }; r__senderProfile_key: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=SendClassification.d.ts.map ================================================ FILE: @types/lib/metadataTypes/SenderProfile.d.ts ================================================ export default SenderProfile; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * SenderProfile MetadataType * * @augments MetadataType */ declare class SenderProfile extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Updates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static update(metadataItem: MetadataTypeItem): Promise<any>; /** * Creates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem: MetadataTypeItem): Promise<any>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} a single item */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; /** * * @param {MetadataTypeItem} metadata a single item * @param {MetadataTypeItem} [metadataCaller] if called from SendClassification this can be used to adjust logs * @param {any} [definition] type defintiion from SendClassification */ static verifySenderEmailAddresses(metadata: MetadataTypeItem, metadataCaller?: MetadataTypeItem, definition?: any): void; /** * prepares a single item for deployment * * @param {MetadataTypeItem} metadata a single query activity * @returns {Promise.<MetadataTypeItem>} Promise */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static postDeployTasks(upsertResults: MetadataTypeMap): Promise<void>; } declare namespace SenderProfile { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { domainVerification: string[]; }; filter: {}; hasExtended: boolean; idField: string; keyField: string; keyIsFixed: boolean; maxKeyLength: number; nameField: string; createdDateField: string; createdNameField: string; lastmodDateField: string; lastmodNameField: string; restPagination: boolean; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.CreatedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ModifiedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: any; template: boolean; }; modifiedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: any; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AutoForwardToEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AutoForwardToName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutoForwardTriggeredSend.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AutoReply: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutoReplyTriggeredSend.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodUnitOfMeasure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DirectForward: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FallbackFromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FromName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ReplyManagementRuleSet.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'RMMRuleCollection.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ReplyToAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ReplyToDisplayName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SenderHeaderEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SenderHeaderName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; UseDefaultRMMRules: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=SenderProfile.d.ts.map ================================================ FILE: @types/lib/metadataTypes/TransactionalEmail.d.ts ================================================ export default TransactionalEmail; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalEmail MetadataType * * @augments TransactionalMessage */ declare class TransactionalEmail extends TransactionalMessage { static subType: string; /** @type {Array} */ static _createdJourneyKeys: any[]; /** * prepares for deployment * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} - */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * helper for {@link TransactionalEmail.createREST} * * @param {MetadataTypeItem} _ not used * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse */ static postCreateTasks(_: MetadataTypeItem, apiResponse: object): Promise<object>; /** * Gets executed after deployment of metadata type * * @returns {Promise.<void>} - */ static postDeployTasks(): Promise<void>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} a single item */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace TransactionalEmail { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { asset: string[]; dataExtension: string[]; list: string[]; journey: string[]; sendClassification: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; classification: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.customerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.dataExtension': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.list': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.r__list_PathName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.autoAddSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.updateSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.trackLinks': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.cc': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.bcc': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.createJourney': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; journey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'journey.interactionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__asset_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__journey_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__sendClassification_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import TransactionalMessage from './TransactionalMessage.js'; //# sourceMappingURL=TransactionalEmail.d.ts.map ================================================ FILE: @types/lib/metadataTypes/TransactionalMessage.d.ts ================================================ export default TransactionalMessage; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalMessage MetadataType * * @augments MetadataType */ declare class TransactionalMessage extends MetadataType { static subType: any; /** * Retrieves Metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves event definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to cache * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(_?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; } declare namespace TransactionalMessage { let definition: { bodyIteratorField: string; dependencies: any[]; dependencyGraph: any; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=TransactionalMessage.d.ts.map ================================================ FILE: @types/lib/metadataTypes/TransactionalPush.d.ts ================================================ export default TransactionalPush; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalPush TransactionalMessage * * @augments TransactionalMessage */ declare class TransactionalPush extends TransactionalMessage { static subType: string; /** * prepares for deployment * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} - */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} a single item */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem; } declare namespace TransactionalPush { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { asset: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.customerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__asset_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.badge': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.sound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.customKeys': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.customKeys[].value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.customKeys[].key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; applicationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import TransactionalMessage from './TransactionalMessage.js'; //# sourceMappingURL=TransactionalPush.d.ts.map ================================================ FILE: @types/lib/metadataTypes/TransactionalSMS.d.ts ================================================ export default TransactionalSMS; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalSMS MetadataType * * @augments TransactionalMessage */ declare class TransactionalSMS extends TransactionalMessage { static subType: string; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static postDeleteTasks(customerKey: string): Promise<void>; /** * helper for {@link TransactionalSMS.preDeployTasks} that loads extracted code content back into JSON * * @param {MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} content for metadata.script */ static _mergeCode(metadata: MetadataTypeItem, deployDir: string, templateName?: string): Promise<string>; /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<CodeExtractItem>} Array with one metadata object and one ssjs string */ static postRetrieveTasks(metadata: MetadataTypeItem): Promise<CodeExtractItem>; /** * helper for {@link TransactionalSMS.postRetrieveTasks} and {@link TransactionalSMS._buildForNested} * * @param {string} metadataScript the code of the file * @returns {Promise.<{fileExt:string,code:string}>} returns found extension and file content */ static prepExtractedCode(metadataScript: string): Promise<{ fileExt: string; code: string; }>; /** * helper for {@link TransactionalSMS.buildTemplateForNested} / {@link TransactionalSMS.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static _buildForNested(templateDir: string, targetDir: string | string[], metadata: MetadataTypeItem, templateVariables: TemplateMap, templateName: string, mode: "definition" | "template"): Promise<string[][]>; /** * very simplified test for HTML code in our SMS * * @param {string} code sms source code * @returns {boolean} true if HTML is found */ static _isHTML(code: string): boolean; } declare namespace TransactionalSMS { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { mobileKeyword: string[]; mobileCode: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: boolean; restPageSize: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.message': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.shortCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.autoAddSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.updateSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.keyword': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import TransactionalMessage from './TransactionalMessage.js'; //# sourceMappingURL=TransactionalSMS.d.ts.map ================================================ FILE: @types/lib/metadataTypes/TriggeredSend.d.ts ================================================ export default TriggeredSend; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MessageSendActivity MetadataType * * @augments MetadataType */ declare class TriggeredSend extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Create a single TSD. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * Updates a single TSD. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem | void} Array with one metadata object and one sql string */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem | void; /** * prepares a TSD for deployment * * @param {MetadataTypeItem} metadata of a single TSD * @returns {Promise.<MetadataTypeItem>} metadata object */ static preDeployTasks(metadata: MetadataTypeItem): Promise<MetadataTypeItem>; /** * TSD-specific refresh method that finds active TSDs and refreshes them * * @param {string[]} [keyArr] metadata keys * @param {boolean} [checkKey] whether to check if the key is valid * @returns {Promise.<string[]>} Returns list of keys that were refreshed */ static refresh(keyArr?: string[], checkKey?: boolean): Promise<string[]>; /** * helper for {@link TriggeredSend.refresh} that extracts the keys from the TSD item map and eli * * @param {MetadataTypeMap} metadata TSD item map * @returns {Promise.<string[]>} keyArr */ static getKeysForValidTSDs(metadata: MetadataTypeMap): Promise<string[]>; /** * helper for {@link TriggeredSend.refresh} that finds active TSDs on the server and filters it by the same rules that {@link TriggeredSend.retrieve} is using to avoid refreshing TSDs with broken dependencies * * @param {boolean} [assetLoaded] if run after Asset.deploy via --refresh option this will skip caching assets * @returns {Promise.<MetadataTypeMapObj>} Promise of TSD item map */ static findRefreshableItems(assetLoaded?: boolean): Promise<MetadataTypeMapObj>; /** * helper for {@link TriggeredSend.refresh} that pauses, publishes and starts a triggered send * * @param {string} key external key of triggered send item * @param {boolean} checkKey whether to check if key exists on the server * @returns {Promise.<boolean>} true if refresh was successful */ static _refreshItem(key: string, checkKey: boolean): Promise<boolean>; } declare namespace TriggeredSend { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { asset: string[]; list: string[]; sendClassification: string[]; senderProfile: string[]; }; filter: { r__folder_Path: string[]; }; folderType: string; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: any; restPagination: any; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; priorityMapping: { High: number; Medium: number; Low: number; }; fields: { AllowedSlots: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; AutoAddSubscribers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; AutoUpdateSubscribers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BatchInterval: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BccEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CCEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DataSchemas: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DisableOnEmailBuildError: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DomainType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DynamicEmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; EmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ExclusionFilter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ExclusionListCollection: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'FooterContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FooterSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'HeaderContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HeaderSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; InteractionObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsAlwaysOn: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsMultipart: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSendLogging: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsWrapped: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; KeepExistingEmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Keyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'List.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'List.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'List.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NewSlotTrigger: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptionFlags: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptionFlagsUpdateMask: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptionVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PreHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Priority: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateDomain.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateDomain.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateIP.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateIP.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; RefreshContent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToDisplayName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; RequestExpirationSeconds: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendLimit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendSourceCustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendSourceDataExtension: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowClose: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowDelete: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowOpen: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SourceAddressType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SuppressTracking: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TestEmailAddr: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendClass: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendStatus: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendSubClass: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendVersionID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; r__asset_name_readOnly: { skipValidation: boolean; }; r__asset_key: { skipValidation: boolean; }; r__email_name: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; r__list_PathName: { skipValidation: boolean; }; c__priority: { skipValidation: boolean; }; r__sendClassification_key: { skipValidation: boolean; }; r__senderProfile_key: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=TriggeredSend.d.ts.map ================================================ FILE: @types/lib/metadataTypes/TriggeredSendSummary.d.ts ================================================ export default TriggeredSendSummary; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TriggeredSendSummary MetadataType * * @augments MetadataType */ declare class TriggeredSendSummary extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem | void} Array with one metadata object and one sql string */ static postRetrieveTasks(metadata: MetadataTypeItem): MetadataTypeItem | void; } declare namespace TriggeredSendSummary { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { triggeredSend: string[]; }; filter: {}; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; folderIdField: string; createdDateField: any; createdNameField: any; lastmodDateField: any; lastmodNameField: any; restPagination: any; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { Bounces: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Clicks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Conversions: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FTAFEmailsSent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FTAFOptIns: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FTAFRequests: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; InProcess: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NotSentDueToError: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NotSentDueToOptOut: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NotSentDueToUndeliverable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Opens: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptOuts: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Queued: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Sent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SurveyResponses: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; UniqueClicks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; UniqueConversions: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; UniqueOpens: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; r__triggeredSend_name: { skipValidation: boolean; }; r__triggeredSend_key: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=TriggeredSendSummary.d.ts.map ================================================ FILE: @types/lib/metadataTypes/User.d.ts ================================================ export default User; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type UserDocument = import("../../types/mcdev.d.js").UserDocument; export type UserDocumentDocument = import("../../types/mcdev.d.js").UserDocumentDocument; export type UserDocumentDiff = import("../../types/mcdev.d.js").UserDocumentDiff; export type UserDocumentMap = import("../../types/mcdev.d.js").UserDocumentMap; export type AccountUserConfiguration = import("../../types/mcdev.d.js").AccountUserConfiguration; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * @typedef {import('../../types/mcdev.d.js').UserDocument} UserDocument * @typedef {import('../../types/mcdev.d.js').UserDocumentDocument} UserDocumentDocument * @typedef {import('../../types/mcdev.d.js').UserDocumentDiff} UserDocumentDiff * @typedef {import('../../types/mcdev.d.js').UserDocumentMap} UserDocumentMap * @typedef {import('../../types/mcdev.d.js').AccountUserConfiguration} AccountUserConfiguration */ /** * MetadataType * * @augments MetadataType */ declare class User extends MetadataType { static userBUassignments: any; static userIdBuMap: any; /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} _ unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir: string, _: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * Retrieves import definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Create a single item. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata: MetadataTypeItem): Promise<any>; /** * Updates a single item. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static update(metadata: MetadataTypeItem): Promise<any>; /** * prepares a item for deployment * * @param {UserDocument} metadata of a single item * @returns {Promise.<UserDocument>} metadata object */ static preDeployTasks(metadata: UserDocument): Promise<UserDocument>; /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadata list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {UserDocumentDiff[]} metadataToUpdate list of items to update * @param {UserDocument[]} metadataToCreate list of items to create * @returns {Promise.<'create'|'update'|'skip'>} action to take */ static createOrUpdate(metadata: MetadataTypeMap, metadataKey: string, hasError: boolean, metadataToUpdate: UserDocumentDiff[], metadataToCreate: UserDocument[]): Promise<"create" | "update" | "skip">; /** * helper for {@link createOrUpdate} * * @private * @param {MetadataTypeItem} metadata single metadata itme * @param {UserDocumentDiff} [updateItem] item to update * @param {UserDocument} [createItem] item to create */ private static _prepareBuAssignments; /** * Gets executed after deployment of metadata type * * @param {UserDocumentMap} upsertResults metadata mapped by their keyField * @returns {Promise.<void>} promise */ static postDeployTasks(upsertResults: UserDocumentMap): Promise<void>; /** * create/update business unit assignments. helper for {@link postDeployTasks} * * @private * @param {UserDocumentMap} upsertResults metadata mapped by their keyField * @returns {Promise.<void>} - */ private static _handleBuAssignments; /** * helper for {@link User.createOrUpdate} * * @private * @param {UserDocument} metadata single created user * @returns {void} */ private static _setPasswordForNewUser; /** * helper for {@link User.createOrUpdate} * It searches for roles that were removed from the user and unassigns them; it also prints a summary of added/removed roles * Adding roles works automatically for roles listed on the user * * @private * @param {UserDocumentDiff} item updated user with before and after state * @returns {void} */ private static _prepareRoleAssignments; /** * helper for {@link User._prepareRoleAssignments} * * @param {string} roleId role.ObjectID * @param {string} roleName role.Name * @param {number} userId user.AccountUserID * @param {boolean} assignmentOnly if true, only assignment configuration will be returned * @param {boolean} [isRoleRemovale] if true, role will be removed from user; otherwise added * @returns {object} format needed by API */ static _getRoleObjectForDeploy(roleId: string, roleName: string, userId: number, assignmentOnly: boolean, isRoleRemovale?: boolean): object; /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveChangelog(): Promise<MetadataTypeMapObj>; /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @private * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ private static _retrieve; /** * Retrieves SOAP via generic fuel-soap wrapper based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {SoapRequestParams} [requestParams] required for the specific request (filter for example) * @param {string} [singleRetrieve] key of single item to filter by * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<MetadataTypeMapObj>} Promise of item map */ static retrieveSOAP(retrieveDir: string, requestParams?: SoapRequestParams, singleRetrieve?: string, additionalFields?: string[]): Promise<MetadataTypeMapObj>; /** * helper for {@link retrieveSOAP} and {@link upsert}; populates userIdBuMap * * @param {MetadataTypeItem[]} [metadataList] - * @returns {Promise.<void>} - */ static cacheBusinessUnitAssignments(metadataList?: MetadataTypeItem[]): Promise<void>; /** * helper for {@link User.retrieveSOAP} * * @private * @param {SoapRequestParams} requestParams required for the specific request (filter for example) * @param {string} soapType e.g. AccountUser * @param {string[]} fields list of fields to retrieve * @param {object} resultsBulk actual return value of this method * @returns {Promise.<boolean>} success flag */ private static _retrieveSOAP_installedPackage; /** * * @param {string} dateStr first date * @param {string} interval defaults to 'days' * @returns {string} time difference */ static "__#private@#timeSinceDate"(dateStr: string, interval?: string): string; /** * helper to print bu names * * @private * @param {number} id bu id * @returns {string} "bu name (bu id)"" */ private static _getBuName; /** * helper that gets BU names from config * * @private */ private static _getBuNames; /** * helper for {@link User.createOrUpdate} to generate a random initial password for new users * note: possible minimum length values in SFMC are 6, 8, 10, 15 chars. Therefore we should default here to 15 chars. * * @private * @param {number} [length] length of password; defaults to 15 * @returns {string} random password */ private static _generatePassword; /** * Creates markdown documentation of all roles * * @param {UserDocumentMap} [metadata] user list * @returns {Promise.<void>} - */ static document(metadata?: UserDocumentMap): Promise<void>; /** * * @private * @param {object[]} users list of users and installed package * @param {'Installed Package'|'User'|'Inactivated User'} type choose what sub type to print * @param {Array[]} columnsToPrint helper array * @returns {string} markdown */ private static _generateDocMd; /** * manages post retrieve steps * * @param {UserDocument} metadata a single item * @returns {MetadataTypeItem | void} a single item */ static postRetrieveTasks(metadata: UserDocument): MetadataTypeItem | void; } declare namespace User { let buIdName: {}; let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: {}; folderType: any; hasExtended: boolean; idField: string; keepId: boolean; keyIsFixed: boolean; keyField: string; nameField: string; createdDateField: string; createdNameField: any; lastmodDateField: string; lastmodNameField: string; maxKeyLength: number; type: string; soapType: string; typeDescription: string; typeName: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; documentInOneFile: boolean; stringifyFieldsBeforeTemplate: string[]; fields: { AccountUserID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ActiveFlag: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AssociatedBusinessUnits: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; BusinessUnit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ChallengeAnswer: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ChallengePhrase: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ModifiedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultApplication: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultBusinessUnit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultBusinessUnitObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Delete: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Email: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsAPIUser: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsLocked: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'LanguageLocale.LocaleCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; LastSuccessfulLogin: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Locale.LocaleCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Locale.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Locale.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; MustChangePassword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; NotificationEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; ObjectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Password: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Roles: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Roles.Role': { skipValidation: boolean; }; 'Roles.Role[].Client': { skipValidation: boolean; }; SsoIdentities: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SsoIdentities.SsoIdentity': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SsoIdentities.SsoIdentity[].IsActive': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SsoIdentities.SsoIdentity[].FederatedID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Unlock: { skipValidation: boolean; isCreateable: boolean; isUpdateable: boolean; template: boolean; }; UserID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; UserPermissions: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'UserPermissions.PartnerKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.ID': { skipValidation: boolean; }; 'UserPermissions.ObjectID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Name': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Description': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Delete': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].PartnerKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].ID': { skipValidation: boolean; }; 'UserPermissions[].ObjectID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Name': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Description': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Delete': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; c__type: { isCreateable: boolean; isUpdateable: boolean; retrieve: any; template: boolean; }; c__AssociatedBusinessUnits: { skipValidation: boolean; }; c__RoleNamesGlobal: { skipValidation: boolean; }; c__LocaleCode: { skipValidation: boolean; }; c__TimeZoneName: { skipValidation: boolean; }; c__AccountUserID: { isCreateable: boolean; isUpdateable: boolean; retrieve: any; template: boolean; }; c__IsLocked_readOnly: { isCreateable: boolean; isUpdateable: boolean; retrieve: any; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=User.d.ts.map ================================================ FILE: @types/lib/metadataTypes/Verification.d.ts ================================================ export default Verification; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type RestError = import("../../types/mcdev.d.js").RestError; export type VerificationItem = import("../../types/mcdev.d.js").VerificationItem; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').RestError} RestError */ /** * @typedef {import('../../types/mcdev.d.js').VerificationItem} VerificationItem */ /** * Verification MetadataType * * @augments MetadataType */ declare class Verification extends MetadataType { static verificationIdKeyMap: any; /** * Retrieves Metadata of Data Verification Activity. * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir?: string, _?: void | string[], __?: void | string[], key?: string): Promise<MetadataTypeMapObj>; /** * helper for {@link this.retrieveRESTcollection} * * @param {RestError} ex exception * @param {string} id id or key of item * @returns {null} - */ static handleRESTErrors(ex: RestError, id: string): null; /** * Retrieves Metadata of item for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(): Promise<MetadataTypeMapObj>; /** * Creates a single item * * @param {VerificationItem} metadata a single item * @returns {Promise} Promise */ static create(metadata: VerificationItem): Promise<any>; /** * Updates a single item * * @param {VerificationItem} metadata a single item * @returns {Promise} Promise */ static update(metadata: VerificationItem): Promise<any>; /** * prepares a verification for deployment * * @param {VerificationItem} metadata a single verification activity definition * @returns {Promise.<VerificationItem>} metadata object */ static preDeployTasks(metadata: VerificationItem): Promise<VerificationItem>; /** * parses retrieved Metadata before saving * * @param {VerificationItem} metadata a single verification activity definition * @returns {VerificationItem} Array with one metadata object and one sql string */ static postRetrieveTasks(metadata: VerificationItem): VerificationItem; } declare namespace Verification { let definition: { bodyIteratorField: string; dependencies: string[]; dependencyGraph: { dataExtension: string[]; }; hasExtended: boolean; idField: string; keyIsFixed: boolean; keyField: string; createdDateField: any; createdNameField: string; lastmodDateField: any; lastmodNameField: any; nameField: string; restPagination: boolean; maxKeyLength: number; type: string; typeDescription: string; typeRetrieveByDefault: boolean; typeCdpByDefault: boolean; typeName: string; fields: { createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataVerificationDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; notificationEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; notificationEmailMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; shouldEmailOnFailure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; shouldStopOnFailure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; targetObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; value1: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; value2: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; verificationType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__automation_step: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; }; } import MetadataType from './MetadataType.js'; //# sourceMappingURL=Verification.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Asset.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let asset: string[]; } let folderType: string; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: string[]; let typeCdpByDefault: boolean; let typeName: string; let stringifyFieldsBeforeTemplate: string[]; let allowMatchingByName: boolean; let fields: { activeDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; allowedBlocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; assetType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'assetType.displayName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'assetType.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'assetType.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; availableViews: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modelVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; blocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; businessUnitAvailability: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.view': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.update': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.delete': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.memberId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'businessUnitAvailability.%.transferOwnership': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; category: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'category.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'category.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'category.parentId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; channels: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; content: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.url': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; contentType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.userId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customFields: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.campaigns': { skipValidation: boolean; }; 'data.approvals': { skipValidation: boolean; }; 'data.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.email.attributes': { skipValidation: boolean; }; 'data.email.legacy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.email.options': { skipValidation: boolean; }; 'data.portfolio': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.site': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.site.content': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'data.site.content.url': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; design: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; enterpriseId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; file: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.fileName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.extension': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.externalUrl': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.fileSize': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.fileCreatedDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.width': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.height': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileProperties.publishedURL': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; legacyData: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; locked: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxBlocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; memberId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; meta: { skipValidation: boolean; }; minBlocks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'modifiedBy.userId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; objectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'owner.userId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sharingProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.localAssets': { skipValidation: boolean; }; 'sharingProperties.sharedWith': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.sharedFrom': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.sharedFromMID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sharingProperties.sharingType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; slots: { skipValidation: boolean; }; 'status.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'status.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; superContent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; tags: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; template: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; thumbnail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; version: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; views: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; let subTypes: string[]; let crosslinkedSubTypes: string[]; let selflinkedSubTypes: string[]; let binarySubtypes: string[]; namespace extendedSubTypes { export let archive: string[]; let asset_1: string[]; export { asset_1 as asset }; export let audio: string[]; export let block: string[]; export let cloudpage: string[]; export let code: string[]; export let coderesource: string[]; export let document: string[]; export let image: string[]; export let message: string[]; export let other: string[]; export let rawimage: string[]; export let template: string[]; export let textfile: string[]; export let video: string[]; } let typeMapping: { asset: number; file: number; block: number; template: number; message: number; custom: number; default: number; image: number; rawimage: number; video: number; document: number; audio: number; archive: number; code: number; textfile: number; ai: number; psd: number; pdd: number; eps: number; gif: number; jpe: number; jpeg: number; jpg: number; jp2: number; jpx: number; pict: number; pct: number; png: number; tif: number; tiff: number; tga: number; bmp: number; wmf: number; vsd: number; pnm: number; pgm: number; pbm: number; ppm: number; svg: number; '3fr': number; ari: number; arw: number; bay: number; cap: number; crw: number; cr2: number; dcr: number; dcs: number; dng: number; drf: number; eip: number; erf: number; fff: number; iiq: number; k25: number; kdc: number; mef: number; mos: number; mrw: number; nef: number; nrw: number; orf: number; pef: number; ptx: number; pxn: number; raf: number; raw: number; rw2: number; rwl: number; rwz: number; srf: number; sr2: number; srw: number; x3f: number; '3gp': number; '3gpp': number; '3g2': number; '3gp2': number; asf: number; avi: number; m2ts: number; mts: number; dif: number; dv: number; mkv: number; mpg: number; f4v: number; flv: number; mjpg: number; mjpeg: number; mxf: number; mpeg: number; mp4: number; m4v: number; mp4v: number; mov: number; swf: number; wmv: number; rm: number; ogv: number; indd: number; indt: number; incx: number; wwcx: number; doc: number; docx: number; dot: number; dotx: number; mdb: number; mpp: number; ics: number; xls: number; xlsx: number; xlk: number; xlsm: number; xlt: number; xltm: number; csv: number; tsv: number; tab: number; pps: number; ppsx: number; ppt: number; pptx: number; pot: number; thmx: number; pdf: number; ps: number; qxd: number; rtf: number; sxc: number; sxi: number; sxw: number; odt: number; ods: number; ots: number; odp: number; otp: number; epub: number; dvi: number; key: number; keynote: number; pez: number; aac: number; m4a: number; au: number; aif: number; aiff: number; aifc: number; mp3: number; wav: number; wma: number; midi: number; oga: number; ogg: number; ra: number; vox: number; voc: number; '7z': number; arj: number; bz2: number; cab: number; gz: number; gzip: number; iso: number; lha: number; sit: number; tgz: number; jar: number; rar: number; tar: number; zip: number; gpg: number; htm: number; html: number; xhtml: number; xht: number; css: number; less: number; sass: number; js: number; json: number; atom: number; rss: number; xml: number; xsl: number; xslt: number; md: number; markdown: number; as: number; fla: number; eml: number; text: number; txt: number; freeformblock: number; textblock: number; htmlblock: number; textplusimageblock: number; imageblock: number; abtestblock: number; dynamicblock: number; stylingblock: number; einsteincontentblock: number; webpage: number; webtemplate: number; templatebasedemail: number; htmlemail: number; textonlyemail: number; socialshareblock: number; socialfollowblock: number; buttonblock: number; layoutblock: number; defaulttemplate: number; smartcaptureblock: number; smartcaptureformfieldblock: number; smartcapturesubmitoptionsblock: number; slotpropertiesblock: number; externalcontentblock: number; codesnippetblock: number; rssfeedblock: number; formstylingblock: number; referenceblock: number; imagecarouselblock: number; customblock: number; liveimageblock: number; livesettingblock: number; contentmap: number; jsonmessage: number; icemailformblock: number; coderesource: number; jscoderesource: number; csscoderesource: number; jsoncoderesource: number; rsscoderesource: number; textcoderesource: number; xmlcoderesource: number; cloudpages: number; landingpage: number; microsite: number; interactivecontent: number; }; } export default _default; //# sourceMappingURL=Asset.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/AttributeGroup.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let attributeSet: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { applicationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; applicationKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeCount: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeGroupIconKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeGroupType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; attributeSetIdentifiers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].definitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].definitionName.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'attributeSetIdentifiers[].namespace': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; canAddProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canAddRelationships: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canChangeProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canModify: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; canRemove: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; connectingID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'connectingID.identifierType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; containsSchemaAttributes: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'definitionName.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; displayOrder: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fullyQualifiedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isHidden: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isOwner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isPrimary: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSystemDefined: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; localizedDescription: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceSetKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceValueKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'localizedDescription.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; mID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; namespace: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; objectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requiredRelationships: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__attributeSet_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=AttributeGroup.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/AttributeSet.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; let attributeSet: string[]; let attributeGroup: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: any; let lastmodNameField: any; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { applicationID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; applicationKey: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; attributeCount: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canAddValues: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canChangeValues: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canModify: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; canRemove: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; categoryID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'connectingID.identifierType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createDate: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; createdBy: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; customObjectOwnerMID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.isDeleteAtEndOfRetentionPeriod': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.isResetRetentionPeriodOnImport': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.isRowBasedRetention': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.periodUnitOfMeasure': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.setDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'dataRetentionProperties.periodLength': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; definitionID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; definitionKey: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; definitionName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'definitionName.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fullyQualifiedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isCustomObjectBacked: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isEvent: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isHidden: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isReadOnly: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isRoot: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isSendable: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isShared: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isSystemDefined: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; isTestaable: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftConnectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.cardinality ': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.identifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'leftItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; localizedDescription: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceSetKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.resourceValueKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'localizedDescription.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; nonStandardAttributeGroupReferences: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'nonStandardAttributeGroupReferences[].attributeGroupType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'nonStandardAttributeGroupReferences[].attributeGroupID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'nonStandardAttributeGroupReferences[].definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.maskType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.maskTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.storageType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.storageTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'obfuscationProperties.valueDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.definitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'parentDefinition.definitionName.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; parentID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; relationshipCount: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; relationships: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].canModify': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].canRemove': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].isGroupToSetRelationship': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].isHidden': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].isSystemDefined': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipIDs': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.r__attributeSet_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftItem.r__attributeGroup_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.r__attributeSet_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].rightItem.r__attributeGroup_key': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipIDs[].type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipIDs[].value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].leftRelationshipReferenceType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].leftAttributeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].rightAttributeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].c__leftFullyQualifiedName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipAttributes[].c__rightFullyQualifiedName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'relationships[].relationshipID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightConnectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.cardinality': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.connectingID.identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.identifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'rightItem.relationshipType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; sendAttributeStorageName: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; sendContactKeyStorageName: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; setDefinitionID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; setDefinitionKey: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'setDefinitionName.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageFieldReferenceID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageFieldReferenceID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; storageLogicalType: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; storageName: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalIsRowIdentifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalObjectFieldAPIName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalObjectFieldDataTypeName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectFieldInformation.externalObjectFieldLength': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; storageObjectIDs: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageObjectInformation.externalObjectAPIName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageReferenceID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'storageReferenceID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; valueDefinitions: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].baseType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].customerDataID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].connectingID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].dataSourceID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].dataSourceName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].dataType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].defaultValue': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].definitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].definitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].definitionName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].description': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].displayOrder': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].fullyQualifiedName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].identifierType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isHidden': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isIdentityValue': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isNullable': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isPrimaryKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isReadOnly': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isSystemDefined': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].isUpdateable': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].length': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].localizedDescription': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].name': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.maskType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.maskTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.storageType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.storageTypeID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].obfuscationProperties.valueDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].ordinal': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].parentDefinition': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].parentIdentifier': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].parentType': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].restrictionLookupListID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].scale': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].setDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].setDefinitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].setDefinitionName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldReferenceID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldReferenceID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldReferenceID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldValueID.type': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageFieldValueID.value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageName': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].storageObjectFieldInformation': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldAPIName': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldDataTypeName': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldLength': { skipValidation: boolean; }; 'valueDefinitions[].storageObjectFieldInformation.externalIsRowIdentifier': { skipValidation: boolean; }; 'valueDefinitions[].valueDefinitionID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; 'valueDefinitions[].valueDefinitionKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; r__folder_Path: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; r__dataExtension_key: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; }; } export default _default; //# sourceMappingURL=AttributeSet.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Automation.definition.d.ts ================================================ declare namespace _default { export namespace activityTypeMapping { let dataExtract: number; let dataFactoryUtility: number; let emailSend: number; let fileTransfer: number; let filter: number; let fireEvent: number; let importFile: number; let journeyEntry: number; let journeyEntryOld: number; let query: number; let script: number; let verification: number; let wait: number; let push: number; let sms: number; let reportDefinition: number; let refreshMobileFilteredList: number; let refreshGroup: number; let interactions: number; let interactionStudioData: number; let importMobileContact: number; } export let bodyIteratorField: string; export let dependencies: string[]; export namespace dependencyGraph { let dataExtract_1: string[]; export { dataExtract_1 as dataExtract }; let emailSend_1: string[]; export { emailSend_1 as emailSend }; let fileTransfer_1: string[]; export { fileTransfer_1 as fileTransfer }; let importFile_1: string[]; export { importFile_1 as importFile }; let query_1: string[]; export { query_1 as query }; let script_1: string[]; export { script_1 as script }; let verification_1: string[]; export { verification_1 as verification }; } export let folderType: string; export let hasExtended: boolean; export namespace filter_1 { let description: string[]; } export { filter_1 as filter }; export let idField: string; export let keyIsFixed: boolean; export let keyField: string; export let nameField: string; export let folderIdField: string; export let createdDateField: string; export let createdNameField: string; export let lastmodDateField: string; export let lastmodNameField: string; export let restPagination: boolean; export let maxKeyLength: number; export namespace scheduleTypeMapping { let MINUTELY: number; let HOURLY: number; let DAILY: number; let WEEKLY: number; let MONTHLY: number; } export namespace statusMapping { let AwaitingTrigger: number; let Building: number; let BuildingError: number; let Error: number; let InactiveTrigger: number; let PausedSchedule: number; let Ready: number; let Running: number; let Scheduled: number; let Stopped: number; } export let fileNameOperatorMapping: { Equals: number; Contains: number; 'Begins with': number; 'Ends with': number; }; export let timeZoneMapping: { 'Afghanistan Standard Time': number; 'Alaskan Standard Time': number; 'Arab Standard Time': number; 'Arabian Standard Time': number; 'Arabic Standard Time': number; 'Argentina Standard Time': number; 'Atlantic Standard Time': number; 'AUS Central Standard Time': number; 'AUS Eastern Standard Time': number; 'Azerbaijan Standard Time': number; 'Azores Standard Time': number; 'Canada Central Standard Time': number; 'Cape Verde Standard Time': number; 'Caucasus Standard Time': number; 'Cen. Australia Standard Time': number; 'Central America Standard Time': number; 'Central Asia Standard Time': number; 'Central Brazilian Standard Time': number; 'Central Europe Standard Time': number; 'Central European Standard Time': number; 'Central Pacific Standard Time': number; 'Central Standard Time': number; 'Central Standard Time (Mexico)': number; 'Central Standard Time (no DST)': number; 'China Standard Time': number; 'Dateline Standard Time': number; 'E. Africa Standard Time': number; 'E. Australia Standard Time': number; 'E. Europe Standard Time': number; 'E. South America Standard Time': number; 'Eastern Standard Time': number; 'Egypt Standard Time': number; 'Ekaterinburg Standard Time': number; 'Fiji Standard Time': number; 'FLE Standard Time': number; 'Georgian Standard Time': number; 'GMT Standard Time': number; 'Greenland Standard Time': number; 'Greenwich Standard Time': number; 'GTB Standard Time': number; 'Hawaiian Standard Time': number; 'India Standard Time': number; 'Iran Standard Time': number; 'Israel Standard Time': number; 'Jordan Standard Time': number; 'Korea Standard Time': number; 'Mauritius Standard Time': number; 'Mid-Atlantic Standard Time': number; 'Middle East Standard Time': number; 'Montevideo Standard Time': number; 'Morocco Standard Time': number; 'Mountain Standard Time': number; 'Mountain Standard Time (Mexico)': number; 'Myanmar Standard Time': number; 'N. Central Asia Standard Time': number; 'Namibia Standard Time': number; 'Nepal Standard Time': number; 'New Zealand Standard Time': number; 'Newfoundland Standard Time': number; 'North Asia East Standard Time': number; 'North Asia Standard Time': number; 'Pacific SA Standard Time': number; 'Pacific Standard Time': number; 'Pacific Standard Time (Mexico)': number; 'Pakistan Standard Time': number; 'Romance Standard Time': number; 'Russian Standard Time': number; 'SA Pacific Standard Time': number; 'SA Western Standard Time': number; 'Samoa Standard Time': number; 'SE Asia Standard Time': number; 'Singapore Standard Time': number; 'South Africa Standard Time': number; 'Sri Lanka Standard Time': number; 'Taipei Standard Time': number; 'Tasmania Standard Time': number; 'Tokyo Standard Time': number; 'Tonga Standard Time': number; 'US Eastern Standard Time': number; 'US Mountain Standard Time': number; 'Venezuela Standard Time': number; 'Vladivostok Standard Time': number; 'W. Australia Standard Time': number; 'W. Central Africa Standard Time': number; 'W. Europe Standard Time': number; 'West Asia Standard Time': number; 'West Pacific Standard Time': number; 'Yakutsk Standard Time': number; }; export let timeZoneDifference: { 1: string; 2: string; 3: string; 4: string; 5: string; 6: string; 7: string; 8: string; 9: string; 10: string; 11: string; 12: string; 13: string; 14: string; 15: string; 16: string; 17: string; 18: string; 19: string; 20: string; 21: string; 22: string; 23: string; 24: string; 25: string; 26: string; 27: string; 28: string; 29: string; 30: string; 31: string; 32: string; 33: string; 34: string; 35: string; 36: string; 37: string; 38: string; 39: string; 40: string; 41: string; 42: string; 43: string; 44: string; 45: string; 46: string; 47: string; 48: string; 49: string; 50: string; 51: string; 52: string; 53: string; 54: string; 55: string; 56: string; 57: string; 58: string; 59: string; 60: string; 61: string; 62: string; 63: string; 64: string; 65: string; 66: string; 67: string; 68: string; 69: string; 70: string; 71: string; 72: string; 73: string; 74: string; 75: string; 76: string; 77: string; 78: string; 79: string; 80: string; 81: string; 82: string; 83: string; 84: string; 85: string; 86: string; 87: string; 88: string; 89: string; 90: string; 91: string; 92: string; }; export let type: string; export let typeDescription: string; export let typeRetrieveByDefault: boolean; export let typeCdpByDefault: boolean; export let typeName: string; export let customDeployTypes: string[]; export let manualDeployTypes: any[]; export let fields: { categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.fileNamePatternTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.fileNamingPattern': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.folderLocationText': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.isPublished': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.queueFiles': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'fileTrigger.triggerActive': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: any; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastRunInstanceId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastRunTime: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; legacyId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastSavedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastSavedByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdByName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; pausedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; pausedName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; updateInProgress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; notifications: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].message': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].channelType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'notifications[].notificationType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startSource: { skipValidation: boolean; }; 'schedule.endDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.icalRecur': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.occurrences': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.pattern': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.rangeTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduleStatus': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.statusId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.timezoneId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.timezoneName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.typeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduleTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; statusId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; steps: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].activityObjectId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].displayOrder': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].objectTypeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].targetDataExtensions': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].serializedObject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].activities[].r__type': { skipValidation: boolean; }; 'steps[].activities[].r__key': { skipValidation: boolean; }; 'steps[].activities[].timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].annotation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].step': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'steps[].stepNumber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; typeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=Automation.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Campaign.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ownerId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; externalKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignCode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'display.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'display.value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; isFavorite: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignOwnerName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignOwner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; campaignStatus: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; }; } export default _default; //# sourceMappingURL=Campaign.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/ContentArea.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let restPagination: any; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { BackgroundColor: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BorderColor: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BorderWidth: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Cellpadding: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Cellspacing: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Content: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FontFamily: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HasFontSize: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsBlank: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsDynamicContent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsLocked: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSurvey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Layout: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Width: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; }; } export default _default; //# sourceMappingURL=ContentArea.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataExtension.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: any; let folderType: string; namespace filter { let CustomerKey: string[]; let Name: string[]; } let templateFields: { AudienceBuilderResult: string[]; CONTEXTUAL_SUPPRESSION_LISTS: string[]; DomainExclusion: string[]; 'Event DE Template': string[]; PushSendLog: string[]; SendLog: string[]; 'SmartCapture - Contacts Template Extension': string[]; SmsSendLog: string[]; SMSMessageTracking: any; SMSSubscriptionLog: any; TriggeredSendDataExtension: string[]; }; namespace dataRetentionPeriodUnitOfMeasureMapping { let Days: number; let Weeks: number; let Months: number; let Years: number; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { CategoryID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriod: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodUnitOfMeasure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DeleteAtEndOfRetentionPeriod: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Fields: { skipValidation: boolean; }; folderContentType: { skipValidation: boolean; }; IsPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsTestable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ResetRetentionPeriodOnImport: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RetainUntil: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RowBasedRetention: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SendableDataExtensionField.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SendableDataExtensionField.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SendableDataExtensionField.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendableSubscriberField: { skipValidation: boolean; }; 'SendableSubscriberField.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Template.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Template.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Template.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_ContentType: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; r__dataExtensionTemplate_name: { skipValidation: boolean; }; c__retentionPolicy: { skipValidation: boolean; }; c__retainUntil: { skipValidation: boolean; }; c__dataRetentionPeriodUnitOfMeasure: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=DataExtension.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataExtensionField.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: any; let filter: {}; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let deleteSynchronously: boolean; let fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DataExtension.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DataExtension.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DataExtension.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultValue: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FieldType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsPrimaryKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsRequired: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; MaxLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Ordinal: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Scale: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=DataExtensionField.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataExtensionTemplate.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let filter: {}; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsSendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsTestable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendableCustomObjectField: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendableSubscriberField: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodUnitOfMeasure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RowBasedRetention: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ResetRetentionPeriodOnImport: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DeleteAtEndOfRetentionPeriod: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; RetainUntil: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=DataExtensionTemplate.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataExtract.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let nameField: string; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace createdBy { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace createdDate { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace dataExtractDefinitionId { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace dataExtractTypeId { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace dataFields { let skipValidation: boolean; } namespace description { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace endDate { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace fileSpec { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace intervalType { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace key { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace modifiedBy { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace modifiedDate { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace name { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace startDate { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace r__dataExtractType_name { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace r__dataExtension_key { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } } } export default _default; //# sourceMappingURL=DataExtract.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataExtractType.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace name { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace extractId { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } } } export default _default; //# sourceMappingURL=DataExtractType.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataFilter.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderType: string; let folderIdField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let restPageSize: number; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace id { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace key { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace createdDate { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace createdBy { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace owner { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace createdByName { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace lastUpdated { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace lastUpdatedBy { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace lastUpdatedByName { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace name { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace categoryId { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace description { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace filterDefinitionXml { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace derivedFromType { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace derivedFromObjectId { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } namespace derivedFromObjectTypeName { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } namespace derivedFromObjectName { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } namespace isSendable { let isCreateable_17: boolean; export { isCreateable_17 as isCreateable }; let isUpdateable_17: boolean; export { isUpdateable_17 as isUpdateable }; let retrieving_17: boolean; export { retrieving_17 as retrieving }; let template_17: boolean; export { template_17 as template }; } namespace r__source_dataExtension_key { let isCreateable_18: boolean; export { isCreateable_18 as isCreateable }; let isUpdateable_18: boolean; export { isUpdateable_18 as isUpdateable }; let retrieving_18: boolean; export { retrieving_18 as retrieving }; let template_18: boolean; export { template_18 as template }; } namespace c__filterDefinition { let skipValidation: boolean; } namespace r__folder_Path { let isCreateable_19: boolean; export { isCreateable_19 as isCreateable }; let isUpdateable_19: boolean; export { isUpdateable_19 as isUpdateable }; let retrieving_19: boolean; export { retrieving_19 as retrieving }; let template_19: boolean; export { template_19 as template }; } } } export default _default; //# sourceMappingURL=DataFilter.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DataFilterHidden.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderType: string; let folderIdField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let restPageSize: number; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace id { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace key { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace createdDate { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace createdBy { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace owner { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace createdByName { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace lastUpdated { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace lastUpdatedBy { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace lastUpdatedByName { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace name { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace categoryId { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace description { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace filterDefinitionXml { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace derivedFromType { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace derivedFromObjectId { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } namespace derivedFromObjectTypeName { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } namespace derivedFromObjectName { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } namespace isSendable { let isCreateable_17: boolean; export { isCreateable_17 as isCreateable }; let isUpdateable_17: boolean; export { isUpdateable_17 as isUpdateable }; let retrieving_17: boolean; export { retrieving_17 as retrieving }; let template_17: boolean; export { template_17 as template }; } namespace r__source_dataExtension_key { let isCreateable_18: boolean; export { isCreateable_18 as isCreateable }; let isUpdateable_18: boolean; export { isUpdateable_18 as isUpdateable }; let retrieving_18: boolean; export { retrieving_18 as retrieving }; let template_18: boolean; export { template_18 as template }; } namespace c__filterDefinition { let skipValidation: boolean; } namespace r__folder_Path { let isCreateable_19: boolean; export { isCreateable_19 as isCreateable }; let isUpdateable_19: boolean; export { isUpdateable_19 as isUpdateable }; let retrieving_19: boolean; export { retrieving_19 as retrieving }; let template_19: boolean; export { template_19 as template }; } } } export default _default; //# sourceMappingURL=DataFilterHidden.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DeliveryProfile.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let filter: {}; let hasExtended: boolean; let idField: string; let keyField: string; let keyIsFixed: boolean; let maxKeyLength: number; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace id { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace key { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace name { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace description { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace createdDate { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace lastUpdated { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } } } export default _default; //# sourceMappingURL=DeliveryProfile.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Discovery.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: any; let dependencies: any[]; let dependencyGraph: any; let endPointMapping: { Address: string; Asset: string; Automation: string; Contacts: string; Data: string; Device: string; Email: string; Guide: string; Hub: string; Interaction: string; 'Interaction-Experimental': string; Legacy: string; Messaging: string; 'Messaging-Experimental': string; OTT: string; 'OTT-Experimental': string; Platform: string; 'Platform-Experimental': string; Provisioning: string; Push: string; SMS: string; }; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { basePath: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; baseUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; discoveryVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; documentationLink: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; kind: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; methods: { skipValidation: boolean; }; metadata: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metadata.supportsResponseEncoding': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; protocol: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; resources: { skipValidation: boolean; }; rootUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; schemas: { skipValidation: boolean; }; servicePath: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; title: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; version: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=Discovery.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/DomainVerification.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let createdDateField: any; let createdNameField: any; let lastmodDateField: any; let lastmodNameField: any; let nameField: string; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace domain { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace emailAddress { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace enterpriseId { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace memberId { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace domainType { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace isSendable { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace status { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace emailSendTime { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } } } export default _default; //# sourceMappingURL=DomainVerification.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Email.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let restPagination: any; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CharacterSet: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ClonedFromID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ContentAreas: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.CategoryID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.Content': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsBlank': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsDynamicContent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsLocked': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.IsSurvey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.Key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].CategoryID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].Content': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsBlank': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsDynamicContent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsLocked': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].IsSurvey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].Key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'ContentAreas[].PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ContentCheckStatus: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; EmailType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Folder: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HasDynamicSubjectLine: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HTMLBody: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsActive: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsHTMLPaste: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PreHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Subject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SyncTextWithHTML: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TextBody: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; }; } export default _default; //# sourceMappingURL=Email.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/EmailSend.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let asset: string[]; let dataExtension: string[]; let deliveryProfile: string[]; let list: string[]; let sendClassification: string[]; let senderProfile: string[]; } let folderType: string; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: any; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { Additional: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; AutoBccEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BccEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CCEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DeduplicateByEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.DomainType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.FooterContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.FooterSalutationSource': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.HeaderContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.HeaderSalutationSource': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.PrivateDomain': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.PrivateIP': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.SourceAddressType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DeliveryScheduledTime: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DomainType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DynamicEmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.Subject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.Status': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; EmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ExclusionFilter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FooterContentArea: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FooterSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HeaderContentArea: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HeaderSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IntegratedTracking: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; InteractionObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsMultipart: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSeedListSend: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSendLogging: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsWrapped: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Keyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; MessageDeliveryType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PreHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PrivateDomain: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PrivateIP: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToDisplayName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SeedListOccurance: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList.CustomObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendDefinitionList: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].CustomObjectID': { skipValidation: boolean; }; 'SendDefinitionList[].SendDefinitionListType': { skipValidation: boolean; }; 'SendDefinitionList[].DataSourceTypeID': { skipValidation: boolean; }; 'SendDefinitionList[].IsTestObject': { skipValidation: boolean; }; 'SendDefinitionList[].SalesForceObjectID': { skipValidation: boolean; }; 'SendDefinitionList[].Name': { skipValidation: boolean; }; 'SendDefinitionList[].r__dataExtension_key': { skipValidation: boolean; }; 'SendDefinitionList[].List.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].List.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendDefinitionList[].r__list_PathName': { skipValidation: boolean; }; 'SenderProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.FromAddress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.FromName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendLimit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowClose: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowDelete: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowOpen: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SourceAddressType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SuppressTracking: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TestEmailAddr: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TimeZone: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TrackingUsers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; r__asset_name_readOnly: { skipValidation: boolean; }; r__asset_key: { skipValidation: boolean; }; r__email_name: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; r__senderProfile_key: { skipValidation: boolean; }; r__sendClassification_key: { skipValidation: boolean; }; r__deliveryProfile_key: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=EmailSend.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Event.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let automation: string[]; let dataExtension: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let validTypes: string[]; let fields: { 'arguments.audienceCount': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.audienceDefinitionID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.audienceDescription': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.audienceSource': { skipValidation: boolean; }; 'arguments.audienceName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.automationId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.buildAudienceDefinitionID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.contactAttributeGroup': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.contactAttributeId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.contactAttributeName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.criteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dataExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dataTargetName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.formName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dateOffset': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dateOffsetUnit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.dateType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.eid': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.eventDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.eventDefinitionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.mid': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.resetHighWatermark': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.serializedObjectType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.transactionKeyDataExtension': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.transactionKeyEvent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'arguments.useHighWatermark': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; automationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; category: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; configurationArguments: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.applicationExtensionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.relationshipIdName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.relationshipName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.isPolymorphic': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactKey.referenceObjectName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.contactPersonType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.dataExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.evaluationCriteriaSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.eventDataConfig': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.eventDataConfig.objects': { skipValidation: boolean; }; 'configurationArguments.eventDataSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.objectAPIName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument.fields': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument.fields.ContactKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.passThroughArgument.fields.Email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.primaryObjectFilterCriteria': { skipValidation: boolean; }; 'configurationArguments.primaryObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.relatedObjectFilterCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.relatedObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.salesforceTriggerCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.unconfigured': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'configurationArguments.whoToInject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataExtensionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dataExtensionName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; disableDEDataLogging: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; eventDefinitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filterDefinitionTemplate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; iconUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; interactionCount: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isVisibleInPicker: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.attributeName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.automationType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.categoryId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.folderPath': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.guidId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.isPlatformObject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastRunInstance': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastRunTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSaveDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSavedBy.email': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSavedBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.lastSavedBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.memberId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.modifiedDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.notifications': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.processes': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.schedule': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.createdBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.iCalRecur': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.lastUpdatedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.scheduleState': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.scheduleStatus': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduleObject.timeZoneId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.scheduledTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.selectedCategoryId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.selectedCategoryId[]': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.status': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.automationData.updateInProgress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.criteriaDescription': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.customAttributeName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.formattedDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.formattedTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.icon': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.original_icon': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.isConfigured': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.runOnceScheduleMode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.scheduleFlowMode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.scheduleState': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys.0': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys.0.from': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.transactionKeys.0.to': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; mode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; publishedInteractionCount: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledDayOfWeek': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledWeek': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.endDateTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.endType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.frequency': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.interval': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.occurrences': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.recurrencePattern': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.scheduledDay': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.startDateTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.monday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.tuesday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.wednesday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.thursday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.friday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.saturday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schedule.sunday': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].dataType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].defaultValue': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].isDevicePreference': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].isNullable': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].isPrimaryKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].maxLength': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.fields[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.sendableCustomObjectField': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.sendableSubscriberField': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'schema.isPlatformObject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceApplicationExtensionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; entrySourceGroupConfigUrl: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__dataExtension_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__automation_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=Event.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/FileLocation.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: any; let createdNameField: any; let lastmodDateField: any; let lastmodNameField: any; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let locationTypeMapping: { 'Enhanced FTP Site Import Directory': number; 'External FTP Site': number; 'External SFTP Site': number; 'External FTPS Site': number; 'Salesforce Objects and Reports': number; Safehouse: number; 'Enhanced FTP Site Export Directory': number; 'Legacy Import Directory': number; 'Relative location under FTP Site': number; 'Amazon Simple Storage Service': number; 'Azure Blob Storage': number; 'Google Cloud Storage': number; }; let locationTypeMappingDeployable: { 'External SFTP Site': string; 'Amazon Simple Storage Service': string; 'Azure Blob Storage': string; 'Google Cloud Storage': string; }; let locationTypeIdMappingDeployable: { 2: string; 13: string; 15: string; 16: string; }; namespace fields { namespace id { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace locationTypeId { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace locationType { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace locationUrl { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace name { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace customerKey { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace description { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace relPath { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace awsFileTransferLocation { let skipValidation: boolean; } namespace azureFileTransferLocation { let skipValidation_1: boolean; export { skipValidation_1 as skipValidation }; } namespace gcpFileTransferLocation { let skipValidation_2: boolean; export { skipValidation_2 as skipValidation }; } namespace sFtpFileTransferLocation { let skipValidation_3: boolean; export { skipValidation_3 as skipValidation }; } namespace c__locationType { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } } } export default _default; //# sourceMappingURL=FileLocation.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/FileTransfer.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: {}; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace createdDate { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace customerKey { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace description { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace fileSpec { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace fileTransferLocationId { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace id { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace isCompressed { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace isEncrypted { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace isFileSpecLocalized { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace isPgp { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace isUpload { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace maxFileAge { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace maxFileAgeScheduleOffset { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace maxImportFrequency { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace modifiedDate { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } namespace name { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } namespace publicKeyManagementId { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } namespace r__fileLocation_name { let skipValidation: boolean; } } } export default _default; //# sourceMappingURL=FileTransfer.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Filter.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataFilter: string[]; let dataExtension: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderType: string; let folderIdField: string; namespace filter { let statusId: number; } let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { export namespace categoryId { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } export namespace createdDate { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } export namespace customerKey { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } export namespace CustomerKey { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } export namespace description { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } export namespace Description { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } export namespace destinationObjectId { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } export namespace DestinationObjectID { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } export namespace destinationTypeId { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } export namespace DestinationTypeID { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } export namespace filterActivityId { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } export namespace filterDefinitionId { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } export namespace FilterDefinitionID { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } export namespace modifiedDate { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } export namespace name { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } export namespace Name { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } export namespace sourceObjectId { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } export namespace SourceObjectID { let isCreateable_17: boolean; export { isCreateable_17 as isCreateable }; let isUpdateable_17: boolean; export { isUpdateable_17 as isUpdateable }; let retrieving_17: boolean; export { retrieving_17 as retrieving }; let template_17: boolean; export { template_17 as template }; } export namespace sourceTypeId { let isCreateable_18: boolean; export { isCreateable_18 as isCreateable }; let isUpdateable_18: boolean; export { isUpdateable_18 as isUpdateable }; let retrieving_18: boolean; export { retrieving_18 as retrieving }; let template_18: boolean; export { template_18 as template }; } export namespace SourceTypeID { let isCreateable_19: boolean; export { isCreateable_19 as isCreateable }; let isUpdateable_19: boolean; export { isUpdateable_19 as isUpdateable }; let retrieving_19: boolean; export { retrieving_19 as retrieving }; let template_19: boolean; export { template_19 as template }; } export namespace filterDefinitionSourceTypeId { let isCreateable_20: boolean; export { isCreateable_20 as isCreateable }; let isUpdateable_20: boolean; export { isUpdateable_20 as isUpdateable }; let retrieving_20: boolean; export { retrieving_20 as retrieving }; let template_20: boolean; export { template_20 as template }; } export namespace statusId_1 { let isCreateable_21: boolean; export { isCreateable_21 as isCreateable }; let isUpdateable_21: boolean; export { isUpdateable_21 as isUpdateable }; let retrieving_21: boolean; export { retrieving_21 as retrieving }; let template_21: boolean; export { template_21 as template }; } export { statusId_1 as statusId }; export namespace resultDEName { let isCreateable_22: boolean; export { isCreateable_22 as isCreateable }; let isUpdateable_22: boolean; export { isUpdateable_22 as isUpdateable }; let retrieving_22: boolean; export { retrieving_22 as retrieving }; let template_22: boolean; export { template_22 as template }; } export namespace resultDEKey { let isCreateable_23: boolean; export { isCreateable_23 as isCreateable }; let isUpdateable_23: boolean; export { isUpdateable_23 as isUpdateable }; let retrieving_23: boolean; export { retrieving_23 as retrieving }; let template_23: boolean; export { template_23 as template }; } export namespace resultDEDescription { let isCreateable_24: boolean; export { isCreateable_24 as isCreateable }; let isUpdateable_24: boolean; export { isUpdateable_24 as isUpdateable }; let retrieving_24: boolean; export { retrieving_24 as retrieving }; let template_24: boolean; export { template_24 as template }; } export namespace r__folder_Path { let isCreateable_25: boolean; export { isCreateable_25 as isCreateable }; let isUpdateable_25: boolean; export { isUpdateable_25 as isUpdateable }; let retrieving_25: boolean; export { retrieving_25 as retrieving }; let template_25: boolean; export { template_25 as template }; } export namespace r__dataFilter_key { let isCreateable_26: boolean; export { isCreateable_26 as isCreateable }; let isUpdateable_26: boolean; export { isUpdateable_26 as isUpdateable }; let retrieving_26: boolean; export { retrieving_26 as retrieving }; let template_26: boolean; export { template_26 as template }; } export namespace r__source_dataExtension_key { let isCreateable_27: boolean; export { isCreateable_27 as isCreateable }; let isUpdateable_27: boolean; export { isUpdateable_27 as isUpdateable }; let retrieving_27: boolean; export { retrieving_27 as retrieving }; let template_27: boolean; export { template_27 as template }; } export namespace r__destination_dataExtension_key { let isCreateable_28: boolean; export { isCreateable_28 as isCreateable }; let isUpdateable_28: boolean; export { isUpdateable_28 as isUpdateable }; let retrieving_28: boolean; export { retrieving_28 as retrieving }; let template_28: boolean; export { template_28 as template }; } } } export default _default; //# sourceMappingURL=Filter.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/FilterDefinition.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keyField: string; let nameField: string; let folderType: string; let folderIdField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let restPageSize: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeName: string; namespace fields { namespace id { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace key { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace createdDate { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace createdBy { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace createdByName { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace lastUpdated { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace lastUpdatedBy { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace lastUpdatedByName { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace name { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace categoryId { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace description { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace filterDefinitionXml { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace derivedFromType { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace derivedFromObjectId { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace derivedFromObjectTypeName { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } namespace derivedFromObjectName { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } namespace isSendable { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } namespace r__source_dataExtension_key { let isCreateable_17: boolean; export { isCreateable_17 as isCreateable }; let isUpdateable_17: boolean; export { isUpdateable_17 as isUpdateable }; let retrieving_17: boolean; export { retrieving_17 as retrieving }; let template_17: boolean; export { template_17 as template }; } namespace c__filterDefinition { let skipValidation: boolean; } namespace r__folder_Path { let isCreateable_18: boolean; export { isCreateable_18 as isCreateable }; let isUpdateable_18: boolean; export { isUpdateable_18 as isUpdateable }; let retrieving_18: boolean; export { retrieving_18 as retrieving }; let template_18: boolean; export { template_18 as template }; } } } export default _default; //# sourceMappingURL=FilterDefinition.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/FilterDefinitionHidden.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keyField: string; let nameField: string; let folderType: string; let folderIdField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let restPageSize: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeName: string; namespace fields { namespace id { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace key { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace createdDate { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace createdBy { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace createdByName { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace lastUpdated { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace lastUpdatedBy { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace lastUpdatedByName { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace name { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace categoryId { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace description { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace filterDefinitionXml { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace derivedFromType { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace derivedFromObjectId { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace derivedFromObjectTypeName { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } namespace derivedFromObjectName { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } namespace isSendable { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } namespace r__source_dataExtension_key { let isCreateable_17: boolean; export { isCreateable_17 as isCreateable }; let isUpdateable_17: boolean; export { isUpdateable_17 as isUpdateable }; let retrieving_17: boolean; export { retrieving_17 as retrieving }; let template_17: boolean; export { template_17 as template }; } namespace c__filterDefinition { let skipValidation: boolean; } namespace r__folder_Path { let isCreateable_18: boolean; export { isCreateable_18 as isCreateable }; let isUpdateable_18: boolean; export { isUpdateable_18 as isUpdateable }; let retrieving_18: boolean; export { retrieving_18 as retrieving }; let template_18: boolean; export { template_18 as template }; } } } export default _default; //# sourceMappingURL=FilterDefinitionHidden.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Folder.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let subTypes: string[]; let deployFolderTypes: string[]; let deployFolderTypesEmailRest: string[]; let deployFolderTypesAssetRest: string[]; let deployFolderBlacklist: string[]; let folderTypesFromParent: string[]; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: boolean; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { $: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; '@_xsi:type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ContentType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; catType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsActive: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsEditable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; editable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AllowChildren: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; extendable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; objectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; parentCatId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; parentId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ParentFolder.Path': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; _generated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=Folder.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/ImportFile.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; let list: string[]; let mobileKeyword: string[]; } namespace destinationObjectTypeMapping { let unknown: number; let DataExtension: number; let List: number; let SMS: number; let Push: number; let WhatsApp: number; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let restConcurrentLimit: number; namespace subscriberImportTypeMapping { let DataExtension_1: number; export { DataExtension_1 as DataExtension }; export let Email: number; } let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace updateTypeMapping { let Add: number; let AddUpdate: number; let Overwrite: number; let Update: number; } namespace blankFileProcessingTypeMapping { let Fail: number; let Process: number; let Skip: number; } let fields: { allowErrors: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; blankFileProcessingType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; customerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dateFormatLocale: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; deleteFile: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; destinationObjectTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; encodingName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fieldMappingType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fieldMappings: { skipValidation: boolean; }; fileNamingPattern: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileSpec: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileTransferLocationTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; fileType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; filter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; hasColumnHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; importDefinitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isOrderedImport: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isSequential: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxFileAgeHours: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxFileAgeScheduleOffsetHours: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; maxImportFrequencyHours: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; }; notificationEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; otherDelimiter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sendEmailNotification: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; standardQuotedStrings: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; subscriberImportTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; updateTypeId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceCustomObjectId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sourceDataExtensionName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__dataAction: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'source.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'source.c__type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.c__type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'destination.r__list_PathName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'source.r__fileLocation_name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__subscriberImportType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__blankFileProcessing: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=ImportFile.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Journey.definition.d.ts ================================================ declare namespace _default { let folderType: string; let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let event: string[]; let dataExtension: string[]; let deliveryProfile: string[]; let list: string[]; let senderProfile: string[]; let sendClassification: string[]; let asset: string[]; let mobileMessage: string[]; let mobileKeyword: string[]; let mobileCode: string[]; } let folderIdField: string; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace priorityMapping { let High: number; let Medium: number; let Low: number; } let fields: { activities: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].outcomes': { skipValidation: boolean; }; 'activities[].arguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitEndDateAttributeDataBound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitForEventId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.executionMode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.startActivityKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.waitQueueId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.definitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.emailSubjectDataBound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.contactId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.contactKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.emailAddress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.sourceCustomObjectId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.sourceCustomObjectKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.fieldType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.eventData': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.obfuscationProperties': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.customObjectKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.definitionInstanceId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.filterResult': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.requestObjectId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityData': { skipValidation: boolean; }; 'activities[].arguments.objectMap': { skipValidation: boolean; }; 'activities[].configurationArguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isReconcilable': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isActivityBatchValidated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSendKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSendId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.campaigns': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.suppressionLists': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.autoAddSubscribers': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.autoUpdateSubscribers': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.bccEmail': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.categoryId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.ccEmail': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.created': { skipValidation: boolean; }; 'activities[].configurationArguments.triggeredSend.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.domainExclusions': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.dynamicEmailSubject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.emailSubject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.exclusionFilter': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isSalesforceTracking': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isMultipart': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isSendLogging': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isStoppedOnJobError': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.keyword': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.modified': { skipValidation: boolean; }; 'activities[].configurationArguments.triggeredSend.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.preHeader': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.replyToAddress': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.replyToDisplayName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.suppressTracking': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.triggeredSendStatus': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.throttleOpens': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.throttleCloses': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.throttleLimit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.isTrackingClicks': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.emailId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__triggeredSend_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.senderProfileId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.deliveryProfileId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__senderProfile_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.sendClassificationId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__deliveryProfile_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__sendClassification_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__list_PathName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.publicationListId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__list_PathName.publicationList': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__list_PathName.suppressionLists': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__dataExtension_key.domainExclusions': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.priority': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.c__priority': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__asset_name_readOnly': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.r__asset_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.triggeredSend.updateSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.applicationExtensionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.r__transactionalEmail_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.applicationExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isModified': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.isSimulation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.googleAnalyticsCampaignName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.useLLTS': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.fuelAgentRequested': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.r__triggeredSend_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitDuration': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitUnit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.specifiedTime': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.timeZone': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitEndDateAttributeExpression': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.specificDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.waitForEventKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.schemaVersionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].configurationArguments.criteria': { skipValidation: boolean; }; 'activities[].configurationArguments.eventDataConfig': { skipValidation: boolean; }; 'activities[].metaData': { skipValidation: boolean; }; 'activities[].schema': { skipValidation: boolean; }; 'activities[].arguments.activityData.updateContactFields[].r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityData.updateContactFields[].r__dataExtensionField_name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'activities[].arguments.activityData.updateContactFields[].field': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; categoryId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; channel: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'defaults.email': { skipValidation: boolean; }; 'defaults.mobileNumber': { skipValidation: boolean; }; 'defaults.properties.analyticsTracking.enabled': { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; 'defaults.properties': { skipValidation: boolean; }; 'defaults.properties.analyticsTracking.analyticsType': { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; 'defaults.properties.analyticsTracking.urlDomainsToTrack': { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; entryMode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; executionMode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; exits: { skipValidation: boolean; }; goals: { skipValidation: boolean; }; healthStats: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastPublishedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'metaData.templateId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; scheduledStatus: { isCreateable: any; isUpdateable: any; retrieving: any; template: any; }; stats: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; triggers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].description': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].type': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].outcomes': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.startActivityKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.dequeueReason': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.lastExecutedActivityKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.filterResult': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.serializedObjectType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.eventDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.eventDefinitionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.dataExtensionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.automationId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.r__event_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].arguments.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.eventDataConfig': { skipValidation: boolean; }; 'triggers[].configurationArguments.primaryObjectFilterCriteria': { skipValidation: boolean; }; 'triggers[].configurationArguments.relatedObjectFilterCriteria': { skipValidation: boolean; }; 'triggers[].configurationArguments.salesforceTriggerCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.objectApiName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.objectAPIName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.version': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.contactKey': { skipValidation: boolean; }; 'triggers[].configurationArguments.contactPersonType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.primaryObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.relatedObjectFilterSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.eventDataSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.evaluationCriteriaSummary': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.applicationExtensionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.passThroughArgument': { skipValidation: boolean; }; 'triggers[].configurationArguments.filterDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.criteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.schemaVersionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.whoToInject': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].configurationArguments.additionalObjectFilterCriteria': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.sourceInteractionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.entrySourceGroupConfigUrl': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.r__event_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.category': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.eventDefinitionId': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.eventDefinitionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.chainType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.configurationRequired': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.iconUrl': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.title': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'triggers[].metaData.scheduleState': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; version: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; workflowApiVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; campaigns: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; metaData: { skipValidation: boolean; }; notifiers: { skipValidation: boolean; }; tags: { skipValidation: boolean; }; r__folder_Path: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=Journey.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/List.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: any; let folderType: string; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let restPagination: any; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { 'AutomatedEmail.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutomatedEmail.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutomatedEmail.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Category: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ListClassification: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ListName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=List.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/MobileCode.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; endDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordLimit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordsUsed: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; code: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; codeType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isShortCode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordsUsedOther: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isGsmCharacterSetOnly: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isMms: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isStackIndependant: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; supportsConcatenation: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isClientOwned: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isOwner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dipSwitches: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sendableCountries: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sendableCountries[].countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sendableCountries[].vendor': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'sendableCountries[].fromNameSupported': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; countryCode: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; moEngineVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=MobileCode.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/MobileKeyword.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let mobileCode: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__codeKeyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__mobileCode_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; startDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; endDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'createdBy.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; dipSwitches: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isInherited: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; decodedId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; restriction: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; keywordType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; companyName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; responseMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; messages: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; code: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.code': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.endDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordLimit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsed': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.codeType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isShortCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsedOther': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isGsmCharacterSetOnly': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isMms': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isStackIndependant': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.supportsConcatenation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isClientOwned': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isOwner': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.dipSwitches': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.moEngineVersion': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=MobileKeyword.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/MobileMessage.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let mobileCode: string[]; let mobileKeyword: string[]; } let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: any; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { allowSingleOptin: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; audience: { skipValidation: boolean; }; 'audience[]': { skipValidation: boolean; }; campaigns: { skipValidation: boolean; }; 'campaigns[]': { skipValidation: boolean; }; r__mobileCode_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.code': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.codeType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.createdDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.dipSwitches': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.endDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isClientOwned': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isGsmCharacterSetOnly': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isMms': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isOwner': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isShortCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.isStackIndependant': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordLimit': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsed': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.keywordsUsedOther': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.lastUpdated': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.moEngineVersion': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[]': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[].countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[].vendor': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.sendableCountries[].fromNameSupported': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.startDate': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'code.supportsConcatenation': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; concatenateMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; currentEditStep: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; doubleOptinConfirmMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; doubleOptinInitialMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; doubleOptinValidResponses: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; duplicateOptInResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; expireHours: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; fromName: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; id: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; invalidMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; isCertified: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isDuplicationAllowed: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isExpireSet: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isFromNameCertificationAccepted: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isSentImmediately: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isSubscriberResponseToAnySubscriptionForShortCode: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isSuppressMt: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isTest: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; isTimeZoneBased: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'keyword.id': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.isInherited': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.keyword': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.keywordType': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'keyword.restriction': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; lastUpdated: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; messageObjectId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; messagesPerPeriod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; minutesPerPeriod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; moStartDate: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; moEndDate: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'moTimezone.name': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'moTimezone.offset': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.key': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.createdDate': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.createdBy': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.lastUpdated': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.lastUpdatedBy': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.name': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.description': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.startDate': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.iCalRecur': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.timeZone': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'mtRecurrence.timeZoneId': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; mtSendDate: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; nextJob: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; nextKeyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; numberMessagesPerPeriod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinErrorMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinInvalidAgeMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinMinimumAge: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; optinType: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; origin: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; outboundSendBehaviorFlag: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; outboundSendTypeFlag: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; periodType: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; programId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; publishedMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; responseMessage: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; sendMethod: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; smsTriggeredSendDefinitionId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; statistics: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.sent': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.delivered': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.undelivered': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'statistics.outbound.unknown': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; statusId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.keyword': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.restriction': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'subscriptionKeyword.isInherited': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.keyword': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.restriction': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'nextKeyword.isInherited': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; subscriberResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyCorrectResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyIncorrectResponseMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyResponsesAllowed: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyTooManyEntriesMessage: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; surveyType: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.description': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.icon': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.id': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.lastUpdated': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; 'template.name': { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; text: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; triggeredSendId: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; triggeredSendName: { isCreatable: boolean; isUpdatable: boolean; retrieving: boolean; template: boolean; }; type: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__campaign_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'r__campaign_key[]': { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=MobileMessage.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Query.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let folderType: string; namespace filter { let description: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; namespace targetUpdateTypeMapping { let Append: number; let Overwrite: number; let Update: number; } let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { export namespace categoryId { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } export namespace createdDate { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } export namespace description_1 { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } export { description_1 as description }; export namespace isFrozen { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } export namespace key { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } export namespace modifiedDate { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } export namespace name { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } export namespace queryDefinitionId { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } export namespace queryText { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } export namespace targetDescription { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } export namespace targetId { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } export namespace targetKey { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } export namespace targetName { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } export namespace targetUpdateTypeId { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } export namespace targetUpdateTypeName { let isCreateable_14: boolean; export { isCreateable_14 as isCreateable }; let isUpdateable_14: boolean; export { isUpdateable_14 as isUpdateable }; let retrieving_14: boolean; export { retrieving_14 as retrieving }; let template_14: boolean; export { template_14 as template }; } export namespace validatedQueryText { let isCreateable_15: boolean; export { isCreateable_15 as isCreateable }; let isUpdateable_15: boolean; export { isUpdateable_15 as isUpdateable }; let retrieving_15: boolean; export { retrieving_15 as retrieving }; let template_15: boolean; export { template_15 as template }; } export namespace r__dataExtension_key { let isCreateable_16: boolean; export { isCreateable_16 as isCreateable }; let isUpdateable_16: boolean; export { isUpdateable_16 as isUpdateable }; let retrieving_16: boolean; export { retrieving_16 as retrieving }; let template_16: boolean; export { template_16 as template }; } export namespace r__folder_Path { let skipValidation: boolean; } } } export default _default; //# sourceMappingURL=Query.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Role.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let deployBlacklist: string[]; let documentInOneFile: boolean; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace CreatedDate { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace CustomerKey { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace Description { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace ModifiedDate { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace Name { let isCreateable_4: any; export { isCreateable_4 as isCreateable }; let isUpdateable_4: any; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; } namespace ObjectID { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace PartnerKey { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace IsSystemDefined { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace PermissionSets { let retrieving_8: boolean; export { retrieving_8 as retrieving }; export let skipCache: boolean; export let skipValidation: boolean; } namespace c__notAssignable { let skipValidation_1: boolean; export { skipValidation_1 as skipValidation }; } } } export default _default; //# sourceMappingURL=Role.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Script.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: any; let folderType: string; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace categoryId { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace createdBy { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace createdDate { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace description { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace folderLocationText { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace key { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace modifiedBy { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace modifiedDate { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace name { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace script { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace ssjsActivityId { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace status { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } namespace statusId { let isCreateable_12: boolean; export { isCreateable_12 as isCreateable }; let isUpdateable_12: boolean; export { isUpdateable_12 as isUpdateable }; let retrieving_12: boolean; export { retrieving_12 as retrieving }; let template_12: boolean; export { template_12 as template }; } namespace parentCategoryId { let isCreateable_13: boolean; export { isCreateable_13 as isCreateable }; let isUpdateable_13: boolean; export { isUpdateable_13 as isUpdateable }; let retrieving_13: boolean; export { retrieving_13 as retrieving }; let template_13: boolean; export { template_13 as template }; } namespace r__folder_Path { let skipValidation: boolean; } } } export default _default; //# sourceMappingURL=Script.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/SendClassification.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let senderProfile: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keyField: string; let keyIsFixed: boolean; let maxKeyLength: number; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace sendClassificationTypeMapping { let Commercial: string; let Transactional: string; } let fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ArchiveEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DeliveryProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DeliveryProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'DeliveryProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; HonorPublicationListOptOutsForTransactionalSends: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendClassificationType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SenderProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SenderProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SenderProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SendPriority: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; c__classification: { skipValidation: boolean; }; r__deliveryProfile_key: { skipValidation: boolean; }; r__senderProfile_key: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=SendClassification.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/SenderProfile.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let domainVerification: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keyField: string; let keyIsFixed: boolean; let maxKeyLength: number; let nameField: string; let createdDateField: string; let createdNameField: string; let lastmodDateField: string; let lastmodNameField: string; let restPagination: boolean; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.CreatedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ModifiedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: any; template: boolean; }; modifiedBy: { isCreateable: boolean; isUpdateable: boolean; retrieving: any; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AutoForwardToEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AutoForwardToName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutoForwardTriggeredSend.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AutoReply: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'AutoReplyTriggeredSend.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodLength: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DataRetentionPeriodUnitOfMeasure: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DirectForward: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FallbackFromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; FromName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'ReplyManagementRuleSet.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'RMMRuleCollection.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ReplyToAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ReplyToDisplayName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SenderHeaderEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; SenderHeaderName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; UseDefaultRMMRules: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=SenderProfile.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/TransactionalEmail.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let asset: string[]; let dataExtension: string[]; let list: string[]; let journey: string[]; let sendClassification: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; classification: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.customerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.dataExtension': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.r__dataExtension_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.list': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.r__list_PathName': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.autoAddSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.updateSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.trackLinks': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.cc': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.bcc': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.createJourney': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; journey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'journey.interactionKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__asset_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__journey_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__sendClassification_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=TransactionalEmail.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/TransactionalMessage.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: any[]; let dependencyGraph: any; let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace name { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace definitionKey { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace description { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace requestId { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace definitionId { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace status { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace createdDate { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace modifiedDate { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } } } export default _default; //# sourceMappingURL=TransactionalMessage.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/TransactionalPush.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let asset: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.customerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; r__asset_key: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.badge': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.sound': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.customKeys': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.customKeys[].value': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'options.customKeys[].key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; applicationId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=TransactionalPush.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/TransactionalSMS.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let mobileKeyword: string[]; let mobileCode: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: boolean; let restPageSize: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; requestId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; definitionId: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; status: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; createdDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; modifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'content.message': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.shortCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.countryCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.autoAddSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.updateSubscriber': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.keyword': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'subscriptions.r__mobileKeyword_key': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; }; } export default _default; //# sourceMappingURL=TransactionalSMS.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/TriggeredSend.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let asset: string[]; let list: string[]; let sendClassification: string[]; let senderProfile: string[]; } namespace filter { let r__folder_Path: string[]; } let folderType: string; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: any; let restPagination: any; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace priorityMapping { let High: number; let Medium: number; let Low: number; } let fields: { AllowedSlots: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; AutoAddSubscribers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; AutoUpdateSubscribers: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BatchInterval: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; BccEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CategoryID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CCEmail: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DataSchemas: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'DeliveryProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Description: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DisableOnEmailBuildError: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DomainType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; DynamicEmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Email.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; EmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ExclusionFilter: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ExclusionListCollection: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'FooterContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FooterSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FromName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'HeaderContentArea.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; HeaderSalutationSource: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; InteractionObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsAlwaysOn: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsMultipart: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsPlatformObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsSendLogging: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; IsWrapped: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; KeepExistingEmailSubject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Keyword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'List.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'List.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'List.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NewSlotTrigger: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptionFlags: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptionFlagsUpdateMask: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptionVersion: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PreHeader: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Priority: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateDomain.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateDomain.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateIP.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'PrivateIP.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; RefreshContent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ReplyToDisplayName: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; RequestExpirationSeconds: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SendClassification.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.CustomerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'SenderProfile.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendLimit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendSourceCustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendSourceDataExtension: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowClose: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowDelete: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SendWindowOpen: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SourceAddressType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SuppressTracking: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TestEmailAddr: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendClass: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendStatus: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendSubClass: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendType: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; TriggeredSendVersionID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; r__asset_name_readOnly: { skipValidation: boolean; }; r__asset_key: { skipValidation: boolean; }; r__email_name: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; r__list_PathName: { skipValidation: boolean; }; c__priority: { skipValidation: boolean; }; r__sendClassification_key: { skipValidation: boolean; }; r__senderProfile_key: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=TriggeredSend.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/TriggeredSendSummary.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let triggeredSend: string[]; } let filter: {}; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let folderIdField: string; let createdDateField: any; let createdNameField: any; let lastmodDateField: any; let lastmodNameField: any; let restPagination: any; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; let fields: { Bounces: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Clicks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Conversions: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FTAFEmailsSent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FTAFOptIns: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; FTAFRequests: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; InProcess: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NotSentDueToError: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NotSentDueToOptOut: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; NotSentDueToUndeliverable: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; ObjectID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Opens: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; OptOuts: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Queued: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; Sent: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; SurveyResponses: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; UniqueClicks: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; UniqueConversions: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; UniqueOpens: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; templating: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; /** Listed in the type documentation but not retrievable */ templating: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; /** Listed in the type documentation but not retrievable */ templating: boolean; }; r__triggeredSend_name: { skipValidation: boolean; }; r__triggeredSend_key: { skipValidation: boolean; }; r__folder_Path: { skipValidation: boolean; }; }; } export default _default; //# sourceMappingURL=TriggeredSendSummary.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/User.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; let dependencyGraph: {}; let folderType: any; let hasExtended: boolean; let idField: string; let keepId: boolean; let keyIsFixed: boolean; let keyField: string; let nameField: string; let createdDateField: string; let createdNameField: any; let lastmodDateField: string; let lastmodNameField: string; let maxKeyLength: number; let type: string; let soapType: string; let typeDescription: string; let typeName: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let documentInOneFile: boolean; let stringifyFieldsBeforeTemplate: string[]; let fields: { AccountUserID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ActiveFlag: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; AssociatedBusinessUnits: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; BusinessUnit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ChallengeAnswer: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ChallengePhrase: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.ModifiedBy': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Client.PartnerClientKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CorrelationID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CreatedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; CustomerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultApplication: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultBusinessUnit: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; DefaultBusinessUnitObject: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Delete: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Email: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsAPIUser: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; IsLocked: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'LanguageLocale.LocaleCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; LastSuccessfulLogin: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Locale.LocaleCode': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Locale.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Locale.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ModifiedDate: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; MustChangePassword: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Name: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; NotificationEmailAddress: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; ObjectID: { isCreateable: any; isUpdateable: any; retrieving: boolean; template: any; }; ObjectState: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Owner: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerKey: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; PartnerProperties: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Password: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Roles: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'Roles.Role': { skipValidation: boolean; }; 'Roles.Role[].Client': { skipValidation: boolean; }; SsoIdentities: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SsoIdentities.SsoIdentity': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SsoIdentities.SsoIdentity[].IsActive': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'SsoIdentities.SsoIdentity[].FederatedID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.ID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.Name': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.ObjectID': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'TimeZone.PartnerKey': { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; Unlock: { skipValidation: boolean; isCreateable: boolean; isUpdateable: boolean; template: boolean; }; UserID: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; UserPermissions: { isCreateable: boolean; isUpdateable: boolean; retrieving: boolean; template: boolean; }; 'UserPermissions.PartnerKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.ID': { skipValidation: boolean; }; 'UserPermissions.ObjectID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Name': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Description': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions.Delete': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].PartnerKey': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].ID': { skipValidation: boolean; }; 'UserPermissions[].ObjectID': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Name': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Value': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Description': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; 'UserPermissions[].Delete': { isCreateable: any; isUpdateable: any; retrieving: boolean; template: boolean; }; c__type: { isCreateable: boolean; isUpdateable: boolean; retrieve: any; template: boolean; }; c__AssociatedBusinessUnits: { skipValidation: boolean; }; c__RoleNamesGlobal: { skipValidation: boolean; }; c__LocaleCode: { skipValidation: boolean; }; c__TimeZoneName: { skipValidation: boolean; }; c__AccountUserID: { isCreateable: boolean; isUpdateable: boolean; retrieve: any; template: boolean; }; c__IsLocked_readOnly: { isCreateable: boolean; isUpdateable: boolean; retrieve: any; template: boolean; }; }; } export default _default; //# sourceMappingURL=User.definition.d.ts.map ================================================ FILE: @types/lib/metadataTypes/definitions/Verification.definition.d.ts ================================================ declare namespace _default { let bodyIteratorField: string; let dependencies: string[]; namespace dependencyGraph { let dataExtension: string[]; } let hasExtended: boolean; let idField: string; let keyIsFixed: boolean; let keyField: string; let createdDateField: any; let createdNameField: string; let lastmodDateField: any; let lastmodNameField: any; let nameField: string; let restPagination: boolean; let maxKeyLength: number; let type: string; let typeDescription: string; let typeRetrieveByDefault: boolean; let typeCdpByDefault: boolean; let typeName: string; namespace fields { namespace createdBy { let isCreateable: boolean; let isUpdateable: boolean; let retrieving: boolean; let template: boolean; } namespace dataVerificationDefinitionId { let isCreateable_1: boolean; export { isCreateable_1 as isCreateable }; let isUpdateable_1: boolean; export { isUpdateable_1 as isUpdateable }; let retrieving_1: boolean; export { retrieving_1 as retrieving }; let template_1: boolean; export { template_1 as template }; } namespace notificationEmailAddress { let isCreateable_2: boolean; export { isCreateable_2 as isCreateable }; let isUpdateable_2: boolean; export { isUpdateable_2 as isUpdateable }; let retrieving_2: boolean; export { retrieving_2 as retrieving }; let template_2: boolean; export { template_2 as template }; } namespace notificationEmailMessage { let isCreateable_3: boolean; export { isCreateable_3 as isCreateable }; let isUpdateable_3: boolean; export { isUpdateable_3 as isUpdateable }; let retrieving_3: boolean; export { retrieving_3 as retrieving }; let template_3: boolean; export { template_3 as template }; } namespace shouldEmailOnFailure { let isCreateable_4: boolean; export { isCreateable_4 as isCreateable }; let isUpdateable_4: boolean; export { isUpdateable_4 as isUpdateable }; let retrieving_4: boolean; export { retrieving_4 as retrieving }; let template_4: boolean; export { template_4 as template }; } namespace shouldStopOnFailure { let isCreateable_5: boolean; export { isCreateable_5 as isCreateable }; let isUpdateable_5: boolean; export { isUpdateable_5 as isUpdateable }; let retrieving_5: boolean; export { retrieving_5 as retrieving }; let template_5: boolean; export { template_5 as template }; } namespace targetObjectId { let isCreateable_6: boolean; export { isCreateable_6 as isCreateable }; let isUpdateable_6: boolean; export { isUpdateable_6 as isUpdateable }; let retrieving_6: boolean; export { retrieving_6 as retrieving }; let template_6: boolean; export { template_6 as template }; } namespace value1 { let isCreateable_7: boolean; export { isCreateable_7 as isCreateable }; let isUpdateable_7: boolean; export { isUpdateable_7 as isUpdateable }; let retrieving_7: boolean; export { retrieving_7 as retrieving }; let template_7: boolean; export { template_7 as template }; } namespace value2 { let isCreateable_8: boolean; export { isCreateable_8 as isCreateable }; let isUpdateable_8: boolean; export { isUpdateable_8 as isUpdateable }; let retrieving_8: boolean; export { retrieving_8 as retrieving }; let template_8: boolean; export { template_8 as template }; } namespace verificationType { let isCreateable_9: boolean; export { isCreateable_9 as isCreateable }; let isUpdateable_9: boolean; export { isUpdateable_9 as isUpdateable }; let retrieving_9: boolean; export { retrieving_9 as retrieving }; let template_9: boolean; export { template_9 as template }; } namespace r__dataExtension_key { let isCreateable_10: boolean; export { isCreateable_10 as isCreateable }; let isUpdateable_10: boolean; export { isUpdateable_10 as isUpdateable }; let retrieving_10: boolean; export { retrieving_10 as retrieving }; let template_10: boolean; export { template_10 as template }; } namespace c__automation_step { let isCreateable_11: boolean; export { isCreateable_11 as isCreateable }; let isUpdateable_11: boolean; export { isUpdateable_11 as isUpdateable }; let retrieving_11: boolean; export { retrieving_11 as retrieving }; let template_11: boolean; export { template_11 as template }; } } } export default _default; //# sourceMappingURL=Verification.definition.d.ts.map ================================================ FILE: @types/lib/retrieveChangelog.d.ts ================================================ #!/usr/bin/env node export {}; //# sourceMappingURL=retrieveChangelog.d.ts.map ================================================ FILE: @types/lib/util/auth.d.ts ================================================ export default Auth; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; declare namespace Auth { /** * For each business unit, set up base credentials to be used. * * @param {AuthObject} authObject details for * @param {string} credential of the instance * @returns {Promise.<void>} - */ function saveCredential(authObject: AuthObject, credential: string): Promise<void>; /** * Returns an SDK instance to be used for API calls * * @param {BuObject} buObject information about current context * @returns {SDK} auth object */ function getSDK(buObject: BuObject): SDK; /** * helper to clear all auth sessions * * @returns {void} */ function clearSessions(): void; } import SDK from 'sfmc-sdk'; //# sourceMappingURL=auth.d.ts.map ================================================ FILE: @types/lib/util/businessUnit.d.ts ================================================ export default BusinessUnit; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; declare namespace BusinessUnit { function refreshBUProperties(properties: Mcdevrc, credentialsName: string): Promise<boolean>; } //# sourceMappingURL=businessUnit.d.ts.map ================================================ FILE: @types/lib/util/cache.d.ts ================================================ declare namespace _default { function initCache(buObject: BuObject): void; function getCache(): MultiMetadataTypeMap; function clearCache(mid?: number, type?: string): void; function getByKey(type: string, key: string): MetadataTypeItem; function setMetadata(type: string, metadataMap: MetadataTypeMap): void; function mergeMetadata(type: string, metadataMap: MetadataTypeMap, overrideMID?: number): void; /** * standardized method for getting data from cache. * * @param {string} metadataType metadata type ie. query * @param {string|number|boolean} searchValue unique identifier of metadata being looked for * @param {string} searchField field name (key in object) which contains the unique identifer * @param {string} returnField field which should be returned * @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID) * @param {boolean} caseInsensitive optional; if true, search is case insensitive * @returns {string} value of specified field. Error is thrown if not found */ function searchForField(metadataType: string, searchValue: string | number | boolean, searchField: string, returnField: string, overrideMID?: number, caseInsensitive?: boolean): string; /** * helper for setFolderId * * @param {string} r__folder_Path folder path value * @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID) * @param {boolean} allowOtherBu getting folder from other BU; FALSE for folder parent search * @returns {number} folder ID */ function getFolderId(r__folder_Path: string, overrideMID?: number, allowOtherBu?: boolean): number; /** * helper for setFolderId * * @param {string} r__folder_Path folder path value * @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID) * @param {boolean} allowOtherBu getting folder from other BU; FALSE for folder parent search * @returns {object} folder item */ function getFolderByPath(r__folder_Path: string, overrideMID?: number, allowOtherBu?: boolean): object; /** * standardized method for getting data from cache - adapted for special case of lists * ! keeping this in util/cache.js rather than in metadataTypes/List.js to avoid potential circular dependencies * * @param {string} searchValue unique identifier of metadata being looked for * @param {'ObjectID'|'ID'|'CustomerKey'} searchField ObjectID:string(uuid), ID:numeric, CustomerKey:string(name + folder ID) * @returns {string} unique folderPath/ListName combo of list */ function getListPathName(searchValue: string, searchField: "ObjectID" | "ID" | "CustomerKey"): string; /** * standardized method for getting data from cache - adapted for special case of lists * ! keeping this in util/cache.js rather than in metadataTypes/List.js to avoid potential circular dependencies * * @param {string} listPathName folderPath/ListName combo of list * @param {'ObjectID'|'ID'|'CustomerKey'|'ListName'} returnField ObjectID:string(uuid), ID:numeric, CustomerKey:string(name + folder ID) * @returns {string} unique ObjectId of list */ function getListObjectId(listPathName: string, returnField: "ObjectID" | "ID" | "CustomerKey" | "ListName"): string; } export default _default; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type ListItem = import("../../types/mcdev.d.js").ListItem; export type ListMap = import("../../types/mcdev.d.js").ListMap; //# sourceMappingURL=cache.d.ts.map ================================================ FILE: @types/lib/util/cli.d.ts ================================================ export default Cli; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type ExplainType = import("../../types/mcdev.d.js").ExplainType; declare namespace Cli { /** * used when initially setting up a project. * loads default config and adds first credential * * @returns {Promise.<string | boolean>} success of init */ function initMcdevConfig(): Promise<string | boolean>; /** * Extends template file for properties.json * * @param {Mcdevrc} properties config file's json * @returns {Promise.<boolean | string>} status */ function addExtraCredential(properties: Mcdevrc): Promise<boolean | string>; /** * * @param {string[]} dependentTypes types that depent on type * @returns {Promise.<boolean>} true if user wants to continue with retrieve */ function postFixKeysReretrieve(dependentTypes: string[]): Promise<boolean>; /** * helper that logs to cli which credentials are already existing in our config file * * @param {Mcdevrc} properties config file's json * @returns {void} */ function logExistingCredentials(properties: Mcdevrc): void; /** * Extends template file for properties.json * update credentials * * @param {Mcdevrc} properties config file's json * @param {string} credName name of credential that needs updating * @param {boolean} [refreshBUs] if this was triggered by mcdev join, do not refresh BUs * @returns {Promise.<string | boolean>} success of update */ function updateCredential(properties: Mcdevrc, credName: string, refreshBUs?: boolean): Promise<string | boolean>; /** * Returns Object with parameters required for accessing API * * @param {Mcdevrc} properties object of all configuration including credentials * @param {string} target code of BU to use * @param {boolean | string} [isCredentialOnly] true:don't ask for BU | string: name of BU * @param {boolean} [allowAll] Offer ALL as option in BU selection * @returns {Promise.<BuObject>} credential to be used for Business Unit */ function getCredentialObject(properties: Mcdevrc, target: string, isCredentialOnly?: boolean | string, allowAll?: boolean): Promise<BuObject>; /** * helps select the right credential in case of bad initial input * * @param {Mcdevrc} properties config file's json * @param {string} [credential] name of valid credential * @param {boolean} [isCredentialOnly] don't ask for BU if true * @param {boolean} [allowAll] Offer ALL as option in BU selection * @returns {Promise.<{businessUnit:string, credential:string}>} selected credential/BU combo */ function _selectBU(properties: Mcdevrc, credential?: string, isCredentialOnly?: boolean, allowAll?: boolean): Promise<{ businessUnit: string; credential: string; }>; /** * helper around _askCredentials * * @param {Mcdevrc} properties from config file * @param {string} [credName] name of credential that needs updating * @param {boolean} [refreshBUs] if this was triggered by mcdev join, do not refresh BUs * @returns {Promise.<boolean | string>} success of refresh or credential name */ function _setCredential(properties: Mcdevrc, credName?: string, refreshBUs?: boolean): Promise<boolean | string>; /** * helper for {@link Cli.addExtraCredential} * * @param {Mcdevrc} properties from config file * @param {string} [credName] name of credential that needs updating * @returns {Promise.<object>} credential info */ function _askCredentials(properties: Mcdevrc, credName?: string): Promise<object>; /** * allows updating the metadata types that shall be retrieved * * @param {Mcdevrc} properties config file's json * @param {string[]} [setTypesArr] skip user prompt and overwrite with this list if given * @returns {Promise.<void>} - */ function selectTypes(properties: Mcdevrc, setTypesArr?: string[]): Promise<void>; /** * shows metadata type descriptions * * @returns {ExplainType[]} list of supported types with their apiNames */ function explainTypes(): ExplainType[]; } //# sourceMappingURL=cli.d.ts.map ================================================ FILE: @types/lib/util/config.d.ts ================================================ export default config; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; declare namespace config { let properties: any; /** * loads central properties from config file * * @param {boolean} [silent] omit throwing errors and print messages; assuming not silent if not set * @param {boolean} [isInit] don't tell the user to run init * @returns {Promise.<Mcdevrc>} central properties object */ function getProperties(silent?: boolean, isInit?: boolean): Promise<Mcdevrc>; /** * check if the config file is correctly formatted and has values * * @param {Mcdevrc} properties javascript object in .mcdevrc.json * @param {boolean} [silent] set to true for internal use w/o cli output * @returns {Promise.<boolean | string[]>} file structure ok OR list of fields to be fixed */ function checkProperties(properties: Mcdevrc, silent?: boolean): Promise<boolean | string[]>; /** * defines how the properties.json should look like * used for creating a template and for checking if variables are set * * @returns {Promise.<Mcdevrc>} default properties */ function getDefaultProperties(): Promise<Mcdevrc>; } //# sourceMappingURL=config.d.ts.map ================================================ FILE: @types/lib/util/devops.d.ts ================================================ export default DevOps; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type BuildFilter = import("../../types/mcdev.d.js").BuildFilter; declare namespace DevOps { /** * Extracts the delta between a commit and the current state for deployment. * Interactive commit selection if no commits are passed. * * @param {Mcdevrc} properties central properties object * @param {string} [range] git commit range * @param {boolean} [saveToDeployDir] if true, copy metadata changes into deploy directory * @param {string} [filterPathsCSV] filter file paths that start with any specified path (comma separated) * @param {number} [commitHistory] cli option to override default commit history value in config * @returns {Promise.<DeltaPkgItem[]>} - */ function getDeltaList(properties: Mcdevrc, range?: string, saveToDeployDir?: boolean, filterPathsCSV?: string, commitHistory?: number): Promise<DeltaPkgItem[]>; /** * wrapper around DevOps.getDeltaList, Builder.buildTemplate and M * * @param {Mcdevrc} properties project config file * @param {string} range git commit range * @param {DeltaPkgItem[]} [diffArr] instead of running git diff the method can also get a list of files to process * @param {number} [commitHistory] cli option to override default commit history value in config * @returns {Promise.<DeltaPkgItem[]>} - */ function buildDeltaDefinitions(properties: Mcdevrc, range: string, diffArr?: DeltaPkgItem[], commitHistory?: number): Promise<DeltaPkgItem[]>; /** * create markdown file for deployment listing * * @param {string} directory - * @param {string} filterPathsCSV - * @param {object} jsonReport - * @returns {void} */ function document(directory: string, filterPathsCSV: string, jsonReport: object): void; /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {Mcdevrc} properties central properties object * @param {BuObject} buObject references credentials * @param {string} metadataType metadata type to build * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ function getFilesToCommit(properties: Mcdevrc, buObject: BuObject, metadataType: string, keyArr: string[]): Promise<string[]>; /** * helper for {@link DevOps.buildDeltaDefinitions} * * @param {DeltaPkgItem[]} delta git delta * @param {string} sourceMarket market for the source BU * @param {Mcdevrc} properties mcdev config * @param {string} targetMlName marketList used to build for the target BU */ function _generateDeleteInstructions(delta: DeltaPkgItem[], sourceMarket: string, properties: Mcdevrc, targetMlName: string): void; } //# sourceMappingURL=devops.d.ts.map ================================================ FILE: @types/lib/util/file.d.ts ================================================ export default FileFs; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; declare const FileFs: typeof fs & { prettierConfig: any; prettierConfigFileType: any; /** * copies a file from one path to another * * @param {string} from - full filepath including name of existing file * @param {string} to - full filepath including name where file should go * @returns {Promise.<{status:'ok'|'skipped'|'failed', statusMessage:string, file:string}>} - results object */ copyFileSimple(from: string, to: string): Promise<{ status: "ok" | "skipped" | "failed"; statusMessage: string; file: string; }>; /** * makes sure Windows accepts path names * * @param {string} path - filename or path * @returns {string} - corrected string */ filterIllegalPathChars(path: string): string; /** * makes sure Windows accepts file names * * @param {string} filename - filename or path * @returns {string} - corrected string */ filterIllegalFilenames(filename: string): string; /** * makes sure Windows accepts file names * * @param {string} filename - filename or path * @returns {string} - corrected string */ reverseFilterIllegalFilenames(filename: string): string; /** * Takes various types of path strings and formats into a platform specific path * * @param {string|string[]} denormalizedPath directory the file will be written to * @returns {string} Path strings */ normalizePath: (denormalizedPath: string | string[]) => string; /** * Saves json content to a file in the local file system. Will create the parent directory if it does not exist * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {object} content filecontent * @returns {Promise} Promise */ writeJSONToFile: (directory: string | string[], filename: string, content: object) => Promise<any>; /** * Saves beautified files in the local file system. Will create the parent directory if it does not exist * ! Important: run 'await File.initPrettier()' in your MetadataType.retrieve() once before hitting this * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without suffix * @param {string} filetype filetype ie. JSON or SSJS * @param {string} content filecontent * @param {TemplateMap} [templateVariables] templating variables to be replaced in the metadata * @returns {Promise.<boolean>} Promise */ writePrettyToFile: (directory: string | string[], filename: string, filetype: string, content: string, templateVariables?: TemplateMap) => Promise<boolean>; /** * helper that applies beautyAmp onto given stringified content; strongly typed for strings only * * @param {string} content code * @param {boolean} [formatHTML] applies formatting to html and ampscript if true * @returns {Promise.<string>} formatted code */ _beautify_beautyAmp_beautify: (content: string, formatHTML?: boolean) => Promise<string>; /** * helper for {@link File.writePrettyToFile}, applying beautyAmp onto given stringified content * * @param {string} content filecontent * @param {boolean} formatHTML should we format HTML or not via prettier included in beautyAmp * @returns {Promise.<string>} original string on error; formatted string on success */ beautify_beautyAmp: (content: string, formatHTML?: boolean) => Promise<string>; /** * helper for {@link File.writePrettyToFile}, applying prettier onto given stringified content * ! Important: run 'await File.initPrettier()' in your MetadataType.retrieve() once before hitting this * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without suffix * @param {string} filetype filetype ie. JSON or SSJS * @param {string} content filecontent * @returns {Promise.<string>} original string on error; formatted string on success */ _beautify_prettier: (directory: string | string[], filename: string, filetype: string, content: string) => Promise<string>; /** * Saves text content to a file in the local file system. Will create the parent directory if it does not exist * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {string} filetype filetype suffix * @param {string} content filecontent * @param {object} [encoding] added for certain file types (like images) * @returns {Promise.<boolean>} Promise */ writeToFile: (directory: string | string[], filename: string, filetype: string, content: string, encoding?: object) => Promise<boolean>; /** * Saves json content to a file in the local file system. Will create the parent directory if it does not exist * * @param {string | string[]} directory directory where the file is stored * @param {string} filename name of the file without '.json' ending * @param {boolean} cleanPath filters illegal chars if true * @returns {Promise.<object | object | void>} Promise or JSON object depending on if async or not; void on error */ readJSONFile: (directory: string | string[], filename: string, cleanPath: boolean) => Promise<object | object | void>; /** * reads file from local file system. * * @param {string | string[]} directory directory where the file is stored * @param {string} filename name of the file without '.json' ending * @param {string} filetype filetype suffix * @param {string} [encoding] read file with encoding (defaults to utf-8) * @returns {Promise.<string>} file contents; void on error */ readFilteredFilename: (directory: string | string[], filename: string, filetype: string, encoding?: string) => Promise<string>; /** * reads directories to a specific depth returning an array * of file paths to be iterated over * * @example ['deploy/mcdev/bu1'] * @param {string} directory directory to checkin * @param {number} depth how many levels to check (1 base) * @param {boolean} [includeStem] include the parent directory in the response * @param {number} [_stemLength] set recursively for subfolders. do not set manually! * @returns {Promise.<string[]>} array of fully defined file paths */ readDirectories: (directory: string, depth: number, includeStem?: boolean, _stemLength?: number) => Promise<string[]>; /** * reads directories to a specific depth returning an array * of file paths to be iterated over using sync api (required in constructors) * TODO - merge with readDirectories. so far the logic is really different * * @example ['deploy/mcdev/bu1'] * @param {string} directory directory to checkin * @param {number} [depth] how many levels to check (1 base) * @param {boolean} [includeStem] include the parent directory in the response * @param {number} [_stemLength] set recursively for subfolders. do not set manually! * @returns {string[] | void} array of fully defined file paths; void on error */ readDirectoriesSync: (directory: string, depth?: number, includeStem?: boolean, _stemLength?: number) => string[] | void; /** * helper that splits the config back into auth & config parts to save them separately * * @param {Mcdevrc} properties central properties object * @returns {Promise.<void>} - */ saveConfigFile(properties: Mcdevrc): Promise<void>; /** * Initalises Prettier formatting lib async. * * @param {string} [filetype] filetype ie. JSON or SSJS * @returns {Promise.<boolean>} success of config load */ initPrettier(filetype?: string): Promise<boolean>; }; import fs from 'fs-extra'; //# sourceMappingURL=file.d.ts.map ================================================ FILE: @types/lib/util/init.config.d.ts ================================================ export default Init; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; declare namespace Init { /** * helper method for this.upgradeProject that upgrades project config if needed * * @param {Mcdevrc} properties config file's json * @returns {Promise.<boolean>} returns true if worked without errors */ function fixMcdevConfig(properties: Mcdevrc): Promise<boolean>; /** * handles creation/update of all config file from the boilerplate * * @param {string} versionBeforeUpgrade 'x.y.z' * @returns {Promise.<boolean>} status of config file creation */ function createIdeConfigFiles(versionBeforeUpgrade: string): Promise<boolean>; /** * recursive helper for {@link Init.fixMcdevConfig} that adds missing settings * * @param {object} propertiersCur current sub-object of project settings * @param {object} defaultPropsCur current sub-object of default settings * @param {string} fieldName dot-concatenated object-path that needs adding * @returns {boolean} was something updated or not */ function _updateLeaf(propertiersCur: object, defaultPropsCur: object, fieldName: string): boolean; /** * returns list of files that need to be updated * * @param {string} projectVersion version found in config file of the current project * @returns {Promise.<{updates:string[],deletes:string[]}>} relevant files with path that need to be updated */ function _getForcedUpdateList(projectVersion: string): Promise<{ updates: string[]; deletes: string[]; }>; /** * handles creation/update of one config file from the boilerplate at a time * * @param {string[]} fileNameArr 0: path, 1: filename, 2: extension with dot * @param {{updates:string[],deletes:string[]}} relevantForced if fileNameArr is in this list we require an override * @param {string} [boilerplateFileContent] in case we cannot copy files 1:1 this can be used to pass in content * @returns {Promise.<boolean>} install successful or error occured */ function _createIdeConfigFile(fileNameArr: string[], relevantForced: { updates: string[]; deletes: string[]; }, boilerplateFileContent?: string): Promise<boolean>; /** * handles deletion of no longer needed config files * * @param {{updates:string[],deletes:string[]}} relevantForced if file is in .deletes, we require deleting/renaming it * @returns {Promise.<boolean>} deletion successful or error occured */ function _removeIdeConfigFiles(relevantForced: { updates: string[]; deletes: string[]; }): Promise<boolean>; /** * helper method for this.upgradeProject that upgrades project config if needed * * @returns {Promise.<boolean>} returns true if worked without errors */ function upgradeAuthFile(): Promise<boolean>; } //# sourceMappingURL=init.config.d.ts.map ================================================ FILE: @types/lib/util/init.d.ts ================================================ export default Init; export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; declare namespace Init { /** * Creates template file for properties.json * * @param {Mcdevrc} properties config file's json * @param {string} [credentialName] identifying name of the installed package / project; if set, will update this credential * @param {boolean} [refreshBUs] if this was triggered by mcdev join, do not refresh BUs * @returns {Promise.<void>} - */ function initProject(properties: Mcdevrc, credentialName?: string, refreshBUs?: boolean): Promise<void>; /** * Creates template file for properties.json * * @returns {Promise.<void>} - */ function joinProject(): Promise<void>; /** * helper for {@link Init.initProject} that optionally creates markets and market lists for all BUs */ function _initMarkets(): Promise<void>; /** * helper for {@link Init.initProject} * * @param {string} bu cred/bu or cred/* or * * @param {string} gitStatus signals what state the git repo is in * @returns {Promise.<void>} - */ function _downloadAllBUs(bu: string, gitStatus: string): Promise<void>; /** * wrapper around npm dependency & configuration file setup * * @param {Mcdevrc} properties config file's json * @param {boolean} [initial] print message if not part of initial setup * @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init * @returns {Promise.<boolean>} success flag */ function upgradeProject(properties: Mcdevrc, initial?: boolean, repoName?: string): Promise<boolean>; /** * check if git repo is being saved on a cloud service and warn the user * * @private * @returns {Promise.<boolean>} true if path is good; false if project seems to be in a cloud service folder */ function _checkPathForCloud(): Promise<boolean>; /** * finds credentials that are set up in config but not in auth file * * @private * @param {Mcdevrc} properties javascript object in .mcdevrc.json * @returns {string[]} list of credential names */ function _getMissingCredentials(properties: Mcdevrc): string[]; } //# sourceMappingURL=init.d.ts.map ================================================ FILE: @types/lib/util/init.git.d.ts ================================================ export default Init; declare namespace Init { /** * check if git repo exists and otherwise create one * * @returns {Promise.<{status: string, repoName: string}>} success flag */ function initGitRepo(): Promise<{ status: string; repoName: string; }>; /** * offer to push the new repo straight to the server * * @returns {Promise.<void>} - */ function gitPush(): Promise<void>; /** * offers to add the git remote origin * * @returns {Promise.<string>} repo name (optionally) */ function _addGitRemote(): Promise<string>; /** * checks global config and ask to config the user info and then store it locally * * @returns {Promise.<void>} - */ function _updateGitConfigUser(): Promise<void>; /** * retrieves the global user.name and user.email values * * @returns {Promise.<{'user.name': string, 'user.email': string}>} user.name and user.email */ function _getGitConfigUser(): Promise<{ "user.name": string; "user.email": string; }>; } //# sourceMappingURL=init.git.d.ts.map ================================================ FILE: @types/lib/util/init.npm.d.ts ================================================ export default Init; declare namespace Init { /** * initiates npm project and then * takes care of loading the pre-configured dependency list * from the boilerplate directory to them as dev-dependencies * * @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init * @returns {Promise.<boolean>} install successful or error occured */ function installDependencies(repoName?: string): Promise<boolean>; /** * ensure we have certain default values in our config * * @param {object} [currentContent] what was read from existing package.json file * @returns {Promise.<{script: object, author: string, license: string}>} extended currentContent */ function _getDefaultPackageJson(currentContent?: object): Promise<{ script: object; author: string; license: string; }>; } //# sourceMappingURL=init.npm.d.ts.map ================================================ FILE: @types/lib/util/replaceContentBlockReference.d.ts ================================================ /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').McdevLogger} McdevLogger * @typedef {import('../../types/mcdev.d.js').Logger} Logger * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SkipInteraction} SkipInteraction * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError * * @typedef {import('../../types/mcdev.d.js').AssetMap} AssetMap * @typedef {import('../../types/mcdev.d.js').AssetItemSimple} AssetItemSimple * @typedef {import('../../types/mcdev.d.js').AssetItemSimpleMap} AssetItemSimpleMap * @typedef {import('../../types/mcdev.d.js').AssetItemIdSimpleMap} AssetItemIdSimpleMap * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * Util that contains logger and simple util methods */ export default class ReplaceContentBlockReference { /** @type {{id: AssetItemIdSimpleMap, key: AssetItemSimpleMap, name: AssetItemSimpleMap}} */ static assetCacheMap: { id: AssetItemIdSimpleMap; key: AssetItemSimpleMap; name: AssetItemSimpleMap; }; /** @type {Object.<string, {id: RegExp[], key: RegExp[], name: RegExp[]}>} */ static "__#private@#regexBy": { [x: string]: { id: RegExp[]; key: RegExp[]; name: RegExp[]; }; }; /** * helper for tests */ static resetCacheMap(): void; /** * used to equalize the reference in the code to whatever is set in the "to" field * * @param {string} str full code string * @param {string} parentName name of the object that was passed in; used in error message only * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {string} replaced string */ static replaceReference(str: string, parentName: string, findAssetKeys?: Set<string>): string; /** * * @param {ContentBlockConversionTypes} from replace with * @param {string|number} identifier id, key or name of asset * @param {string} parentName name of the object that was passed in; used in error message only * @param {boolean} [isSsjs] replaces backslashes with double backslashes in name if true * @param {boolean} [handleOutside] don not print error message if asset not found * @returns {AssetItemSimple} asset object */ static "__#private@#getAssetBy"(from: ContentBlockConversionTypes, identifier: string | number, parentName: string, isSsjs?: boolean, handleOutside?: boolean): AssetItemSimple; /** * * @param {AssetItemSimple} asset asset object * @param {ContentBlockConversionTypes} to replace with * @param {boolean} [isSsjs] replaces backslashes with double backslashes in name if true * @returns {string} replaced string */ static "__#private@#replaceWith"(asset: AssetItemSimple, to: ContentBlockConversionTypes, isSsjs?: boolean): string; /** * ensures we cache the right things from disk and if required from server * * @param {Mcdevrc} properties properties for auth * @param {BuObject} buObject properties for auth * @param {boolean} [retrieveSharedOnly] for --dependencies only, do not have to re-retrieve local assets * @returns {Promise.<void>} - */ static createCache(properties: Mcdevrc, buObject: BuObject, retrieveSharedOnly?: boolean): Promise<void>; /** * helper for {@link ReplaceContentBlockReference.createCache} that converts AssetMap into AssetItemSimple entries in this.assetCacheMap * * @param {AssetMap} metadataMap list of local or shared assets */ static createCacheForMap(metadataMap: AssetMap): void; /** * helper for {@link ReplaceContentBlockReference.createCache} * * @param {BuObject} buObject references credentials * @param {Mcdevrc} properties central properties object * @param {boolean} [retrieveSharedOnly] for --dependencies only, do not have to re-retrieve local assets * @returns {Promise.<{localAssets: AssetMap, sharedAssets: AssetMap}>} - */ static _retrieveCache(buObject: BuObject, properties: Mcdevrc, retrieveSharedOnly?: boolean): Promise<{ localAssets: AssetMap; sharedAssets: AssetMap; }>; } export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type McdevLogger = import("../../types/mcdev.d.js").McdevLogger; export type Logger = import("../../types/mcdev.d.js").Logger; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SkipInteraction = import("../../types/mcdev.d.js").SkipInteraction; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type SDKError = import("../../types/mcdev.d.js").SDKError; export type AssetMap = import("../../types/mcdev.d.js").AssetMap; export type AssetItemSimple = import("../../types/mcdev.d.js").AssetItemSimple; export type AssetItemSimpleMap = import("../../types/mcdev.d.js").AssetItemSimpleMap; export type AssetItemIdSimpleMap = import("../../types/mcdev.d.js").AssetItemIdSimpleMap; export type ContentBlockConversionTypes = import("../../types/mcdev.d.js").ContentBlockConversionTypes; //# sourceMappingURL=replaceContentBlockReference.d.ts.map ================================================ FILE: @types/lib/util/util.d.ts ================================================ export namespace Util { let authFileName: string; let boilerplateDirectory: string; let configFileName: string; let defaultGitBranch: string; let parentBuName: string; let standardizedSplitChar: string; let folderNameSlashEscapeChar: string; let skipInteraction: SkipInteraction; let packageJsonMcdev: any; let OPTIONS: {}; let changedKeysMap: {}; let matchedByName: {}; /** * helper that allows filtering an object by its keys * * @param {Object.<string,*>} originalObj object that you want to filter * @param {string[]} [whitelistArr] positive filter. if not provided, returns originalObj without filter * @returns {Object.<string,*>} filtered object that only contains keys you provided */ function filterObjByKeys(originalObj: { [x: string]: any; }, whitelistArr?: string[]): { [x: string]: any; }; /** * extended Array.includes method that allows check if an array-element starts with a certain string * * @param {string[]} arr your array of strigns * @param {string} search the string you are looking for * @returns {boolean} found / not found */ function includesStartsWith(arr: string[], search: string): boolean; /** * extended Array.includes method that allows check if an array-element starts with a certain string * * @param {string[]} arr your array of strigns * @param {string} search the string you are looking for * @returns {number} array index 0..n or -1 of not found */ function includesStartsWithIndex(arr: string[], search: string): number; /** * check if a market name exists in current mcdev config * * @param {string} market market localizations * @param {Mcdevrc} properties local mcdev config * @returns {boolean} found market or not */ function checkMarket(market: string, properties: Mcdevrc): boolean; /** * check if a market name exists in current mcdev config * * @param {string[]} marketArr market localizations * @param {Mcdevrc} properties local mcdev config * @returns {boolean} found market or not */ function checkMarketList(marketArr: string[], properties: Mcdevrc): boolean; /** * ensure provided MarketList exists and it's content including markets and BUs checks out * * @param {string} mlName name of marketList * @param {Mcdevrc} properties General configuration to be used in retrieve */ function verifyMarketList(mlName: string, properties: Mcdevrc): void; /** * * @param {string | TypeKeyCombo} selectedTypes supported metadata type * @param {string[]} [keyArr] name/key of the metadata * @param {string} [commandName] for log output only * @returns {TypeKeyCombo | undefined} true if everything is valid; false otherwise */ function checkAndPrepareTypeKeyCombo(selectedTypes: string | TypeKeyCombo, keyArr?: string[], commandName?: string): TypeKeyCombo | undefined; /** * used to ensure the program tells surrounding software that an unrecoverable error occured * * @returns {void} */ function signalFatalError(): void; /** * SFMC accepts multiple true values for Boolean attributes for which we are checking here. * The same problem occurs when evaluating boolean CLI flags * * @param {*} attrValue value * @returns {boolean} attribute value == true ? true : false */ function isTrue(attrValue: any): boolean; /** * SFMC accepts multiple false values for Boolean attributes for which we are checking here. * The same problem occurs when evaluating boolean CLI flags * * @param {*} attrValue value * @returns {boolean} attribute value == false ? true : false */ function isFalse(attrValue: any): boolean; function isEqual(item1: string | number | boolean | any[] | object, item2: string | number | boolean | any[] | object): boolean; function _isEqualArray(array1: any[], array2: any[]): boolean; function _isEqualObject(item1: object, item2: object): boolean; /** * helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy * * @param {string} selectedType type or type-subtype * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {boolean} type ok or not */ function _isValidType(selectedType: string, handleOutside?: boolean): boolean; /** * helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy * * @param {Mcdevrc} properties javascript object in .mcdevrc.json * @param {string} businessUnit name of BU * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {boolean} bu found or not */ function isValidBU(properties: Mcdevrc, businessUnit: string, handleOutside?: boolean): boolean; /** * helper that deals with extracting type and subtype * * @param {string} selectedType "type" or "type-subtype" * @returns {{type:string, subType:string}} first elem is type, second elem is subType */ function getTypeAndSubType(selectedType: string): { type: string; subType: string; }; /** * helper for getDefaultProperties() * * @param {'typeRetrieveByDefault'|'typeCdpByDefault'} field relevant field in type definition * @returns {string[]} type choices */ function getTypeChoices(field: "typeRetrieveByDefault" | "typeCdpByDefault"): string[]; /** * helper for cli.selectTypes and init.config.fixMcdevConfig that converts subtypes back to main type if all and only defaults were selected * this keeps the config automatically upgradable when we add new subtypes or change what is selected by default * * @param {'typeRetrieveByDefault'|'typeCdpByDefault'} field relevant field in type definition * @param {string[]} selectedTypes what types the user selected * @param {'asset'} [type] metadata type * @returns {string[]} filtered selectedTypes */ function summarizeSubtypes(field: "typeRetrieveByDefault" | "typeCdpByDefault", selectedTypes: string[], type?: "asset"): string[]; let logFileName: string; function _createNewLoggerTransport(noLogFile?: boolean): object; let loggerTransports: any; let logger: Logger; function startLogger(restart?: boolean, noLogFile?: boolean): void; function metadataLogger(level: string, type: string, method: string, payload: any, source?: string): void; function replaceByObject(str: string | object, obj: TemplateMap): string | object; function inverseGet(objs: object, val: string | number): string; /** *helper for Mcdev.fixKeys. Retrieve dependent metadata * * @param {string} fixedType type of the metadata passed as a parameter to fixKeys function * @returns {string[]} array of types that depend on the given type */ function getDependentMetadata(fixedType: string): string[]; /** * Returns Order in which metadata needs to be retrieved/deployed * * @param {string[]} typeArr which should be retrieved/deployed * @returns {Object.<string, string[]>} retrieve/deploy order as array */ function getMetadataHierachy(typeArr: string[]): { [x: string]: string[]; }; /** * let's you dynamically walk down an object and get a value * * @param {string} path 'fieldA.fieldB.fieldC' * @param {object} obj some parent object * @returns {any} value of obj.path */ function resolveObjPath(path: string, obj: object): any; /** * helper to run other commands as if run manually by user * * @param {string} cmd to be executed command * @param {string[]} [args] list of arguments * @param {boolean} [hideOutput] if true, output of command will be hidden from CLI * @returns {string|void} output of command if hideOutput is true */ function execSync(cmd: string, args?: string[], hideOutput?: boolean): string | void; /** * standardize check to ensure only one result is returned from template search * * @param {MetadataTypeItem[]} results array of metadata * @param {string} keyToSearch the field which contains the searched value * @param {string} searchValue the value which is being looked for * @returns {MetadataTypeItem} metadata to be used in building template */ function templateSearchResult(results: MetadataTypeItem[], keyToSearch: string, searchValue: string): MetadataTypeItem; /** * configures what is displayed in the console * * @param {object} argv list of command line parameters given by user * @param {boolean} [argv.silent] only errors printed to CLI * @param {boolean} [argv.verbose] chatty user CLI output * @param {boolean} [argv.debug] enables developer output & features * @returns {void} */ function setLoggingLevel(argv: { silent?: boolean; verbose?: boolean; debug?: boolean; }): void; /** * outputs a warning that the given type is still in beta * * @param {string} type api name of the type thats in beta */ function logBeta(type: string): void; /** * outputs a warning that the given method is deprecated * * @param {string} method name of the method * @param {string} [useInstead] optionally specify which method to use instead */ function logDeprecated(method: string, useInstead?: string): void; function logNotSupported(definition: any, method: string, item?: MetadataTypeItem): void; namespace color { let reset: string; let dim: string; let bright: string; let underscore: string; let blink: string; let reverse: string; let hidden: string; let fgBlack: string; let fgRed: string; let fgGreen: string; let fgYellow: string; let fgBlue: string; let fgMagenta: string; let fgCyan: string; let fgWhite: string; let fgGray: string; let bgBlack: string; let bgRed: string; let bgGreen: string; let bgYellow: string; let bgBlue: string; let bgMagenta: string; let bgCyan: string; let bgWhite: string; let bgGray: string; } /** * helper that wraps a message in the correct color codes to have them printed gray * * @param {string} msg log message that should be wrapped with color codes * @returns {string} gray msg */ function getGrayMsg(msg: string): string; /** * helper that returns the prefix of item specific log messages * * @param {any} definition metadata definition * @param {MetadataTypeItem} metadataItem metadata item * @returns {string} msg prefix */ function getMsgPrefix(definition: any, metadataItem: MetadataTypeItem): string; /** * helper that returns the prefix of item specific log messages * * @param {any} definition metadata definition * @param {MetadataTypeItem} metadataItem metadata item * @returns {string} key or key/name combo */ function getTypeKeyName(definition: any, metadataItem: MetadataTypeItem): string; /** * helper that returns the prefix of item specific log messages * * @param {any} definition metadata definition * @param {MetadataTypeItem} metadataItem metadata item * @returns {string} key or key/name combo */ function getKeyName(definition: any, metadataItem: MetadataTypeItem): string; /** * helper to print the subtypes we filtered by * * @param {string[]} subTypeArr list of subtypes to be printed * @param {string} [indent] optional prefix of spaces to be added to the log message * @returns {void} */ function logSubtypes(subTypeArr: string[], indent?: string): void; /** * helper to print the subtypes we filtered by * * @param {string[] | string} keyArr list of subtypes to be printed * @param {boolean} [isId] optional flag to indicate if key is an id * @returns {string} string to be appended to log message */ function getKeysString(keyArr: string[] | string, isId?: boolean): string; /** * pause execution of code; useful when multiple server calls are dependent on each other and might not be executed right away * * @param {number} ms time in miliseconds to wait * @returns {Promise.<void>} - promise to wait for */ function sleep(ms: number): Promise<void>; /** * helper for Asset.extractCode and Script.prepExtractedCode to determine if a code block is a valid SSJS block * * @example the following is invalid: * <script runat="server"> * // 1 * </script> * <script runat="server"> * // 2 * </script> * * the following is valid: * <script runat="server"> * // 3 * </script> * @param {string} code code block to check * @returns {string} the SSJS code if code block is a valid SSJS block, otherwise null */ function getSsjs(code: string): string; /** * allows us to filter just like with SQL's LIKE operator * * @param {string} testString field value to test * @param {string} search search string in SQL LIKE format * @returns {boolean} true if testString matches search */ function stringLike(testString: string, search: string): boolean; /** * returns true if no LIKE filter is defined or if all filters match * * @param {MetadataTypeItem} metadata a single metadata item * @param {object} definition type definition * @param {object} [filters] only used in recursive calls * @returns {boolean} true if no LIKE filter is defined or if all filters match */ function fieldsLike(metadata: MetadataTypeItem, definition: object, filters?: object): boolean; /** * helper used by SOAP methods to ensure the type always uses an upper-cased first letter * * @param {string} str string to capitalize * @returns {string} str with first letter capitalized */ function capitalizeFirstLetter(str: string): string; /** * helper for Retriever and Deployer class * * @param {string | string[]} typeArr - * @param {string[]} keyArr - * @param {boolean} [returnEmpty] returns array with null element if false/not set; Retriever needs this to be false; Deployer needs it to be true * @returns {TypeKeyCombo} - */ function createTypeKeyCombo(typeArr: string | string[], keyArr: string[], returnEmpty?: boolean): TypeKeyCombo; /** * helper that converts TypeKeyCombo objects into a string with all relevant -m parameters * * @param {TypeKeyCombo} [selectedTypes] selected metadata types & key * @returns {string} object converted into --metadata parameters */ function convertTypeKeyToCli(selectedTypes?: TypeKeyCombo): string; /** * helper that converts TypeKeyCombo objects into a string with all relevant -m parameters * * @param {TypeKeyCombo} [selectedTypes] selected metadata types & key * @returns {string} object converted into --metadata parameters */ function convertTypeKeyToString(selectedTypes?: TypeKeyCombo): string; /** * helper that checks how many keys are defined in TypeKeyCombo object * * @param {TypeKeyCombo} [selectedTypes] selected metadata types & key * @returns {number} amount of keys across all types */ function getTypeKeyCount(selectedTypes?: TypeKeyCombo): number; /** * async version of Array.find() * returns the first element in the provided array that satisfies the provided testin function * * @param {Array} arr your test array * @param {Function} asyncCallback callback * @returns {Promise.<any | undefined>} first element that passed the test */ function findAsync(arr: any[], asyncCallback: Function): Promise<any | undefined>; /** * * @param {Array} array array to be chunked * @param {number} chunk_size integer > 0 * @returns {Array[]} array of arrays with max chunk_size members per element, last element might have less */ function chunk(array: any[], chunk_size: number): any[][]; /** * recursively find all values of the given key in the object * * @param {any} object data to search in * @param {string} key attribute to find * @returns {Array} all values of the given key */ function findLeafVals(object: any, key: string): any[]; /** * helper that returns a new object with sorted attributes of the given object * * @param {object} obj object with unsorted attributes * @returns {object} obj but with sorted attributes */ function sortObjectAttributes(obj: object): object; } export type AuthObject = import("../../types/mcdev.d.js").AuthObject; export type BuObject = import("../../types/mcdev.d.js").BuObject; export type Cache = import("../../types/mcdev.d.js").Cache; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; export type CodeExtractItem = import("../../types/mcdev.d.js").CodeExtractItem; export type DeltaPkgItem = import("../../types/mcdev.d.js").DeltaPkgItem; export type McdevLogger = import("../../types/mcdev.d.js").McdevLogger; export type Logger = import("../../types/mcdev.d.js").Logger; export type Mcdevrc = import("../../types/mcdev.d.js").Mcdevrc; export type MetadataTypeItem = import("../../types/mcdev.d.js").MetadataTypeItem; export type MetadataTypeItemDiff = import("../../types/mcdev.d.js").MetadataTypeItemDiff; export type MetadataTypeItemObj = import("../../types/mcdev.d.js").MetadataTypeItemObj; export type MetadataTypeMap = import("../../types/mcdev.d.js").MetadataTypeMap; export type MetadataTypeMapObj = import("../../types/mcdev.d.js").MetadataTypeMapObj; export type MultiMetadataTypeList = import("../../types/mcdev.d.js").MultiMetadataTypeList; export type MultiMetadataTypeMap = import("../../types/mcdev.d.js").MultiMetadataTypeMap; export type SkipInteraction = import("../../types/mcdev.d.js").SkipInteraction; export type SoapRequestParams = import("../../types/mcdev.d.js").SoapRequestParams; export type TemplateMap = import("../../types/mcdev.d.js").TemplateMap; export type TypeKeyCombo = import("../../types/mcdev.d.js").TypeKeyCombo; export type SDKError = import("../../types/mcdev.d.js").SDKError; //# sourceMappingURL=util.d.ts.map ================================================ FILE: @types/lib/util/validations.d.ts ================================================ /** * * @param {any} definition type definition * @param {any} item MetadataItem * @param {string} targetDir folder in which the MetadataItem is deployed from (deploy/cred/bu) * @param {CodeExtract[]} [codeExtractItemArr] array of code snippets * @returns {Promise.<validationRuleList>} MetadataItem */ export default function validation(definition: any, item: any, targetDir: string, codeExtractItemArr?: CodeExtract[]): Promise<validationRuleList>; export type validationRuleList = import("../../types/mcdev.d.js").validationRuleList; export type validationRuleFix = import("../../types/mcdev.d.js").validationRuleFix; export type validationRuleTest = import("../../types/mcdev.d.js").validationRuleTest; export type CodeExtract = import("../../types/mcdev.d.js").CodeExtract; //# sourceMappingURL=validations.d.ts.map ================================================ FILE: @types/types/mcdev.d.d.ts ================================================ declare const _default: {}; export default _default; export type BuObject = { /** * installed package client id */ clientId?: string; /** * installed package client secret */ clientSecret?: string; /** * subdomain part of Authentication Base Uri */ tenant?: string; /** * Enterprise ID = MID of the parent BU */ eid?: number; /** * MID of the BU to work with */ mid?: number; /** * name of the BU to interact with */ businessUnit?: string; /** * name of the credential to interact with */ credential?: string; }; export type TemplateMap = { [x: string]: string; }; export type SupportedMetadataTypes = "asset" | "asset-archive" | "asset-asset" | "asset-audio" | "asset-block" | "asset-code" | "asset-document" | "asset-image" | "asset-message" | "asset-other" | "asset-rawimage" | "asset-template" | "asset-textfile" | "asset-video" | "attributeGroup" | "attributeSet" | "automation" | "campaign" | "contentArea" | "dataExtension" | "dataExtensionField" | "dataExtensionTemplate" | "dataExtract" | "dataExtractType" | "discovery" | "deliveryProfile" | "email" | "emailSend" | "event" | "fileLocation" | "fileTransfer" | "filter" | "folder" | "importFile" | "journey" | "list" | "mobileCode" | "mobileKeyword" | "mobileMessage" | "query" | "role" | "script" | "sendClassification" | "senderProfile" | "transactionalEmail" | "transactionalPush" | "transactionalSMS" | "triggeredSend" | "user" | "verification"; /** * object-key=SupportedMetadataTypes, value=array of external keys */ export type TypeKeyCombo = { [x: string]: string[]; }; /** * generic metadata item */ export type MetadataTypeItem = any; /** * key=customer key */ export type MetadataTypeMap = { [x: string]: any; }; /** * key=Supported MetadataType */ export type MultiMetadataTypeMap = { [x: string]: { [x: string]: any; }; }; /** * key=Supported MetadataType */ export type MultiMetadataTypeList = { [x: string]: any[]; }; export type MetadataTypeMapObj = { metadata: MetadataTypeMap; type: string; }; export type MetadataTypeItemObj = { metadata: MetadataTypeItem; type: string; }; /** * key=MID */ export type Cache = { [x: number]: { [x: string]: { [x: string]: any; }; }; }; /** * used during update */ export type MetadataTypeItemDiff = { before: MetadataTypeItem; after: MetadataTypeItem; }; export type CodeExtractItem = { /** * metadata of one item w/o code */ json: MetadataTypeItem; /** * list of code snippets in this item */ codeArr: CodeExtract[]; /** * mostly set to null, otherwise list of subfolders */ subFolder: string[]; }; export type CodeExtract = { /** * mostly set to null, otherwise subfolders path split into elements */ subFolder: string[]; /** * name of file w/o extension */ fileName: string; /** * file extension */ fileExt: string; /** * file content */ content: string; /** * optional for binary files */ encoding?: "base64"; }; export type QueryItem = { /** * name */ name: string; /** * key */ key: string; /** * - */ description: string; /** * Object ID of DE (removed before save) */ targetId?: string; /** * key of target data extension */ targetKey: string; /** * key of target data extension */ r__dataExtension_key: string; /** * e.g. "2020-09-14T01:42:03.017" */ createdDate: string; /** * e.g. "2020-09-14T01:42:03.017" */ modifiedDate: string; /** * defines how the query writes into the target data extension */ targetUpdateTypeName: "Overwrite" | "Update" | "Append"; /** * 0|1|2, mapped to targetUpdateTypeName via this.definition.targetUpdateTypeMapping */ targetUpdateTypeId?: number; /** * Description DE (removed before save) */ targetDescription?: string; /** * looks like this is always set to false */ isFrozen: boolean; /** * contains SQL query with line breaks converted to '\n'. The content is extracted during retrieval and written into a separate *.sql file */ queryText?: string; /** * holds folder ID, replaced with r__folder_Path during retrieve */ categoryId?: string; /** * folder path in which this DE is saved */ r__folder_Path: string; /** * Object ID of query */ queryDefinitionId?: string; }; export type QueryMap = { [x: string]: QueryItem; }; export type ScriptItem = { /** * name */ name: string; /** * key */ key: string; /** * - */ description: string; /** * e.g. "2020-09-14T01:42:03.017" */ createdDate: string; /** * e.g. "2020-09-14T01:42:03.017" */ modifiedDate: string; /** * contains script with line breaks converted to '\n'. The content is extracted during retrieval and written into a separate *.ssjs file */ script?: string; /** * holds folder ID, replaced with r__folder_Path during retrieve */ categoryId?: string; /** * folder path in which this DE is saved */ r__folder_Path: string; }; export type ScriptMap = { [x: string]: ScriptItem; }; export type AssetItem = { [x: string]: any; }; export type AssetMap = { [x: string]: { [x: string]: any; }; }; export type AssetSubType = "archive" | "asset" | "audio" | "block" | "code" | "document" | "image" | "message" | "other" | "rawimage" | "template" | "textfile" | "video"; export type DataExtensionFieldItem = { /** * id */ ObjectID?: string; /** * key in format [DEkey].[FieldName] */ CustomerKey?: string; /** * - */ DataExtension?: { CustomerKey: string; }; /** * name of field */ Name: string; /** * custom attribute that is only used when trying to rename a field from Name to Name_new */ Name_new?: string; /** * empty string for not set */ DefaultValue: string; /** * - */ IsRequired: true | false; /** * opposite of IsRequired */ IsNullable?: true | false; /** * - */ IsPrimaryKey: true | false; /** * 1, 2, 3, ... */ Ordinal: number; /** * can only be set on create */ FieldType: "Text" | "Number" | "Date" | "Boolean" | "Decimal" | "EmailAddress" | "Phone" | "Locale"; /** * field length */ MaxLength: number | string; /** * the number of places after the decimal that the field can hold; example: "0","1", ... */ Scale: string; }; /** * key: name of field, value: DataExtensionFieldItem */ export type DataExtensionFieldMap = { [x: string]: DataExtensionFieldItem; }; export type DataExtensionItem = { /** * key */ CustomerKey: string; /** * name */ Name: string; /** * - */ Description: string; /** * iso format */ CreatedDate?: string; /** * iso format */ ModifiedDate?: string; /** * - */ IsSendable: true | false; /** * - */ IsTestable: true | false; /** * - */ SendableDataExtensionField: { Name: string; }; /** * - */ SendableSubscriberField: { Name: string; }; /** * list of DE fields */ Fields: DataExtensionFieldItem[]; /** * retrieved from associated folder */ r__folder_ContentType: "dataextension" | "salesforcedataextension" | "synchronizeddataextension" | "shared_dataextension" | "shared_salesforcedataextension"; /** * folder path in which this DE is saved */ r__folder_Path: string; /** * holds folder ID, replaced with r__folder_Path during retrieve */ CategoryID?: string; /** * name of optionally associated DE template */ r__dataExtensionTemplate_name?: string; /** * - */ Template?: { CustomerKey?: string; }; /** * empty string or US date + 12:00:00 AM */ RetainUntil: string; /** * YYYY-MM-DD */ c__retainUntil: string; /** * readable name of retention policy */ c__retentionPolicy?: "none" | "allRecordsAndDataextension" | "allRecords" | "individialRecords"; /** * number of days/weeks/months/years before retention kicks in */ DataRetentionPeriodLength?: number; /** * 3:Days, 4:Weeks, 5:Months, 6:Years */ DataRetentionPeriodUnitOfMeasure?: number; /** * 3:Days, 4:Weeks, 5:Months, 6:Years */ c__dataRetentionPeriodUnitOfMeasure?: string; /** * true for retention policy individialRecords */ RowBasedRetention?: boolean; /** * ? */ ResetRetentionPeriodOnImport: boolean; /** * true for retention policy allRecords */ DeleteAtEndOfRetentionPeriod?: boolean; }; export type DataExtensionMap = { [x: string]: DataExtensionItem; }; export type UserDocument = { /** * - */ TYPE: "User" | "Installed Package" | "Inactivated User"; /** * equal to UserID; optional in update/create calls */ ID?: string; /** * equal to ID; required in update/create calls */ UserID: string; /** * user.AccountUserID */ AccountUserID?: number; /** * copy of AccountUserID */ c__AccountUserID: number; /** * user.CustomerKey */ CustomerKey: string; /** * user.Name */ Name: string; /** * user.Email */ Email: string; /** * user.NotificationEmailAddress */ NotificationEmailAddress: string; /** * user.ActiveFlag === true ? '✓' : '-' */ ActiveFlag: boolean; /** * user.IsAPIUser === true ? '✓' : '-' */ IsAPIUser: boolean; /** * user.MustChangePassword === true ? '✓' : '-' */ MustChangePassword: boolean; /** * default MID; BUName after we resolved it */ DefaultBusinessUnit: number; /** * associatedBus */ c__AssociatedBusinessUnits: number[]; /** * (API only) */ Roles?: { Role?: object[]; }; /** * roles */ c__RoleNamesGlobal: string[]; /** * userPermissions */ UserPermissions: string[]; /** * this.timeSinceDate(user.LastSuccessfulLogin) */ LastSuccessfulLogin: string; /** * user.CreatedDate */ CreatedDate: string; /** * user.ModifiedDate */ ModifiedDate: string; /** * - */ Client: { ID?: number; ModifiedBy?: number; }; /** * - */ c__type: "User" | "Installed Package"; /** * (API only) */ IsLocked?: boolean; /** * used to unlock a user that has IsLocked === true */ Unlock?: boolean; /** * copy of IsLocked */ c__IsLocked_readOnly: boolean; /** * name of timezone */ c__TimeZoneName: string; /** * (API only) */ TimeZone?: { Name?: string; ID?: string; }; /** * only used to set the password. cannot be retrieved */ Password?: string; /** * fr-CA, en-US, ... */ c__LocaleCode: "en-US" | "fr-CA" | "fr-FR" | "de-DE" | "it-IT" | "ja-JP" | "pt-BR" | "es-419" | "es-ES"; /** * (API only) */ Locale?: { LocaleCode?: "en-US" | "fr-CA" | "fr-FR" | "de-DE" | "it-IT" | "ja-JP" | "pt-BR" | "es-419" | "es-ES"; }; /** * - */ SsoIdentity?: object; /** * - */ SsoIdentities?: any[] | object; }; export type UserDocumentDiff = { before: UserDocument; after: UserDocument; }; /** * key=customer key */ export type UserDocumentMap = { [x: string]: UserDocument; }; export type UserDocumentDocumentHelper = { /** * docs: user.ActiveFlag === true ? '✓' : '-' */ ActiveFlagDocs: string; /** * docs: user.IsAPIUser === true ? '✓' : '-' */ IsAPIUserDocs: string; /** * docs: user.MustChangePassword === true ? '✓' : '-' */ MustChangePasswordDocs: string; /** * docs: default MID; BUName after we resolved it */ DefaultBusinessUnitDocs: string; /** * docs: list of roles as concatenated string */ RolesDocs: string; /** * docs: list of associated BUs as concatenated string */ AssociatedBusDocs: string; /** * docs: user name who last modified this user */ ModifiedBy: string | number; /** * docs: name of timezone */ TimeZoneName: string; /** * docs: if the user cannot login */ IsLockedDocs: string; }; export type UserDocumentDocument = UserDocument & UserDocumentDocumentHelper; export type AccountUserConfiguration = { /** * wrapper */ Client: { ID: number; }; /** * empty string */ PartnerKey?: string; /** * User ID e.g:717133502 */ ID: number | string; /** * empty string */ ObjectID?: string; /** * 0,1 */ Delete?: number; /** * - */ BusinessUnitAssignmentConfiguration: BusinessUnitAssignmentConfiguration; }; export type BusinessUnitAssignmentConfiguration = { /** * wrapper */ BusinessUnitIds: { BusinessUnitId: number[] | number; }; /** * assign BU if false, remove assignment if true */ IsDelete: boolean; }; export type AutomationActivity = { /** * key of associated activity */ r__key: string; /** * name (not key) of associated activity */ name?: string; /** * used by wait activity if a specific time of day was set */ timeZone?: string; /** * Id of assoicated activity type; see this.definition.activityTypeMapping */ objectTypeId?: number; /** * Object Id of assoicated metadata item */ activityObjectId?: string; /** * order within step; starts with 1 or higher number */ displayOrder?: number; /** * see this.definition.activityTypeMapping */ r__type: string; }; export type AutomationStep = { /** * description */ name: string; /** * equals AutomationStep.name */ annotation?: string; /** * step iterator; starts with 1 */ step?: number; /** * step iterator, automatically set during deployment */ stepNumber?: number; /** * - */ activities: AutomationActivity[]; }; /** * REST format */ export type AutomationSchedule = { /** * legacy id of schedule */ id: string; /** * equals schedule.scheduleTypeId; upsert endpoint requires scheduleTypeId. retrieve endpoint returns typeId */ typeId: number; /** * equals schedule.typeId; upsert endpoint requires scheduleTypeId. retrieve endpoint returns typeId */ scheduleTypeId?: number; /** * example: '2021-05-07T09:00:00' */ startDate: string; /** * example: '2021-05-07T09:00:00' */ endDate: string; /** * example: 'FREQ=DAILY;UNTIL=20790606T160000;INTERVAL=1' */ icalRecur: string; /** * same as icalRecur but returned by legacy-API; example: 'FREQ=DAILY;UNTIL=20790606T160000;INTERVAL=1' */ iCalRecur?: string; /** * example: 'W. Europe Standard Time'; see this.definition.timeZoneMapping */ timezoneName: string; /** * same as timezoneName but returned by legacy-API; example: 'W. Europe Standard Time'; see this.definition.timeZoneMapping */ timeZone?: string; /** * kept in legacy API only, exact description of what this schedule does */ description?: string; /** * see this.definition.timeZoneMapping */ timezoneId?: number; /** * same as timezoneId but returned by legacy-API; see this.definition.timeZoneMapping */ timeZoneId?: number; /** * ? */ rangeTypeId?: number; /** * ? */ pattern?: any; /** * ? */ scheduledTime?: any; /** * ? */ scheduledStatus?: string; }; /** * SOAP format */ export type AutomationScheduleSoap = { /** * 'Minutely'|'Hourly'|'Daily'|'Weekly'|'Monthly'|'Yearly' */ RecurrenceType?: string; /** * - */ Recurrence: { $?: object; YearlyRecurrencePatternType?: "ByYear"; MonthlyRecurrencePatternType?: "ByMonth"; WeeklyRecurrencePatternType?: "ByWeek"; DailyRecurrencePatternType?: "ByDay"; MinutelyRecurrencePatternType?: "Interval"; HourlyRecurrencePatternType?: "Interval"; YearInterval?: number; MonthInterval?: number; WeekInterval?: number; DayInterval?: number; HourInterval?: number; MinuteInterval?: number; }; /** * internal variable for CLI output only */ _interval?: number; /** * - */ TimeZone: { ID: number; IDSpecified?: true; }; /** * internal variable for CLI output only */ _timezoneString?: string; /** * AutomationSchedule.startDate */ StartDateTime: string; /** * AutomationSchedule.startDate; internal variable for CLI output only */ _StartDateTime?: string; /** * AutomationSchedule.endDate */ EndDateTime?: string; /** * set to 'EndOn' if AutomationSchedule.icalRecur contains 'UNTIL'; otherwise to 'EndAfter' */ RecurrenceRangeType: "EndOn" | "EndAfter"; /** * only exists if RecurrenceRangeType=='EndAfter' */ Occurrences?: number; }; export type AutomationItem = { /** * Object Id */ id: string; /** * legacy Object Id - used for handling notifications */ legacyId?: string; /** * Object Id as returned by SOAP API */ ObjectID?: string; /** * legacy id */ programId?: string; /** * key (Rest API) */ key: string; /** * key (SOAP API) */ CustomerKey?: string; /** * name (Rest API) */ name?: string; /** * name (SOAP API) */ Name?: string; /** * notifications */ notifications?: any; /** * - */ description?: string; /** * Starting Source = Schedule / File Drop */ type?: "scheduled" | "triggered" | "automationtriggered"; /** * Starting Source = Schedule / File Drop; from legacy api */ automationType?: "scheduled" | "triggered" | "automationtriggered"; /** * automation status */ status?: "Scheduled" | "Running" | "Ready" | "Building" | "PausedSchedule" | "InactiveTrigger"; /** * automation status */ statusId?: number; /** * only existing if type=scheduled */ schedule?: AutomationSchedule; /** * only existing if type=triggered */ fileTrigger?: { fileNamingPattern: string; fileNamePatternTypeId: number; folderLocationText: string; isPublished: boolean; queueFiles: boolean; triggerActive: boolean; }; /** * only existing if type=automationtriggered */ automationTrigger?: object; /** * - */ startSource?: { schedule?: AutomationSchedule; fileDrop?: { fileNamePattern: string; fileNamePatternTypeId: number; folderLocation: string; queueFiles: boolean; }; typeId: number; }; /** * - */ steps?: AutomationStep[]; /** * folder path */ r__folder_Path?: string; /** * holds folder ID, replaced with r__folder_Path during retrieve */ categoryId?: string; /** * user name of person who created this automation */ createdName?: string; /** * iso format */ createdDate?: string; /** * user name of person who last modified this automation */ modifiedName?: string; /** * iso format */ modifiedDate?: string; /** * user name of person who paused this automation */ pausedName?: string; /** * iso format */ pausedDate?: string; }; export type VerificationItem = { /** * ID / Key */ dataVerificationDefinitionId: string; /** * key */ verificationType: "IsEqualTo" | "IsLessThan" | "IsGreaterThan" | "IsOutsideRange" | "IsInsideRange" | "IsNotEqualTo" | "IsNotLessThan" | "IsNotGreaterThan" | "IsNotOutsideRange" | "IsNotInsideRange"; /** * used for all verificationTypes; lower value for IsOutsideRange, IsInsideRange, IsNotOutsideRange, IsNotInsideRange */ value1: number; /** * only used for IsOutsideRange, IsInsideRange, IsNotOutsideRange, IsNotInsideRange; otherwise set to 0 */ value2: number; /** * flag to stop automation if verification fails */ shouldStopOnFailure: boolean; /** * flag to send email if verification fails */ shouldEmailOnFailure: boolean; /** * email address to send notification to; empty string if shouldEmailOnFailure=false */ notificationEmailAddress: string; /** * email message to send; empty string if shouldEmailOnFailure=false */ notificationEmailMessage: string; /** * user id of creator */ createdBy: number; /** * ObjectID of target data extension */ targetObjectId?: string; /** * key of target data extension */ r__dataExtension_key: string; /** * custom key for verifications based on automation, step and activity number */ c__automation_step: string; }; export type AutomationMap = { [x: string]: AutomationItem; }; export type AutomationMapObj = { metadata: AutomationMap; type: string; }; export type AutomationItemObj = { metadata: object | AutomationItem; type: string; }; export type McdevDeltaPkgItem = { /** * relative path to file */ file: string; /** * changed lines */ changes: number; /** * added lines */ insertions: number; /** * deleted lines */ deletions: number; /** * is a binary file */ binary: boolean; /** * git thinks this file was moved */ moved: boolean; /** * git thinks this relative path is where the file was before */ fromPath?: string; /** * metadata type */ type: string; /** * key */ externalKey: string; /** * name */ name: string; /** * what git recognized as an action */ gitAction: "move" | "add/update" | "delete"; /** * mcdev credential name */ _credential: string; /** * mcdev business unit name inside of _credential */ _businessUnit: string; }; export type DeltaPkgItem = import("simple-git").DiffResultTextFile & McdevDeltaPkgItem; export type RestError = import("sfmc-sdk/util").RestError; export type SOAPError = import("sfmc-sdk/util").SOAPError; export type SDKError = SOAPError & RestError; /** * signals what to insert automatically for things usually asked via wizard */ export type SkipInteraction = { /** * client id of installed package */ client_id?: string; /** * client secret of installed package */ client_secret?: string; /** * tenant specific auth url of installed package */ auth_url?: string; /** * MID of the Parent Business Unit */ account_id?: number; /** * how you would like the credential to be named */ credentialName?: string; /** * URL of Git remote server */ gitRemoteUrl?: string; /** * will trigger re-downloading latest versions of dependent types after fixing keys */ fixKeysReretrieve?: boolean; /** * used by mcdev init to directly push to a remote */ gitPush?: string; /** * used by mcdev init to directly push to a remote */ developmentBu?: string; /** * used by mcdev init to directly push to a remote */ downloadBUs?: string; }; export type FilterItem = { /** * folder id */ categoryId: number; /** * - */ createdDate?: string; /** * key */ customerKey: string; /** * DE/List ID */ destinationObjectId: string; /** * 1:SubscriberList, 2:DataExtension, 3:GroupWizard, 4:BehavioralData */ destinationTypeId: 1 | 2 | 3 | 4; /** * ? */ filterActivityId: string; /** * ObjectID of filterDefinition */ filterDefinitionId: string; /** * - */ modifiedDate: string; /** * name */ name: string; /** * - */ description?: string; /** * DE/List ID */ sourceObjectId: string; /** * required for upsert; unknown purpose; set to null */ resultGroupFolderId: null; /** * required for upsert; unknown purpose; set to null */ resultGroupName: null; /** * required for upsert; unknown purpose; set to null */ sourceId: null; /** * 1:SubscriberList, 2:DataExtension, 3:GroupWizard, 4:BehavioralData */ sourceTypeId: 1 | 2 | 3 | 4; /** * seems to be a duplicate of sourceTypeId? */ filterDefinitionSourceTypeId?: 1 | 2 | 3 | 4; /** * description of destination DE */ resultDEDescription?: string; /** * name of destination DE */ resultDEName?: string; /** * key of destination DE */ resultDEKey?: string; /** * ? */ statusId: number; /** * relationship to filterDefinition */ r__dataFilter_key?: string; /** * relationship to dataExtension source */ r__source_dataExtension_key?: string; /** * relationship to dataExtension destination */ r__destination_dataExtension_key?: string; /** * relationship to folder */ r__folder_Path?: string; }; export type FilterMap = { [x: string]: FilterItem; }; /** * /automation/v1/filterdefinitions/<id> (not used) */ export type AutomationFilterDefinitionItem = { /** * object id */ id: string; /** * external key */ key: string; /** * - */ createdDate: string; /** * user id */ createdBy: number; /** * - */ createdName: string; /** * (omitted by API if empty) */ description?: string; /** * - */ modifiedDate: string; /** * user id */ modifiedBy: number; /** * - */ modifiedName: string; /** * name */ name: string; /** * folder id */ categoryId: string; /** * from REST API defines the filter in XML form */ filterDefinitionXml: string; /** * 1:list/profile attributes/measures, 2: dataExtension */ derivedFromType: 1 | 2; /** * ? */ isSendable: boolean; }; /** * /email/v1/filters/filterdefinition/<id> */ export type DataFilterItem = { /** * object id */ id: string; /** * external key */ key: string; /** * date */ createdDate: string; /** * user id */ createdBy: number; /** * name */ createdName: string; /** * (omitted by API if empty) */ description?: string; /** * date */ lastUpdated: string; /** * user id */ lastUpdatedBy: number; /** * name */ lastUpdatedName: string; /** * name */ name: string; /** * folder id */ categoryId: string; /** * from REST API defines the filter in XML form */ filterDefinitionXml: string; /** * 1:list/profile attributes/measures, 2: dataExtension */ derivedFromType: 1 | 2; /** * Id of DataExtension - present if derivedFromType=2 */ derivedFromObjectId: string; /** * - */ derivedFromObjectTypeName: "DataExtension" | "SubscriberAttributes"; /** * name of DataExtension */ derivedFromObjectName?: string; /** * ? */ isSendable: boolean; /** * copied from SOAP API, defines the filter in readable form */ c__filterDefinition?: { ConditionSet: FilterConditionSet; }; /** * relationship to list source (if derivedFromType=1) */ r__source_list_PathName?: string; /** * relationship to dataExtension source (if derivedFromType=2) */ r__source_dataExtension_key?: string; }; export type FilterConditionSet = { /** * - */ Condition: FilterCondition | FilterCondition[]; /** * - */ ConditionSet: FilterConditionSet; }; export type FilterCondition = { /** * comparison operator (actually \@_Operator) */ Operator: "IsEmpty" | "IsNotEmpty" | "Equals"; /** * object id of field (actually \@_ID) */ ID?: string; /** * filter value to compare against */ Value?: string; /** * name of field */ r__dataExtensionField_name?: string; }; export type DataFilterMap = { [x: string]: DataFilterItem; }; export type AuthObject = { /** * client_id client_id for sfmc-sdk auth */ client_id: string; /** * client_secret for sfmc-sdk auth */ client_secret: string; /** * mid of business unit to auth against */ account_id: number; /** * authentication base url */ auth_url: string; }; export type SoapRequestParams = { /** * request id */ continueRequest?: string; /** * additional options (CallsInConversation, Client, ConversationID, Priority, RequestType, SaveOptions, ScheduledTime, SendResponseTo, SequenceCode) */ options?: object; /** * ? */ clientIDs?: any; /** * simple or complex * complex */ filter?: SoapSDKFilter; /** * all BUs or just one */ QueryAllAccounts?: boolean; }; export type SoapFilterSimple = { /** * field */ property: string; /** * various options */ simpleOperator: "equals" | "notEquals" | "isNull" | "isNotNull" | "greaterThan" | "lessThan" | "greaterThanOrEqual" | "lessThanOrEqual" | "between" | "IN" | "in" | "like"; /** * field value */ value?: string | number | boolean | string[] | number[]; }; export type SoapFilterComplex = { /** * string for simple or a new filter-object for complex */ leftOperand: SoapSDKFilter; /** * various options */ logicalOperator: "AND" | "OR"; /** * string for simple or a new filter-object for complex; omit for isNull and isNotNull */ rightOperand: SoapSDKFilter; }; export type SoapSDKFilterSimple = { /** * string for simple or a new filter-object for complex */ leftOperand: SoapFilterSimple["property"]; /** * various options */ operator: SoapFilterSimple["simpleOperator"]; /** * string for simple or a new filter-object for complex; omit for isNull and isNotNull */ rightOperand?: SoapFilterSimple["value"]; }; export type SoapSDKFilterComplex = { /** * string for simple or a new filter-object for complex */ leftOperand: SoapFilterComplex["leftOperand"]; /** * various options */ operator: SoapFilterComplex["logicalOperator"]; /** * string for simple or a new filter-object for complex; omit for isNull and isNotNull */ rightOperand: SoapFilterComplex["rightOperand"]; }; export type SoapSDKFilter = SoapSDKFilterSimple | SoapSDKFilterComplex; export type AssetRequestParams = { /** * request id */ continueRequest?: string; /** * additional options (CallsInConversation, Client, ConversationID, Priority, RequestType, SaveOptions, ScheduledTime, SendResponseTo, SequenceCode) */ options?: object; /** * ? * complex */ clientIDs?: any; /** * pagination */ page?: object; /** * list of fields we want returned */ fields?: string[]; /** * pagination */ sort?: { property: string; direction: "ASC" | "DESC"; }[]; /** * simple or complex filter */ query?: AssetFilter | AssetFilterSimple; }; export type AssetFilter = { /** * string for simple or a new filter-object for complex */ leftOperand: AssetFilter | AssetFilterSimple; /** * various options */ logicalOperator: "AND" | "OR"; /** * string for simple or a new filter-object for complex; omit for isNull and isNotNull */ rightOperand?: SoapSDKFilter | AssetFilterSimple; }; export type AssetFilterSimple = { /** * field */ property: string; /** * various options */ simpleOperator: "equal" | "notEquals" | "isNull" | "isNotNull" | "greaterThan" | "lessThan" | "greaterThanOrEqual" | "lessThanOrEqual" | "between" | "IN" | "in" | "like"; /** * field value */ value: string | number | boolean | any[]; }; export type Mcdevrc = { /** * list of credentials */ credentials: object; /** * configure options for mcdev */ options: object; /** * configure directories for mcdev to read/write to */ directories: { businessUnits: string; deploy: string; docs: string; retrieve: string; template: string; templateBuilds: string; }; /** * templating variables grouped by markets */ markets: { [x: string]: any; }; /** * combination of markets and BUs for streamlined deployments */ marketList: object; /** * templating variables grouped by markets */ metaDataTypes: { retrieve: string[]; createDeltaPkg: string[]; documentOnRetrieve: string[]; }; /** * mcdev version that last updated the config file */ version: string; }; export type LoggerLevel = "error" | "verbose" | "info" | "debug"; export type McdevLogger = { /** * (msg) print info message */ level?: LoggerLevel; /** * (msg) print error message; wrapper around winstonLogger.error that also sets error code to 1 */ error: (msg: string) => void; /** * print error with trace message */ errorStack: (ex: SDKError, message?: string) => void; }; export type Logger = import("winston").Logger & McdevLogger; export type AssetItemSimple = { id: number; key: string; name: string; }; export type AssetItemSimpleMap = { [x: string]: AssetItemSimple; }; export type AssetItemIdSimpleMap = { [x: number]: AssetItemSimple; }; export type ContentBlockConversionTypes = "id" | "key" | "name"; export type ExplainType = { /** * readable name of type */ name: string; /** * api parameter name for type */ apiName: string; /** * more info on what this type is about */ description: string; /** * is it retrieved by default OR list of subtypes that are retrieved by default */ retrieveByDefault: boolean | string[]; /** * supported features */ supports: { retrieve: boolean; create: boolean; update: boolean; delete: boolean; changeKey: boolean; buildTemplate: boolean; retrieveAsTemplate: boolean; }; }; export type ListItem = { /** * wrapper */ Client?: { ID: number; }; /** * not used */ PartnerKey?: string; /** * "2021-06-21T11:54:57.103" */ CreatedDate?: string; /** * "2021-06-21T11:54:57.103" */ ModifiedDate?: string; /** * unique identifier per BU */ ID?: number; /** * not used */ ObjectID?: string; /** * unique identifer per BU */ CustomerKey?: string; /** * customn field that tracks the exact directory path of the current folder including its own name */ Path?: string; /** * wrapper */ ParentFolder?: { ID: number; ObjectID?: string; Path?: string; }; /** * folder name */ Name: string; /** * deprecated option to describe the folder content */ Description?: string; /** * e.g. "shared_data"; see folder-subtypes for complete list */ ContentType: string; /** * ? */ IsActive: boolean; /** * option to disable renaming/moving this folder via GUI */ IsEditable: boolean; /** * option to prevent creating subfolders via GUI */ AllowChildren: boolean; /** * helper flag for Deployer class to signal if the folder was auto-generated or manually placed */ _generated?: boolean; }; /** * key=id */ export type ListIdMap = { [x: number]: ListItem; }; /** * key=customer key */ export type ListMap = { [x: string]: ListItem; }; /** * returned by /data/v1/integration/member/salesforce/object/<OBJECT NAME>/referenceobjects */ export type ReferenceObject = { /** * label */ displayname: string; /** * api name of salesforce object */ referenceObjectName: string; /** * name of lookup/MD field on related object ending on __r (way to return fields from other object) */ relationshipName: string; /** * name of lookup/MD field on related object ending on __c (returning id) */ relationshipIdName: string; /** * if this lookup can point to multiple objects or not */ isPolymorphic: boolean; }; /** * returned by /legacy/v1/beta/integration/member/salesforce/object/<OBJECT NAME> */ export type SfObjectPicklist = { /** * - */ active: boolean; /** * - */ defaultValue: boolean; /** * what you see in the GUI */ label: string; /** * whats stored in the DB */ value: string; }; /** * returned by /legacy/v1/beta/integration/member/salesforce/object/<OBJECT NAME> */ export type SfObjectField = { /** * "Annual Revenue" */ label: string; /** * "AnnualRevenue" */ name: string; /** * type */ datatype: "currency" | "string" | "int" | "picklist" | "textarea" | "boolean" | "date" | "datetime" | "email"; /** * 0-4000 */ length: number; /** * == not required */ nillable: boolean; /** * is it a custom field */ custom: boolean; /** * always true? */ updateable: boolean; /** * always true? */ createable: boolean; /** * - */ defaultedoncreate: boolean; /** * - */ externalid: boolean; /** * - */ idlookup: boolean; /** * - */ precision: number; /** * - */ scale: number; /** * "Currency" */ displaydatatype: "Currency" | "Text" | "Number" | "Picklist" | "Text Area (long)" | "Checkbox" | "Date" | "Date/Time" | "Email"; /** * "Lead", */ objectname: string; /** * "", */ relationname: string; /** * - */ isnamefield: boolean; /** * list of values */ picklist?: SfObjectPicklist[]; }; export type configurationArguments = { /** * SalesforceObjectTriggerV2 */ applicationExtensionKey: string; /** * 3.0 */ version: string; /** * what record event in SF triggers this */ salesforceTriggerCriteria: "Created" | "Updated" | "CreatedUpdated"; /** * what objects are used by this event */ eventDataConfig: { objects: eventDataConfigObject[]; }; /** * TODO */ primaryObjectFilterCriteria: Conditions; /** * TODO */ relatedObjectFilterCriteria: Conditions; /** * seems to only exist on journey but not on event and also not on every journey */ additionalObjectFilterCriteria?: object; /** * defines how this event links to the all contacts list */ contactKey: { relationshipIdName: string; relationshipName: string; isPolymorphic: boolean; referenceObjectName: string; fieldName?: string; }; /** * TODO */ passThroughArgument: { fields: { ContactKey: string; Email: object; HasOptedOutOfEmail?: string; }; }; /** * primaryObjectFilterCriteria in simplified string-form */ primaryObjectFilterSummary: string; /** * relatedObjectFilterCriteria in simplified string-form */ relatedObjectFilterSummary: string; /** * eventDataConfig in simplified string-form */ eventDataSummary: string[]; /** * salesforceTriggerCriteria plus semi-colon */ evaluationCriteriaSummary: "Created;" | "Updated;" | "Created;Updated;"; /** * if objectAPIName==CampaignMember then this is also CampaignMember; otherwise it's Contact */ contactPersonType: "CampaignMember" | "Contact"; /** * the SF object on which the salesforceTriggerCriteria is listening on */ objectAPIName: string; /** * "objectAPIName (Contact / Lead / Contacts and Leads)" */ whoToInject: string; /** * empty string for SF events */ criteria: string; /** * set to 0 for SF events */ schemaVersionId: number; }; /** * part of configurationArguments */ export type eventDataConfigObject = { /** * CampaignMember:Campaign: */ dePrefix: string; /** * ? */ isPolymorphic: boolean; /** * field on parent object containing the id; ends on __c for custom fields; same as referenceObject for standard fields; can be "Contacts and Leads" */ referenceObject: string; /** * field on parent object acting as lookup; ends on __r for custom fields; same as referenceObject for standard fields; can be "Common" */ relationshipName: string; /** * ? */ relationshipIdName?: string; /** * list of field names that are used by this journey */ fields: string[]; }; /** * part of configurationArguments */ export type Conditions = { /** * - */ operand: "AND" | "OR"; /** * list of conditions */ conditions: (Conditions | FieldCondition)[]; }; /** * part of configurationArguments */ export type FieldCondition = { /** * is 0 for booleans, otherwise field length */ _length: number; /** * type */ datatype: "currency" | "string" | "int" | "picklist" | "textarea" | "boolean" | "date" | "datetime" | "email"; /** * field API name; "TR1__Email__c" */ fieldName: string; /** * "CampaignMember-CampaignMember" */ folderId: string; /** * "CampaignMember-CampaignMember-TR1__Email__c" */ id: string; /** * ? */ isPolymorphic: boolean; /** * likely the field label; "Email" */ name: string; /** * condition comparator */ operator: "equals" | "EQUALS" | "WASSET"; /** * value to compare the field with if operator is sth like "equals"; booleans are stored as upper-camel-case string! */ value?: string; /** * ? */ precision: number; /** * "Contacts and Leads" */ referenceObjectName: string; /** * "CommonId"; can be an empty string */ relationshipIdName: string; /** * "Common"; can be an empty string */ relationshipName: string; /** * ? */ scale: number; /** * seems to be equal to name-attribute?; "Email" */ text: string; }; export type validationRuleFix = () => boolean | null; export type validationRuleTest = () => boolean; export type validationRule = { /** * error message to display in case of a failed test */ failedMsg: string; /** * test to run */ passed: validationRuleTest; /** * test to run */ fix?: validationRuleFix; }; /** * key=rule name */ export type validationRuleList = { [x: string]: validationRule; }; export type DomainVerificationItem = { /** * EID */ enterpriseId?: number; /** * MID */ memberId?: number; /** * domain or email address used in retrieve and create */ domain?: string; /** * email address used in update call for isSendable field */ emailAddress?: string; /** * returned by retrieve */ status?: "Verified" | "Pending"; /** * returned by retrieve and required for update call */ domainType?: "SAP" | "UserDomain" | "PrivateDomain" | "RegisteredDomain"; /** * automatically true upon creation. can be changed to false via update */ isSendable: boolean; /** * e.g. ""2023-06-19T11:11:17.32"" */ emailSendTime?: string; /** * for bulk-creation only: email address to send notifications to when done */ notificationEmail?: string; /** * for bulk-creation only: list of email addresses to verify */ addresses?: string[]; /** * for bulk-creation only: instead of an array in addresses, specify the name of a DE */ deTable?: string; /** * for bulk-creation only: instead of an array in addresses, specify the name of a DE column/field here */ deColumn?: string; }; export type BuildFilter = { /** * include key filters */ include?: BuildFilterKeys; /** * exclude key filters */ exclude?: BuildFilterKeys; }; export type BuildFilterKeys = { /** * object with keys representing metadata types ("*" for all types, or specific type names) and values being arrays of string patterns to match against */ key?: any; }; //# sourceMappingURL=mcdev.d.d.ts.map ================================================ FILE: CONTRIBUTING.md ================================================ <h1 id="contributing-to-sfmc-devtools">Contributing to Accenture Salesforce Marketing Cloud DevTools</h1> <p>First and foremost, thank you! We appreciate that you want to contribute to Accenture Salesforce Marketing Cloud DevTools, your time is valuable, and your contributions mean a lot to us.</p> <h2 id="important-">Important!</h2> <p>By contributing to this project, you:</p> <ul> <li>Agree that you have authored 100% of the content</li> <li>Agree that you have the necessary rights to the content</li> <li>Agree that you have received the necessary permissions from your employer to make the contributions (if applicable)</li> <li>Agree that the content you contribute may be provided under the Project license(s)</li> <li>Agree that, if you did not author 100% of the content, the appropriate licenses and copyrights have been added along with any other necessary attribution.</li> </ul> <h2 id="getting-started">Getting started</h2> <p><strong>What does "contributing" mean?</strong></p> <p>Creating an issue is the simplest form of contributing to a project. But there are many ways to contribute, including the following:</p> <ul> <li>Updating or correcting documentation</li> <li>Feature requests</li> <li>Bug reports</li> </ul> <h2 id="issues">Issues</h2> <p>Please only create issues for bug reports or feature requests. Issues discussing any other topics may be closed by the project's maintainers without further explanation.</p> <p>Do not create issues about bumping dependencies unless a bug has been identified and you can demonstrate that it effects this repo.</p> ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020-2025 Accenture Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Accenture SFMC DevTools [![view on npm](https://badgen.net/github/release/Accenture/sfmc-devtools)](https://www.npmjs.org/package/mcdev) [![view on npm](https://badgen.net/npm/node/mcdev)](https://www.npmjs.org/package/mcdev) [![license](https://badgen.net/npm/license/mcdev)](https://www.npmjs.org/package/mcdev) [![npm module downloads](https://badgen.net/npm/dt/mcdev)](https://www.npmjs.org/package/mcdev) [![GitHub closed issues](https://badgen.net/github/closed-issues/Accenture/sfmc-devtools)](https://github.com/Accenture/sfmc-devtools/issues?q=is%3Aissue+is%3Aclosed) [![GitHub releases](https://badgen.net/github/releases/Accenture/sfmc-devtools)](https://github.com/Accenture/sfmc-devtools/releases) Accenture Salesforce Marketing Cloud DevTools (mcdev) is a rapid deployment/rollout, backup and development tool for Salesforce Marketing Cloud. It allows you to retrieve and deploy configuration and code across Business Units and instances. ## Quick start ### Install Run the following to install Accenture SFMC DevTools on your computer: ```bash npm install -g mcdev ``` ### VSCode Extension We also provide a [VSCode extension](https://marketplace.visualstudio.com/items?itemName=Accenture-oss.sfmc-devtools-vscode) that integrates SFMC DevTools into your IDE. You can install it from the [VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=Accenture-oss.sfmc-devtools-vscode). ### Include in your package First, install it as dependency: ```bash npm install mcdev --save ``` You can then include it in your code with JavaScript/ES module imports: ```javascript import mcdev from 'mcdev'; ``` That will load `node_packages/mcdev/lib/index.js`. It can make sense to directly include other files if you have a special scenario. We've done that in our example for [retrieveChangelog.js](https://github.com/Accenture/sfmc-devtools/blob/main/lib/retrieveChangelog.js) or in more detail, in our child-project [sfmc-devtools-copado](https://github.com/Accenture/sfmc-devtools-copado) to get full control over certain aspects. ## Documentation Please checkout the [GitHub wiki](https://github.com/Accenture/sfmc-devtools/wiki) for the full documentation. ## Changelog Find info on the latest releases with a detailed changelog in the [GitHub Releases tab](https://github.com/Accenture/sfmc-devtools/releases). ## Contribute If you want to enhance Accenture SFMC DevTools you are welcome to fork the repo and create a pull request. Please understand that we will have to conduct a code review before accepting your changes. More details on how to best do that are described in our [wiki](https://github.com/Accenture/sfmc-devtools/wiki/10.-Contribute). ## Main Contacts The people that lead this project: <table><tbody><tr><td align="center" valign="top" width="11%"> <a href="https://www.linkedin.com/in/joernberkefeld/"> <img src="https://github.com/JoernBerkefeld.png" width="250" height="250"><br /> <b>Jörn Berkefeld</b> </a><br> <a href="https://github.com/JoernBerkefeld">GitHub profile</a> </td><td align="center" valign="top" width="11%"> <a href="https://www.linkedin.com/in/douglasmidgley/"> <img src="https://github.com/DougMidgley.png" width="250" height="250"><br /> <b>Doug Midgley</b> </a><br> <a href="https://github.com/DougMidgley">GitHub profile</a> </td></tr></tbody></table> ## Copyright Copyright (c) 2020-2025 Accenture. [MIT licensed](https://github.com/Accenture/sfmc-devtools/blob/main/LICENSE). ================================================ FILE: boilerplate/config.json ================================================ { "credentials": { "default": { "eid": 0, "businessUnits": {} } }, "options": { "formatOnSave": true, "formatErrorLog": false, "deployment": { "commitHistory": 10, "sourceTargetMapping": { "deployment-source": "deployment-target" }, "branchSourceTargetMapping": { "sit": { "deployment-sit-source": "deployment-sit-target" }, "uat": { "deployment-uat-source": "deployment-uat-target" }, "prod": { "deployment-prod-source": "deployment-prod-target" } }, "targetBranchBuMapping": { "release/*": "MySandbox/QA-DE", "master": ["MyProduction/PROD-DE", "MyProduction/PROD-NL"] } }, "validation": { "retrieve": { "noAmpscriptHtmlTag": "warn", "noGuidKeys": "warn", "noRootFolder": "warn" }, "buildDefinition": { "noAmpscriptHtmlTag": "warn", "noGuidKeys": "warn", "noRootFolder": "warn" }, "deploy": { "noAmpscriptHtmlTag": "warn", "noGuidKeys": "warn", "noRootFolder": "warn", "overrides": [ { "type": ["journey"], "options": { "noGuidKeys": "warn" } } ] } }, "documentType": "md", "documentStandardRoles": false, "exclude": {}, "include": {}, "serverTimeOffset": -6 }, "directories": { "businessUnits": "businessUnits/", "deploy": "deploy/", "docs": "docs/", "retrieve": "retrieve/", "template": "template/", "templateBuilds": ["retrieve/", "deploy/"] }, "markets": { "DEV-NL": { "mid": "12345", "buName": "DEV - Child NL", "sharedFolder": "/Shared Data Extensions/DEV/NL", "suffix": "_DEV_NL", "countryCodeIn": "'NL'" }, "QA-DE": { "mid": "12346", "buName": "QA - Child DE", "sharedFolder": "/Shared Data Extensions/QA/DE", "suffix": "_QA_DE", "countryCodeIn": "'DE'" }, "PROD-DE": { "mid": "12349", "buName": "DE - Germany", "sharedFolder": "/Shared Data Extensions/DE - Germany", "suffix": "_DE", "countryCodeIn": "'DE'" }, "PROD-NL": { "mid": "12351", "buName": "NL - Netherlands", "sharedFolder": "/Shared Data Extensions/NL - Netherlands", "suffix": "_NL", "countryCodeIn": "'NL'" } }, "marketList": { "deployment-source": { "description": "Define one 1:1 BU-Market combo here to as source for automated creation of deployment packages; you can create more than one source market list" }, "deployment-target": { "description": "Define n BU-Market combo here to as target for automated creation of deployment packages; you can create more than one target market list and they can be as complex as you like" } }, "metaDataTypes": { "documentOnRetrieve": ["user", "automation", "dataExtension", "role"], "retrieve": [], "createDeltaPkg": [] } } ================================================ FILE: boilerplate/files/.beautyamp.json ================================================ { "ampscript": { "capitalizeAndOrNot": true, "capitalizeIfFor": true, "capitalizeSet": true, "capitalizeVar": true, "maxParametersPerLine": 4 }, "editor": { "insertSpaces": true, "tabSize": 4 } } ================================================ FILE: boilerplate/files/.editorconfig ================================================ root = true [*] end_of_line = lf indent_style = space indent_size = 4 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true ================================================ FILE: boilerplate/files/.gitattributes ================================================ # Set the default behavior, in case people don't have core.autocrlf set. * text=auto eol=lf # Declare files that will always have LF line endings on checkout. *.ssjs text eol=lf gitlab-language=javascript ================================================ FILE: boilerplate/files/.npmrc ================================================ save-prefix='~' ================================================ FILE: boilerplate/files/.prettierrc ================================================ { "useTabs": false, "tabWidth": 4, "printWidth": 100, "singleQuote": true, "trailingComma": "none", "overrides": [ { "files": "*.ssjs", "options": { "parser": "babel", "trailingComma": "none" } }, { "files": "*.sql", "options": { "formatter": "sql-formatter", "language": "tsql", "identifierCase": "preserve", "dataTypeCase": "preserve", "functionCase": "upper", "keywordCase": "upper" } }, { "files": ".mcdev-validations.js", "options": { "trailingComma": "es5" } } ] } ================================================ FILE: boilerplate/files/.vscode/extensions.json ================================================ { // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp // List of extensions which should be recommended for users of this workspace. "recommendations": [ // collaboration "Accenture-oss.sfmc-devtools-vscode", "aaron-bond.better-comments", "johnpapa.vscode-peacock", // Linters "dbaeumer.vscode-eslint", // Formatting & colors "editorconfig.editorconfig", "esbenp.prettier-vscode", "xnerd.ampscript-language", "FiB.beautyAmp", // coding helper "MarketingThibs.ampscriptsnippets", // file icons for ampscript "vscode-icons-team.vscode-icons", // Markdown / Readme.md "joernberkefeld.markdown-preview-bitbucket-innersource" ] } ================================================ FILE: boilerplate/files/.vscode/settings.json ================================================ { "explorer.compactFolders": false, "explorer.fileNesting.enabled": true, "explorer.fileNesting.expand": false, "explorer.fileNesting.patterns": { "*.ts": "${capture}.js", "*.js": "${capture}.js.map, ${capture}.min.js, ${capture}.d.ts, ${capture}.asset-code-meta.json", "*.jsx": "${capture}.js", "*.tsx": "${capture}.ts", "tsconfig.json": "tsconfig.*.json", "package.json": "package-lock.json, yarn.lock", "*-doc.md": "${capture}-meta.json", "*-meta.amp": "${capture}-meta.json", "*-meta.html": "${capture}-meta.json", "*-meta.sql": "${capture}-meta.json", "*-meta.ssjs": "${capture}-meta.json", "*-meta.js": "${capture}-meta.json", "*-meta.css": "${capture}-meta.json", "*-meta.rss": "${capture}-meta.json", "*-meta.txt": "${capture}-meta.json", "*-meta.xml": "${capture}-meta.json", "*.asset-asset-meta.html": "${dirname}.asset-asset-meta.json", "*.asset-message-meta.html": "${dirname}.asset-message-meta.json", "*.asset-template-meta.html": "${dirname}.asset-template-meta.json", "*.css": "${capture}.asset-code-meta.json", "*.docx": "${capture}.asset-document-meta.json", "*.eps": "${capture}.asset-image-meta.json", "*.gif": "${capture}.asset-image-meta.json", "*.html": "${capture}.asset-code-meta.json", "*.ics": "${capture}.asset-document-meta.json", "*.jpeg": "${capture}.asset-image-meta.json", "*.jpg": "${capture}.asset-image-meta.json", "*.pdf": "${capture}.asset-document-meta.json", "*.png": "${capture}.asset-image-meta.json", "*.txt": "${capture}.asset-textfile-meta.json" }, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "editor.formatOnSave": true, "files.associations": { "*.ssjs": "javascript", "*.html": "ampscript" }, "files.eol": "\n", "files.exclude": { "node_modules": true }, "javascript.validate.enable": false, "[sql]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[html]": { "editor.defaultFormatter": "FiB.beautyAmp" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[AMPscript]": { "editor.defaultFormatter": "FiB.beautyAmp" }, "vsicons.associations.files": [ { "icon": "apex", "languages": [ { "ids": "ampscript", "defaultExtension": "amp" }, { "ids": "AMPscript", "defaultExtension": "amp" } ], "light": true, "format": "FileFormat.svg" } ] } ================================================ FILE: boilerplate/files/README.md ================================================ # Salesforce Marketing Cloud - powered by Accenture Accenture SFMC DevTools This project relies on **Accenture SFMC DevTools**! - Get it, check out the official docs & get support here: https://github.com/Accenture/sfmc-devtools --- © 2024 Accenture - [www.accenture.com](https://www.accenture.com/) ================================================ FILE: boilerplate/files/eslint.config.js ================================================ import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import eslintPluginUnicorn from 'eslint-plugin-unicorn'; import globals from 'globals'; import jsdoc from 'eslint-plugin-jsdoc'; import js from '@eslint/js'; import sfmcSsjs from 'eslint-config-ssjs'; export default [ { ignores: ['deploy/**/*', 'docs/**/*', 'logs/**/*', 'node_modules/**/*', 'template/**/*'] }, js.configs.recommended, eslintPluginPrettierRecommended, jsdoc.configs['flat/recommended'], eslintPluginUnicorn.configs['flat/recommended'], { plugins: { jsdoc }, rules: { 'unicorn/better-regex': 'off', 'unicorn/prefer-string-raw': 'off', 'unicorn/catch-error-name': [ 'error', { name: 'ex' } ], 'unicorn/explicit-length-check': 'off', 'unicorn/no-null': 'off', 'unicorn/prefer-module': 'off', 'unicorn/prevent-abbreviations': 'off', 'unicorn/filename-case': 'off', 'unicorn/no-array-callback-reference': 'off', 'unicorn/no-array-reduce': 'off', 'unicorn/no-await-expression-member': 'off', 'unicorn/no-hex-escape': 'off', 'unicorn/no-nested-ternary': 'off', 'unicorn/no-static-only-class': 'off', 'unicorn/no-unused-properties': 'warn', 'unicorn/numeric-separators-style': 'off', 'unicorn/prefer-array-some': 'off', 'unicorn/prefer-set-has': 'off', 'unicorn/prefer-spread': 'off', 'unicorn/prefer-string-replace-all': 'error', 'padded-blocks': 'off', 'prefer-rest-params': 'off', 'prefer-spread': 'off', 'jsdoc/require-jsdoc': [ 'warn', { require: { FunctionDeclaration: true, MethodDefinition: true, ClassDeclaration: true, ArrowFunctionExpression: false, FunctionExpression: true } } ], 'valid-jsdoc': 'off', 'spaced-comment': [ 'warn', 'always', { block: { exceptions: ['*'], balanced: true } } ] } }, { ...sfmcSsjs.configs.recommended, files: ['**/*.ssjs'], rules: { 'unicorn/text-encoding-identifier-case': 'off', 'unicorn/prefer-string-replace-all': 'off' } }, { files: ['**/*.js'], languageOptions: { globals: { ...globals.browser }, ecmaVersion: 2022 }, rules: { 'no-var': 'error', 'prefer-const': 'error', 'prettier/prettier': 'warn' } }, { files: ['lib/**.js', '.mcdev-validations.js'], languageOptions: { globals: { ...globals.nodeBuiltin }, ecmaVersion: 2022, sourceType: 'module' }, settings: { jsdoc: { mode: 'typescript', preferredTypes: { array: 'Array', 'array.<>': '[]', 'Array.<>': '[]', 'array<>': '[]', 'Array<>': '[]', Object: 'object', 'object.<>': 'Object.<>', 'object<>': 'Object.<>', 'Object<>': 'Object.<>', set: 'Set', 'set.<>': 'Set.<>', 'set<>': 'Set.<>', 'Set<>': 'Set.<>', promise: 'Promise', 'promise.<>': 'Promise.<>', 'promise<>': 'Promise.<>', 'Promise<>': 'Promise.<>' } } }, rules: { 'logical-assignment-operators': ['error', 'always'], 'arrow-body-style': ['error', 'as-needed'], curly: 'error', 'jsdoc/check-line-alignment': 2, 'jsdoc/require-jsdoc': [ 'warn', { require: { FunctionDeclaration: true, MethodDefinition: true, ClassDeclaration: true, ArrowFunctionExpression: false, FunctionExpression: true } } ], 'jsdoc/require-param-type': 'error', 'jsdoc/tag-lines': [ 'warn', 'any', { startLines: 1 } ], 'jsdoc/no-undefined-types': 'off', 'jsdoc/valid-types': 'off', 'spaced-comment': [ 'warn', 'always', { block: { exceptions: ['*'], balanced: true } } ], 'no-var': 'error', 'prefer-const': 'error', 'prettier/prettier': 'warn' } }, { files: ['eslint.config.js'], languageOptions: { globals: { ...globals.node }, ecmaVersion: 2022 }, rules: { 'no-var': 'error', 'prefer-const': 'error', 'prettier/prettier': 'warn' } } ]; ================================================ FILE: boilerplate/forcedUpdates.json ================================================ [ { "version": "7.9.1", "files": ["eslint.config.js"] }, { "version": "7.7.2", "files": [".vscode/extensions.json"] }, { "version": "7.7.0", "files": [".gitignore"] }, { "version": "7.6.2", "files": [".vscode/extensions.json"] }, { "version": "7.4.3", "files": ["eslint.config.js", ".prettierrc"] }, { "version": "7.4.2", "files": [".vscode/settings.json"] }, { "version": "7.4.1", "files": [".gitignore"] }, { "version": "7.3.2", "files": [".gitattributes"] }, { "version": "7.3.1", "files": [".vscode/settings.json"] }, { "version": "7.3.0", "files": [".vscode/settings.json"] }, { "version": "7.1.0", "files": [".vscode/settings.json", ".gitignore"] }, { "version": "7.0.3", "files": ["eslint.config.js"], "filesRemove": [".eslintignore", ".eslintrc"] }, { "version": "7.0.0", "files": [ ".vscode/extensions.json", ".vscode/settings.json", ".beautyamp.json", ".prettierrc" ] }, { "version": "5.0.0", "files": [".vscode/settings.json", ".prettierrc"] }, { "version": "4.3.4", "files": [".vscode/settings.json"] }, { "version": "4.1.12", "files": [".vscode/settings.json"] }, { "version": "4.1.1", "files": [".vscode/settings.json"] }, { "version": "4.0.0", "files": [".vscode/settings.json", ".vscode/extensions.json", ".prettierrc"] }, { "version": "3.1.0", "files": [".vscode/settings.json"] } ] ================================================ FILE: boilerplate/gitignore-template ================================================ *.DS_Store node_modules/ /deploy/ /docs/badKeys/ /logs/ **/QueryStudioResults at* .mcdev-auth.json .mcdev/template/ *.error.log *.BAK ================================================ FILE: boilerplate/npm-dependencies.json ================================================ [ "@eslint/js", "eslint-config-prettier", "eslint-config-ssjs", "eslint-plugin-jsdoc", "eslint-plugin-prettier", "eslint-plugin-unicorn", "eslint", "globals", "prettier-plugin-sql", "prettier", "sfmc-boilerplate" ] ================================================ FILE: docs/dist/considerations.md ================================================ # Metadata Type findings & considerations ## Automation API: SOAP / REST ## Campaign API: SOAP Child Metadata: - [CampaignAsset](#CampaignAsset) ## CampaignAsset API: SOAP ## DataExtension API: SOAP Child Metadata: - [DataExtensionField](#DataExtensionField) Considerations: - **"SendableSubscriberField": { "Name": "\_SubscriberKey" }** is part of a DataExtension while retrieving, but a DataExtension cannot be created/updated with this property. **\_SubscriberKey** must be replaced with **Subscriber Key** before creating/updating - The referenced **CategoryID** represents the folder in which the DataExtension is located. these IDs are auto generated and therefore differ between BUs. When a DataExtension is deployed between BUs, the **CategoryID**s must be mapped between source and target ## DataExtensionField API: SOAP Considerations: - DataExtensionFields can only be created or updated - Instead of using the **CustomerKey** for updates like other metadata types, it uses the **ObjectID** which is auto generated and therefore different in each BU. ObjectIDs must be mapped between source and target if they are deployed between BUs - Some properties cannot be updated, but are also not throwing an error when they are part of the request (e.g. **Scale**) ## Email API: SOAP ## Folder API: SOAP Child Metadata: - [DataExtension](#DataExtension) - [Automation](#Automation) Considerations: - Folders are identified by their **ID** instead of their **CustomerKey**, this **ID** is auto generated and therefore different in each BU. - **CustomerKey** field can be empty and the **Name** only needs to be unique inside a sub-folder. A unique identifier can be created by building the complete path of a folder (e.g. **/grandparent/parent/folder**). Such a unique identifier can be used to map Folder **ID**s between BUs. This kind of mapping does not support moving folders into other subfolders, because the unique identifier would then change ## List API: SOAP ## Query API: SOAP ================================================ FILE: eslint.config.js ================================================ import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import eslintPluginUnicorn from 'eslint-plugin-unicorn'; import globals from 'globals'; import mochaPlugin from 'eslint-plugin-mocha'; import jsdoc from 'eslint-plugin-jsdoc'; import js from '@eslint/js'; export default [ { ignores: ['docs/**/*', 'node_modules/**/*', 'retrieve/**/*'], }, js.configs.recommended, eslintPluginPrettierRecommended, mochaPlugin.configs.recommended, jsdoc.configs['flat/recommended'], eslintPluginUnicorn.configs['recommended'], { languageOptions: { globals: { ...globals.nodeBuiltin, Atomics: 'readonly', SharedArrayBuffer: 'readonly', }, ecmaVersion: 2022, sourceType: 'module', }, settings: { jsdoc: { mode: 'typescript', preferredTypes: { array: 'Array', 'array.<>': '[]', 'Array.<>': '[]', 'array<>': '[]', 'Array<>': '[]', Object: 'object', 'object.<>': 'Object.<>', 'object<>': 'Object.<>', 'Object<>': 'Object.<>', set: 'Set', 'set.<>': 'Set.<>', 'set<>': 'Set.<>', 'Set<>': 'Set.<>', promise: 'Promise', 'promise.<>': 'Promise.<>', 'promise<>': 'Promise.<>', 'Promise<>': 'Promise.<>', }, }, }, rules: { 'logical-assignment-operators': ['error', 'always'], 'unicorn/better-regex': 'off', 'unicorn/catch-error-name': [ 'error', { name: 'ex', }, ], 'unicorn/explicit-length-check': 'off', 'unicorn/filename-case': 'off', 'unicorn/no-array-callback-reference': 'off', 'unicorn/no-array-reduce': 'off', 'unicorn/no-await-expression-member': 'off', 'unicorn/no-empty-file': 'off', 'unicorn/no-hex-escape': 'off', 'unicorn/no-nested-ternary': 'off', 'unicorn/no-null': 'off', 'unicorn/no-static-only-class': 'off', 'unicorn/no-unused-properties': 'warn', 'unicorn/numeric-separators-style': 'off', 'unicorn/prefer-array-some': 'off', 'unicorn/prefer-module': 'off', 'unicorn/prefer-set-has': 'off', 'unicorn/prefer-spread': 'off', 'unicorn/prefer-string-replace-all': 'error', 'unicorn/prevent-abbreviations': 'off', 'arrow-body-style': ['error', 'as-needed'], curly: 'error', 'no-console': 'error', 'jsdoc/check-line-alignment': 2, 'jsdoc/require-jsdoc': [ 'warn', { require: { FunctionDeclaration: true, MethodDefinition: true, ClassDeclaration: true, ArrowFunctionExpression: false, FunctionExpression: true, }, }, ], 'jsdoc/require-param-type': 'error', 'jsdoc/tag-lines': [ 'warn', 'any', { startLines: 1, }, ], 'jsdoc/no-undefined-types': 'off', 'jsdoc/valid-types': 'off', 'spaced-comment': [ 'warn', 'always', { block: { exceptions: ['*'], balanced: true, }, }, ], }, }, { files: ['**/*.js'], rules: { 'no-var': 'error', 'prefer-const': 'error', 'prettier/prettier': 'warn', 'prefer-arrow-callback': 'warn', }, }, { files: ['test/*.js'], rules: { 'mocha/no-mocha-arrows': 'off', 'mocha/no-pending-tests': 'off', }, }, ]; ================================================ FILE: lib/Builder.js ================================================ 'use strict'; import { Util } from './util/util.js'; import File from './util/file.js'; import config from './util/config.js'; import Cli from './util/cli.js'; import auth from './util/auth.js'; import MetadataTypeInfo from './MetadataTypeInfo.js'; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * Builds metadata from a template using market specific customisation */ class Builder { /** * Creates a Builder, uses v2 auth if v2AuthOptions are passed. * * @param {Mcdevrc} properties properties for auth saved * @param {BuObject} buObject properties for auth */ constructor(properties, buObject) { this.properties = properties; this.templateDir = properties.directories.template; this.retrieveDir = File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]); this.buObject = buObject; // allow multiple target directories const templateBuildsArr = Array.isArray(properties.directories.templateBuilds) ? properties.directories.templateBuilds : [properties.directories.templateBuilds]; this.targetDir = templateBuildsArr.map((directoriesTemplateBuilds) => File.normalizePath([ directoriesTemplateBuilds, buObject.credential, buObject.businessUnit, ]) ); /** * @type {MultiMetadataTypeList} */ this.metadata = {}; } /** * Builds a specific metadata file by name * * @param {string} metadataType metadata type to build * @param {string[]} nameArr name of metadata to build * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MultiMetadataTypeList>} Promise */ async _buildDefinition(metadataType, nameArr, templateVariables) { const type = metadataType; try { const result = ( await Promise.all( nameArr.map((name) => { // with npx and powershell spaces are not parsed correctly as part of a string // we hence require users to put %20 in their stead and have to convert that back name = name.split('%20').join(' '); MetadataTypeInfo[type].client = auth.getSDK(this.buObject); MetadataTypeInfo[type].properties = this.properties; MetadataTypeInfo[type].buObject = this.buObject; return MetadataTypeInfo[type].buildDefinition( this.templateDir, this.targetDir, name, templateVariables ); }) ) ).filter(Boolean); if (result && type === result[0]?.type) { // result elements can be undefined for each key that we did not find this.metadata[type] = result.map((element) => element.metadata); } } catch (ex) { Util.logger.errorStack(ex, 'mcdev.buildDefinition'); } return this.metadata; } /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} keyArr customerkey of the metadata * @param {string[]} marketArr market localizations * @returns {Promise.<MultiMetadataTypeList>} - */ static async buildTemplate(businessUnit, selectedType, keyArr, marketArr) { const properties = await config.getProperties(); if (!properties) { return; } if (!Util._isValidType(selectedType)) { return; } if (selectedType.includes('-')) { Util.logger.error( `:: '${selectedType}' is not a valid metadata type. Please don't include subtypes.` ); return; } /** @type {TemplateMap} */ const templateVariables = {}; if (marketArr[0] !== '__clone__') { // if __clone__ is passed, we don't want to actually change anything but simply clone the metadata as-is for (const market of marketArr) { if (Util.checkMarket(market, properties)) { Object.assign(templateVariables, properties.markets[market]); } else { // do not execute the rest of this method if a market was invalid return; } } } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (buObject !== null) { const builder = new Builder(properties, buObject); return builder._buildTemplate(selectedType, keyArr, templateVariables); } } /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} metadataType metadata type to create a template of * @param {string[]} keyArr customerkey of metadata to create a template of * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MultiMetadataTypeList>} Promise */ async _buildTemplate(metadataType, keyArr, templateVariables) { const type = metadataType; try { const removeKeys = []; /** @type {MetadataTypeItemObj[]} */ const result = ( await Promise.all( keyArr.map(async (key) => { MetadataTypeInfo[type].properties = this.properties; MetadataTypeInfo[type].buObject = this.buObject; try { /** @type {MetadataTypeItemObj} */ const response = await MetadataTypeInfo[type].buildTemplate( this.retrieveDir, this.templateDir, key, templateVariables ); if (!response) { removeKeys.push(key); } return response; } catch (ex) { removeKeys.push(key); Util.logger.errorStack(ex, ` ☇ skipping template asset: ${key}`); } }) ) ).filter(Boolean); // remove keys that errored out keyArr.splice(0, keyArr.length, ...keyArr.filter((key) => !removeKeys.includes(key))); if (result && type === result[0]?.type) { // result elements can be undefined for each key that we did not find this.metadata[type] = result.map((element) => element.metadata); } } catch (ex) { Util.logger.errorStack(ex, 'mcdev.buildTemplate'); } return this.metadata; } /** * Build a specific metadata file based on a template. * * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} nameArr name of the metadata * @param {string[]} marketArr market localizations * @returns {Promise.<MultiMetadataTypeList>} - */ static async buildDefinition(businessUnit, selectedType, nameArr, marketArr) { const properties = await config.getProperties(); if (!properties) { return; } if (!Util._isValidType(selectedType)) { return; } if (selectedType.includes('-')) { Util.logger.error( `:: '${selectedType}' is not a valid metadata type. Please don't include subtypes.` ); return; } /** @type {TemplateMap} */ const templateVariables = {}; if (marketArr[0] !== '__clone__') { // if __clone__ is passed, we don't want to actually change anything but simply clone the metadata as-is for (const market of marketArr) { if (Util.checkMarket(market, properties)) { Object.assign(templateVariables, properties.markets[market]); } else { // do not execute the rest of this method if a market was invalid return; } } } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (buObject !== null) { const builder = new Builder(properties, buObject); return builder._buildDefinition(selectedType, nameArr, templateVariables); } } /** * Build a specific metadata file based on a template using a list of bu-market combos * * @param {string} listName name of list of BU-market combos * @param {string} type supported metadata type * @param {string[]} nameArr name of the metadata * @returns {Promise.<object>} - */ static async buildDefinitionBulk(listName, type, nameArr) { const properties = await config.getProperties(); if (!properties) { return; } try { Util.verifyMarketList(listName, properties); } catch (ex) { Util.logger.error(ex.message); return; } if (type && !MetadataTypeInfo[type]) { Util.logger.error(`:: '${type}' is not a valid metadata type`); return; } let i = 0; const responseObj = {}; for (const businessUnit in properties.marketList[listName]) { if (businessUnit === 'description') { // skip, it's just a metadata on this list and not a BU continue; } i++; /** @type {string | string[] | string[][]} */ const market = properties.marketList[listName][businessUnit]; const marketList = 'string' === typeof market ? [market] : market; for (const market of marketList) { // one can now send multiple markets to buildTemplate/buildDefinition and hence that also needs to work for marketLists const marketArr = 'string' === typeof market ? [market] : market; for (const market of marketArr) { if (!Util.checkMarket(market, properties)) { return; } } Util.logger.info(`Executing for '${businessUnit}': '${marketArr.join('-')}'`); // omitting "await" to speed up creation responseObj[businessUnit] ||= {}; responseObj[businessUnit][marketArr.join('-')] = await this.buildDefinition( businessUnit, type, nameArr, marketArr ); } } if (!i) { Util.logger.error('Please define properties.marketList in your config'); } return responseObj; } /** * helper for buildDefinitionBulk, createDeltaPkg * * @param {string} listName market list name * @returns {Promise.<void>} - */ static async purgeDeployFolderList(listName) { const properties = await config.getProperties(); if (!properties) { return; } for (const businessUnit in properties.marketList[listName]) { if (businessUnit === 'description') { // skip, it's just a metadata on this list and not a BU continue; } if (!Util.isValidBU(properties, businessUnit, true)) { throw new Error(`'${businessUnit}' in Market ${listName} is not defined.`); } await this.purgeDeployFolder(businessUnit); } } /** * helper for buildDefiniton, purgeDeployFolderList * * @param {string} businessUnit cred/bu combo * @returns {Promise.<void>} - */ static async purgeDeployFolder(businessUnit) { const properties = await config.getProperties(); if (!properties) { return; } if (!Util.isValidBU(properties, businessUnit, true)) { throw new Error(`'${businessUnit}' does not exist.`); } const deployDir = File.normalizePath([ properties.directories.deploy, ...businessUnit.split('/'), ]); // Clear output folder structure for selected sub-type // only run this if the standard deploy folder is a target of buildDefinition (which technically could be changed) Util.logger.info(` - 🚮 purging folder ${deployDir}`); try { await File.remove(deployDir); } catch { // sometimes the first attempt is not successful for some operating system reason. Trying again mostly solves this await File.remove(deployDir); } } } export default Builder; ================================================ FILE: lib/Deployer.js ================================================ 'use strict'; import MetadataTypeInfo from './MetadataTypeInfo.js'; import path from 'node:path'; import Cli from './util/cli.js'; import { Util } from './util/util.js'; import File from './util/file.js'; import config from './util/config.js'; import cache from './util/cache.js'; import auth from './util/auth.js'; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * * @typedef {import('../types/mcdev.d.js').ListMap} ListMap */ /** * Reads metadata from local directory and deploys it to specified target business unit. * Source and target business units are also compared before the deployment to apply metadata specific patches. */ class Deployer { /** * Creates a Deployer, uses v2 auth if v2AuthOptions are passed. * * @param {Mcdevrc} properties General configuration to be used in retrieve * @param {BuObject} buObject properties for auth */ constructor(properties, buObject) { this.buObject = buObject; this.properties = properties; this.deployDir = File.normalizePath([ properties.directories.deploy, buObject.credential, buObject.businessUnit, ]); this.retrieveDir = File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]); // prep folders for auto-creation MetadataTypeInfo.folder.client = auth.getSDK(buObject); MetadataTypeInfo.folder.buObject = buObject; MetadataTypeInfo.folder.properties = properties; } /** * Deploys all metadata located in the 'deploy' directory to the specified business unit * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<Object.<string, MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type) */ static async deploy(businessUnit, selectedTypesArr, keyArr) { Util.logger.info('mcdev:: Deploy'); /** @type {Object.<string, MultiMetadataTypeMap>} */ const buMultiMetadataTypeMap = {}; const properties = await config.getProperties(); if (!properties) { return; } const deployDirBak = properties.directories.deploy; if (Util.OPTIONS.fromRetrieve) { properties.directories.deploy = properties.directories.retrieve; } if (selectedTypesArr) { for (const selectedType of Array.isArray(selectedTypesArr) ? selectedTypesArr : Object.keys(selectedTypesArr)) { if (!Util._isValidType(selectedType)) { return; } } } if (Util.OPTIONS.fromRetrieve) { // check if either type & key or typeKeyCombo including keys was supplied // we dont want to allow deploying without key from the retrieve dir for safety reasons let keysFound = false; if ( Array.isArray(selectedTypesArr) && selectedTypesArr.length && Array.isArray(keyArr) && keyArr.length ) { // check legacy way of passing in type(s) and key(s) keysFound = true; } else if ( selectedTypesArr && !Array.isArray(selectedTypesArr) && Object.values(selectedTypesArr).length ) { // TypeKeyCombo - a single null value (== no keys for one type) should lead to the error keysFound = true; for (const keys of Object.values(selectedTypesArr)) { if (keys === null) { keysFound = false; break; } } } if (!keysFound) { Util.logger.error('type & key need to be defined to deploy from retrieve folder'); return; } } let counter_credBu = 0; if (businessUnit === '*') { if (Util.OPTIONS.changeKeyValue) { Util.logger.error('--changeKeyValue is not supported for deployments to all BUs'); return; } // all credentials and all BUs shall be deployed to const deployFolders = await File.readDirectories( properties.directories.deploy, 2, false ); for (const buPath of deployFolders.filter((r) => r.includes(path.sep))) { const [cred, bu] = buPath.split(path.sep); const multiMetadataTypeMap = await this._deployBU( cred, bu, properties, selectedTypesArr, keyArr ); buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; counter_credBu++; Util.logger.info(''); Util.startLogger(true); } } else { // anything but "*" passed in let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already if ( properties.credentials && (!properties.credentials[cred] || (bu !== '*' && properties.credentials[cred].businessUnits[bu])) ) { const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); if (buObject === null) { return; } else { cred = buObject.credential; bu = buObject.businessUnit; } } if (bu === '*' && properties.credentials && properties.credentials[cred]) { if (Util.OPTIONS.changeKeyValue) { Util.logger.error( '--changeKeyValue is not supported for deployments to all BUs' ); return; } // valid credential given and -all- BUs targeted Util.logger.info(`:: Deploying all BUs for ${cred}`); let counter_credBu = 0; // for (const bu in properties.credentials[cred].businessUnits) { const deployFolders = await File.readDirectories( File.normalizePath([properties.directories.deploy, cred]), 1, false ); for (const buPath of deployFolders) { const multiMetadataTypeMap = await this._deployBU( cred, buPath, properties, selectedTypesArr, keyArr ); buMultiMetadataTypeMap[cred + '/' + buPath] = multiMetadataTypeMap; counter_credBu++; Util.logger.info(''); Util.startLogger(true); } Util.logger.info(` :: ${counter_credBu} BUs for ${cred}\n`); } else { // either bad credential or specific BU or no BU given const multiMetadataTypeMap = await this._deployBU( cred, bu, properties, selectedTypesArr, keyArr ); counter_credBu++; buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; } } if (Util.OPTIONS.fromRetrieve) { properties.directories.deploy = deployDirBak; } if (counter_credBu !== 0) { Util.logger.info(`:: Deployed ${counter_credBu} BUs\n`); } return buMultiMetadataTypeMap; } /** * helper for {@link Deployer.deploy} * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {Mcdevrc} properties General configuration to be used in retrieve * @param {string[] | TypeKeyCombo} [typeArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<MultiMetadataTypeMap>} ensure that BUs are worked on sequentially */ static async _deployBU(cred, bu, properties, typeArr, keyArr) { // ensure changes to the typeArr on one BU do not affect other BUs called in the same go typeArr = structuredClone(typeArr); const buPath = `${cred}/${bu}`; Util.logger.info(`:: Deploying to ${buPath}`); const buObject = await Cli.getCredentialObject(properties, buPath, null, true); let multiMetadataTypeMap; if (buObject !== null) { cache.initCache(buObject); const deployer = new Deployer(properties, buObject); try { // await is required or the calls end up conflicting multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.deploy failed'); } } return multiMetadataTypeMap; } /** * Deploy all metadata that is located in the deployDir * * @param {string[] | TypeKeyCombo} [types] limit deployment to given metadata type (can include subtype) * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<MultiMetadataTypeMap>} Promise of all deployed metadata */ async _deploy(types, keyArr) { const typeArr = types ? (Array.isArray(types) ? types : Object.keys(types)) : undefined; const typeKeyCombo = Array.isArray(types) ? Util.createTypeKeyCombo(typeArr, keyArr, true) : types; if (await File.pathExists(this.deployDir)) { /** @type {MultiMetadataTypeMap} */ this.metadata = await Deployer.readBUMetadata(this.deployDir, typeArr); // filter found metadata by key if given if (typeArr && Array.isArray(typeArr)) { for (const selectedType of typeArr) { const type = selectedType.split('-')[0]; this.metadata[type] = Util.filterObjByKeys( this.metadata[type], typeKeyCombo[selectedType] ); if (!this.metadata[type] || !Object.keys(this.metadata[type]).length) { // the type array is not set if the folder wasnt there. it is set but empty if the folder was there but no metadata was found Util.logger.warn( `No deployable metadata found for type ${type} ${keyArr?.length ? 'with keys ' + keyArr.join(', ') : ''}` ); delete this.metadata[type]; } } } } else { this.metadata = null; Util.logger.error( 'Please create a directory called deploy and include your metadata in it: ' + this.deployDir ); return null; } if (this.metadata === null || !Object.keys(this.metadata).length) { Util.logger.error('No metadata found in deploy folder for selected BU'); return null; } if (Util.OPTIONS.changeKeyValue && Object.keys(this.metadata).length) { if (Object.keys(this.metadata).length > 1) { Util.logger.error('--changeKeyValue expects a single type to be deployed'); return null; } else if (Object.keys(Object.values(this.metadata)[0]).length > 1) { Util.logger.error('--changeKeyValue expects a single key to be deployed'); return null; } } const foundDeployTypes = Object.keys(this.metadata) // remove empty types .filter((type) => Object.keys(this.metadata[type]).length) // make sure we keep the subtype in this list if that's what the user defined .map((type) => type === 'asset' && Util.includesStartsWith(typeArr, type) ? typeArr[Util.includesStartsWithIndex(typeArr, type)] : type ); if (!foundDeployTypes.length) { throw new Error('No metadata found for deployment'); } const deployOrder = Util.getMetadataHierachy(foundDeployTypes); if (!Util.OPTIONS.fromRetrieve) { // remove auto-created folder-directory from previous deployments unless 'folder' was specifically listed as to-be-deployed type if (!typeArr || !typeArr.includes('folder')) { await File.remove(File.normalizePath([this.deployDir, 'folder'])); } // run this AFTER identifying deployOrder or else ALL folders will be cached await Deployer.createFolderDefinitions( this.deployDir, this.metadata, Object.keys(this.metadata) ); } // build cache, including all metadata types which will be deployed (Avoids retrieve later) for (const metadataType in deployOrder) { const type = metadataType; const subTypeArr = deployOrder[metadataType]; // add metadata & client to metadata process class instead of passing cache/mapping every time MetadataTypeInfo[type].client = auth.getSDK(this.buObject); MetadataTypeInfo[type].properties = this.properties; MetadataTypeInfo[type].buObject = this.buObject; Util.logger.info(`Caching dependent Metadata: ${metadataType}`); Util.logSubtypes(subTypeArr); const result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr); if (result?.metadata) { // in case of dataExtensionField retrieveForCache() will return undefined on purpose cache.setMetadata(type, result.metadata); } } /** @type {MultiMetadataTypeMap} */ const multiMetadataTypeMap = {}; // deploy metadata files, extending cache once deploys for (const metadataType in deployOrder) { // TODO rewrite to allow deploying only a specific sub-type; currently, subtypes are ignored when executing deploy const type = metadataType; if (this.metadata[type]) { Util.logger.info( 'Deploying: ' + metadataType + (Util.OPTIONS.fromRetrieve ? ' (from retrieve folder)' : '') ); const result = await MetadataTypeInfo[type].deploy( this.metadata[type], this.deployDir, type === 'folder' && (!typeArr || !typeArr.includes('folder')) ? null : this.retrieveDir ); multiMetadataTypeMap[type] = result; cache.mergeMetadata(type, result); } } return multiMetadataTypeMap; } /** * Returns metadata of a business unit that is saved locally * * @param {string} deployDir root directory of metadata. * @param {string[]} [typeArr] limit deployment to given metadata type * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {Promise.<MultiMetadataTypeMap>} Metadata of BU in local directory */ static async readBUMetadata(deployDir, typeArr, listBadKeys) { /** @type {MultiMetadataTypeMap} */ const buMetadata = {}; try { await File.ensureDir(deployDir); const metadataTypes = await File.readdir(deployDir); for (const metadataType of metadataTypes) { if ( MetadataTypeInfo[metadataType] && (!typeArr || Util.includesStartsWith(typeArr, metadataType)) ) { // check if folder name is a valid metadataType, then check if the user limited to a certain type in the command params buMetadata[metadataType] = await MetadataTypeInfo[metadataType].getJsonFromFS( File.normalizePath([deployDir, metadataType]), listBadKeys, typeArr ); } } if (Object.keys(buMetadata).length === 0) { throw new Error('No metadata found in deploy folder for selected BU & type'); } return buMetadata; } catch (ex) { throw new Error(ex.message, { cause: ex }); } } /** * parses asset metadata to auto-create folders in target folder * * @param {string} deployDir root directory of metadata. * @param {MultiMetadataTypeMap} metadata list of metadata * @param {string[]} metadataTypeArr list of metadata types * @returns {Promise.<object>} folder metadata */ static async createFolderDefinitions(deployDir, metadata, metadataTypeArr) { let i = 0; /** @type {ListMap} */ const folderMetadata = {}; const allowedDeFolderContentTypes = ['dataextension', 'shared_dataextension']; for (const metadataType of metadataTypeArr) { // check if folder or folder-like metadata type is in dependencies if ( !MetadataTypeInfo[metadataType].definition.dependencies.includes('folder') && !MetadataTypeInfo[metadataType].definition.dependencies.some((dep) => dep.startsWith('folder-') ) ) { Util.logger.debug(` ☇ skipping ${metadataType} folders: folder not a dependency`); continue; } if (!MetadataTypeInfo[metadataType].definition.folderType) { Util.logger.debug(` ☇ skipping ${metadataType} folders: folderType not set`); continue; } if ( !MetadataTypeInfo.folder.definition.deployFolderTypes.includes( MetadataTypeInfo[metadataType].definition.folderType ) ) { Util.logger.warn( ` ☇ skipping ${metadataType} folders: folderType ${MetadataTypeInfo[metadataType].definition.folderType} not supported for deployment. Please consider creating folders for this type manually as a pre-deployment step, if you see errors about missing dependent folders for this type later in this log.` ); continue; } Util.logger.debug( ` - create ${metadataType} folders: Creating relevant folders in deploy dir` ); const allFolders = Object.keys(metadata[metadataType]) .filter( // filter out root folders (which would not have a slash in their path) (key) => metadata[metadataType][key].r__folder_Path?.includes('/') ) .filter( // filter out dataExtension folders other than standard & shared (--> synchronized / salesforce are not allowed) (key) => metadataType !== 'dataExtension' || allowedDeFolderContentTypes.includes( metadata[metadataType][key].r__folder_ContentType ) ) .map((key) => metadata[metadataType][key].r__folder_Path); // deduplicate const folderPathSet = new Set(allFolders); for (const item of [...folderPathSet].toSorted()) { let aggregatedPath = ''; const parts = item.split('/'); for (const pathElement of parts) { if (aggregatedPath) { aggregatedPath += '/'; } aggregatedPath += pathElement; folderPathSet.add(aggregatedPath); } } const folderPathArrExtended = [...folderPathSet] // strip root folders .filter((folderName) => folderName.includes('/')) .toSorted(); for (const folder of folderPathArrExtended) { i++; let contentType = MetadataTypeInfo[metadataType].definition.folderType; if ( metadataType === 'dataExtension' && folder.startsWith('Shared Items/Shared Data Extensions') ) { contentType = 'shared_dataextension'; } if ( metadataType === 'triggeredSend' && folder.startsWith('Journey Builder Sends/') ) { contentType = 'triggered_send_journeybuilder'; } if (metadataType === 'asset' && folder.startsWith('CloudPages/')) { contentType = 'cloudpages'; } folderMetadata[`on-the-fly-${i}`] = { Path: folder, // unescape folder name slash escape chars to get the actual SFMC folder name Name: folder.split('/').pop().replaceAll(Util.folderNameSlashEscapeChar, '/'), Description: '', // required for Create, omitted for update via definition file ContentType: contentType, IsActive: true, // would be auto-updated for existing folders if needed IsEditable: true, // would be auto-updated for existing folders if needed AllowChildren: true, // would be auto-updated for existing folders if needed _generated: true, }; } } if (i > 0) { MetadataTypeInfo.folder.definition.fields._generated.retrieving = true; // ensure we keep that flag in deploy folder // await results to allow us to re-read it right after await MetadataTypeInfo.folder.saveResults(folderMetadata, deployDir); MetadataTypeInfo.folder.definition.fields._generated.retrieving = false; // reset flag Util.logger.info(`Created folders in deploy dir: ${i}`); // reload from file system to ensure we use the same logic for building the temporary JSON metadata.folder = await MetadataTypeInfo.folder.getJsonFromFS( File.normalizePath([deployDir, 'folder']) ); } return folderMetadata; } } export default Deployer; ================================================ FILE: lib/MetadataTypeDefinitions.js ================================================ 'use strict'; import asset from './metadataTypes/definitions/Asset.definition.js'; import attributeGroup from './metadataTypes/definitions/AttributeGroup.definition.js'; import attributeSet from './metadataTypes/definitions/AttributeSet.definition.js'; import automation from './metadataTypes/definitions/Automation.definition.js'; import campaign from './metadataTypes/definitions/Campaign.definition.js'; import contentArea from './metadataTypes/definitions/ContentArea.definition.js'; import dataFilter from './metadataTypes/definitions/DataFilter.definition.js'; import dataFilterHidden from './metadataTypes/definitions/DataFilterHidden.definition.js'; import dataExtension from './metadataTypes/definitions/DataExtension.definition.js'; import dataExtensionField from './metadataTypes/definitions/DataExtensionField.definition.js'; import dataExtensionTemplate from './metadataTypes/definitions/DataExtensionTemplate.definition.js'; import dataExtract from './metadataTypes/definitions/DataExtract.definition.js'; import dataExtractType from './metadataTypes/definitions/DataExtractType.definition.js'; import deliveryProfile from './metadataTypes/definitions/DeliveryProfile.definition.js'; import discovery from './metadataTypes/definitions/Discovery.definition.js'; import domainVerification from './metadataTypes/definitions/DomainVerification.definition.js'; import email from './metadataTypes/definitions/Email.definition.js'; import emailSend from './metadataTypes/definitions/EmailSend.definition.js'; import event from './metadataTypes/definitions/Event.definition.js'; import fileLocation from './metadataTypes/definitions/FileLocation.definition.js'; import fileTransfer from './metadataTypes/definitions/FileTransfer.definition.js'; import filter from './metadataTypes/definitions/Filter.definition.js'; import folder from './metadataTypes/definitions/Folder.definition.js'; import importFile from './metadataTypes/definitions/ImportFile.definition.js'; import journey from './metadataTypes/definitions/Journey.definition.js'; import list from './metadataTypes/definitions/List.definition.js'; import mobileCode from './metadataTypes/definitions/MobileCode.definition.js'; import mobileKeyword from './metadataTypes/definitions/MobileKeyword.definition.js'; import mobileMessage from './metadataTypes/definitions/MobileMessage.definition.js'; import query from './metadataTypes/definitions/Query.definition.js'; import role from './metadataTypes/definitions/Role.definition.js'; import script from './metadataTypes/definitions/Script.definition.js'; import sendClassification from './metadataTypes/definitions/SendClassification.definition.js'; import senderProfile from './metadataTypes/definitions/SenderProfile.definition.js'; import transactionalMessage from './metadataTypes/definitions/TransactionalMessage.definition.js'; import transactionalEmail from './metadataTypes/definitions/TransactionalEmail.definition.js'; import transactionalPush from './metadataTypes/definitions/TransactionalPush.definition.js'; import transactionalSMS from './metadataTypes/definitions/TransactionalSMS.definition.js'; import triggeredSend from './metadataTypes/definitions/TriggeredSend.definition.js'; import triggeredSendSummary from './metadataTypes/definitions/TriggeredSendSummary.definition.js'; import user from './metadataTypes/definitions/User.definition.js'; import verification from './metadataTypes/definitions/Verification.definition.js'; /** * Provides access to definitions of all metadataType classes */ export default { asset, attributeGroup, attributeSet, automation, campaign, contentArea, dataFilter, dataFilterHidden, dataExtension, dataExtensionField, dataExtensionTemplate, dataExtract, dataExtractType, deliveryProfile, discovery, domainVerification, email, emailSend, event, fileLocation, fileTransfer, filter, folder, importFile, journey, list, mobileCode, mobileKeyword, mobileMessage, query, role, script, sendClassification, senderProfile, transactionalMessage, transactionalEmail, transactionalPush, transactionalSMS, triggeredSend, triggeredSendSummary, user, verification, }; ================================================ FILE: lib/MetadataTypeInfo.js ================================================ 'use strict'; import asset from './metadataTypes/Asset.js'; import attributeGroup from './metadataTypes/AttributeGroup.js'; import attributeSet from './metadataTypes/AttributeSet.js'; import automation from './metadataTypes/Automation.js'; import campaign from './metadataTypes/Campaign.js'; import contentArea from './metadataTypes/ContentArea.js'; import dataFilter from './metadataTypes/DataFilter.js'; import dataFilterHidden from './metadataTypes/DataFilterHidden.js'; import dataExtension from './metadataTypes/DataExtension.js'; import dataExtensionField from './metadataTypes/DataExtensionField.js'; import dataExtensionTemplate from './metadataTypes/DataExtensionTemplate.js'; import dataExtract from './metadataTypes/DataExtract.js'; import dataExtractType from './metadataTypes/DataExtractType.js'; import deliveryProfile from './metadataTypes/DeliveryProfile.js'; import discovery from './metadataTypes/Discovery.js'; import domainVerification from './metadataTypes/DomainVerification.js'; import email from './metadataTypes/Email.js'; import emailSend from './metadataTypes/EmailSend.js'; import event from './metadataTypes/Event.js'; import fileLocation from './metadataTypes/FileLocation.js'; import fileTransfer from './metadataTypes/FileTransfer.js'; import filter from './metadataTypes/Filter.js'; import folder from './metadataTypes/Folder.js'; import importFile from './metadataTypes/ImportFile.js'; import journey from './metadataTypes/Journey.js'; import list from './metadataTypes/List.js'; import mobileCode from './metadataTypes/MobileCode.js'; import mobileKeyword from './metadataTypes/MobileKeyword.js'; import mobileMessage from './metadataTypes/MobileMessage.js'; import query from './metadataTypes/Query.js'; import role from './metadataTypes/Role.js'; import script from './metadataTypes/Script.js'; import sendClassification from './metadataTypes/SendClassification.js'; import senderProfile from './metadataTypes/SenderProfile.js'; import transactionalEmail from './metadataTypes/TransactionalEmail.js'; import transactionalPush from './metadataTypes/TransactionalPush.js'; import transactionalSMS from './metadataTypes/TransactionalSMS.js'; import triggeredSend from './metadataTypes/TriggeredSend.js'; import triggeredSendSummary from './metadataTypes/TriggeredSendSummary.js'; import user from './metadataTypes/User.js'; import verification from './metadataTypes/Verification.js'; /** * Provides access to all metadataType classes */ export default { asset, attributeGroup, attributeSet, automation, campaign, contentArea, dataExtension, dataExtensionField, dataExtensionTemplate, dataExtract, dataExtractType, dataFilter, dataFilterHidden, deliveryProfile, discovery, domainVerification, email, emailSend, event, fileLocation, fileTransfer, filter, folder, importFile, journey, list, mobileCode, mobileKeyword, mobileMessage, query, role, script, sendClassification, senderProfile, transactionalEmail, transactionalPush, transactionalSMS, triggeredSend, triggeredSendSummary, user, verification, }; ================================================ FILE: lib/Retriever.js ================================================ 'use strict'; import MetadataTypeInfo from './MetadataTypeInfo.js'; import MetadataDefinitions from './MetadataTypeDefinitions.js'; import { Util } from './util/util.js'; import File from './util/file.js'; import cache from './util/cache.js'; import auth from './util/auth.js'; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * Retrieves metadata from a business unit and saves it to the local filesystem. */ class Retriever { /** * Creates a Retriever, uses v2 auth if v2AuthOptions are passed. * * @param {Mcdevrc} properties General configuration to be used in retrieve * @param {BuObject} buObject properties for auth */ constructor(properties, buObject) { this.buObject = buObject; this.properties = properties; this.retrieveDir = properties.directories.retrieve; this.templateDir = properties.directories.template; this.savePath = File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]); } /** * Retrieve metadata of specified types into local file system and Retriever.metadata * * @param {string[]} metadataTypes list of metadata types to retrieve; can include subtypes! * @param {string[] | TypeKeyCombo} [namesOrKeys] name of Metadata to retrieveAsTemplate or list of keys for normal retrieval * @param {TemplateMap} [templateVariables] Object of values which can be replaced (in case of templating) * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.<MultiMetadataTypeList>} Promise of a list of retrieved items grouped by type {automation:[...], query:[...]} */ async retrieve(metadataTypes, namesOrKeys, templateVariables, changelogOnly) { /** * @type {MultiMetadataTypeList} */ const retrieveChangelog = {}; /** @type {TypeKeyCombo} */ const typeKeyMap = !namesOrKeys || Array.isArray(namesOrKeys) ? Util.createTypeKeyCombo( metadataTypes, Array.isArray(namesOrKeys) ? namesOrKeys : undefined ) : namesOrKeys; // ensure we know which real dependencies we have to ensure we cache those completely const dependencies = this._getTypeDependencies(metadataTypes); const deployOrder = Util.getMetadataHierachy(metadataTypes); for (const type in deployOrder) { if (!MetadataTypeInfo[type]) { throw new Error(`invalid type "${type}" in dependencies.`); } const subTypeArr = deployOrder[type]; // if types were added by getMetadataHierachy() for caching, make sure the key-list is set to [null] for them which will retrieve all // if we have a subtype, we need to find the correct key-list for it typeKeyMap[type] ||= typeKeyMap[ Object.keys(typeKeyMap).find((k) => k.startsWith(type + '-')) ] || [null]; // add client to metadata process class instead of passing every time MetadataTypeInfo[type].client = auth.getSDK(this.buObject); MetadataTypeInfo[type].properties = this.properties; MetadataTypeInfo[type].buObject = this.buObject; try { let result; if ( !metadataTypes.includes(type) && (!Array.isArray(subTypeArr) || (Array.isArray(subTypeArr) && !metadataTypes.includes(`${type}-${subTypeArr?.[0]}`))) ) { // type not in list of types to retrieve, but is a dependency of one of them if (changelogOnly && type !== 'folder') { // no extra caching needed for list view except for folders continue; } Util.logger.info(`Caching dependent Metadata: ${type}`); Util.logSubtypes(subTypeArr); result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr); } else if (templateVariables) { // type is in list of types to retrieve and we have template variables Util.logger.info(`Retrieving as Template: ${type}`); if (subTypeArr?.length > 1) { Util.logger.warn( `retrieveAsTemplate only works with one subtype, ignoring all but first subtype from your list: ${subTypeArr.join( ', ' )}` ); } result = await Promise.all( typeKeyMap[type].map((name) => MetadataTypeInfo[type].retrieveAsTemplate( this.templateDir, name, templateVariables, subTypeArr?.[0] ) ) ); } else { // type is in list of types to retrieve and we don't have template variables let cacheResult = null; if ( (typeKeyMap[type].length > 1 || typeKeyMap[type][0] !== null) && dependencies.includes(type) ) { // if we have a key-list and the type is a dependency, we need to cache the whole type Util.logger.info(`Caching dependent Metadata: ${type}`); Util.logSubtypes(subTypeArr); cacheResult = await MetadataTypeInfo[type].retrieveForCache( null, subTypeArr ); } else if ( dependencies.includes(type) && Object.prototype.hasOwnProperty.call( MetadataTypeInfo[type], 'retrieveSharedForCache' ) ) { // some types exist locally and shared from other BUs (parent and siblings). those need to be put into the cache or else we wont find them when looking for dependencies // note: retrieveSharedForCache() returns a plain metadata map, not a {metadata: ...} wrapper const cacheSharedResult = await MetadataTypeInfo[type].retrieveSharedForCache(); cache.mergeMetadata(type, cacheSharedResult); } Util.logger.info( `Retrieving: ${type}` + (typeKeyMap[type][0] === null ? '' : Util.getKeysString(typeKeyMap[type])) ); result = await (changelogOnly ? MetadataTypeInfo[type].retrieveChangelog(null, subTypeArr) : Promise.all( typeKeyMap[type].map((key) => MetadataTypeInfo[type].retrieve( this.savePath, null, subTypeArr, key ) ) )); if (Array.isArray(result) && cacheResult !== null) { // if we have a key-list and the type is a dependency, we need to cache the whole type result = [cacheResult, ...result]; } if (changelogOnly) { // add folder to changelog for (const key of Object.keys(result.metadata)) { MetadataTypeInfo[type].setFolderPath(result.metadata[key]); } } } if (result) { if (Array.isArray(result)) { for (const result_i of result) { if (result_i?.metadata && Object.keys(result_i.metadata).length) { cache.mergeMetadata(type, result_i.metadata); } } if ( metadataTypes.includes(type) || metadataTypes.some((el) => el.startsWith(type + '-')) ) { retrieveChangelog[type] = result .filter((el) => !!el) .map((element) => element.metadata); } } else { cache.mergeMetadata(type, result.metadata); if ( metadataTypes.includes(type) || metadataTypes.some((el) => el.startsWith(type + '-')) ) { retrieveChangelog[type] = result.metadata; } } } } catch (ex) { if ( ex.code === 'invalid_client' || ex.message.startsWith('Client authentication failed.') ) { // do not continue retrieving if we logged an authentication issue Util.logger.error(ex.message); break; } else { Util.logger.errorStack(ex, ` - Retrieving ${type} failed`); } } } return retrieveChangelog; } /** * helper for Retriever.retrieve to get all dependencies of the given types * * @param {string[]} metadataTypes list of metadata types to retrieve; can include subtypes! * @returns {string[]} unique list dependent metadata types */ _getTypeDependencies(metadataTypes) { let dependencies = []; for (const metadataType of metadataTypes) { const type = metadataType.split('-')[0]; // if they have dependencies then add a dependency pair for each type if (MetadataDefinitions[type].dependencies.length > 0) { dependencies.push( ...MetadataDefinitions[type].dependencies.map((dep) => dep.split('-')[0]) ); } } dependencies = [...new Set(dependencies)]; return dependencies; } } export default Retriever; ================================================ FILE: lib/cli.js ================================================ #!/usr/bin/env node /** * CLI entry for SFMC DevTools */ import { Util } from './util/util.js'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; import Mcdev from './index.js'; // use this instead of setting "true" directly to more easily find deprecated commands in this file const isDeprecated = true; /** * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ yargs(hideBin(process.argv)) .scriptName('mcdev') .usage('$0 <command> [options]') .command( ['retrieve [BU] [TYPE] [KEY]', 'r'], 'retrieves metadata of a business unit', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to retrieve from (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type that shall be exclusively downloaded', }) .positional('KEY', { type: 'string', describe: 'metadata keys that shall be exclusively downloaded', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for retrieve:', describe: 'type or type:key or type:i:id or type:n:name to retrieve; if not provided, all metadata will be retrieved', }) .option('like', { type: 'string', group: 'Options for retrieve:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .option('skipValidation', { alias: 'sv', group: 'Options for retrieve:', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('fix', { group: 'Options for retrieve:', describe: 'should ONLY be used to identify what items would be filtered out or changed during build/deploy. This does not actually change anything on the server.', }) .option('format', { type: 'boolean', alias: 'f', group: 'Options for retrieve:', describe: 'allows overwriting options.formatOnSave from the config file. Disable formatting via --no-format', }) .option('purge', { type: 'boolean', group: 'Options for retrieve:', describe: 'deletes the relevant retrieve folder before retrieving', }) .option('onlyPublished', { type: 'boolean', alias: 'op', group: 'Options for retrieve:', describe: 'only retrieve the version of the metadata that was published', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.retrieve(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.retrieve(argv.BU, typeKeyCombo); } } ) .command( ['deploy [BU] [TYPE] [KEY]', 'd'], 'deploys local metadata to a business unit', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to deploy to (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type that shall be exclusively uploaded', }) .positional('KEY', { type: 'string', describe: 'metadata key that shall be exclusively uploaded', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for deploy:', describe: 'type or type:key or type:i:id or type:n:name to deploy; if not provided, all metadata will be deploy', }) .option('keySuffix', { type: 'string', alias: 'ks', group: 'Options for deploy:', describe: 'allows you to add a suffix to the key of the metadata to be deployed', }) .option('autoMidSuffix', { type: 'boolean', group: 'Options for deploy:', describe: 'for asset: enables the automatic addition of the MID to the key of the deployed metadata when deploying cross-BU. Alternatively, use --keySuffix or templating-based suffixes', }) .option('changeKeyField', { type: 'string', alias: 'ckf', group: 'Options for deploy:', describe: 'enables updating the key of the deployed metadata with the value in provided field (e.g. c__newKey). Can be used to sync name and key fields.', }) .option('changeKeyValue', { type: 'string', alias: 'ckv', group: 'Options for deploy:', describe: 'allows updating the key of the metadata to the provided value. Only available if a single type and key is deployed', }) .option('fromRetrieve', { type: 'boolean', alias: 'fr', group: 'Options for deploy:', describe: 'deploy from retrieve folder', }) .option('refresh', { type: 'boolean', alias: 'r', group: 'Options for deploy:', describe: 'for asset-message: runs refresh command for related triggeredSends after deploy', }) .option('execute', { type: 'boolean', alias: 'e', group: 'Options for deploy:', describe: 'executes item after deploy; this will run the item once immediately', }) .option('schedule', { type: 'boolean', alias: 's', group: 'Options for deploy:', describe: 'start existing schedule instead of running item once immediately (only works for automations)', }) .option('fixShared', { group: 'Options for deploy:', describe: "ensure that updates to shared DataExtensions become visible in child BU's data designer (SF Known issue W-11031095)", }) .option('noUpdate', { group: 'Options for deploy:', describe: 'if set, no metadata will be updated, only new metadata will be created', }) .option('publish', { group: 'Options for deploy:', describe: 'publishes the entity after deploy (only works on journeys)', }) .option('validate', { group: 'Options for deploy:', describe: 'validate the entity after deploy (only works on journeys)', }) .option('skipStatusCheck', { group: 'Options for deploy:', describe: 'only relevant if used together with --publish. if you do not care if publishing actually worked you can skip the checks with this option.', }) .option('matchName', { group: 'Options for deploy:', describe: 'Some metadata types allow updating resources despite a key mismatch by matching the name. That avoids clean-ups on all BUs but instead allows you to continously get higher environmetns into a better shape.', }) .option('skipValidation', { alias: 'sv', group: 'Options for deploy:', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('format', { type: 'boolean', alias: 'f', group: 'Options for deploy:', describe: 'allows overwriting options.formatOnSave from the config file. Disable formatting via --no-format', }) .option('ignoreFolder', { type: 'boolean', alias: 'if', group: 'Options for deploy:', describe: 'works with --matchName and allows skipping folder match if there is only 1 name match', }) .option('ignoreSfFields', { type: 'boolean', alias: 'isf', group: 'Options for deploy:', describe: 'relevant for Salesforce triggered journeys and events; allows ignoring errors on missing Salesforce fields in case the API returns other info than the GUI. CAUTION!', }) .option('fix', { group: 'Options for deploy:', describe: 'auto-fix validation issues if the rule is able to do it', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.deploy(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.deploy(argv.BU, typeKeyCombo); } } ) .command( ['init [credentialsName]'], `creates '${Util.configFileName}' in your root or adds additional credentials to the existing one`, (yargs) => yargs.positional('credentialsName', { type: 'string', describe: 'name of your installed package', }), (argv) => { Mcdev.setOptions(argv); Mcdev.initProject(argv.credentialsName); } ) .command(['join'], `clones an existing project from git`, {}, (argv) => { Mcdev.setOptions(argv); Mcdev.joinProject(); }) .command( ['reloadBUs [credentialsName]', 'rb', 'refreshBUs'], 'loads the list of available BUs from the server and saves it to your config', (yargs) => yargs.positional('credentialsName', { type: 'string', describe: 'name of your installed package', }), (argv) => { Mcdev.setOptions(argv); Mcdev.findBUs(argv.credentialsName); } ) .command( ['badKeys [BU]'], 'lists metadata with random API names in specified Business Unit directory', (yargs) => yargs.positional('BU', { type: 'string', describe: 'the business unit to deploy to', }), (argv) => { Mcdev.setOptions(argv); Mcdev.badKeys(argv.BU); } ) .command( ['document <BU> <TYPE>', 'doc'], 'Creates Markdown or HTML documentation for the selected type', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to generate docs for (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type to generate docs for; currently supported: dataExtension, role', }), (argv) => { Mcdev.setOptions(argv); Mcdev.document(argv.BU, argv.TYPE); } ) .command( ['delete <BU> [TYPE] [KEY]', 'del'], 'deletes metadata of selected type and external key', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to delete from (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type to delete from;', }) .positional('KEY', { type: 'string', describe: 'the key to delete', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for delete:', describe: 'type or type:key or type:i:id or type:n:name to delete', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata, ['key', 'id']); if ('undefined' === typeof typeKeyCombo) { if (argv.TYPE && argv.KEY) { Mcdev.deleteByKey(argv.BU, argv.TYPE, csvToArray(argv.KEY)); } } else { Mcdev.deleteByKey(argv.BU, typeKeyCombo, null); } } ) .command( ['resolveId <BU> <TYPE> <ID>', 'rid'], 'resolves metadata key by ID', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to search in (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type to search in; currently supported: asset', }) .positional('ID', { type: 'string', describe: 'the id to resolve', }) .option('json', { type: 'boolean', group: 'Options for resolveId:', describe: 'optionaly return info in json format', }), // TODO: add option --metadata (argv) => { Mcdev.setOptions(argv); Mcdev.resolveId(argv.BU, argv.TYPE, argv.ID); } ) .command( ['retrieveAsTemplate <BU> <TYPE> <NAME> <MARKET>', 'rt'], '[DEPRECATED] Retrieves a specific metadata file by name from the server for templating', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to deploy to (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('NAME', { type: 'string', describe: 'name of the metadata component', }) .positional('MARKET', { type: 'string', describe: 'market used for reverse building template', }), (argv) => { Mcdev.setOptions(argv); Mcdev.retrieveAsTemplate(argv.BU, argv.TYPE, csvToArray(argv.NAME), argv.MARKET); }, [], isDeprecated ) .command( ['clone'], 'clones items across BUs. Alias for: mcdev build --mf __clone__ --mt __clone__', (yargs) => yargs .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Required parameters for clone:', describe: 'type:key combos to clone', demandOption: true, }) .option('buFrom', { type: 'string', alias: 'bf', group: 'Required parameters for clone:', describe: 'the business unit to create the templates from (in format "credential name/BU name")', demandOption: true, }) .option('buTo', { type: 'string', alias: 'bt', group: 'Required parameters for clone:', describe: 'the business unit to deploy to; required unless --bulk is set', }) .option('dependencies', { type: 'boolean', alias: 'D', group: 'Options for clone:', describe: 'create templates for all dependencies of the metadata component', }) .option('retrieve', { type: 'boolean', alias: 'r', group: 'Options for clone:', describe: 're-retrieves potentially relevant metadata before running buildTemplate (all if --dependencies is used)', }) .option('skipValidation', { alias: 'sv', group: 'Options for clone:', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('purge', { group: 'Options for clone:', describe: 'deletes the relevant deploy folder before building the definition. Add "--no-purge" to skip the question and not delete anything', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' !== typeof typeKeyCombo) { Mcdev.clone(argv.buFrom, argv.buTo, typeKeyCombo); } } ) .command( ['build'], 'runs buildTemplate followed by buildDefinition', (yargs) => yargs .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Required parameters for build:', describe: 'type:key combos to build template for', demandOption: true, }) .option('buFrom', { type: 'string', alias: 'bf', group: 'Required parameters for build:', describe: 'the business unit to create the templates from (in format "credential name/BU name")', demandOption: true, }) .option('buTo', { type: 'string', alias: 'bt', group: 'Required parameters for build:', describe: 'the business unit to deploy to; required unless --bulk is set', }) .option('marketFrom', { type: 'string', array: true, alias: 'mf', group: 'Required parameters for build:', describe: 'market used for reverse building template', demandOption: true, }) .option('marketTo', { type: 'string', array: true, alias: 'mt', group: 'Required parameters for build:', describe: 'market used for building deployable definition', demandOption: true, }) .option('bulk', { type: 'boolean', group: 'Options for build:', describe: 'if defined, the marketTo parameter has to be a marketList and buildDefinitionBulk is executed', }) .option('dependencies', { type: 'boolean', alias: 'D', group: 'Options for build:', describe: 'create templates for all dependencies of the metadata component', }) .option('retrieve', { type: 'boolean', alias: 'r', group: 'Options for build:', describe: 're-retrieves potentially relevant metadata before running buildTemplate (all if --dependencies is used)', }) .option('skipValidation', { alias: 'sv', group: 'Options for build:', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('purge', { group: 'Options for build:', describe: 'deletes the relevant deploy folder before building the definition. Add "--no-purge" to skip the question and not delete anything', }) .option('fix', { group: 'Options for build:', describe: 'auto-fix validation issues if the rule is able to do it', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' !== typeof typeKeyCombo) { Mcdev.build( argv.buFrom, argv.buTo, typeKeyCombo, argv.marketFrom, argv.marketTo, argv.bulk ); } } ) .command( ['buildTemplate <BU> [TYPE] [KEY] [MARKET]', 'bt'], 'builds a template out of a specific metadata file already in your retrieve folder', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to create the templates from (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .positional('MARKET', { type: 'string', describe: 'market used for reverse building template', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for buildTemplate:', describe: 'type:key combos to build template for', }) .option('market', { type: 'string', array: true, group: 'Options for buildTemplate:', describe: 'market used for reverse building template', }) .option('dependencies', { type: 'boolean', alias: 'D', group: 'Options for buildTemplate:', describe: 'create templates for all dependencies of the metadata component', }) .option('retrieve', { type: 'boolean', alias: 'r', group: 'Options for buildTemplate:', describe: 're-retrieves potentially relevant metadata before building (all if --dependencies is used)', }) .check((argv) => { if (!argv.MARKET && !argv.market) { throw new Error( 'Error: You need to provide a market for reverse building the template' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.buildTemplate( argv.BU, argv.TYPE, csvToArray(argv.KEY), argv.MARKET ? [argv.MARKET] : argv.market ); } else { Mcdev.buildTemplate( argv.BU, typeKeyCombo, null, argv.MARKET ? [argv.MARKET] : argv.market ); } } ) .command( ['buildDefinition <BU> [TYPE] [FILENAME] [MARKET]', 'bd'], 'builds metadata definition based on template', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to deploy to', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('FILENAME', { type: 'string', describe: 'File name of the metadata template without the extension', }) .positional('MARKET', { type: 'string', describe: 'market used for building deployable definition', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for buildDefinition:', describe: 'type:templateName combos to build template for', }) .option('market', { type: 'string', array: true, group: 'Options for buildDefinition:', describe: 'market used for building deployable definition', }) .option('skipValidation', { alias: 'sv', group: 'Options for buildDefinition:', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('purge', { group: 'Options for buildDefinition:', describe: 'deletes the relevant deploy folder before building the definition. Add "--no-purge" to skip the question and not delete anything', }) .option('fix', { group: 'Options for buildDefinition:', describe: 'auto-fix validation issues if the rule is able to do it', }) .check((argv) => { if (!argv.MARKET && !argv.market) { throw new Error( 'Error: You need to provide a market for reverse building the template' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.buildDefinition( argv.BU, argv.TYPE, csvToArray(argv.FILENAME), argv.MARKET ? [argv.MARKET] : argv.market ); } else { Mcdev.buildDefinition( argv.BU, typeKeyCombo, null, argv.MARKET ? [argv.MARKET] : argv.market ); } } ) .command( ['buildDefinitionBulk <LISTNAME> [TYPE] [FILENAME]', 'bdb'], 'builds metadata definition based on template en bulk', (yargs) => yargs .positional('LISTNAME', { type: 'string', describe: 'name of list of BU-market combos', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('FILENAME', { type: 'string', describe: 'File name of the metadata template without the extension', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for buildDefinitionBulk:', describe: 'type:templateName combos to build template for', }) .option('skipValidation', { alias: 'sv', group: 'Options for buildDefinitionBulk:', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('purge', { group: 'Options for buildDefinitionBulk:', describe: 'deletes the relevant deploy folder before building the definition. Add "--no-purge" to skip the question and not delete anything', }) .option('fix', { group: 'Options for buildDefinitionBulk:', describe: 'auto-fix validation issues if the rule is able to do it', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, csvToArray(argv.FILENAME)); } else { Mcdev.buildDefinitionBulk(argv.LISTNAME, typeKeyCombo); } } ) .command( ['selectTypes', 'st'], 'lets you choose what metadata types to retrieve', {}, (argv) => { Mcdev.setOptions(argv); Mcdev.selectTypes(); } ) .command( ['explainTypes', 'et'], 'explains metadata types that can be retrieved', (yargs) => yargs.option('json', { type: 'boolean', group: 'Options for explainTypes:', describe: 'optionaly return info in json format', }), (argv) => { Mcdev.setOptions(argv); Mcdev.explainTypes(); } ) .command( ['createDeltaPkg [commitrange]', 'cdp'], 'Copies commit-based file delta into deploy folder', (yargs) => yargs .positional('commitrange', { type: 'string', describe: 'Pull Request target branch or git commit range', }) .option('range', { type: 'string', alias: ['branch', 'commit', 'R'], group: 'Options for createDeltaPkg:', describe: 'Pull Request target branch or git commit range', }) .option('filter', { type: 'string', group: 'Options for createDeltaPkg:', describe: 'Disable templating & instead filter by the specified BU path (comma separated), can include subtype, will be prefixed with "retrieve/"', }) .option('commitHistory', { type: 'number', group: 'Options for createDeltaPkg:', describe: 'Number of commits to look back for changes (supersedes config)', }) .option('dependencies', { type: 'boolean', alias: 'D', group: 'Options for build (run via createDeltaPkg):', describe: 'create templates for all dependencies of the metadata component', }) .option('retrieve', { type: 'boolean', alias: 'r', group: 'Options for build (run via createDeltaPkg):', describe: 're-retrieves potentially relevant metadata before running buildTemplate (all if --dependencies is used)', }) .option('skipValidation', { alias: 'sv', group: 'Options for build (run via createDeltaPkg):', describe: 'allows reducing validation rules from error to warn to handle edge cases', }) .option('purge', { group: 'Options for build (run via createDeltaPkg):', describe: 'deletes the relevant deploy folder before building the definition. Add "--no-purge" to skip the question and not delete anything', }) .option('fix', { group: 'Options for build (run via createDeltaPkg)', describe: 'auto-fix validation issues if the rule is able to do it', }), (argv) => { Mcdev.setOptions(argv); Mcdev.createDeltaPkg(argv); } ) .command( ['getFilesToCommit <BU> <TYPE> <KEY>', 'fc'], 'returns a list of relative paths to files one needs to include in a commit', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to deploy to (in format "credential name/BU name")', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }), // TODO: add option --metadata (argv) => { Mcdev.setOptions(argv); Mcdev.getFilesToCommit(argv.BU, argv.TYPE, csvToArray(argv.KEY)); } ) .command( ['refresh <BU> [TYPE] [KEY]', 're'], 'ensures that updates are properly published', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit to execute the refresh on', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for execute:', describe: 'type or type:key or type:i:id or type:n:name to fix', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.refresh(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.refresh(argv.BU, typeKeyCombo); } } ) .command( ['execute <BU> [TYPE] [KEY]', 'exec', 'start', 'resume'], 'executes the entity', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for execute:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for execute:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .option('schedule', { type: 'boolean', group: 'Options for execute:', describe: 'optionally start existing schedule instead of running item once immediately (only works for automations)', }) .check((argv) => { if (!argv.TYPE && !argv.metadata) { throw new Error( 'Error: Either specify the metadata type after the BU or use --metadata' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.execute(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.execute(argv.BU, typeKeyCombo); } } ) .command( ['publish <BU> [TYPE] [KEY]', 'activate'], 'publishes the entity', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for publish:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for publish:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .option('skipStatusCheck', { group: 'Options for publish:', describe: 'if you don not care if publishing actually worked you can skip the checks', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.publish(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.publish(argv.BU, typeKeyCombo); } } ) .command( ['validate <BU> [TYPE] [KEY]'], 'validates the entity', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for validate:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for validate:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.validate(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.validate(argv.BU, typeKeyCombo); } } ) .command( ['schedule <BU> [TYPE] [KEY]', 'sched'], 'starts the predefined schedule of the item (shortcut for running execute --schedule)', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for schedule:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for schedule:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .check((argv) => { if (!argv.TYPE && !argv.metadata) { throw new Error( 'Error: Either specify the metadata type after the BU or use --metadata' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.schedule(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.schedule(argv.BU, typeKeyCombo); } } ) .command( ['pause <BU> [TYPE] [KEY]', 'p'], 'pauses the entity (automation etc.)', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for pause:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for pause:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .check((argv) => { if (!argv.TYPE && !argv.metadata) { throw new Error( 'Error: Either specify the metadata type after the BU or use --metadata' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.pause(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.pause(argv.BU, typeKeyCombo); } } ) .command( ['stop <BU> [TYPE] [KEY]'], 'stops the entity (journey etc.)', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for pause:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for pause:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .check((argv) => { if (!argv.TYPE && !argv.metadata) { throw new Error( 'Error: Either specify the metadata type after the BU or use --metadata' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.stop(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.stop(argv.BU, typeKeyCombo); } } ) .command( ['audit <BU>'], 'shows audit log for the entity (journey etc.)', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to start an item', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for audit:', describe: 'type or type:key or type:i:id or type:n:name to fix', demandOption: true, }) .option('like', { type: 'string', group: 'Options for audit:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); Mcdev.audit(argv.BU, typeKeyCombo); } ) .command( ['fixKeys <BU> [TYPE] [KEY]', 'fx'], 'changes the key of the items to match the name', (yargs) => yargs .positional('BU', { type: 'string', describe: 'the business unit where to fix keys', }) .positional('TYPE', { type: 'string', describe: 'metadata type', }) .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Options for fixKeys:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('like', { type: 'string', group: 'Options for fixKeys:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', }) .option('keySuffix', { type: 'string', alias: 'ks', group: 'Options for fixKeys:', describe: 'allows you to add a suffix to the key of the metadata to be deployed.', }) .option('execute', { type: 'boolean', alias: 'e', group: 'Options for fixKeys:', describe: 'optional: executes item after deploy; this will run the item once immediately', }) .option('schedule', { type: 'boolean', alias: 's', group: 'Options for fixKeys:', describe: 'optionally start existing schedule instead of running item once immediately (only works for automations)', }) .check((argv) => { if (!argv.TYPE && !argv.metadata) { throw new Error( 'Error: Either specify the metadata type after the BU or use --metadata' ); } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); if ('undefined' === typeof typeKeyCombo) { Mcdev.fixKeys(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); } else { Mcdev.fixKeys(argv.BU, typeKeyCombo); } } ) .command( ['replaceContentBlock', 'rcb'], 'Replaces ContentBlockById, ContentBlockByKey or ContentBlockByName functions with each other in AMPscript', (yargs) => yargs .option('bu', { type: 'string', group: 'Required parameters for replaceContentBlock:', describe: 'the business unit on which to perform the operation (in format "credential name/BU name")', demandOption: true, }) .option('to', { type: 'string', alias: 't', choices: ['key', 'name', 'id'], group: 'Required parameters for replaceContentBlock:', describe: 'what ampscript function to replace it with (key, name, id)', demandOption: true, }) .option('metadata', { type: 'string', array: true, alias: 'm', group: 'Optional parameters for replaceContentBlock:', describe: 'type or type:key or type:i:id or type:n:name to fix', }) .option('from', { type: 'string', alias: 'f', choices: ['key', 'name', 'id'], array: true, group: 'Optional parameters for replaceContentBlock:', describe: 'what ampscript function to search for (key, name, id); automatically set to values not used by --to if not provided', }) .option('skipRetrieve', { type: 'boolean', alias: 'sr', group: 'Optional parameters for replaceContentBlock:', describe: 'if you have already just downloaded the metadata and want to skip the retrieve step', }) .option('skipDeploy', { type: 'boolean', group: 'Optional parameters for replaceContentBlock:', describe: 'if you have want to carefully examine the changed files in your retrieve folder you can run this dry-run mode which skips the deploy step at the end', }) .option('refresh', { type: 'boolean', alias: 'r', group: 'Optional parameters for replaceContentBlock:', describe: 'for asset-message: runs refresh command for related triggeredSends after deploy', }) .check((argv) => { if (argv.from) { for (const from of argv.from) { if (from == argv.to) { throw new Error('Error: --from and --to cannot be the same'); } } } return true; }), (argv) => { Mcdev.setOptions(argv); const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata); Mcdev.replaceCbReference(argv.bu, typeKeyCombo, argv.to, argv.from); } ) .command( ['describeSoap <TYPE>', 'describe', 'soap'], 'Contributor help: describes SOAP API objects and fields', (yargs) => yargs .positional('TYPE', { type: 'string', describe: 'Soap object name', }) .option('bu', { type: 'string', group: 'Optional parameters for describeSoap:', describe: 'defaults to _ParentBU_ but if you', }) .option('json', { type: 'boolean', group: 'Options for describeSoap:', describe: 'optionaly return info in json format', }), (argv) => { Mcdev.setOptions(argv); Mcdev.describeSoap(argv.TYPE, argv.bu); } ) .command( ['upgrade', 'up'], 'Add NPM dependencies and IDE configuration files to your project', {}, (argv) => { Mcdev.setOptions(argv); Mcdev.upgrade(); } ) .option('verbose', { type: 'boolean', description: 'Run with verbose CLI output', }) .option('debug', { type: 'boolean', description: 'Enable developer & edge-case features', }) .option('silent', { type: 'boolean', description: 'Only output errors to CLI', }) .option('noLogColors', { type: 'boolean', description: 'do not use color codes in CLI log output', }) .option('noLogFile', { type: 'boolean', description: 'Only output log to CLI but not to files', }) .option('skipInteraction', { alias: ['yes', 'y'], description: 'Interactive questions where possible and go with defaults instead', }) .option('api', { choices: ['log', 'cli'], description: 'Print API calls to log', }) .option('errorLog', { type: 'boolean', description: 'Create a second log file that only contains error messages', }) .demandCommand(1, 'Please enter a valid command') .strict() .recommendCommands() .wrap(yargs(hideBin(process.argv)).terminalWidth()) .epilog( 'Copyright 2025. Accenture. Get support at https://github.com/Accenture/sfmc-devtools/issues' ) .help().argv; /** * helper to convert CSVs into an array. if only one value was given, it's also returned as an array * * @param {string} csv potentially comma-separated value or null * @returns {string[]} values split into an array. */ function csvToArray(csv) { // eslint-disable-next-line unicorn/no-negated-condition return !csv ? null : csv.includes(',') ? csv .split(',') .map((item) => // allow whitespace in comma-separated lists item.trim() ) // make sure trailing commas are ignored .filter(Boolean) : [csv.trim()].filter(Boolean); } ================================================ FILE: lib/index.js ================================================ 'use strict'; import { Util } from './util/util.js'; import auth from './util/auth.js'; import File from './util/file.js'; import config from './util/config.js'; import Init from './util/init.js'; import InitGit from './util/init.git.js'; import Cli from './util/cli.js'; import DevOps from './util/devops.js'; import BuHelper from './util/businessUnit.js'; import Builder from './Builder.js'; import Deployer from './Deployer.js'; import MetadataTypeInfo from './MetadataTypeInfo.js'; import MetadataTypeDefinitions from './MetadataTypeDefinitions.js'; import Retriever from './Retriever.js'; import cache from './util/cache.js'; import ReplaceContentBlockReference from './util/replaceContentBlockReference.js'; import pLimit from 'p-limit'; import path from 'node:path'; import { confirm } from '@inquirer/prompts'; /** * @typedef {import('../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../types/mcdev.d.js').SkipInteraction} SkipInteraction * @typedef {import('../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../types/mcdev.d.js').ExplainType} ExplainType * @typedef {import('../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes * @typedef {import('../types/mcdev.d.js').BuildFilter} BuildFilter */ /** * main class */ class Mcdev { /** * @returns {string} current version of mcdev */ static version() { console.log('mcdev v' + Util.packageJsonMcdev.version); // eslint-disable-line no-console return Util.packageJsonMcdev.version; } /** * helper method to use unattended mode when including mcdev as a package * * @param {SkipInteraction} [skipInteraction] signals what to insert automatically for things usually asked via wizard * @returns {void} */ static setSkipInteraction(skipInteraction) { Util.skipInteraction = skipInteraction; } /** * configures what is displayed in the console * * @param {object} argv list of command line parameters given by user * @param {boolean} [argv.silent] only errors printed to CLI * @param {boolean} [argv.verbose] chatty user CLI output * @param {boolean} [argv.debug] enables developer output & features * @returns {void} */ static setLoggingLevel(argv) { Util.setLoggingLevel(argv); } static knownOptions = [ '_runningTest', '_welcomeMessageShown', 'api', 'autoMidSuffix', 'changeKeyField', 'changeKeyValue', 'commitHistory', 'dependencies', 'errorLog', 'execute', 'filter', 'fix', 'fixShared', 'format', 'fromRetrieve', 'ignoreFolder', 'ignoreSfFields', 'json', 'keySuffix', 'onlyPublished', 'like', 'matchName', 'noLogColors', 'noLogFile', 'noUpdate', 'publish', 'purge', 'range', 'referenceFrom', 'referenceTo', 'refresh', 'retrieve', 'schedule', 'skipDeploy', 'skipInteraction', 'skipRetrieve', 'skipStatusCheck', 'skipValidation', 'validate', ]; /** * allows setting system wide / command related options * * @param {object} argv list of command line parameters given by user * @returns {void} */ static setOptions(argv) { for (const option of this.knownOptions) { if (argv[option] !== undefined) { Util.OPTIONS[option] = argv[option]; } } // set logging level const loggingOptions = ['silent', 'verbose', 'debug']; for (const option of loggingOptions) { if (argv[option] !== undefined) { this.setLoggingLevel(argv); break; } } // set skip interaction if (argv.skipInteraction !== undefined) { this.setSkipInteraction(argv.skipInteraction); } } /** * handler for 'mcdev createDeltaPkg * * @param {object} argv yargs parameters * @param {string} [argv.commitrange] git commit range via positional * @param {string} [argv.range] git commit range via option * @param {string} [argv.filter] filter file paths that start with any * @param {number} [argv.commitHistory] filter file paths that start with any * @param {DeltaPkgItem[]} [argv.diffArr] list of files to include in delta package (skips git diff when provided) * @returns {Promise.<DeltaPkgItem[]>} list of changed items */ static async createDeltaPkg(argv) { Util.startLogger(); Util.logger.info('Create Delta Package ::'); const properties = await config.getProperties(); if (!properties) { return; } if (argv.commitrange) { Util.logger.warn( `Depecation Notice: Please start using --range to define the commit range or target branch. The positional argument will be removed in the next major release.` ); } const range = argv.commitrange || Util.OPTIONS.range; try { return await (argv.filter ? // get source market and source BU from config DevOps.getDeltaList(properties, range, true, argv.filter, argv.commitHistory) : // If no custom filter was provided, use deployment marketLists & templating DevOps.buildDeltaDefinitions( properties, range, argv.diffArr, argv.commitHistory )); } catch (ex) { Util.logger.error(ex.message); } } /** * @returns {Promise} . */ static async selectTypes() { Util.startLogger(); const properties = await config.getProperties(); if (!properties) { return; } await Cli.selectTypes(properties); } /** * @returns {ExplainType[]} list of supported types with their apiNames */ static explainTypes() { return Cli.explainTypes(); } /** * @returns {Promise.<boolean>} success flag */ static async upgrade() { Util.startLogger(); const properties = await config.getProperties(false, true); if (!properties) { return; } if ((await InitGit.initGitRepo()).status === 'error') { return false; } return Init.upgradeProject(properties, false); } /** * helper to show an off-the-logs message to users */ static #welcomeMessage() { if (Util.OPTIONS._welcomeMessageShown) { // ensure we don't spam the user in case methods are called multiple times return; } Util.OPTIONS._welcomeMessageShown = true; const color = Util.color; /* eslint-disable no-console */ if (process.env['USERDNSDOMAIN'] === 'DIR.SVC.ACCENTURE.COM') { // Accenture internal message console.log( `\n` + ` Thank you for using Accenture SFMC DevTools on your Accenture laptop!\n` + ` We are trying to understand who is using mcdev across the globe and would therefore appreciate it if you left a message\n` + ` in our Accenture Teams channel ${color.bgWhite}telling us about your journey with mcdev${color.reset}: ${color.fgBlue}https://go.accenture.com/mcdevTeams${color.reset}.\n` + `\n` + ` For any questions or concerns, please feel free to create a ticket in GitHub: ${color.fgBlue}https://bit.ly/mcdev-support${color.reset}.\n` ); } else { // external message console.log( `\n` + ` Thank you for using Accenture SFMC DevTools!\n` + `\n` + ` For any questions or concerns, please feel free to create a ticket in GitHub: ${color.fgBlue}https://bit.ly/mcdev-support${color.reset}.\n` ); } /* eslint-enable no-console */ } /** * Retrieve all metadata from the specified business unit into the local file system. * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit retrieval to given metadata type * @param {string[]} [keys] limit retrieval to given metadata key * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.<object>} - */ static async retrieve(businessUnit, selectedTypesArr, keys, changelogOnly) { this.#welcomeMessage(); console.time('Time'); // eslint-disable-line no-console Util.startLogger(); Util.logger.info('mcdev:: Retrieve'); const properties = await config.getProperties(); if (!properties) { return; } // assume a list was passed in and check each entry's validity if (selectedTypesArr) { for (const selectedType of Array.isArray(selectedTypesArr) ? selectedTypesArr : Object.keys(selectedTypesArr)) { if (!Util._isValidType(selectedType)) { return; } } } const resultsObj = {}; if (businessUnit === '*') { Util.logger.info(':: Retrieving all BUs for all credentials'); let counter_credTotal = 0; for (const cred in properties.credentials) { Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { resultsObj[`${cred}/${bu}`] = await this.#retrieveBU( cred, bu, selectedTypesArr, keys ); counter_credBu++; Util.startLogger(true); } counter_credTotal += counter_credBu; Util.logger.info(`:: ${counter_credBu} BUs of ${cred}\n`); } const credentialCount = Object.keys(properties.credentials).length; Util.logger.info( `:: Done for ${counter_credTotal} BUs of ${credentialCount} credential${ credentialCount === 1 ? '' : 's' } in total\n` ); } else { let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already if ( properties.credentials && (!properties.credentials[cred] || (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) ) { const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); if (buObject === null) { return; } else { cred = buObject.credential; bu = buObject.businessUnit; } } if (bu === '*' && properties.credentials && properties.credentials[cred]) { Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { resultsObj[`${cred}/${bu}`] = await this.#retrieveBU( cred, bu, selectedTypesArr, keys ); counter_credBu++; Util.startLogger(true); } Util.logger.info(`:: Done for ${counter_credBu} BUs of ${cred}\n`); } else { // retrieve a single BU; return const retrieveChangelog = await this.#retrieveBU( cred, bu, selectedTypesArr, keys, changelogOnly ); if (changelogOnly) { console.timeEnd('Time'); // eslint-disable-line no-console return retrieveChangelog; } else { resultsObj[`${cred}/${bu}`] = retrieveChangelog; } Util.logger.info(`:: Done\n`); } } // merge all results into one object for (const credBu in resultsObj) { for (const type in resultsObj[credBu]) { const base = resultsObj[credBu][type][0]; for (let i = 1; i < resultsObj[credBu][type].length; i++) { // merge all items into the first array Object.assign(base, resultsObj[credBu][type][i]); } resultsObj[credBu][type] = resultsObj[credBu][type][0]; } } console.timeEnd('Time'); // eslint-disable-line no-console return resultsObj; } /** * helper for {@link Mcdev.retrieve} * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit retrieval to given metadata type/subtype * @param {string[]} [keys] limit retrieval to given metadata key * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.<object>} ensure that BUs are worked on sequentially */ static async #retrieveBU(cred, bu, selectedTypesArr, keys, changelogOnly) { // ensure changes to the selectedTypesArr on one BU do not affect other BUs called in the same go selectedTypesArr = structuredClone(selectedTypesArr); const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); if (buObject !== null) { cache.initCache(buObject); cred = buObject.credential; bu = buObject.businessUnit; Util.logger.info(''); Util.logger.info(`:: Retrieving ${cred}/${bu}`); const retrieveTypesArr = []; if (selectedTypesArr) { for (const selectedType of Array.isArray(selectedTypesArr) ? selectedTypesArr : Object.keys(selectedTypesArr)) { const { type, subType } = Util.getTypeAndSubType(selectedType); const removePathArr = [properties.directories.retrieve, cred, bu, type]; if ( type && subType && MetadataTypeInfo[type] && MetadataTypeDefinitions[type].subTypes.includes(subType) ) { // Clear output folder structure for selected sub-type removePathArr.push(subType); retrieveTypesArr.push(selectedType); } else if (type && MetadataTypeInfo[type]) { // Clear output folder structure for selected type retrieveTypesArr.push(type); } const areKeySet = Array.isArray(selectedTypesArr) ? !!keys : selectedTypesArr[selectedType] !== null; if ((!areKeySet && !Util.OPTIONS.like) || Util.OPTIONS.purge) { Util.logger.debug(`:: Cleaning output folder for ${selectedType}`); // dont delete directories if we are just re-retrieving a single file or if we are re-retrieving only files matching the --like criteria let isCleaned = false; const MAX_RETRIES = 10; let retryCount = 0; do { try { await File.remove(File.normalizePath(removePathArr)); isCleaned = true; } catch (ex) { // to avoid EBUSY: resource busy or locked errors on Windows, we retry after a short wait retryCount++; if (retryCount >= MAX_RETRIES) { Util.logger.error( `Failed to clean output folder for ${selectedType} after ${MAX_RETRIES} attempts: ${ex && ex.message ? ex.message : ex}` ); break; } await Util.sleep(100); } } while (!isCleaned); } else { Util.logger.debug(`:: NOT cleaning output folder for ${selectedType}`); } } } if (!retrieveTypesArr.length) { // assume no type was given and config settings are used instead: // Clear output folder structure await File.remove(File.normalizePath([properties.directories.retrieve, cred, bu])); // removes subtypes and removes duplicates retrieveTypesArr.push( ...new Set(properties.metaDataTypes.retrieve.map((type) => type.split('-')[0])) ); for (const selectedType of retrieveTypesArr) { const test = Util._isValidType(selectedType); if (!test) { Util.logger.error( `Please remove the type ${selectedType} from your ${Util.configFileName}` ); return; } } } const retriever = new Retriever(properties, buObject); try { // await is required or the calls end up conflicting const retrieveChangelog = await retriever.retrieve( retrieveTypesArr, Array.isArray(selectedTypesArr) ? keys : selectedTypesArr, null, changelogOnly ); return retrieveChangelog; } catch (ex) { Util.logger.errorStack(ex, 'mcdev.retrieve failed'); } } } /** * Deploys all metadata located in the 'deploy' directory to the specified business unit * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} [selectedTypesArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys * @returns {Promise.<Object.<string, MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type) */ static async deploy(businessUnit, selectedTypesArr, keyArr) { this.#welcomeMessage(); console.time('Time'); // eslint-disable-line no-console Util.startLogger(); const deployResult = await Deployer.deploy(businessUnit, selectedTypesArr, keyArr); console.timeEnd('Time'); // eslint-disable-line no-console return deployResult; } /** * Creates template file for properties.json * * @param {string} [credentialsName] identifying name of the installed package / project * @returns {Promise.<void>} - */ static async initProject(credentialsName) { Util.startLogger(); Util.logger.info('mcdev:: Setting up project'); const properties = await config.getProperties(!!credentialsName, true); try { await Init.initProject(properties, credentialsName); } catch (ex) { Util.logger.error(ex.message); } } /** * Clones an existing project from git repository and installs it * * @returns {Promise.<void>} - */ static async joinProject() { Util.startLogger(); Util.logger.info('mcdev:: Joining an existing project'); try { await Init.joinProject(); } catch (ex) { Util.logger.error(ex.message); } } /** * Refreshes BU names and ID's from MC instance * * @param {string} credentialsName identifying name of the installed package / project * @returns {Promise.<void>} - */ static async findBUs(credentialsName) { Util.startLogger(); Util.logger.info('mcdev:: Load BUs'); const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, credentialsName, true); if (buObject !== null) { BuHelper.refreshBUProperties(properties, buObject.credential); } } /** * Creates docs for supported metadata types in Markdown and/or HTML format * * @param {string} businessUnit references credentials from properties.json * @param {string} type metadata type * @returns {Promise.<void>} - */ static async document(businessUnit, type) { Util.startLogger(); Util.logger.info('mcdev:: Document'); const properties = await config.getProperties(); if (!properties) { return; } if (type && !MetadataTypeInfo[type]) { Util.logger.error(`:: '${type}' is not a valid metadata type`); return; } try { const parentBUOnlyTypes = ['user', 'role']; const buObject = await Cli.getCredentialObject( properties, parentBUOnlyTypes.includes(type) ? businessUnit.split('/')[0] : businessUnit, parentBUOnlyTypes.includes(type) ? Util.parentBuName : null ); if (buObject !== null) { MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; MetadataTypeInfo[type].document(); } } catch (ex) { Util.logger.error('mcdev.document ' + ex.message); Util.logger.debug(ex.stack); Util.logger.info( 'If the directoy does not exist, you may need to retrieve this BU first.' ); } } /** * deletes metadata from MC instance by key * * @param {string} businessUnit references credentials from properties.json * @param {string | TypeKeyCombo} selectedTypes supported metadata type (single) or complex object * @param {string[] | string} [keys] Identifier of metadata * @returns {Promise.<boolean>} true if successful, false otherwise */ static async deleteByKey(businessUnit, selectedTypes, keys) { Util.startLogger(); Util.logger.info('mcdev:: delete'); /** @typedef {string[]} */ let selectedTypesArr; /** @typedef {TypeKeyCombo} */ let selectedTypesObj; let keyArr; keyArr = 'string' === typeof keys ? [keys] : keys; if ('string' === typeof selectedTypes) { selectedTypesArr = [selectedTypes]; } else { selectedTypesObj = selectedTypes; // reset keys array because it will be overriden by values from selectedTypesObj keyArr = null; } // check if types are valid for (const selectedType of selectedTypesArr || Object.keys(selectedTypesObj)) { if (!Util._isValidType(selectedType)) { return; } } const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (!buObject) { return; } let client; try { client = auth.getSDK(buObject); } catch (ex) { Util.logger.error(ex.message); return; } let status = true; for (const type of selectedTypesArr || Object.keys(selectedTypesObj)) { keyArr = selectedTypesArr ? keyArr : selectedTypesObj[type]; if (!keyArr) { Util.logger.error(`No keys set for ${type}`); return; } MetadataTypeInfo[type].client = client; MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; await MetadataTypeInfo[type].preDeleteTasks(keyArr); const deleteLimit = pLimit( MetadataTypeInfo[type].definition.deleteSynchronously ? 1 : 20 ); await Promise.allSettled( keyArr.map((key) => deleteLimit(async () => { try { const result = await MetadataTypeInfo[type].deleteByKey(key); status &&= result; } catch (ex) { Util.logger.errorStack( ex, ` - Deleting ${type} ${key} on BU ${businessUnit} failed` ); status = false; } return status; }) ) ); } return status; } /** * get name & key for provided id * * @param {string} businessUnit references credentials from properties.json * @param {string} type supported metadata type * @param {string} id Identifier of metadata * @returns {Promise.<{key:string, name:string, path:string}>} key, name and path of metadata; null if not found */ static async resolveId(businessUnit, type, id) { Util.startLogger(); if (!Util.OPTIONS.json) { Util.logger.info('mcdev:: resolveId'); } if (!Util._isValidType(type)) { return; } const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (buObject !== null) { try { MetadataTypeInfo[type].client = auth.getSDK(buObject); } catch (ex) { Util.logger.error(ex.message); return; } if (!Util.OPTIONS.json) { Util.logger.info( Util.getGrayMsg(` - Searching ${type} with id ${id} on BU ${businessUnit}`) ); } try { MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; return await MetadataTypeInfo[type].resolveId(id); } catch (ex) { Util.logger.errorStack(ex, ` - Could not resolve ID of ${type} ${id}`); } } } /** * ensures triggered sends are restarted to ensure they pick up on changes of the underlying emails * * @param {string} businessUnit references credentials from properties.json * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async refresh(businessUnit, selectedTypes, keys) { return this.#runMethod('refresh', businessUnit, selectedTypes, keys); } /** * method for contributors to get details on SOAP objects * * @param {string} type references credentials from properties.json * @param {string} [businessUnit] defaults to first credential's ParentBU * @returns {Promise.<void>} - */ static async describeSoap(type, businessUnit) { Util.startLogger(); Util.logger.info('mcdev:: describe SOAP'); const properties = await config.getProperties(); if (!properties) { return; } const credential = Object.keys(properties.credentials)[0]; businessUnit ||= credential + '/' + Object.keys(properties.credentials[credential].businessUnits)[0]; const buObject = await Cli.getCredentialObject(properties, businessUnit); if (!buObject) { return; } try { const client = auth.getSDK(buObject); const response = await client.soap.describe(type); if (response?.ObjectDefinition?.Properties) { Util.logger.info( `Properties for SOAP object ${response.ObjectDefinition.ObjectType}:` ); const properties = response.ObjectDefinition.Properties.map((prop) => { delete prop.PartnerKey; delete prop.ObjectID; return prop; }); if (Util.OPTIONS.json) { console.log(JSON.stringify(properties, null, 2)); // eslint-disable-line no-console } else { console.table(properties); // eslint-disable-line no-console } return properties; } else { throw new Error( `Soap object ${type} not found. Please check the spelling and retry` ); } } catch (ex) { Util.logger.error(ex.message); } } /** * Converts metadata to legacy format. Output is saved in 'converted' directory * * @param {string} businessUnit references credentials from properties.json * @returns {Promise.<void>} - */ static async badKeys(businessUnit) { Util.startLogger(); const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (buObject !== null) { Util.logger.info('Gathering list of Name<>External Key mismatches (bad keys)'); const retrieveDir = File.filterIllegalPathChars( File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]) ); const docPath = File.normalizePath([ properties.directories.docs, 'badKeys', buObject.credential, ]); const filename = File.normalizePath([ docPath, File.filterIllegalFilenames(buObject.businessUnit) + '.badKeys.md', ]); await File.ensureDir(docPath); if (await File.pathExists(filename)) { await File.remove(filename); } const regex = new RegExp(String.raw`(\w+-){4}\w+`); await File.ensureDir(retrieveDir); const metadata = await Deployer.readBUMetadata(retrieveDir, null, true); let output = '# List of Metadata with Name-Key mismatches\n'; for (const metadataType in metadata) { let listEntries = ''; for (const entry in metadata[metadataType]) { const metadataEntry = metadata[metadataType][entry]; if (regex.test(entry)) { if (metadataType === 'query' && metadataEntry.Status === 'Inactive') { continue; } listEntries += '- ' + entry + (metadataEntry.name || metadataEntry.Name ? ' => ' + (metadataEntry.name || metadataEntry.Name) : '') + '\n'; } } if (listEntries !== '') { output += '\n## ' + metadataType + '\n\n' + listEntries; } } await File.writeToFile( docPath, File.filterIllegalFilenames(buObject.businessUnit) + '.badKeys', 'md', output ); Util.logger.info('Bad keys documented in ' + filename); } } /** * Retrieve a specific metadata file and templatise. * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} name name of the metadata * @param {string} market market which should be used to revert template * @returns {Promise.<MultiMetadataTypeList>} - */ static async retrieveAsTemplate(businessUnit, selectedType, name, market) { Util.startLogger(); Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); const properties = await config.getProperties(); if (!properties) { return; } if (!Util._isValidType(selectedType)) { return; } const { type, subType } = Util.getTypeAndSubType(selectedType); let retrieveTypesArr; if ( type && subType && MetadataTypeInfo[type] && MetadataTypeDefinitions[type].subTypes.includes(subType) ) { retrieveTypesArr = [selectedType]; } else if (type && MetadataTypeInfo[type]) { retrieveTypesArr = [type]; } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (buObject !== null) { cache.initCache(buObject); const retriever = new Retriever(properties, buObject); if (Util.checkMarket(market, properties)) { return retriever.retrieve(retrieveTypesArr, name, properties.markets[market]); } } } /** * @param {string} businessUnit references credentials from properties.json * @param {TypeKeyCombo} typeKeyList limit retrieval to given metadata type * @returns {Promise.<TypeKeyCombo>} selected types including dependencies */ static async addDependentCbReferences(businessUnit, typeKeyList) { if (!Util.OPTIONS.dependencies) { return; } const initialAssetNumber = typeKeyList['asset']?.length || 0; const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); Util.logger.info( 'Searching for additional dependencies that were linked via ContentBlockByKey, ContentBlockByName and ContentBlockById' ); await ReplaceContentBlockReference.createCache(properties, buObject, true); // because we re-use the replaceReference logic here we need to manually set this value /** @type {ContentBlockConversionTypes[]} */ Util.OPTIONS.referenceFrom = ['key', 'name', 'id']; /** @type {ContentBlockConversionTypes} */ Util.OPTIONS.referenceTo = 'key'; /** @type {Set.<string>} */ const assetDependencies = new Set(); const retrieveDir = File.filterIllegalPathChars( File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]) ); // check all non-asset types for dependencies for (const depType in typeKeyList) { if ( !Object.prototype.hasOwnProperty.call( MetadataTypeInfo[depType], 'replaceCbReference' ) || depType === 'asset' ) { continue; } MetadataTypeInfo[depType].properties = properties; MetadataTypeInfo[depType].buObject = buObject; await MetadataTypeInfo[depType].getCbReferenceKeys( typeKeyList[depType], retrieveDir, assetDependencies ); } // add dependencies to selectedTypes if (assetDependencies.size) { const depType = 'asset'; if (typeKeyList[depType]) { typeKeyList[depType].push(...assetDependencies); } else { typeKeyList[depType] = [...assetDependencies]; } // remove duplicates in main object after adding dependencies typeKeyList[depType] = [...new Set(typeKeyList[depType])]; } // check all assets for dependencies recursively if (typeKeyList.asset?.length) { const depType = 'asset'; const Asset = MetadataTypeInfo[depType]; Asset.properties = properties; Asset.buObject = buObject; const additionalAssetDependencies = [ ...(await Asset.getCbReferenceKeys( typeKeyList[depType], retrieveDir, new Set(typeKeyList[depType]) )), ]; if (additionalAssetDependencies.length) { Util.logger.info( `Found ${additionalAssetDependencies.length - initialAssetNumber} additional assets linked via ContentBlockByX.` ); } // remove duplicates in main object after adding dependencies typeKeyList[depType] = [...new Set(typeKeyList[depType])]; } // reset cache regardless of whether assets were found, to avoid stale data in programmatic use MetadataTypeInfo['asset'].getJsonFromFSCache = null; return typeKeyList; } /** * * @param {string} businessUnit references credentials from properties.json * @param {TypeKeyCombo} typeKeyList limit retrieval to given metadata type * @returns {Promise.<TypeKeyCombo>} dependencies */ static async addDependencies(businessUnit, typeKeyList) { if (!Util.OPTIONS.dependencies) { return; } Util.logger.info( 'You might see warnings about items not being found if you have not re-retrieved everything lately.' ); // try re-retrieve without passing selectedTypes to ensure we find all dependencies await this._reRetrieve(businessUnit, true, null, typeKeyList); Util.logger.info( 'Searching for selected items and their dependencies in your project folder' ); /** @type {TypeKeyCombo} */ const dependencies = {}; /** @type {TypeKeyCombo} */ const notFoundList = {}; const initiallySelectedTypesArr = Object.keys(typeKeyList); const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); for (const type of initiallySelectedTypesArr) { MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; await MetadataTypeInfo[type].getDependentFiles( typeKeyList[type], dependencies, notFoundList, true ); } if (Util.getTypeKeyCount(notFoundList)) { // if we have missing items, we need to retrieve them Util.logger.warn( `We recommend you retrieve the missing items with the following command and then re-run buildDefinition:` ); Util.logger.warn( ` mcdev retrieve ${businessUnit} ${Util.convertTypeKeyToCli(notFoundList)}` ); } // remove duplicates & empty types for (const type in dependencies) { if (dependencies[type].length) { dependencies[type] = [...new Set(dependencies[type])]; } else { delete dependencies[type]; } } // add dependencies to selectedTypes if (Object.keys(dependencies).length) { Util.logger.info( `Found ${Util.getTypeKeyCount(dependencies)} items across ${Object.keys(dependencies).length} types.` ); for (const type in dependencies) { if (typeKeyList[type]) { typeKeyList[type].push(...dependencies[type]); } else { typeKeyList[type] = dependencies[type]; } // remove duplicates in main object after adding dependencies typeKeyList[type] = [...new Set(typeKeyList[type])]; } } return dependencies; } /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnitTemplate references credentials from properties.json * @param {string} businessUnitDefinition references credentials from properties.json * @param {TypeKeyCombo} typeKeyCombo limit retrieval to given metadata type * @returns {Promise.<MultiMetadataTypeList | object>} response from buildDefinition */ static async clone(businessUnitTemplate, businessUnitDefinition, typeKeyCombo) { return this.build( businessUnitTemplate, businessUnitDefinition, typeKeyCombo, ['__clone__'], ['__clone__'] ); } /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnitTemplate references credentials from properties.json * @param {string} businessUnitDefinition references credentials from properties.json * @param {TypeKeyCombo} typeKeyCombo limit retrieval to given metadata type * @param {string[]} marketTemplate market localizations * @param {string[]} marketDefinition market localizations * @param {boolean} [bulk] runs buildDefinitionBulk instead of buildDefinition; requires marketList to be defined and given via marketDefinition * @param {BuildFilter} [filter] market list specific filter for buildTemplate * @returns {Promise.<MultiMetadataTypeList | object>} response from buildDefinition */ static async build( businessUnitTemplate, businessUnitDefinition, typeKeyCombo, marketTemplate, marketDefinition, bulk, filter ) { if (!bulk && !businessUnitDefinition) { Util.logger.error( 'Please provide a business unit to deploy to via --buTo or activate --bulk' ); return; } // check if types are valid for (const type of Object.keys(typeKeyCombo)) { if (!Util._isValidType(type)) { return; } if (!Array.isArray(typeKeyCombo[type]) || typeKeyCombo[type].length === 0) { Util.logger.error('You need to define keys, not just types to run build'); // we need an array of keys here return; } } // redirect templates to temporary folder when executed via build() const properties = await config.getProperties(); if (!properties) { return; } const templateDirBackup = properties.directories.template; properties.directories.template = '.mcdev/template/'; Util.logger.info('mcdev:: Build Template & Build Definition'); const templates = await this.buildTemplate( businessUnitTemplate, typeKeyCombo, null, marketTemplate, filter ); // check if any templates were found if (!Object.keys(templates).length || !Util.getTypeKeyCount(typeKeyCombo)) { Util.logger.error('No templates created. Aborting build'); properties.directories.template = templateDirBackup; return; } if (typeof Util.OPTIONS.purge !== 'boolean') { // deploy folder is in targets for definition creation // recommend to purge their content first Util.OPTIONS.purge = await confirm({ message: `Do you want to empty relevant BU sub-folders in /${properties.directories.deploy} (ensures no files from previous deployments remain)?`, default: true, }); } const response = bulk ? await this.buildDefinitionBulk(marketDefinition[0], typeKeyCombo, null) : await this.buildDefinition( businessUnitDefinition, typeKeyCombo, null, marketDefinition ); // reset temporary template folder try { await File.remove(properties.directories.template); } catch { // sometimes the first attempt is not successful for some operating system reason. Trying again mostly solves this await File.remove(properties.directories.template); } properties.directories.template = templateDirBackup; return response; } /** * Build a template based on a list of metadata files in the retrieve folder. * * @param {string} businessUnit references credentials from properties.json * @param {string | TypeKeyCombo} selectedTypes limit retrieval to given metadata type * @param {string[] | undefined} keyArr customerkey of the metadata * @param {string[]} marketArr market localizations * @param {BuildFilter} [filter] market list specific filter * @returns {Promise.<MultiMetadataTypeList>} - */ static async buildTemplate(businessUnit, selectedTypes, keyArr, marketArr, filter) { this.#welcomeMessage(); Util.startLogger(); Util.logger.info('mcdev:: Build Template from retrieved files'); const properties = await config.getProperties(); if (!properties) { return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (!Util.checkMarketList(marketArr, properties)) { return; } const typeKeyList = Util.checkAndPrepareTypeKeyCombo( selectedTypes, keyArr, 'buildTemplate' ); if (!typeKeyList) { return; } this.applyKeyFilters(typeKeyList, filter); if (!Util.OPTIONS.dependencies) { await this._reRetrieve(businessUnit, false, typeKeyList); } // convert names to keys const retrieveDir = File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]); for (const type of Object.keys(typeKeyList)) { const keyArr = typeKeyList[type]; if (keyArr.some((key) => key.startsWith('name:'))) { // at least one key was provided as a name -> load all files from disk to try and find that key const builTemplateCache = Object.values( await MetadataTypeInfo[type].getJsonFromFS(retrieveDir + path.sep + type) ); typeKeyList[type] = keyArr .map((key) => { if (key.startsWith('name:')) { // key was defined by name. try and find matching item on disk const name = key.slice(5); const foundKeysByName = builTemplateCache .filter( (item) => name == item[MetadataTypeInfo[type].definition.nameField] ) .map((item) => item[MetadataTypeInfo[type].definition.keyField]); if (foundKeysByName.length === 1) { key = foundKeysByName[0]; Util.logger.debug( `- found ${type} key '${key}' for name '${name}'` ); return key; } else if (foundKeysByName.length > 1) { Util.logger.error( `Found multiple keys (${foundKeysByName.join(', ')}) for name: ${key}` ); return; } else { Util.logger.error(`Could not find any keys for name: ${name}`); return; } } else { return key; } }) .filter(Boolean); } } // if dependencies are enabled, we need to search for them and add them to our await this.addDependencies(businessUnit, typeKeyList); await this.addDependentCbReferences(businessUnit, typeKeyList); /** @type {MultiMetadataTypeList} */ const returnObj = {}; for (const type of Object.keys(typeKeyList).toSorted()) { // ensure keys are sorted again, after finding dependencies, to enhance log readability typeKeyList[type].sort(); const result = await Builder.buildTemplate( businessUnit, type, typeKeyList[type], marketArr ); if (result[type]) { returnObj[type] = result[type]; } } Util.logger.info(`Templated ${Util.getTypeKeyCount(returnObj)} items`); return returnObj; } /** * helper for {@link buildTemplate} to apply include/exclude key filters * * @param {TypeKeyCombo | undefined} typeKeyList supported metadata type * @param {BuildFilter} filter market list specific filter for buildTemplate */ static applyKeyFilters(typeKeyList, filter) { if (!filter) { Util.logger.debug(`no filter object defined on template market`); return; } const excludeKey = filter?.exclude?.key; if (excludeKey && Object.keys(excludeKey)?.length) { Util.logger.debug('exclude-key-filters: ' + Object.keys(excludeKey)); for (const type of Object.keys(typeKeyList)) { const excludeKeyType = []; if (excludeKey['*']) { // if excludeKey is defined for all types, use it excludeKeyType.push(...excludeKey['*']); } if (excludeKey[type]) { // if excludeKey is defined for this type, expand list with it excludeKeyType.push(...excludeKey[type]); } if (!excludeKeyType.length) { continue; } typeKeyList[type] = typeKeyList[type].filter((key) => { for (const element of excludeKeyType) { if (Util.stringLike(key, element)) { Util.logger.info(`🚫 ☇ filtered ${type} ${key}: exclude-filter-match`); return false; } } return true; }); } } else { Util.logger.debug(`no exclude-filter defined`); } const includeKey = filter?.include?.key; if (includeKey && Object.keys(includeKey)?.length) { Util.logger.debug('include-key-filters: ' + Object.keys(includeKey)); for (const type of Object.keys(typeKeyList)) { const includeKeyType = []; if (includeKey['*']) { // if includeKey is defined for all types, use it includeKeyType.push(...includeKey['*']); } if (includeKey[type]) { // if includeKey is defined for this type, expand list with it includeKeyType.push(...includeKey[type]); } if (!includeKeyType.length) { continue; } typeKeyList[type] = typeKeyList[type].filter((key) => { let included = false; for (const element of includeKeyType) { if (Util.stringLike(key, element)) { included = true; break; } } if (!included) { Util.logger.info(`🚫 ☇ filtered ${type} ${key}: no include-filter-match`); return false; } return true; }); } } else { Util.logger.debug(`no include-filter defined`); } } /** * Build a specific metadata file based on a template. * * @param {string} businessUnit references credentials from properties.json * @param {boolean} [alwaysAsk] by default this code only runs if --retrieve is set; this flag allows to always ask * @param {TypeKeyCombo} [selectedTypes] limit retrieval to given metadata type * @param {TypeKeyCombo} [defaultPlusTheseTypes] if we run build for a non-standard type we need to tell it what to download on top * @returns {Promise.<void>} - */ static async _reRetrieve( businessUnit, alwaysAsk = false, selectedTypes, defaultPlusTheseTypes ) { let runRetrieveNow; if (!Util.OPTIONS.skipInteraction && Util.OPTIONS.retrieve === undefined && alwaysAsk) { runRetrieveNow = await confirm({ message: `Do you want to re-retrieve ${selectedTypes ? Util.convertTypeKeyToString(selectedTypes) : 'all metadata'} for ${businessUnit} now?`, default: false, }); } if (runRetrieveNow || Util.OPTIONS.retrieve) { Util.logger.info( `Re-retrieving ${businessUnit}: ${selectedTypes ? Util.convertTypeKeyToString(selectedTypes) : 'all metadata'}` ); /** @type {TypeKeyCombo | string[]} */ let retrieveTypes = selectedTypes ? structuredClone(selectedTypes) : null; if (defaultPlusTheseTypes) { if (selectedTypes) { // we need to work with a clone here because retrieve() modifies the object passed in as 2nd parameter retrieveTypes = Object.assign( retrieveTypes, structuredClone(defaultPlusTheseTypes) ); } else { const properties = await config.getProperties(); retrieveTypes = [ ...new Set( properties.metaDataTypes.retrieve.map((type) => type.split('-')[0]) ), ...Object.keys(defaultPlusTheseTypes), ]; } } await this.retrieve(businessUnit, retrieveTypes); } } /** * Build a specific metadata file based on a template. * * @param {string} businessUnit references credentials from properties.json * @param {string | TypeKeyCombo} selectedTypes limit retrieval to given metadata type * @param {string[] | undefined} nameArr name of the metadata * @param {string[]} marketArr market localizations * @returns {Promise.<MultiMetadataTypeList>} - */ static async buildDefinition(businessUnit, selectedTypes, nameArr, marketArr) { this.#welcomeMessage(); Util.startLogger(); Util.logger.info('mcdev:: Build Definition from Template'); const properties = await config.getProperties(); if (!properties) { return; } if (!Util.checkMarketList(marketArr, properties)) { return; } const typeKeyList = Util.checkAndPrepareTypeKeyCombo( selectedTypes, nameArr, 'buildDefinition' ); if (!typeKeyList) { return; } if (Util.OPTIONS.purge) { const buObject = await Cli.getCredentialObject(properties, businessUnit); await Builder.purgeDeployFolder(buObject.credential + '/' + buObject.businessUnit); } else { Util.logger.info(` ☇ skipping purge of folder`); } /** @type {MultiMetadataTypeList} */ const returnObj = {}; for (const type of Object.keys(typeKeyList).toSorted()) { const result = await Builder.buildDefinition( businessUnit, type, typeKeyList[type], marketArr ); returnObj[type] = result[type]; } Util.logger.info('Done'); return returnObj; } /** * Build a specific metadata file based on a template using a list of bu-market combos * * @param {string} listName name of list of BU-market combos * @param {string | TypeKeyCombo} selectedTypes supported metadata type * @param {string[]} [nameArr] name of the metadata * @returns {Promise.<object>} - */ static async buildDefinitionBulk(listName, selectedTypes, nameArr) { this.#welcomeMessage(); Util.startLogger(); Util.logger.info('mcdev:: Build Definition from Template Bulk'); const properties = await config.getProperties(); if (!properties) { return; } try { Util.verifyMarketList(listName, properties); } catch (ex) { Util.logger.error(ex.message); return; } const typeKeyList = Util.checkAndPrepareTypeKeyCombo( selectedTypes, nameArr, 'buildDefinitionBulk' ); if (!typeKeyList) { return; } if (Util.OPTIONS.purge) { await Builder.purgeDeployFolderList(listName); } else { Util.logger.info(` ☇ skipping purge of folder`); } /** @type {MultiMetadataTypeList} */ const returnObj = {}; for (const type of Object.keys(typeKeyList).toSorted()) { Util.logger.info(Util.getGrayMsg(`buildDefinitionBulk for ${type}`)); const result = await Builder.buildDefinitionBulk(listName, type, typeKeyList[type]); returnObj[type] = result; } Util.logger.info('Done'); return returnObj; } /** * * @param {string} businessUnit references credentials from properties.json * @param {string} selectedType supported metadata type * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(businessUnit, selectedType, keyArr) { Util.startLogger(); Util.logger.info('mcdev:: getFilesToCommit'); const properties = await config.getProperties(); if (!properties) { return; } if (!Util._isValidType(selectedType)) { return; } if (selectedType.includes('-')) { Util.logger.error( `:: '${selectedType}' is not a valid metadata type. Please don't include subtypes.` ); return; } const buObject = await Cli.getCredentialObject(properties, businessUnit); if (buObject !== null) { return DevOps.getFilesToCommit(properties, buObject, selectedType, keyArr); } } /** * Publish an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async publish(businessUnit, selectedTypes, keys) { return this.#runMethod('publish', businessUnit, selectedTypes, keys); } /** * Publish an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async validate(businessUnit, selectedTypes, keys) { return this.#runMethod('validate', businessUnit, selectedTypes, keys); } /** * Start/execute an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async execute(businessUnit, selectedTypes, keys) { return this.#runMethod('execute', businessUnit, selectedTypes, keys); } /** * Schedule an item (shortcut for execute --schedule) * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async schedule(businessUnit, selectedTypes, keys) { return this.#runMethod('schedule', businessUnit, selectedTypes, keys); } /** * pause an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async pause(businessUnit, selectedTypes, keys) { return this.#runMethod('pause', businessUnit, selectedTypes, keys); } /** * stop an item * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async stop(businessUnit, selectedTypes, keys) { return this.#runMethod('stop', businessUnit, selectedTypes, keys); } /** * stop an item * * @param {string} businessUnit name of BU * @param {TypeKeyCombo} selectedTypes limit to given metadata types * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async audit(businessUnit, selectedTypes) { return this.#runMethod('audit', businessUnit, selectedTypes); } /** * Updates the key to match the name field * * @param {string} businessUnit name of BU * @param {TypeKeyCombo | undefined} selectedTypesObj limit retrieval to given metadata type * @param {string} to what to replace with * @param {string[]} [fromList] what to replace * @returns {Promise.<Object.<string, object>>} key1: business unit name, key2:type value: list of fixed item keys */ static async replaceCbReference(businessUnit, selectedTypesObj, to, fromList) { const allowedFromTo = ['key', 'name', 'id']; if (!allowedFromTo.includes(to)) { Util.logger.error( `Invalid value for argument: --to, Given: "${to}", Choices: "${allowedFromTo.join('", "')}"` ); return; } if (fromList) { if (!Array.isArray(fromList)) { // equalize to array fromList = [fromList]; } for (const from of fromList) { if (!allowedFromTo.includes(from)) { Util.logger.error( `Invalid value for argument: --from, Given: "${from}", Choices: "${allowedFromTo.join('", "')}"` ); } if (from == to) { Util.logger.error('--from and --to cannot be the same'); } } } // define final from/to values and, if from was not set, auto-set it to remaining values not set for to const referenceFrom = fromList || allowedFromTo.filter((item) => item !== to); const referenceTo = to; // if called via CLI, saving the from/to values in OPTIONS was done already, but we need to cover package includes as well this.setOptions({ referenceFrom, referenceTo }); const properties = await config.getProperties(); if (!properties) { return; } if (!Util.isValidBU(properties, businessUnit)) { return; } /** @typedef {string[]} */ let selectedTypesArr; if (selectedTypesObj) { // check if types are valid for (const selectedType of Object.keys(selectedTypesObj)) { if (!Util._isValidType(selectedType)) { return; } } } else { // do it for all types that have a replaceCbReference method selectedTypesArr = [ ...new Set( properties.metaDataTypes.retrieve .map((type) => type.split('-')[0]) .filter((type) => Object.prototype.hasOwnProperty.call( MetadataTypeInfo[type], 'replaceCbReference' ) ) ), ]; } Util.logger.info( `:: Replacing ${referenceFrom.map((from) => 'ContentBlockBy' + Util.capitalizeFirstLetter(from)).join(' and ')} with ContentBlockBy${Util.capitalizeFirstLetter(to)} for ${(Array.isArray( selectedTypesArr ) ? selectedTypesArr : Object.keys(selectedTypesObj) ).join(', ')}` ); const response = await this.#runMethod( 'replaceCbReference', businessUnit, selectedTypesArr || selectedTypesObj ); return response; } /** * Updates the key to match the name field * * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} selectedTypes limit retrieval to given metadata type * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, object>>} key1: business unit name, key2:type value: list of fixed item keys */ static async fixKeys(businessUnit, selectedTypes, keys) { const properties = await config.getProperties(); if (!properties) { return; } // make sure validation rules dont keep us from fixing the keys this.setOptions({ skipValidation: true }); let reRetrieveAll = false; /** @typedef {string[]} */ let selectedTypesArr; /** @typedef {TypeKeyCombo} */ let selectedTypesObj; if (selectedTypes) { // check if types are valid for (const selectedType of Array.isArray(selectedTypes) ? selectedTypes : Object.keys(selectedTypes)) { if (!Util._isValidType(selectedType)) { return; } } if (Array.isArray(selectedTypes)) { selectedTypesArr = selectedTypes; } else { selectedTypesObj = selectedTypes; } } else { // do it for all standard retrieve types selectedTypesArr = [ ...new Set( properties.metaDataTypes.retrieve .map((type) => type.split('-')[0]) .filter( (type) => !MetadataTypeDefinitions[type].keyIsFixed && MetadataTypeDefinitions[type].keyField !== MetadataTypeDefinitions[type].nameField && MetadataTypeDefinitions[type].keyField !== MetadataTypeDefinitions[type].idField ) ), ]; Util.logger.info( `:: Fixing keys for ${selectedTypesArr ? selectedTypesArr.join(', ') : Object.keys(selectedTypesObj).join(', ')}` ); reRetrieveAll = true; this.setOptions({ skipInteraction: { fixKeysReretrieve: false }, }); } // `Type 'event' is not supported for fixKeys for compatibility reasons. Draft Journeys would otherwise be broken after the key change. If you do need to update an event key, use deploy --changeKeyValue or --changeKeyField instead.`; if (Array.isArray(selectedTypes) && selectedTypes.includes('event')) { selectedTypesArr = selectedTypes.filter((type) => type !== 'event'); } else if (selectedTypesObj && selectedTypesObj.event) { delete selectedTypesObj.event; } const response = await this.#runMethod( 'fixKeys', businessUnit, selectedTypesArr || selectedTypesObj, keys ); if (reRetrieveAll) { // only done if selectedTypesArr is set as fallback Util.logger.info( `Retrieving latest versions of ${selectedTypesArr.join(', ')} from server` ); const buObject = await Cli.getCredentialObject(properties, businessUnit, null, true); const retriever = new Retriever(properties, buObject); await retriever.retrieve(selectedTypesArr, null, null, false); } return response; } /** * run a method across BUs * * @param {'schedule'|'execute'|'pause'|'stop'|'publish'|'validate'|'fixKeys'|'replaceCbReference'|'refresh'|'audit'} methodName what to run * @param {string} businessUnit name of BU * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys */ static async #runMethod(methodName, businessUnit, selectedTypes, keys) { Util.startLogger(); let lang_past; let lang_present; let requireType; let requireKeyOrLike; let checkMetadataSupport; /** @type {Object.<string, Object.<string, string[]>>} */ const resultObj = {}; switch (methodName) { case 'schedule': { lang_past = 'scheduled'; lang_present = 'scheduling'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } case 'execute': { lang_past = 'executed'; lang_present = 'executing'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } case 'pause': { lang_past = 'paused'; lang_present = 'pausing'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } case 'stop': { lang_past = 'stopped'; lang_present = 'stopping'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } case 'publish': { lang_past = 'published'; lang_present = 'publishing'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } case 'validate': { lang_past = 'validated'; lang_present = 'validating'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } case 'fixKeys': { lang_past = 'fixed keys'; lang_present = 'fixing keys'; requireType = false; requireKeyOrLike = false; checkMetadataSupport = false; break; } case 'replaceCbReference': { lang_past = 'replaced references'; lang_present = 'replacing references'; requireType = false; requireKeyOrLike = false; checkMetadataSupport = true; break; } case 'refresh': { lang_past = 'refreshed'; lang_present = 'refreshing'; requireType = true; requireKeyOrLike = false; checkMetadataSupport = true; break; } case 'audit': { lang_past = 'audited'; lang_present = 'auditing'; requireType = true; requireKeyOrLike = true; checkMetadataSupport = true; break; } } /** @typedef {string[]} */ let selectedTypesArr; /** @typedef {TypeKeyCombo} */ let selectedTypesObj; if (selectedTypes) { // check if types are valid for (const selectedType of Array.isArray(selectedTypes) ? selectedTypes : Object.keys(selectedTypes)) { if (!Util._isValidType(selectedType)) { return resultObj; } if ( checkMetadataSupport && !Object.prototype.hasOwnProperty.call( MetadataTypeInfo[selectedType], methodName ) ) { Util.logger.error( ` ☇ skipping ${selectedType}: ${methodName} is not supported yet for ${selectedType}` ); return resultObj; } } if (Array.isArray(selectedTypes)) { selectedTypesArr = selectedTypes; } else { selectedTypesObj = selectedTypes; } } if ( requireType && !Array.isArray(selectedTypesArr) && (!selectedTypesObj || !Object.keys(selectedTypesObj).length) ) { Util.logger.error('At least one metadata type needs to be defined.'); return resultObj; } const properties = await config.getProperties(); if (!properties) { return; } for (const selectedType of selectedTypesArr || Object.keys(selectedTypesObj)) { Util.logger.info(`mcdev:: ${methodName} ${selectedType}`); let counter_credBu = 0; let counter_credKeys = 0; const keyArr = selectedTypesArr ? keys : selectedTypesObj[selectedType]; if ( requireKeyOrLike && (!Array.isArray(keyArr) || !keyArr.length) && (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length) ) { Util.logger.error('At least one key or a --like filter is required.'); return resultObj; } else if ( Array.isArray(keyArr) && keyArr.length && Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length ) { Util.logger.error('You can either specify keys OR a --like filter.'); return resultObj; } if (businessUnit === '*') { Util.OPTIONS._multiBuExecution = true; Util.logger.info( `:: ${lang_present} the ${selectedType} on all BUs for all credentials` ); let counter_credTotal = 0; for (const cred in properties.credentials) { Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); // reset counter per cred counter_credKeys = 0; counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { resultObj[cred + '/' + bu] ||= {}; resultObj[cred + '/' + bu][selectedType] = await this.#runOnBU( methodName, cred, bu, selectedType, keyArr ); counter_credBu++; counter_credKeys += resultObj[cred + '/' + bu][selectedType].length; Util.startLogger(true); } counter_credTotal += counter_credBu; Util.logger.info( `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}` ); } Util.logger.info( `:: ${lang_past} ${selectedType} on ${counter_credTotal} BUs in total\n` ); } else { let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already if ( properties.credentials && (!properties.credentials[cred] || (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) ) { const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); if (buObject === null) { return resultObj; } else { cred = buObject.credential; bu = buObject.businessUnit; } } if (bu === '*' && properties.credentials && properties.credentials[cred]) { Util.OPTIONS._multiBuExecution = true; Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); for (const bu in properties.credentials[cred].businessUnits) { resultObj[cred + '/' + bu] ||= {}; resultObj[cred + '/' + bu][selectedType] = await this.#runOnBU( methodName, cred, bu, selectedType, keyArr ); counter_credBu++; counter_credKeys += resultObj[cred + '/' + bu][selectedType].length; Util.startLogger(true); } Util.logger.info( `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}` ); } else { // execute runMethod for the entity on one BU only resultObj[cred + '/' + bu] ||= {}; resultObj[cred + '/' + bu][selectedType] = await this.#runOnBU( methodName, cred, bu, selectedType, keyArr ); Util.logger.info(`:: Done`); } } } return resultObj; } /** * helper for Mcdev.#runMethod * * @param {'schedule'|'execute'|'pause'|'stop'|'publish'|'validate'|'fixKeys'|'replaceCbReference'|'refresh'|'audit'} methodName what to run * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string} [type] limit execution to given metadata type * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.<string[]>} list of keys that were affected */ static async #runOnBU(methodName, cred, bu, type, keyArr) { const properties = await config.getProperties(); if (!properties) { return; } const resultArr = []; const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); try { if (!type) { throw new Error('No type was provided'); } if (buObject !== null) { cache.initCache(buObject); cred = buObject.credential; bu = buObject.businessUnit; } Util.logger.info(`:: ${methodName} ${type} on ${cred}/${bu}`); MetadataTypeInfo[type].client = auth.getSDK(buObject); MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; switch (methodName) { case 'fixKeys': { { resultArr.push(...(await this.#fixKeys(cred, bu, type, keyArr))); break; } } case 'replaceCbReference': { { resultArr.push(...(await this.#replaceCbReference(cred, bu, type, keyArr))); break; } } default: { if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { keyArr = await this.#retrieveKeysWithLike(type, buObject); } resultArr.push(...(await MetadataTypeInfo[type][methodName](keyArr))); } } } catch (ex) { Util.logger.errorStack(ex, 'mcdev.' + methodName + ' failed'); } return resultArr; } /** * helper for Mcdev.#runOnBU * * @param {string} selectedType limit execution to given metadata type * @param {BuObject} buObject properties for auth * @returns {Promise.<string[]>} keyArr */ static async #retrieveKeysWithLike(selectedType, buObject) { const properties = await config.getProperties(); if (!properties) { return; } // cache depenencies const deployOrder = Util.getMetadataHierachy([selectedType]); for (const type in deployOrder) { const subTypeArr = deployOrder[type]; MetadataTypeInfo[type].client = auth.getSDK(buObject); MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; Util.logger.info(`Caching dependent Metadata: ${type}`); Util.logSubtypes(subTypeArr); const result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr); if (result) { if (Array.isArray(result)) { for (const result_i of result) { if (result_i?.metadata && Object.keys(result_i.metadata).length) { cache.mergeMetadata(type, result_i.metadata); } } } else { cache.setMetadata(type, result.metadata); } } } // find all keys in chosen type that match the like-filter const keyArr = []; const metadataMap = cache.getCache()[selectedType]; if (!metadataMap) { throw new Error(`Selected type ${selectedType} could not be cached`); } Util.logger.info( Util.getGrayMsg(`Found ${Object.keys(metadataMap).length} ${selectedType}s`) ); for (const originalKey in metadataMap) { // hide postRetrieveOutput Util.setLoggingLevel({ silent: true }); metadataMap[originalKey] = await MetadataTypeInfo[selectedType].postRetrieveTasks( metadataMap[originalKey] ); // reactivate logging Util.setLoggingLevel({}); if (Util.fieldsLike(metadataMap[originalKey], MetadataTypeDefinitions[selectedType])) { keyArr.push(originalKey); } } Util.logger.info( Util.getGrayMsg( `Identified ${keyArr.length} ${selectedType}${ keyArr.length === 1 ? '' : 's' } that match${keyArr.length === 1 ? 'es' : ''} the like-filter` ) ); return keyArr; } /** * Updates the key to match the name field * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string} type limit execution to given metadata type * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.<string[]>} list of keys that were affected */ static async #fixKeys(cred, bu, type, keyArr) { const properties = await config.getProperties(); if (!properties) { return; } /** @type {string[]} */ let actuallyFixedKeys; const resultArr = []; if ( MetadataTypeDefinitions[type].keyIsFixed === true || MetadataTypeDefinitions[type].keyField === MetadataTypeDefinitions[type].idField ) { Util.logger.error(`Key cannot be updated for this type`); return resultArr; } const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); try { Util.logger.info(`Retrieving latest versions of ${type} from server`); const retriever = new Retriever(properties, buObject); const retrieved = await retriever.retrieve([type], keyArr, null, false); const metadataMap = Object.values(retrieved)[0][0]; const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(metadataMap); if (keysForDeploy.length < 1) { Util.logger.warn( `No items found with a key-name mismatch that match your criteria.\n` ); return resultArr; } this.setOptions({ changeKeyField: MetadataTypeDefinitions[type].nameField, fromRetrieve: true, }); const deployed = await Deployer.deploy(cred + '/' + bu, [type], keysForDeploy); actuallyFixedKeys = Object.keys(Object.values(Object.values(deployed)[0])[0]); resultArr.push(...actuallyFixedKeys); const dependentTypes = await Util.getDependentMetadata(type); if (actuallyFixedKeys && actuallyFixedKeys.length) { Util.logger.info( `Successfully updated ${actuallyFixedKeys.length} key${ actuallyFixedKeys.length === 1 ? '' : 's' } of type ${type}` ); if (dependentTypes.length) { Util.logger.warn( `Please re-retrieve the following types as your local copies might now be outdated: ${Util.getGrayMsg( dependentTypes.join(', ') )}` ); const reRetrieve = await Cli.postFixKeysReretrieve(dependentTypes); if (reRetrieve) { Util.logger.info( `Retrieving latest versions of ${dependentTypes.join(', ')} from server` ); const retriever = new Retriever(properties, buObject); await retriever.retrieve(dependentTypes, null, null, false); } } else { Util.logger.info( `No dependent types found that need to be re-retrieved after fixing keys of type ${type}.` ); } } else { Util.logger.warn(`No keys of type ${type} updated.`); } } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } return resultArr; } /** * Updates the key to match the name field * * @param {string} cred name of Credential * @param {string} bu name of BU * @param {string} type limit execution to given metadata type * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.<string[]>} list of keys that were affected */ static async #replaceCbReference(cred, bu, type, keyArr) { const properties = await config.getProperties(); if (!properties) { return; } /** @type {string[]} */ let updatedKeys; const resultArr = []; const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, null, true ); const savePath = File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, ]); await ReplaceContentBlockReference.createCache(properties, buObject); try { let metadataMap; if (Util.OPTIONS.skipRetrieve) { Util.logger.warn( 'Skipping retrieve due to --skipRetrieve flag. Hope you know what you are doing.' ); metadataMap = await MetadataTypeInfo[type].getJsonFromFS( File.normalizePath([savePath, type]) ); } else { Util.logger.info(`Retrieving latest versions of ${type} from server`); const retriever = new Retriever(properties, buObject); const retrieved = await retriever.retrieve([type], keyArr); metadataMap = Object.values(retrieved)[0][0]; } const keysForDeploy = await MetadataTypeInfo[type].replaceCbReferenceLoop( metadataMap, savePath ); if (keysForDeploy.length < 1) { Util.logger.warn(`No items found that can be updated.\n`); return resultArr; } if (Util.OPTIONS.skipDeploy) { resultArr.push(...keysForDeploy); Util.logger.warn('DRY-RUN MODE: Skipping deploy due to --skipDeploy flag.'); Util.logger.info( 'Once you are satisfied with the result, re-run without --skipRetrieve nor --skipDeploy to actually deploy the changes or run:' ); Util.logger.info(` mcdev d ${cred}/${bu} ${type} "${keysForDeploy.join(',')}"`); } else { this.setOptions({ fromRetrieve: true, }); const deployed = await Deployer.deploy(cred + '/' + bu, [type], keysForDeploy); updatedKeys = Object.keys(Object.values(Object.values(deployed)[0])[0]); resultArr.push(...updatedKeys); if (updatedKeys && updatedKeys.length) { Util.logger.info( `Successfully updated ${updatedKeys.length} item${ updatedKeys.length === 1 ? '' : 's' } of type ${type}` ); } else { Util.logger.warn(`Nothing updated for type ${type}`); } } } catch (ex) { Util.logger.errorStack(ex, 'mcdev.replaceCbReference failed'); } return resultArr; } /** * helper to convert CSVs into an array. if only one value was given, it's also returned as an array * * @param {string|string[]|undefined} metadataOption potentially comma-separated value or null * @param {string[]} [allowedIdentifiers] 'key', 'id', 'name' * @param {boolean} [firstOnly] removes all but the first entry if enabled * @returns {TypeKeyCombo} values split into an array. */ static metadataToTypeKey( metadataOption, allowedIdentifiers = ['key', 'id', 'name'], firstOnly = false ) { if (!metadataOption) { return undefined; // eslint-disable-line unicorn/no-useless-undefined } else if (!Array.isArray(metadataOption)) { metadataOption = [metadataOption]; } if (firstOnly) { // delete everything but the first entry metadataOption.length = 1; } const metadataOptionMap = metadataOption.map((item) => { const itemArr = item.split(':'); const type = itemArr.shift(); switch (itemArr.length) { case 0: { // no ":" found return { type }; } case 1: { // 1 ":" found if (allowedIdentifiers.includes('key')) { return { type, key: itemArr[0] }; } break; } default: { // 2 or more ":" found switch (itemArr[0]) { case 'key': case 'k': { if (allowedIdentifiers.includes('key')) { // remove k/key itemArr.shift(); return { type, key: itemArr.join(':') }; } break; } case 'id': case 'i': { if (allowedIdentifiers.includes('id')) { // remove i/id itemArr.shift(); return { type, id: itemArr.join(':') }; } break; } case 'name': case 'n': { if (allowedIdentifiers.includes('name')) { // remove n/name itemArr.shift(); return { type, name: itemArr.join(':') }; } break; } default: { // assume ":" is part of the key (e.g. possible for DE-fields) if (allowedIdentifiers.includes('key')) { return { type, key: itemArr.join(':') }; } } } } } }); /** @type {TypeKeyCombo} */ const response = {}; for (const item of metadataOptionMap) { if (item) { if (item.key || item.id || item.name) { if (!response[item.type]) { response[item.type] = []; } response[item.type].push( item.key || (item.id ? 'id:' + item.id : item.name ? 'name:' + item.name : null) ); } else { if (!response[item.type]) { response[item.type] = null; } } } } return Object.keys(response).length >= 1 ? response : undefined; } } export default Mcdev; ================================================ FILE: lib/metadataTypes/Asset.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import pLimit from 'p-limit'; import cliProgress from 'cli-progress'; import cache from '../util/cache.js'; import TriggeredSend from './TriggeredSend.js'; import Folder from './Folder.js'; import ReplaceCbReference from '../util/replaceContentBlockReference.js'; import toposort from 'toposort'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * @typedef {import('../../types/mcdev.d.js').AssetSubType} AssetSubType * @typedef {import('../../types/mcdev.d.js').AssetMap} AssetMap * @typedef {import('../../types/mcdev.d.js').AssetItem} AssetItem * @typedef {import('../../types/mcdev.d.js').AssetRequestParams} AssetRequestParams * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * FileTransfer MetadataType * * @augments MetadataType */ class Asset extends MetadataType { /** * Retrieves Metadata of Asset * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} _ unused parameter * @param {string[]} [subTypeArr] optionally limit to a single AssetSubType * @param {string} [key] customer key * @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current * @returns {Promise.<{metadata: AssetMap, type: string}>} Promise */ static async retrieve(retrieveDir, _, subTypeArr, key, loadShared = false) { const items = []; if (subTypeArr) { // check if elements in subTypeArr exist in this.definition.subTypes const invalidSubTypes = subTypeArr.filter( (subType) => !this.definition.subTypes.includes(subType) ); if (invalidSubTypes.length) { throw new Error(`Invalid subType(s) found: ${invalidSubTypes.join(', ')}`); } } subTypeArr ||= this._getSubTypes(); if (retrieveDir) { await File.initPrettier(); } if (retrieveDir && !cache.getCache()?.asset) { // cache this for 3 reasons: // 1) subtypes asset, message and template reference other content blocks by id/key/objectId as part of their views // 2) subtype message references a template if it is template-based // 3) all non-binary subtypes support ampscript / ssjs which can load otherc content blocks via ContentBlockyByX() Util.logger.info(' - Caching dependent Metadata: asset'); const resultLocal = await this.retrieveForCache( undefined, this.definition.selflinkedSubTypes, undefined, false ); cache.mergeMetadata('asset', resultLocal.metadata); Util.logger.info(' - Caching dependent Metadata: shared asset'); const resultShared = await this.retrieveForCache( undefined, this.definition.selflinkedSubTypes, undefined, true ); cache.mergeMetadata('asset', resultShared.metadata); } if (retrieveDir) { if (key) { // running post-delete tasks to clean up potential old files await this.postDeleteTasks(key); // retrieve by key/id/name items.push( ...(await this.requestSubType(null, retrieveDir, key, null, loadShared)) ); } else { // retrieve all // loop through subtypes and return results of each subType for caching (saving is handled per subtype) for (const subType of subTypeArr) { // each subtype contains multiple different specific types (images contains jpg and png for example) // we use await here to limit the risk of too many concurrent api requests at time items.push( ...(await this.requestSubType(subType, retrieveDir, key, null, loadShared)) ); } } } else { // caching items.push(...(await this.requestSubType(subTypeArr, null, null, null, loadShared))); } const metadata = this.parseResponseBody({ items: items }); if (retrieveDir) { Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(metadata).length})` + Util.getKeysString(key) ); } return { metadata: metadata, type: this.definition.type }; } /** * Retrieves asset metadata for caching * * @param {void | string[]} [_] parameter not used * @param {string[]} [subTypeArr] optionally limit to a single subtype * @param {void | string} [__] parameter not used * @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current * @returns {Promise.<{metadata: AssetMap, type: string}>} Promise */ static retrieveForCache(_, subTypeArr, __, loadShared = false) { return this.retrieve(null, null, subTypeArr, undefined, loadShared); } /** * Retrieves asset metadata for templating * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {AssetSubType} [selectedSubType] optionally limit to a single subtype * @returns {Promise.<{metadata: AssetItem, type: string}>} Promise */ static async retrieveAsTemplate(templateDir, name, templateVariables, selectedSubType) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); const items = []; const subTypes = selectedSubType ? [selectedSubType] : this._getSubTypes(); await File.initPrettier(); // loop through subtypes and return results of each subType for caching (saving is handled per subtype) for (const subType of subTypes) { // each subtype contains multiple different specific types (images contains jpg and png for example) // we use await here to limit the risk of too many concurrent api requests at time items.push( ...(await this.requestSubType( subType, templateDir, 'name:' + name, templateVariables )) ); } const metadata = this.parseResponseBody({ items: items }); if (!Object.keys(metadata).length) { Util.logger.error(`${this.definition.type} '${name}' not found on server.`); } Util.logger.info(`Downloaded: ${this.definition.type} (${Object.keys(metadata).length})`); return { metadata: Object.values(metadata)[0], type: this.definition.type }; } /** * helper for {@link Asset.retrieve} + {@link Asset.retrieveAsTemplate} * * @private * @returns {string[]} AssetSubType array */ static _getSubTypes() { const selectedSubTypeArr = this.properties.metaDataTypes.retrieve.filter((type) => type.startsWith('asset-') ); /* eslint-disable unicorn/prefer-ternary */ if ( this.properties.metaDataTypes.retrieve.includes('asset') || !selectedSubTypeArr.length ) { // if "asset" is found in config assume to download the default subtypes only return this.definition.typeRetrieveByDefault; } else { return selectedSubTypeArr.map((type) => type.replace('asset-', '')); } /* eslint-enable unicorn/prefer-ternary */ } /** * Returns Order in which metadata needs to be retrieved/deployed and skips components with missing components * * @param {AssetMap} metadataMap metadata thats about to be deployed * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<AssetMap>} keyField => metadata map but sorted to ensure dependencies are deployed in correct order */ static async _getUpsertOrderAndSkipMissing(metadataMap, deployDir) { /** * one entry for each dependency with the first item being the key thats required by the second item * * @type {string[][]} */ const dependencies = []; /** @type {ContentBlockConversionTypes[]} */ Util.OPTIONS.referenceFrom = ['key', 'name', 'id']; /** @type {ContentBlockConversionTypes} */ Util.OPTIONS.referenceTo = 'key'; // loop through all metadata types which are being retrieved/deployed for (const key in metadataMap) { const errors = []; const findAssetKeys = new Set(); // find asset references in metadata const findAssetKeyMeta = Util.findLeafVals(metadataMap[key], 'r__asset_key'); for (const metaKey of findAssetKeyMeta) { if (metadataMap[key] || cache.getByKey(this.definition.type, metaKey)) { findAssetKeys.add(metaKey); } else { errors.push( `content block ${metaKey} that is referenced via r__asset_key was not found on BU nor in deployment package` ); } } try { // find asset references in code await this.replaceCbReference(metadataMap[key], deployDir, findAssetKeys); } catch (ex) { if (ex.code === 200) { // no dependent keys found // good from this perspective } else { errors.push( `content block ${ex.message} that is referenced via ContentBlockByX was not found on BU nor in deployment package` ); } } if (errors.length) { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}:${errors.length > 1 ? '\n ·' : ''} ${errors.join('\n · ')}` ); } else { const dependentKeys = [...findAssetKeys]; if (dependentKeys.length > 0) { dependencies.push(...dependentKeys.map((depKey) => [depKey, key])); } else { Util.logger.debug('Asset._getUpsertOrder: no dependent keys found for ' + key); dependencies.push([undefined, key]); } } } // sort list & remove the undefined dependencies const flatList = toposort(dependencies).filter((a) => !!a); /** @type {AssetMap} */ const metadataTypeMapSorted = {}; // group subtypes per type for (const key of flatList) { if (metadataMap[key]) { metadataTypeMapSorted[key] = metadataMap[key]; } } return metadataTypeMapSorted; } /** * MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. * * @param {AssetMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<AssetMap>} keyField => metadata map */ static async upsert(metadataMap, deployDir) { // add already existing, cached items to our cache map to ensure we can find them ReplaceCbReference.createCacheForMap(cache.getCache().asset); // await ReplaceCbReference.createCache(this.properties, this.buObject, true); // fill the cache map with our deployment package to ensure we can find ReplaceCbReference.createCacheForMap(metadataMap); // assets can link to other assets (via template, content block reference and SSJS/AMPscript) and deployment would fail if we did not sort this here metadataMap = await this._getUpsertOrderAndSkipMissing(metadataMap, deployDir); return super.upsert(metadataMap, deployDir, true); } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static async postUpdateTasks(metadataEntry, apiResponse) { // ensure we do not have any old files left aftert content blocks changed their type or got removed await this.postDeleteTasks(metadataEntry[this.definition.keyField]); return apiResponse; } /** * Creates a single asset * * @param {AssetItem} metadata a single asset * @returns {Promise} Promise */ static create(metadata) { delete metadata.businessUnitAvailability; const uri = '/asset/v1/content/assets/'; return super.createREST(metadata, uri); } /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static async postCreateTasks(metadataEntry, apiResponse) { if (apiResponse[this.definition.idField]) { // this also happens inside of MetadataType.upsert but we need it for createCacheMap() // ensure we have the ID in the cache metadataEntry[this.definition.idField] = apiResponse[this.definition.idField]; } if (apiResponse.objectID) { // ensure we have the asset objectId in the cache metadataEntry.objectID = apiResponse.objectID; } // make this newly created item available in cache for other itmes that might reference it /** @type {MetadataTypeMap} */ const newObject = { [metadataEntry[this.definition.keyField]]: metadataEntry }; ReplaceCbReference.createCacheForMap(newObject); return apiResponse; } /** * Updates a single asset * * @param {AssetItem} metadata a single asset * @returns {Promise} Promise */ static update(metadata) { const uri = '/asset/v1/content/assets/' + metadata.id; return super.updateREST(metadata, uri); } /** * Retrieves Metadata of a specific asset type * * @param {string|string[]} subType group of similar assets to put in a folder (ie. images) * @param {string} [retrieveDir] target directory for saving assets * @param {string} [key] key/id/name to filter by * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @param {boolean} [loadShared] optionally retrieve assets from other BUs that were shared with the current * @returns {Promise.<object[]>} Promise */ static async requestSubType(subType, retrieveDir, key, templateVariables, loadShared = false) { const subTypeArr = Array.isArray(subType) ? subType : [subType]; if (retrieveDir) { if (Array.isArray(subType)) { throw new TypeError( 'requestSubType should not be called with multiple subtypes when retrieving to disk.' ); } else if (!key) { Util.logger.info(`- Retrieving Subtype: ${subType}`); } } else { // in this mode we can accept arrays because we don't need to save this to a subtype folder but just want the records Util.logSubtypes(subTypeArr); } /** @type {AssetSubType[]} */ const extendedSubTypeArr = key ? [null] : subTypeArr.flatMap((subType) => this.definition.extendedSubTypes[subType]); // the API can only assetType.ids at a time or else will throw: "DbUtility.GetPagedCollection passing through non-timeout DB error (30001)" const subtypeIdsList = key ? [null] : Util.chunk( extendedSubTypeArr ?.map((subTypeItemName) => this.definition.typeMapping[subTypeItemName]) .toSorted((a, b) => a - b), 50 ); const uri = '/asset/v1/content/assets/query' + (loadShared ? '?scope=shared' : ''); /** @type {AssetRequestParams} */ const payload = { page: { page: 1, pageSize: 50, }, query: null, fields: [ 'category', 'createdDate', 'createdBy', 'modifiedDate', 'modifiedBy', 'objectID', ], // get folder to allow duplicate name check against cache }; if (retrieveDir) { payload.fields = [ 'fileProperties', 'status', 'category', 'createdDate', 'createdBy', 'modifiedDate', 'modifiedBy', 'availableViews', 'data', 'tags', 'meta', 'content', ]; } let items = []; for (const subtypeIds of subtypeIdsList) { if (key) { if (key.startsWith('id:')) { payload.query = { property: this.definition.idField, simpleOperator: 'equal', value: key.slice(3), }; } else if (key.startsWith('name:')) { payload.query = { property: this.definition.nameField, simpleOperator: 'equal', value: key.slice(5), }; } else { payload.query = { property: this.definition.keyField, simpleOperator: 'equal', value: key, }; } } else { payload.query = { property: 'assetType.id', simpleOperator: 'in', value: subtypeIds, }; // payload.sort = [{ property: 'id', direction: 'ASC' }]; } // for caching we do not need these fields /** @type {boolean} */ let moreResults; let lastPage = 0; do { payload.page.page = lastPage + 1; const response = await this.client.rest.post(uri, payload); if (response?.items?.length) { // sometimes the api will return a payload without items // --> ensure we only add proper items-arrays here items = items.concat(response.items); if (key && subType === null) { subType = this.#getMainSubtype(response?.items[0].assetType.name); } } // check if any more records if (response?.message?.includes('all shards failed')) { // When running certain filters, there is a limit of 10k on ElastiCache. // Since we sort by ID, we can get the last ID then run new requests from there payload.query = { leftOperand: { property: 'assetType.id', simpleOperator: 'in', value: subtypeIds, }, logicalOperator: 'AND', rightOperand: { property: 'id', simpleOperator: 'greaterThan', value: items.at(-1).id, }, }; lastPage = 0; moreResults = true; } else if (response.page * response.pageSize < response.count) { moreResults = true; lastPage = Number(response.page); } else { moreResults = false; } } while (moreResults); } // only when we save results do we need the complete metadata or files. caching can skip these if (retrieveDir && !Array.isArray(subType)) { let downloadedItemsMap = {}; if (items.length > 0) { for (const item of items) { if (item.customerKey.trim() !== item.customerKey) { Util.logger.warn( ` - ${this.definition.type} ${item[this.definition.nameField]} (${ item[this.definition.keyField] }) has leading or trailing spaces in customerKey. Please remove them in SFMC.` ); } } // we have to wait on execution or it potentially causes memory reference issues when changing between BUs downloadedItemsMap = await this.requestAndSaveExtended( items, subType, retrieveDir, templateVariables ); } // always show the summary even if we already had the progress bar in the console Util.logger.info( ` Downloaded asset${subType ? '-' + subType : ''}: ${Object.keys(downloadedItemsMap).length}` ); return Object.values(downloadedItemsMap); } else { return items; } } /** * Retrieves extended metadata (files or extended content) of asset * * @param {Array} items array of items to retrieve * @param {string} subType group of similar assets to put in a folder (ie. images) * @param {string} retrieveDir target directory for saving assets * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMap>} Promise */ static async requestAndSaveExtended(items, subType, retrieveDir, templateVariables) { // disable CLI logs other than error while retrieving subtype const loggerLevelBak = Util.logger.level; if (loggerLevelBak !== 'error') { // disable logging to cli other than Errors Util.setLoggingLevel({ silent: true }); } const extendedBar = new cliProgress.SingleBar( { format: ' Downloading [{bar}] {percentage}% | {value}/{total} | asset-' + subType, }, cliProgress.Presets.shades_classic ); const completed = []; const failed = []; const metadataMap = {}; let filterCounter = 0; // put in do loop to manage issues with connection timeout do { // use promise execution limiting to avoid rate limits on api, but speed up execution // start the progress bar with a total value of 200 and start value of 0 extendedBar.start(items.length - completed.length, 0); try { const rateLimit = pLimit(5); await Promise.all( items.map((item, index) => rateLimit(async () => { const metadataMapSaveSingle = {}; // this is a file so extended is at another endpoint if (item?.fileProperties?.extension && !completed.includes(item.id)) { try { // retrieving the extended file does not need to be awaited await this._retrieveExtendedFile(item, subType, retrieveDir); } catch (ex) { failed.push({ item: item, error: ex }); } // still return even if extended failed metadataMap[item.customerKey] = item; // even if the extended file failed, still save the metadata metadataMapSaveSingle[item.customerKey] = item; } // this is a complex type which stores data in the asset itself else if (!completed.includes(item.id)) { try { const extendedItem = await this.client.rest.get( 'asset/v1/content/assets/' + item.id ); // only return the metadata if we have extended content metadataMap[item.customerKey] = extendedItem; // only save the metadata if we have extended content metadataMapSaveSingle[item.customerKey] = extendedItem; // overwrite the original item with the extended content to ensure retrieve() returns it items[index] = extendedItem; } catch (ex) { failed.push({ item: item, error: ex }); } } completed.push(item.id); if (metadataMapSaveSingle[item.customerKey]) { const savedItem = await this.saveResults( metadataMapSaveSingle, retrieveDir, 'asset-' + subType, templateVariables ); if (!savedItem[item.customerKey]) { // filtered by like-option delete metadataMap[item.customerKey]; filterCounter++; } } // update the current value in your application.. extendedBar.increment(); if (metadataMap[item.customerKey]) { return metadataMap[item.customerKey]; } }) ) ); // stop the progress bar extendedBar.stop(); Asset._resetLogLevel(loggerLevelBak, failed); if (filterCounter) { Util.logger.info( ` - Filtered ${this.definition.type}-${subType}: ${filterCounter} (downloaded but not saved to disk)` ); } return metadataMap; } catch (ex) { extendedBar.stop(); Asset._resetLogLevel(loggerLevelBak, failed); // timeouts should be retried, others can be exited if (ex.code !== 'ETIMEDOUT') { throw ex; } } } while (completed.length === items.length); return metadataMap; } /** * helper that reset the log level and prints errors * * @private * @param {'info'|'verbose'|'debug'|'error'} loggerLevelBak original logger level * @param {object[]} failed array of failed items */ static _resetLogLevel(loggerLevelBak, failed) { // re-enable CLI logs // reset logging level let obj; switch (loggerLevelBak) { case 'info': { obj = {}; break; } case 'verbose': { obj = { verbose: true }; break; } case 'debug': { obj = { debug: true }; break; } case 'error': { obj = { silent: true }; } } Util.setLoggingLevel(obj); if (failed.length) { Util.logger.warn( ` - Failed to download ${failed.length} extended file${ failed.length > 1 ? 's' : '' }:` ); for (const fail of failed) { Util.logger.warn( ` - "${fail.item.name}" (${fail.item.customerKey}): ${fail.error.message} (${ fail.error.code })${ fail.error.endpoint ? Util.getGrayMsg( ' - ' + fail.error.endpoint.split('rest.marketingcloudapis.com')[1] ) : '' }` ); } Util.logger.info( ' - You will still find a JSON file for each of these in the download directory.' ); } } /** * Some metadata types store their actual content as a separate file, e.g. images * This method retrieves these and saves them alongside the metadata json * * @param {AssetItem} metadata a single asset * @param {string} subType group of similar assets to put in a folder (ie. images) * @param {string} retrieveDir target directory for saving assets * @returns {Promise.<void>} - */ static async _retrieveExtendedFile(metadata, subType, retrieveDir) { const file = await this.client.rest.get('asset/v1/content/assets/' + metadata.id + '/file'); // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the fileName // however, their solution was not following standards: fileName="header.png (4) " and then extension="png (4) " const fileExt = metadata.fileProperties.extension.split(' ')[0]; File.writeToFile( [retrieveDir, this.definition.type, subType], metadata.customerKey, fileExt, file, 'base64' ); } /** * helper for {@link Asset.preDeployTasks} * Some metadata types store their actual content as a separate file, e.g. images * This method reads these from the local FS stores them in the metadata object allowing to deploy it * * @param {AssetItem} metadata a single asset * @param {string} subType group of similar assets to put in a folder (ie. images) * @param {string} deployDir directory of deploy files * @param {boolean} [pathOnly] used by getFilesToCommit which does not need the binary file to be actually read * @returns {Promise.<string>} if found will return the path of the binary file */ static async _readExtendedFileFromFS(metadata, subType, deployDir, pathOnly = false) { // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the fileName // however, their solution was not following standards: fileName="header.png (4) " and then extension="png (4) " if (!metadata?.fileProperties?.extension) { return; } const fileExt = metadata.fileProperties.extension.split(' ')[0]; const path = File.normalizePath([ deployDir, this.definition.type, subType, `${metadata.customerKey}.${fileExt}`, ]); if (await File.pathExists(path)) { if (!pathOnly) { metadata.file = await File.readFilteredFilename( [deployDir, this.definition.type, subType], metadata.customerKey, fileExt, 'base64' ); } return path; } } /** * manages post retrieve steps * * @param {AssetItem} metadata a single asset * @returns {CodeExtractItem} metadata */ static postRetrieveTasks(metadata) { // folder this.setFolderPath(metadata); // template-based emails if (metadata.assetType.name === 'templatebasedemail') { // get template try { if (metadata.views?.html?.template?.id) { metadata.views.html.template.r__asset_key = cache.searchForField( 'asset', metadata.views?.html?.template?.id, 'id', 'customerKey' ); delete metadata.views.html.template.id; delete metadata.views.html.template.name; delete metadata.views.html.template.assetType; delete metadata.views.html.template.availableViews; delete metadata.views.html.template.data; delete metadata.views.html.template.modelVersion; } } catch { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find email template with id (${metadata.views.html.template.id})` ); } } // get asset-asset try { if (metadata.meta?.thumbnailRefAssetId) { // cloudpages', 'landingpage', 'microsite', 'interactivecontent' metadata.meta.r__asset_key = cache.searchForField( 'asset', metadata.meta?.thumbnailRefAssetId, 'id', 'customerKey' ); delete metadata.meta.thumbnailRefAssetId; } } catch { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find associated cloudpage content with id (${metadata.meta.thumbnailRefAssetId})` ); } if ( ['landingpage', 'microsite', 'interactivecontent'].includes(metadata.assetType.name) && typeof metadata.content === 'string' ) { // cloudpages', 'landingpage', 'microsite', 'interactivecontent' metadata.content = JSON.parse(metadata.content); } if (typeof metadata.data?.site?.content === 'string') { // for all xx-coderesource types metadata.data.site.content = JSON.parse(metadata.data.site.content); } if (metadata.meta?.cloudPages) { metadata.meta.cloudPages.c__published = metadata.meta.cloudPages.publishDate ? true : false; } // extract HTML for selected subtypes and convert payload for easier processing in MetadataType.saveResults() return this._extractCode(metadata); } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} metadata metadata mapped by their keyField * @param {MetadataTypeMap} _ originalMetadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static async postDeployTasks(metadata, _, createdUpdated) { if (Util.OPTIONS.refresh) { if (createdUpdated.updated) { // only run this if assets were updated. for created assets we do not expect await this._refreshTriggeredSend(metadata); } else { Util.logger.warn( 'You set the --refresh flag but no updated assets found. Skipping refresh of triggeredSendDefinitions.' ); } } } /** * 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. * * @private * @param {MetadataTypeMap} metadata metadata mapped by their keyField * @returns {Promise.<void>} - */ static async _refreshTriggeredSend(metadata) { // get legacyData.legacyId from assets to compare to TSD's metadata.Email.ID to const legacyIdArr = Object.keys(metadata) .map((key) => metadata[key]?.legacyData?.legacyId) .filter(Boolean); if (!legacyIdArr.length) { Util.logger.warn( 'No legacyId found in updated emails. Skipping refresh of triggeredSendDefinitions.' ); return; } // prep triggeredSendDefinition class TriggeredSend.properties = this.properties; TriggeredSend.buObject = this.buObject; TriggeredSend.client = this.client; try { // find refreshable TSDs const tsdObj = (await TriggeredSend.findRefreshableItems(true))?.metadata; const tsdCountInitial = Object.keys(tsdObj).length; const emailCount = legacyIdArr.length; // filter TSDs by legacyId for (const key in tsdObj) { if (!legacyIdArr.includes(tsdObj[key].Email.ID)) { delete tsdObj[key]; } } const tsdCountFiltered = Object.keys(tsdObj).length; Util.logger.info( `Found ${tsdCountFiltered} out of ${tsdCountInitial} total triggeredSendDefinitions for ${emailCount} deployed emails. Commencing validation...` ); // get keys of TSDs to refresh const keyArr = await TriggeredSend.getKeysForValidTSDs(tsdObj); await TriggeredSend.refresh(keyArr); } catch { Util.logger.warn('Failed to refresh triggeredSendDefinition'); } } /** * prepares an asset definition for deployment * * @param {AssetItem} metadata a single asset * @param {string} deployDir directory of deploy files * @returns {Promise.<AssetItem>} Promise */ static async preDeployTasks(metadata, deployDir) { // additonalattributes fail where the value is "" so we need to remove them from deploy if (metadata?.data?.email?.attributes?.length > 0) { metadata.data.email.attributes = metadata.data.email.attributes.filter( (attr) => attr.value ); } // folder this.setFolderId(metadata); if (!cache.getByKey(this.definition.type, metadata[this.definition.keyField])) { if (metadata.assetType.name === 'webpage') { // we are attempting to CREATE a cloudpage asset which needs to be prevented. throw new Error( 'CloudPage content cannot be created via mcdev. Please create it via the UI first, then you can update the content or key.' ); } if ( this.definition.extendedSubTypes.cloudpage.includes(metadata.assetType.name) || this.definition.extendedSubTypes.coderesource.includes(metadata.assetType.name) ) { // if we do create those, we get the error "Asset <id> not found" because the internal endpoint internal/v2/cloudpages/sites won't find it. throw new Error( 'CloudPage assets cannot be created via mcdev. Please create it via the UI first, then you can update the content or key.' ); } } // template-based emails if ( metadata.assetType.name === 'templatebasedemail' && metadata.views?.html?.template?.r__asset_key ) { // template metadata.views.html.template.id = cache.searchForField( 'asset', metadata.views.html.template.r__asset_key, 'customerKey', 'id' ); metadata.views.html.template.name = cache.searchForField( 'asset', metadata.views.html.template.r__asset_key, 'customerKey', 'name' ); metadata.views.html.template.assetType = { id: 4, name: 'template', displayName: 'Template', }; metadata.views.html.template.data = { email: { options: { generateFrom: null } }, }; metadata.views.html.template.availableViews = []; metadata.views.html.template.modelVersion = 2; delete metadata.views.html.template.r__asset_key; } if (metadata.meta?.r__asset_key) { // cloudpages: 'landingpage', 'microsite', 'interactivecontent' // get asset-asset metadata.meta.thumbnailRefAssetId = cache.searchForField( 'asset', metadata.meta.r__asset_key, 'customerKey', 'id' ); delete metadata.meta.r__asset_key; } if (metadata.meta?.cloudPages?.c__published) { // TODO: removal should be done via asset.definition instead delete metadata.meta.cloudPages.c__published; } if ( ['landingpage', 'microsite', 'interactivecontent'].includes(metadata.assetType.name) && typeof metadata.content === 'object' ) { // cloudpages: 'landingpage', 'microsite', 'interactivecontent' metadata.content = JSON.stringify(metadata.content); } if (typeof metadata.data?.site?.content === 'object') { // coderesource: for all xx-coderesource types metadata.data.site.content = JSON.stringify(metadata.data.site.content); } // restore asset type id which is needed for deploy metadata.assetType.id = this.definition.typeMapping[metadata.assetType.name]; // define asset's subtype const subType = this._getSubtype(metadata); // #0 format blocks in slots for deployment await this._preDeployTasksBocks(metadata); // #1 get text extracts back into the JSON await this._mergeCode(metadata, deployDir, subType); // #2 get file from local disk and insert as base64 await this._readExtendedFileFromFS(metadata, subType, deployDir); // only execute #3 if we are deploying / copying from one BU to another, not while using mcdev as a developer tool if ( Util.OPTIONS.autoMidSuffix && this.buObject.mid && metadata.memberId != this.buObject.mid && // soft comparison to accomodate for string-version of mid !metadata[this.definition.keyField].endsWith(this.buObject.mid) ) { // #3 make sure customer key is unique by suffixing it with target MID (unless we are deploying to the same MID) // check if this suffixed with the source MID const suffix = '-' + this.buObject.mid; // for customer key max is 36 chars metadata[this.definition.keyField] = metadata[this.definition.keyField].slice(0, Math.max(0, 36 - suffix.length)) + suffix; } if (!Util.OPTIONS.matchName) { // #4 make sure the name is unique const assetCache = cache.getCache()[this.definition.type]; const namesInFolder = Object.keys(assetCache) .filter((key) => assetCache[key].category.id === metadata.category.id) .map((key) => ({ type: this.#getMainSubtype(assetCache[key].assetType.name), key: key, name: assetCache[key].name, })); // if the name is already in the folder for a different key, add a number to the end metadata[this.definition.nameField] = this.findUniqueName( metadata[this.definition.keyField], metadata[this.definition.nameField], namesInFolder, this.#getMainSubtype(metadata.assetType.name) ); } return metadata; } /** * find the subType matching the extendedSubType * * @param {string} extendedSubType webpage, htmlblock, etc * @returns {string} subType: block, message, other, etc */ static #getMainSubtype(extendedSubType) { return Object.keys(this.definition.extendedSubTypes).find((subType) => this.definition.extendedSubTypes[subType].includes(extendedSubType) ); } /** * determines the subtype of the current asset * * @private * @param {AssetItem} metadata a single asset * @returns {string} subtype */ static _getSubtype(metadata) { for (const sub in this.definition.extendedSubTypes) { if (this.definition.extendedSubTypes[sub].includes(metadata.assetType.name)) { return sub; } } return; } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string} targetDir Directory where built definitions will be saved * @param {AssetItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'definition' ); } /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example assets of type codesnippetblock will result in 1 json and 1 amp/html file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {AssetItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'template' ); } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {AssetItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async _buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, mode ) { // * because asset's _mergeCode() is overwriting 'metadata', clone it to ensure the main file is not modified by what we do in here metadata = structuredClone(metadata); // #1 text extracts // define asset's subtype const subType = this._getSubtype(metadata); // get HTML from filesystem const fileList = await this._mergeCode(metadata, templateDir, subType, templateName); // replace template variables with their values for (const extractedFile of fileList) { try { if (mode === 'definition') { // replace template variables with their values extractedFile.content = this.applyTemplateValues( extractedFile.content, templateVariables ); } else if (mode === 'template') { // replace template values with corresponding variable names extractedFile.content = this.applyTemplateNames( extractedFile.content, templateVariables ); } } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ metadata[this.definition.keyField] }: ${extractedFile.fileName}.${extractedFile.fileExt}.` ); } // apply templating to subfolders extractedFile.subFolder = extractedFile.subFolder .map((el) => (el === templateName ? metadata[this.definition.keyField] : el)) .map((el) => this.applyTemplateValues(el, templateVariables)); // apply templating to filenames of extracted code extractedFile.fileName = extractedFile.fileName .split('.') .map((el) => (el === templateName ? metadata[this.definition.keyField] : el)) .join('.'); } // #2 binary extracts if (metadata?.fileProperties?.extension) { // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the fileName // however, their solution was not following standards: fileName="header.png (4) " and then extension="png (4) " const fileExt = metadata.fileProperties.extension.split(' ')[0]; const filecontent = await File.readFilteredFilename( [templateDir, this.definition.type, subType], templateName, fileExt, 'base64' ); // keep old name if creating templates, otherwise use new name const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName; fileList.push({ subFolder: [this.definition.type, subType], fileName: fileName, fileExt: fileExt, content: filecontent, encoding: 'base64', }); } const nestedFilePaths = []; // write to file (#1 + #2) const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; for (const targetDir of targetDirArr) { for (const extractedFile of fileList) { if (extractedFile.fileExt === 'ssjs') { const ssjs = Util.getSsjs(extractedFile?.content); if (ssjs) { extractedFile.content = ssjs; } } File.writeToFile( [targetDir, ...extractedFile.subFolder], extractedFile.fileName, extractedFile.fileExt, extractedFile.content, extractedFile.encoding || null ); nestedFilePaths.push([ File.normalizePath([targetDir, ...extractedFile.subFolder]), extractedFile.fileName + '.' + this.definition.type + '-meta.' + extractedFile.fileExt, ]); } } return nestedFilePaths; } /** * generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single script activity definition * @param {boolean} [hideWarning] when checking content blocks we do want to set the folder path but if we cant, lets not cludder the log with warnings about it */ static setFolderPath(metadata, hideWarning = false) { try { // we get folders type "asset" from EID and MID to accomodate for shared assets. That however is an issue if we are retrieving a local asset with the same folder. const folderId = metadata.category.id; const folderMap = cache.getCache().folder; if (!folderMap) { throw new Error('No folders found in cache'); } const potentialFolders = []; for (const folder of Object.values(folderMap)) { if (folder.ID === folderId) { if ( (metadata.memberId && metadata.memberId === folder?.Client?.ID) || folder?.Client?.ID === this.buObject.mid ) { metadata.r__folder_Path = folder.Path; delete metadata.category; return; } else { potentialFolders.push(folder); } } } if (potentialFolders.length >= 1) { metadata.r__folder_Path = potentialFolders[0].Path; delete metadata.category; } else { throw new Error(`No folders found with ID ${folderId}`); } } catch (ex) { if (!hideWarning) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find folder (${ex.message})` ); } } } /** * Asset-specific script that retrieves the folder ID from cache and updates the given metadata with it before deploy * * @param {MetadataTypeItem} metadata a single item */ static setFolderId(metadata) { if (!metadata.r__folder_Path) { throw new Error( `Dependent folder could not be found because r__folder_Path is not set` ); } metadata.category = { id: cache.getFolderId(metadata.r__folder_Path), }; delete metadata.r__folder_Path; } /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {AssetItem} metadata a single asset definition * @returns {Promise.<void>} fileList for templating (disregarded during deployment) */ static async _preDeployTasksBocks(metadata) { switch (metadata.assetType.name) { case 'templatebasedemail': // message case 'htmlemail': case 'webpage': { // metadata.views.html.slots.<>.blocks.<>.content (optional) if (metadata?.views?.html?.slots) { await this._preDeployTasksBocks_slots(metadata.views.html.slots); } break; } case 'template': { // metadata.slots.<>.blocks.<>.content (optional) if (metadata?.slots) { await this._preDeployTasksBocks_slots(metadata.slots); } break; } } } /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @returns {Promise.<void>} - */ static async _preDeployTasksBocks_slots(metadataSlots) { for (const slot in metadataSlots) { if (Object.prototype.hasOwnProperty.call(metadataSlots, slot)) { const slotObj = metadataSlots[slot]; // found slot if (slotObj.blocks) { for (const block in slotObj.blocks) { if (Object.prototype.hasOwnProperty.call(slotObj.blocks, block)) { const asset = slotObj.blocks[block]; if (asset.r__asset_key) { // by only running the following if r__asset_key was set, we simply skip anything that wasnt resolved during retrieve asset.customerKey = asset.r__asset_key; asset.id = cache.searchForField( 'asset', asset.r__asset_key, 'customerKey', 'id' ); asset.objectID = cache.searchForField( 'asset', asset.r__asset_key, 'customerKey', 'objectID' ); delete asset.r__asset_key; asset.thumbnail = { thumbnailUrl: '/v1/assets/' + asset.id + '/thumbnail', }; } if (asset.r__folder_Path) { // if we convert this into a folder path then renamed folders might end up blocking deployments, therefore, we instead omit this detail from now on delete asset.r__folder_Path; } await this._preDeployTasksBocks(asset); } } } } } } /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {AssetItem} metadata a single asset definition * @param {string} deployDir directory of deploy files * @param {string} subType asset-subtype name; full list in AssetSubType * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @param {boolean} [fileListOnly] does not read file contents nor update metadata if true * @returns {Promise.<CodeExtract[]>} fileList for templating (disregarded during deployment) */ static async _mergeCode(metadata, deployDir, subType, templateName, fileListOnly = false) { const subtypeExtension = `.${this.definition.type}-${subType}-meta`; const fileList = []; let subDirArr; let readDirArr; // unfortunately, asset's key can contain spaces at beginning/end which can break the file system when folders are created with it const customerKey = metadata.customerKey.trim(); const templateFileName = templateName || customerKey; switch (metadata.assetType.name) { case 'templatebasedemail': // message case 'htmlemail': { // message // this complex type always creates its own subdir per asset subDirArr = [this.definition.type, subType]; readDirArr = [deployDir, ...subDirArr, templateFileName]; // metadata.views.html.content (mandatory) // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs const fileName = 'views.html.content' + subtypeExtension; if ( (await File.pathExists( File.normalizePath([...readDirArr, `${fileName}.html`]) )) && metadata.views.html ) { if (!fileListOnly) { metadata.views.html.content = await File.readFilteredFilename( readDirArr, fileName, 'html' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName], fileName: fileName, fileExt: 'html', content: metadata.views.html.content, }); } } // metadata.views.html.content (optional) // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs const fileNamePreheader = 'views.preheader.content' + subtypeExtension; if ( (await File.pathExists( File.normalizePath([...readDirArr, `${fileNamePreheader}.amp`]) )) && metadata.views.preheader ) { if (!fileListOnly) { metadata.views.preheader.content = await File.readFilteredFilename( readDirArr, fileNamePreheader, 'amp' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName], fileName: fileNamePreheader, fileExt: 'amp', content: metadata.views.preheader.content, }); } } // metadata.views.text.content (optional) // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs const fileNameText = 'views.text.content' + subtypeExtension; if ( (await File.pathExists( File.normalizePath([...readDirArr, `${fileNameText}.amp`]) )) && metadata.views.text ) { if (!fileListOnly) { metadata.views.text.content = await File.readFilteredFilename( readDirArr, fileNameText, 'amp' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName], fileName: fileNameText, fileExt: 'amp', content: metadata.views.text.content, }); } } else if (metadata.views.text) { // ensure the text version gets generated from html metadata.views.text.data = { email: { options: { generateFrom: 'html', }, }, }; metadata.views.text.generateFrom = 'html'; } // metadata.views.html.slots.<>.blocks.<>.content (optional) if (metadata?.views?.html?.slots) { await this._mergeCode_slots( 'views.html.slots', metadata.views.html.slots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, templateName, fileListOnly ); } break; } case 'template': { // template-template // this complex type always creates its own subdir per asset subDirArr = [this.definition.type, subType]; readDirArr = [deployDir, ...subDirArr, templateFileName]; const fileName = 'content' + subtypeExtension; const fileExtArr = ['html']; for (const ext of fileExtArr) { if ( await File.pathExists( File.normalizePath([...readDirArr, `${fileName}.${ext}`]) ) ) { // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs if (!fileListOnly) { metadata.content = await File.readFilteredFilename( readDirArr, fileName, ext ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName], fileName: fileName, fileExt: ext, content: metadata.content, }); } // break loop when found break; } } // metadata.slots.<>.blocks.<>.content (optional) if (metadata?.slots) { await this._mergeCode_slots( 'slots', metadata.slots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, templateName, fileListOnly ); } break; } case 'textonlyemail': { // message // metadata.views.text.content subDirArr = [this.definition.type, subType]; readDirArr = [deployDir, ...subDirArr]; if ( await File.pathExists( File.normalizePath([ ...readDirArr, `${templateFileName}${subtypeExtension}.amp`, ]) ) ) { // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs if (!fileListOnly) { metadata.views.text.content = await File.readFilteredFilename( readDirArr, templateFileName + subtypeExtension, 'amp' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: subDirArr, fileName: templateFileName + subtypeExtension, fileExt: 'amp', content: metadata.views.text.content, }); } } break; } case 'webpage': { // asset // this complex type always creates its own subdir per asset subDirArr = [this.definition.type, subType]; readDirArr = [deployDir, ...subDirArr, templateFileName]; // metadata.views.html.slots.<>.blocks.<>.content (optional) (pre & post 20222) if (metadata?.views?.html?.slots) { await this._mergeCode_slots( 'views.html.slots', metadata.views.html.slots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, templateName, fileListOnly ); } // +++ old webpages / pre-2022 +++ // metadata.views.html.content (mandatory) if ( (await File.pathExists( File.normalizePath([ ...readDirArr, `views.html.content${subtypeExtension}.html`, ]) )) && // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs metadata.views?.html ) { if (!fileListOnly) { metadata.views.html.content = await File.readFilteredFilename( readDirArr, 'views.html.content' + subtypeExtension, 'html' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName], fileName: 'views.html.content' + subtypeExtension, fileExt: 'html', content: metadata.views.html.content, }); } } // +++ new webpages / 2022+ +++ // metadata.content if ( await File.pathExists( File.normalizePath([...readDirArr, `content${subtypeExtension}.html`]) ) ) { // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs if (!fileListOnly) { metadata.content = await File.readFilteredFilename( readDirArr, 'content' + subtypeExtension, 'html' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName], fileName: 'content' + subtypeExtension, fileExt: 'html', content: metadata.views.html.content, }); } } break; } case 'jscoderesource': // coderesource case 'csscoderesource': // coderesource case 'jsoncoderesource': // coderesource case 'rsscoderesource': // coderesource case 'textcoderesource': // coderesource case 'xmlcoderesource': // coderesource case 'buttonblock': // block - Button Block case 'freeformblock': // block case 'htmlblock': // block case 'icemailformblock': // block - Interactive Content Email Form case 'imageblock': // block - Image Block case 'textblock': // block case 'smartcaptureblock': // other case 'codesnippetblock': { // other // metadata.content subDirArr = [this.definition.type, subType]; readDirArr = [deployDir, ...subDirArr]; const fileExtArr = [ 'html', 'ssjs', 'amp', 'js', 'css', 'rss', 'txt', 'xml', 'jsonc', ]; for (const ext of fileExtArr) { if ( await File.pathExists( File.normalizePath([ ...readDirArr, `${templateFileName}${subtypeExtension}.${ext}`, ]) ) ) { // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs if (!fileListOnly) { metadata.content = await File.readFilteredFilename( readDirArr, templateFileName + subtypeExtension, ext ); if (ext === 'ssjs') { metadata.content = `<script runat="server">\n${metadata.content}</script>`; } } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: subDirArr, fileName: templateFileName + subtypeExtension, fileExt: ext, content: metadata.content, }); } // break loop when found break; } } break; } } return fileList; } /** * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {string} prefix usually the customerkey * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @param {string[]} readDirArr directory of deploy files * @param {string} subtypeExtension asset-subtype name ending on -meta * @param {string[]} subDirArr directory of files w/o leading deploy dir * @param {object[]} fileList directory of files w/o leading deploy dir * @param {string} customerKey external key of template (could have been changed if used during templating) * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @param {boolean} [fileListOnly] does not read file contents nor update metadata if true * @returns {Promise.<void>} - */ static async _mergeCode_slots( prefix, metadataSlots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, templateName, fileListOnly = false ) { const templateFileName = templateName || customerKey; for (const slot in metadataSlots) { if (Object.prototype.hasOwnProperty.call(metadataSlots, slot)) { const slotObj = metadataSlots[slot]; // found slot if (slotObj.blocks) { for (const block in slotObj.blocks) { if (Object.prototype.hasOwnProperty.call(slotObj.blocks, block)) { const asset = slotObj.blocks[block]; const fileName = `${prefix}.[${slot}-${block}]${subtypeExtension}`; if ( await File.pathExists( File.normalizePath([ ...readDirArr, 'blocks', `${fileName}.html`, ]) ) ) { // the main content can be empty (=not set up yet) hence check if we did extract sth or else readFile() will print error msgs // if an extracted block was found, save it back into JSON if (!fileListOnly) { asset.content = await File.readFilteredFilename( [...readDirArr, 'blocks'], fileName, 'html' ); } if (templateName) { // to use this method in templating, store a copy of the info in fileList fileList.push({ subFolder: [...subDirArr, templateFileName, 'blocks'], fileName: fileName, fileExt: 'html', content: asset.content, }); } } if (asset.slots) { // * recursion: each block can have slots of its own await this._mergeCode_slots( `${prefix}.[${slot}-${block}]`, asset.slots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, templateName, fileListOnly ); } else if (asset?.views?.html?.slots) { // * recursion: each block can have slots of its own await this._mergeCode_slots( `${prefix}.[${slot}-${block}]`, asset.views.html.slots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, templateName, fileListOnly ); } } } } } } } /** * helper for {@link Asset.postRetrieveTasks} that finds code content in JSON and extracts it * to allow saving that separately and formatted * * @param {AssetItem} metadata a single asset definition * @returns {CodeExtractItem} { json: metadata, codeArr: object[], subFolder: string[] } */ static _extractCode(metadata) { const codeArr = []; let subType; // unfortunately, asset's key can contain spaces at beginning/end which can break the file system when folders are created with it const customerKey = metadata.customerKey.trim(); switch (metadata.assetType.name) { case 'templatebasedemail': // message-templatebasedemail case 'htmlemail': { // message-htmlemail // metadata.views.html.content (mandatory) if (metadata.views?.html?.content?.length) { codeArr.push({ subFolder: null, fileName: 'views.html.content', fileExt: 'html', content: metadata.views.html.content, }); delete metadata.views.html.content; } // metadata.views.preheader.content (optional) if (metadata.views?.preheader?.content?.length) { codeArr.push({ subFolder: null, fileName: 'views.preheader.content', fileExt: 'amp', content: metadata.views.preheader.content, }); delete metadata.views.preheader.content; } // metadata.views.text.content (optional) if (metadata.views?.text?.content?.length) { codeArr.push({ subFolder: null, fileName: 'views.text.content', fileExt: 'amp', content: metadata.views.text.content, }); delete metadata.views.text.content; } // metadata.views.html.slots.<>.blocks.<>.content (optional) if (metadata.views?.html?.slots) { this._extractCode_slots('views.html.slots', metadata.views.html.slots, codeArr); } return { json: metadata, codeArr: codeArr, subFolder: [customerKey], }; } case 'template': { // template-template // metadata.content const fileExt = 'html'; if (metadata?.content?.length) { codeArr.push({ subFolder: null, fileName: 'content', fileExt: fileExt, content: metadata.content, }); delete metadata.content; } // metadata.slots.<>.blocks.<>.content (optional) if (metadata.slots) { this._extractCode_slots('slots', metadata.slots, codeArr); } return { json: metadata, codeArr: codeArr, subFolder: [customerKey], }; } case 'textonlyemail': { // message-textonlyemail // metadata.views.text.content if (metadata.views?.text?.content?.length) { codeArr.push({ subFolder: null, fileName: customerKey, fileExt: 'amp', content: metadata.views.text.content, }); delete metadata.views.text.content; } return { json: metadata, codeArr: codeArr, subFolder: null }; } case 'webpage': { // asset-webpage // metadata.views.html.content (pre & post 20222) if (metadata.views?.html?.content?.length) { codeArr.push({ subFolder: null, fileName: 'views.html.content', fileExt: 'html', content: metadata.views.html.content, }); delete metadata.views.html.content; } // +++ old webpages / pre-2022 +++ // metadata.views.html.slots.<>.blocks.<>.content (optional) if (metadata.views?.html?.slots) { this._extractCode_slots('views.html.slots', metadata.views.html.slots, codeArr); } // +++ new webpages / 2022+ +++ // metadata.content if (metadata?.content?.length) { codeArr.push({ subFolder: null, fileName: 'content', fileExt: 'html', content: metadata.content, }); delete metadata.content; } return { json: metadata, codeArr: codeArr, subFolder: [customerKey], }; } case 'jscoderesource': // coderesource case 'csscoderesource': // coderesource case 'jsoncoderesource': // coderesource case 'rsscoderesource': // coderesource case 'textcoderesource': // coderesource case 'xmlcoderesource': { // metadata.content const content = metadata?.content; const fileExt = metadata.assetType.name .replace('coderesource', '') .replace('text', 'txt') .replace('json', 'jsonc'); if (content?.length) { codeArr.push({ subFolder: null, fileName: customerKey, fileExt: fileExt, content: content, }); delete metadata.content; } return { json: metadata, codeArr: codeArr, subFolder: null }; } case 'buttonblock': // block-buttonblock case 'freeformblock': // block-freeformblock case 'htmlblock': // block-htmlblock case 'icemailformblock': // block-icemailformblock - Interactive Content Email Form case 'imageblock': // block-imageblock - Image Block case 'textblock': // block-textblock case 'smartcaptureblock': // other-smartcaptureblock case 'codesnippetblock': { // other-codesnippetblock // metadata.content let fileExt; let content = metadata?.content; const ssjs = Util.getSsjs(metadata?.content); if (ssjs) { fileExt = 'ssjs'; content = ssjs; } else if ( metadata.assetType.name === 'codesnippetblock' && // extracted code snippets should end on the right extension content?.includes('%%[') ) { fileExt = 'amp'; } else { fileExt = 'html'; } if (content?.length) { codeArr.push({ subFolder: null, fileName: customerKey, fileExt: fileExt, content: content, }); delete metadata.content; } return { json: metadata, codeArr: codeArr, subFolder: null }; } default: { subType = this._getSubtype(metadata); if (!this.definition.binarySubtypes.includes(subType)) { Util.logger.debug( 'not processed metadata.assetType.name: ' + metadata.assetType.name ); } return { json: metadata, codeArr: codeArr, subFolder: null }; } } } /** * helper for {@link Asset.postRetrieveTasks} via {@link Asset._extractCode} * * @param {string} prefix usually the customerkey * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @param {object[]} codeArr to be extended array for extracted code * @returns {void} */ static _extractCode_slots(prefix, metadataSlots, codeArr) { for (const slot in metadataSlots) { if (Object.prototype.hasOwnProperty.call(metadataSlots, slot)) { const slotObj = metadataSlots[slot]; // found slot for (const block in slotObj.blocks) { if (Object.prototype.hasOwnProperty.call(slotObj.blocks, block)) { const asset = slotObj.blocks[block]; if (asset.content) { // found content block const code = asset.content; codeArr.push({ subFolder: ['blocks'], fileName: `${prefix}.[${slot}-${block}]`, fileExt: 'html', content: code, }); delete asset.content; } // clean up fields from the other content block if (asset.id) { try { asset.r__asset_key = cache.searchForField( 'asset', asset.id, 'id', 'customerKey' ); // only delete this if we found the asset in cache, otherwise ignore delete asset.id; delete asset.objectID; delete asset.customerKey; delete asset.thumbnail; } catch { Util.logger.debug( ` - asset id:${asset.id} / key:${asset.customerKey} / name:${asset.name} not found in cache` ); } } if (asset.category?.id) { // if we convert this into a folder path then renamed folders might end up blocking deployments, therefore, we instead omit this detail from now on delete asset.category; } if (asset.slots) { // * recursion: each block can have slots of its own this._extractCode_slots( `${prefix}.[${slot}-${block}]`, asset.slots, codeArr ); } } } } } } /** * Returns file contents mapped to their fileName without '.json' ending * * @param {string} dir directory with json files, e.g. /retrieve/cred/bu/asset, /deploy/cred/bu/asset, /template/asset * @param {boolean} [_] unused parameter * @param {string[]} [selectedSubType] asset, message, ... * @returns {Promise.<MetadataTypeMap>} fileName => fileContent map */ static async getJsonFromFS(dir, _, selectedSubType) { const fileName2FileContent = {}; try { for (const subtype of this.definition.subTypes) { if ( selectedSubType && !selectedSubType.includes('asset-' + subtype) && !selectedSubType.includes('asset') ) { continue; } const currentdir = File.normalizePath([dir, subtype]); await this._getJsonFromFS(currentdir, subtype, fileName2FileContent); } } catch (ex) { // this will catch issues with readdir Util.metadataLogger('debug', this.definition.type, 'getJsonFromFS', ex); throw ex; } return fileName2FileContent; } /** * helper for {@link Asset.getJsonFromFS} that reads the file system for metadata files * * @param {string} currentdir directory to scan * @param {string} subtype single subtype of asset * @param {MetadataTypeMap} fileName2FileContent fileName => fileContent map */ static async _getJsonFromFS(currentdir, subtype, fileName2FileContent) { if (await File.pathExists(currentdir)) { const fileEnding = `.asset-${subtype}-meta.json`; const fileEndingLength = fileEnding.length; const files = await File.readdir(currentdir, { withFileTypes: true }); for (const dirent of files) { const fileName = dirent.name; try { if (dirent.isDirectory()) { await this._getJsonFromFS( File.normalizePath([currentdir, fileName]), subtype, fileName2FileContent ); } else if (fileName.endsWith('.json')) { const errorDir = currentdir.split('\\').join('/'); const fileContent = await File.readJSONFile(currentdir, fileName, false); // ! convert numbers to string to allow numeric keys to be checked properly const key = Number.isInteger(fileContent[this.definition.keyField]) ? fileContent[this.definition.keyField].toString() : fileContent[this.definition.keyField]; if (fileName.endsWith(fileEnding)) { // subtype will change the metadata suffix length const fileNameWithoutEnding = File.reverseFilterIllegalFilenames( fileName.slice(0, -fileEndingLength) ); if (key === fileNameWithoutEnding) { fileName2FileContent[fileNameWithoutEnding] = fileContent; } else { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}: Name of the metadata file and the JSON-key (${this.definition.keyField}) must match. Expected: ${key}${fileEnding}. Actual: ` + Util.getGrayMsg(`${errorDir}/`) + fileName ); } } else { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}: Name of the metadata file must end on the extended metadata suffix. Expected: ${key}${fileEnding}. Actual: ` + Util.getGrayMsg(`${errorDir}/`) + fileName ); } } } catch (ex) { // by catching this in the loop we gracefully handle the issue and move on to the next file Util.metadataLogger('debug', this.definition.type, 'getJsonFromFS', ex); } } } } /** * check template directory for complex types that open subfolders for their subtypes * * @param {string} templateDir Directory where metadata templates are stored * @param {string} templateName name of the metadata file * @returns {Promise.<string>} AssetSubType name */ static async findSubType(templateDir, templateName) { const typeDirArr = [this.definition.type]; let subType; for (const st of this.definition.subTypes) { const fileNameFull = templateName + '.' + this.definition.type + `-${st}-meta.json`; if ( (await File.pathExists( File.normalizePath([templateDir, ...typeDirArr, st, fileNameFull]) )) || (await File.pathExists( File.normalizePath([templateDir, ...typeDirArr, st, templateName, fileNameFull]) )) ) { subType = st; break; } } return subType; } /** * optional method used for some types to try a different folder structure * * @param {string} templateDir Directory where metadata templates are stored * @param {string[]} typeDirArr current subdir for this type * @param {string} templateName name of the metadata template * @param {string} fileName name of the metadata template file w/o extension * @returns {Promise.<string>} metadata in string form */ static async readSecondaryFolder(templateDir, typeDirArr, templateName, fileName) { // handles subtypes that create 1 folder per asset -> currently causes the below File.ReadFile to error out typeDirArr.push(templateName); return await File.readFilteredFilename([templateDir, ...typeDirArr], fileName, 'json'); } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const basePath = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, ]); const fileList = ( await Promise.all( keyArr.map(async (key) => { // get subType, path an fileName by scanning the retrieve folder let subType; let filePath; let fileName; for (const st of this.definition.subTypes) { fileName = `${key}.${this.definition.type}-${st}-meta.json`; if ( await File.pathExists( File.normalizePath([basePath, this.definition.type, st, fileName]) ) ) { subType = st; filePath = [basePath, this.definition.type, st]; break; } else if ( await File.pathExists( File.normalizePath([ basePath, this.definition.type, st, key, fileName, ]) ) ) { subType = st; filePath = [basePath, this.definition.type, st, key]; break; } } if ( Array.isArray(filePath) && (await File.pathExists(File.normalizePath([...filePath, fileName]))) ) { // #1 load json to be able to find extracted text files & binary files const metadata = await File.readJSONFile(filePath, fileName, false); // #2 find all extracted text files const fileListNested = ( await this._mergeCode(metadata, basePath, subType, metadata.customerKey) ).map((item) => File.normalizePath([ basePath, ...item.subFolder, `${item.fileName}.${item.fileExt}`, ]) ); // ensure we dont overlook other versions when using this logic to auto-delete older files const fileListNestedSet = new Set(fileListNested); for (const filePath of fileListNested) { // allowed file extensions at this point are only html, ssjs and amp const baseFilePath = filePath.replace(/\.[^/.]+$/, ''); fileListNestedSet.add(`${baseFilePath}.html`); fileListNestedSet.add(`${baseFilePath}.ssjs`); fileListNestedSet.add(`${baseFilePath}.amp`); } const response = [ File.normalizePath([...filePath, fileName]), ...fileListNestedSet, ]; // #3 get binary file const binaryFilePath = await this._readExtendedFileFromFS( metadata, subType, basePath, false ); if (binaryFilePath) { response.push(binaryFilePath); } return response; } else { return []; } }) ) ).flat(); return fileList; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} id value or null */ static async _getIdForSingleRetrieve(key) { const name = key.startsWith('name:') ? key.slice(5) : null; const filter = name ? '?$filter=name%20eq%20' + encodeURIComponent(name) : '?$filter=customerKey%20eq%20' + encodeURIComponent(key); const results = await this.client.rest.get('/asset/v1/content/assets/' + filter); const items = results?.items || []; const found = items.find((item) => name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key ); return found?.id || null; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} id id field * @returns {Promise.<string>} key value or null */ static async _getKeyForSingleRetrieve(id) { const results = await this.client.rest.get('/asset/v1/content/assets/' + id); return results?.customerKey || null; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id let id; if (key?.startsWith('id:')) { id = key.slice(3); // we need to get the actual key so that postDeletetTasks know what to do key = await this._getKeyForSingleRetrieve(id); } else { id = key ? await this._getIdForSingleRetrieve(key) : null; } if (!id) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/asset/v1/content/assets/' + id, key); } /** * clean up after deleting a metadata item * cannot use the generic method due to the complexity of how assets are saved to disk * * @param {string} key Identifier of metadata item * @returns {Promise.<void>} - */ static async postDeleteTasks(key) { if (key?.startsWith('id:')) { // sad } const fileArr = await this.getFilesToCommit([key]); if (!Array.isArray(fileArr) || fileArr.length === 0) { Util.logger.verbose(` - ${this.definition.type} ${key} does not exist on disk`); return; } // check if asset sits in its own folder const ownFolderIndex = fileArr[0].indexOf(key + '\\') > 0 ? fileArr[0].indexOf(key + '\\') : fileArr[0].indexOf(key + '/'); if (ownFolderIndex > 0) { fileArr.push(fileArr[0].slice(0, ownFolderIndex + key.length)); } for (const filePath of fileArr) { await File.remove(filePath); } } /** * get name & key for provided id * * @param {string} id Identifier of metadata * @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 */ static async resolveId(id) { let response; const json = { key: '', isShared: false, name: '', path: '', folder: '', mid: 0, legacyId: 0, error: '', sharedWith: [], }; try { response = await this.client.rest.get( 'asset/v1/content/assets/' + id + '?$fields=id,customerKey,name,memberId,legacyData,sharingProperties' ); } catch (ex) { if (ex.response?.status !== 404) { throw ex; } } if (response?.id) { const item = response; const subType = this.#getMainSubtype(item.assetType.name); // prep response object json.key = item[this.definition.keyField]; json.name = item[this.definition.nameField]; json.mid = item.memberId; json.isShared = item.memberId != this.buObject.mid; json.sharedWith = item.sharingProperties?.sharedWith || null; json.legacyId = item.legacyData?.legacyId; const ownerBUName = json.isShared ? Util.inverseGet( this.properties.credentials[this.buObject.credential].businessUnits, json.mid ) : this.buObject.businessUnit; // find path for code of content block, fall back to json if not found; undefined if not even the json exists let path = await this.#getPath(subType, item, ownerBUName); if (!json.sharedWith) { delete json.sharedWith; } if (!json.isShared && !path) { // if not shared, we should have the file on disk; attempt download if (!cache.getCache()?.folder) { // folders not cached yet but required to fill json.path Folder.client = this.client; Folder.buObject = this.buObject; Folder.properties = this.properties; const result = await Folder.retrieveForCache(null, ['asset', 'asset-shared']); if (!cache.getCache()) { cache.initCache(this.buObject); } cache.setMetadata('folder', result.metadata); } await this.retrieve( File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, ]), null, [subType], json.key ); // try again path = await this.#getPath(subType, item, this.buObject.businessUnit); } if (path) { json.path = path; delete json.error; } else { json.error = 'file not found on local disk'; delete json.path; } const fileContent = await this.#getJson(subType, item); if (fileContent?.r__folder_Path) { json.folder = fileContent.r__folder_Path; } if (!json.legacyId) { delete json.legacyId; } if (Util.OPTIONS.json) { // for automated processing by VSCode extension, optionally print the json console.log(JSON.stringify(json, null, 2)); // eslint-disable-line no-console } else { Util.logger.info(` - ID: ${id}`); Util.logger.info(` - Key: ${item[this.definition.keyField]}`); Util.logger.info(` - Name: ${item[this.definition.nameField]}`); if (json.isShared) { Util.logger.warn(' - Shared from: ' + ownerBUName + ' (' + json.mid + ')'); } if (json.sharedWith && Array.isArray(json.sharedWith)) { Util.logger.warn( ` - Shared with: ${json.sharedWith .map( (mid) => Util.inverseGet( this.properties.credentials[this.buObject.credential] .businessUnits, mid ) + ' (' + mid + ')' ) .toSorted() .join(', ')}` ); } if (json.legacyId) { Util.logger.info(` - Legacy ID: ${json.legacyId}`); } Util.logger.info(` - How to use:`); Util.logger.info(` %%= ContentBlockByKey("${json.key}") =%%`); if (json.folder) { Util.logger.info( ` %%= ContentBlockByName("${ json.folder .split('/') .map((s) => s.replaceAll(Util.folderNameSlashEscapeChar, '/')) .join('\\') + '\\' + json.name }") =%%` ); if (json.folder.includes('&') || json.name.includes('&')) { Util.logger.warn( ` - ContentBlockByName will fail because your path or name contains the & or & symbol. Please replace it with 'and' or remove it.` ); } } Util.logger.info( ' - local link: ' + (path || `404. Try running mcdev r ${this.buObject.credential}/${ownerBUName} ${this.definition.type}-${subType} ${item[this.definition.keyField]}`) ); } return json; } else { json.error = 'id not found'; delete json.key; delete json.mid; delete json.name; delete json.path; delete json.folder; delete json.isShared; delete json.legacyId; delete json.sharedWith; if (Util.OPTIONS.json) { console.log(JSON.stringify(json, null, 2)); // eslint-disable-line no-console return json; } Util.logger.error(` - ${this.definition.type} with id ${id} not found on BU`); return json; } } /** * helper for {@link Asset.resolveId} that finds the path to the asset's code * * @param {string} subType asset subtype * @param {object} item api response for metadata * @param {string} buName owner business unit name * @returns {Promise.<string>} path to the asset's code */ static async #getPath(subType, item, buName) { const pathBase1 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`; const pathBase2 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`; const paths = []; for (const ext of ['html', 'ssjs', 'amp', 'json']) { paths.push(pathBase1 + ext, pathBase2 + ext); } const path = await Util.findAsync(paths, async (p) => await File.pathExists(p)); return path; } /** * helper for {@link Asset.resolveId} that loads the JSON file for the asset * * @param {string} subType asset subtype * @param {object} item api response for metadata * @returns {Promise.<object>} JS object of the asset we loaded from disk */ static async #getJson(subType, item) { const mid = item.memberId; const buName = mid === this.buObject.mid ? this.buObject.businessUnit : Object.keys( this.properties.credentials[this.buObject.credential].businessUnits ).find( (buName) => this.properties.credentials[this.buObject.credential].businessUnits[ buName ] == mid ); const pathBase1 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`; const pathBase2 = `./retrieve/${this.buObject.credential}/${buName}/${this.definition.type}/${subType}/${item[this.definition.keyField]}/${item[this.definition.keyField]}.${this.definition.type}-${subType}-meta.`; const paths = [pathBase1 + 'json', pathBase2 + 'json']; const path = await Util.findAsync(paths, async (p) => await File.pathExists(p)); const pathArr = path.split('/'); const fileName = pathArr.pop().slice(0, -5); const fileContent = await File.readJSONFile(pathArr.join('/'), fileName, false); return fileContent; } /** * * @param {MetadataTypeItem} item single metadata item * @param {string} retrieveDir directory where metadata is saved * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem>} key of the item that was updated */ static async replaceCbReference(item, retrieveDir, findAssetKeys) { const responseItem = structuredClone(item); const parentName = `${this.definition.type} ${item[this.definition.keyField]}`; let changes = false; let error; // *** type specific logic *** const subType = this.#getMainSubtype(item.assetType.name); /** @type {CodeExtract[]} */ const fileList = await this._mergeCode( item, retrieveDir, subType, item[this.definition.keyField], false ); const fileListChanged = []; for (const file of fileList) { try { file.content = ReplaceCbReference.replaceReference( file.content, parentName, findAssetKeys ); changes = true; fileListChanged.push(file); } catch (ex) { if (ex.code !== 200) { error = ex; } } } if (!findAssetKeys) { // save what was changed regardless of other errors for (const extractedFile of fileListChanged) { File.writeToFile( [retrieveDir, ...extractedFile.subFolder], extractedFile.fileName, extractedFile.fileExt, extractedFile.content, extractedFile.encoding || null ); } } if (error) { throw error; } if (!changes) { const ex = new Error('No changes made to the code.'); // @ts-expect-error custom error object ex.code = 200; throw ex; } // *** finish *** // replaceReference will throw an error if nothing was updated which will end execution here // no error means we have a new item to deploy and need to update the item in our retrieve folder return responseItem; } /** * this iterates over all items found in the retrieve folder and executes the type-specific method for replacing references * * @param {MetadataTypeMap} metadataMap list of metadata (keyField => metadata) * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<string[]>} Returns list of keys for which references were replaced */ static async replaceCbReferenceLoop(metadataMap, retrieveDir, findAssetKeys) { const keysForDeploy = []; if (!metadataMap) { // 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 return keysForDeploy; } const fromDescription = Util.OPTIONS.referenceFrom .map((from) => 'ContentBlockBy' + Util.capitalizeFirstLetter(from)) .join(' and '); if (Object.keys(metadataMap).length) { Util.logger.debug(` - Searching in ${this.definition.type} `); const deployMap = {}; for (const key in metadataMap) { const item = metadataMap[key]; if (this.isFiltered(item, true) || this.isFiltered(item, false)) { // we would not have saved these items to disk but they exist in the cache and hence need to be skipped here continue; } try { // add key but make sure to turn it into string or else numeric keys will be filtered later deployMap[key] = await this.replaceCbReference( item, retrieveDir, findAssetKeys ); // ! this method is equal to the super version except that it does not run saveToDisk here // await this.saveToDisk(deployMap, key, baseDir); if (findAssetKeys) { keysForDeploy.push(...[...findAssetKeys].map((key) => key + '')); } else { keysForDeploy.push(key + ''); Util.logger.info( ` - added ${this.definition.type} to update queue: ${key}` ); } } catch (ex) { if (ex.code !== 200) { // dont print error if we simply did not find relevant content blocks Util.logger.errorStack( ex, 'issue with ' + this.definition.type + ' ' + key ); } if (!findAssetKeys) { Util.logger.info( Util.getGrayMsg( ` ☇ skipping ${this.definition.type} ${ item[this.definition.keyField] }: no ${fromDescription} found` ) ); } } } if (!findAssetKeys) { Util.logger.info( `Found ${keysForDeploy.length} ${this.definition.type}${keysForDeploy.length === 1 ? '' : 's'} to update` ); } } return keysForDeploy; } /** * * @param {string[]} keyArr limit retrieval to given metadata type * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} findAssetKeys list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<Set.<string>>} found asset keys */ static async getCbReferenceKeys(keyArr, retrieveDir, findAssetKeys) { if (!Object.prototype.hasOwnProperty.call(this, 'replaceCbReference')) { // only types that have a replaceCbReference method actually have ampscript/ssjs return; } if (!this.getJsonFromFSCache) { // avoid re-reading the same files in every recursive iteration this.getJsonFromFSCache = await this.getJsonFromFS( File.normalizePath([retrieveDir, this.definition.type]) ); } // get all metadata of the current type; then filter by keys in selectedTypes const metadataMap = Util.filterObjByKeys(this.getJsonFromFSCache, [...findAssetKeys]); const newKeysFound = new Set( await this.replaceCbReferenceLoop(metadataMap, retrieveDir, findAssetKeys) ); if (newKeysFound.size) { const keysToCrawl = []; for (const value of newKeysFound) { if (!keyArr.includes(value)) { keyArr.push(value); keysToCrawl.push(value); } } Util.logger.info(Util.getGrayMsg(` - asset: ${keysToCrawl.join(', ')}`)); if (keysToCrawl.length) { findAssetKeys = new Set([ ...findAssetKeys, ...(await this.getCbReferenceKeys(keyArr, retrieveDir, new Set(keysToCrawl))), ]); } } return findAssetKeys; } /** * optional helper for {@link this.getDependentTypes} * * @param {object} metadataItem metadata json read from filesystem * @param {TypeKeyCombo} dependentTypeKeyCombo list started in this.getDependentTypes */ static getDependentFilesExtra(metadataItem, dependentTypeKeyCombo) { const dependentKeyArr = []; // search: // - metadata.views.html.slots // - metadata.slots if (metadataItem.views?.html?.slots) { this._getDependentFilesExtra(metadataItem.views.html.slots, dependentKeyArr); } if (metadataItem.slots) { this._getDependentFilesExtra(metadataItem.slots, dependentKeyArr); } if (dependentKeyArr.length) { dependentTypeKeyCombo.asset ||= []; dependentTypeKeyCombo.asset.push(...dependentKeyArr); } } /** * @param {object} slots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots * @param {string[]} dependentKeyArr list of found keys */ static _getDependentFilesExtra(slots, dependentKeyArr) { for (const slot in slots) { for (const block in slots[slot].blocks) { const asset = slots[slot].blocks[block]; if (asset.r__asset_key) { dependentKeyArr.push(asset.r__asset_key); } if (asset.views?.html?.slots) { // * recursion: each block can have slots of its own this._getDependentFilesExtra(asset.views.html.slots, dependentKeyArr); } if (asset.slots) { // * recursion: each block can have slots of its own this._getDependentFilesExtra(asset.slots, dependentKeyArr); } } } } /** * helper for {@link MetadataType.createOrUpdate} * * @param {MetadataTypeItem} metadataItem to be deployed item * @returns {MetadataTypeItem} cached item or undefined */ static getCacheMatchedByName(metadataItem) { let cacheMatchedByName; if (Util.OPTIONS.matchName) { // make sure to run the search ONLY if OPTIONS.matchName is true and definition.allowMatchingByName signals support const assetCache = cache.getCache()?.asset; const potentials = []; for (const key in assetCache) { const cachedAsset = assetCache[key]; if ( cachedAsset[this.definition.nameField] === metadataItem[this.definition.nameField] && cachedAsset.assetType.id === metadataItem.assetType.id ) { potentials.push(cachedAsset); } } let deployFolderPath; if (potentials.length >= 1) { deployFolderPath = cache.searchForField( 'folder', metadataItem.category.id, 'ID', 'Path' ); } if (potentials.length > 1) { const potentialsWithMatchingFolder = potentials.filter( (el) => el.category.id === metadataItem.category.id ); throw new Error( `found multiple name matches in cache. New folder: "${deployFolderPath}". Identified keys: ${potentials.map((p) => p[this.definition.keyField]).join(', ')}. ` + (potentialsWithMatchingFolder.length ? `Folder for ${potentialsWithMatchingFolder[0][this.definition.keyField]} matches the new folder. ` : '') ); } else if (potentials.length === 1) { if (potentials[0].category.id === metadataItem.category.id) { cacheMatchedByName = potentials[0]; Util.logger.info( Util.getGrayMsg( ` - found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" and folder "${deployFolderPath}": ${cacheMatchedByName[this.definition.keyField]}` ) ); } else { const cacheFolderPath = cache.searchForField( 'folder', potentials[0].category.id, 'ID', 'Path' ); throw new Error( `found match in cache by name but folder is different. New folder: "${deployFolderPath}". Existing: "${cacheFolderPath}": Identified key: ${potentials[0][this.definition.keyField]}` ); } } else { Util.logger.debug( ` - no name-match found for ${this.definition.type} ${metadataItem[this.definition.keyField]}. Creating new asset instead.` ); } } return cacheMatchedByName; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Asset.definition = MetadataTypeDefinitions.asset; export default Asset; ================================================ FILE: lib/metadataTypes/AttributeGroup.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj */ /** * AttributeGroup MetadataType * * @augments MetadataType */ class AttributeGroup extends MetadataType { /** * Retrieves Metadata of schema attribute groups. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { return super.retrieveREST( retrieveDir, '/hub/v1/contacts/schema/attributeGroups', null, key ); } /** * Retrieves Metadata of schema attribute groups for caching. * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache() { return super.retrieveREST(null, '/hub/v1/contacts/schema/attributeGroups'); } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single metadata * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(metadata) { // Member ID delete metadata.mID; // attributeSet metadata.r__attributeSet_key = metadata.attributeSetIdentifiers.map((attributeSet) => { try { const key = cache.searchForField( 'attributeSet', attributeSet.definitionID, 'definitionID', 'definitionKey' ); if (key !== attributeSet.definitionKey) { Util.logger.debug( `AttributeSet key mismatch. Overwriting ${attributeSet.definitionKey} with ${key}` ); } return key; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]} (for ${ attributeSet.definitionKey }): ${ex.message}` ); return attributeSet; } }); delete metadata.attributeSetIdentifiers; // requiredRelationships // TODO: implement // description is not returned by API when empty. Set to empty string to propose the field as an option to users metadata.description ||= ''; // applicationKey is only used by system generated attribute groups and otherwise it's empty. if (metadata.applicationKey === '') { // remove useless field delete metadata.applicationKey; } // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - to be sure we check it here and remove it if it's the case if (metadata.connectingID?.identifierType === 'FullyQualifiedName') { // remove useless field delete metadata.connectingID; } // containsSchemaAttributes is only true for system generated attribute groups and otherwise it's false. if (!metadata.containsSchemaAttributes) { delete metadata.containsSchemaAttributes; } // isSystemDefined is only true for system generated attribute groups and cannot be deployed if (!metadata.isSystemDefined) { delete metadata.isSystemDefined; } return metadata; } /** * prepares for deployment * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} Promise */ } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; AttributeGroup.definition = MetadataTypeDefinitions.attributeGroup; export default AttributeGroup; ================================================ FILE: lib/metadataTypes/AttributeSet.js ================================================ 'use strict'; import AttributeGroup from './AttributeGroup.js'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj */ /** * AttributeSet MetadataType * * @augments MetadataType */ class AttributeSet extends MetadataType { static systemValueDefinitions; /** * Retrieves Metadata of schema set Definitions. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { if (retrieveDir && !cache.getCache()?.attributeGroup) { // ! attributeGroup and attributeSet both link to each other. caching attributeGroup here "manually", assuming that it's quicker than the other way round Util.logger.info(' - Caching dependent Metadata: attributeGroup'); AttributeGroup.buObject = this.buObject; AttributeGroup.client = this.client; AttributeGroup.properties = this.properties; const result = await AttributeGroup.retrieveForCache(); cache.setMetadata('attributeGroup', result.metadata); } return super.retrieveREST(retrieveDir, '/hub/v1/contacts/schema/setDefinitions', null, key); } /** * Retrieves Metadata of schema set definitions for caching. * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache() { return super.retrieveREST(null, '/hub/v1/contacts/schema/setDefinitions'); } /** * used to identify updated shared data extensions that are used in attributeSets. * helper for DataExtension.#fixShared_onBU * * @param {Object.<string, string>} sharedDataExtensionMap ID-Key relationship of shared data extensions * @param {object} fixShared_fields DataExtensionField.fixShared_fields * @returns {Promise.<string[]>} Promise of list of shared dataExtension IDs */ static async fixShared_retrieve(sharedDataExtensionMap, fixShared_fields) { if (!Object.keys(sharedDataExtensionMap).length) { return []; } const result = await super.retrieveREST(null, '/hub/v1/contacts/schema/setDefinitions'); const metadataMap = result?.metadata; if (metadataMap && Object.keys(metadataMap).length) { const sharedDeIds = Object.keys(metadataMap) .filter( (asKey) => metadataMap[asKey].storageLogicalType === 'ExactTargetSchema' || metadataMap[asKey].storageLogicalType === 'DataExtension' ) .filter((asKey) => { // check if dataExtension ID is found on any attributeSet of this BU if (sharedDataExtensionMap[metadataMap[asKey].storageReferenceID.value]) { Util.logger.debug( ` shared dataExtension ID ${metadataMap[asKey].storageReferenceID.value} found in attributeSet ${asKey}` ); return true; } else { return false; } }) .filter((asKey) => { // check if any of the dataExtension fields dont exist on the attributeSet or are out of date const deKey = sharedDataExtensionMap[metadataMap[asKey].storageReferenceID.value]; const asFields = metadataMap[asKey].valueDefinitions; const deFields = Object.values(fixShared_fields[deKey]); return deFields.some((deField) => { const search = asFields.filter((asf) => asf.name === deField.Name); if (!search.length) { Util.logger.debug( Util.getGrayMsg( ` - Field ${deField.Name} not found in attributeSet; Note: only first recognized difference is printed to log` ) ); return true; } const asField = search[0]; if (asField.dataType !== deField.FieldType) { Util.logger.debug( Util.getGrayMsg( ` - Field ${deField.Name} FieldType changed (old: ${asField.dataType}; new: ${deField.FieldType}); Note: only first recognized difference is printed to log` ) ); return true; } asField.defaultValue ||= ''; if ( (asField.defaultValue && deField.DefaultValue === '') || (deField.FieldType === 'Boolean' && deField.DefaultValue !== '' && (deField.DefaultValue ? 'True' : 'False' !== asField.defaultValue)) || (deField.FieldType !== 'Boolean' && deField.DefaultValue !== asField.defaultValue) ) { Util.logger.debug( ` - Field ${deField.Name} DefaultValue changed (old: ${asField.defaultValue}; new: ${deField.DefaultValue}); Note: only first recognized difference is printed to log` ); return true; } // some field types don't carry the length property. reset to 0 to ease comparison asField.length ||= 0; if (asField.length !== deField.MaxLength) { Util.logger.debug( ` - Field ${deField.Name} MaxLength changed (old: ${asField.length}; new: ${deField.MaxLength}); Note: only first recognized difference is printed to log` ); return true; } if (asField.isNullable !== deField.IsRequired) { Util.logger.debug( ` - Field ${deField.Name} IsRequired changed (old: ${asField.isNullable}; new: ${deField.IsRequired}); Note: only first recognized difference is printed to log` ); return true; } if (asField.isPrimaryKey !== deField.IsPrimaryKey) { Util.logger.debug( ` - Field ${deField.Name} IsPrimaryKey changed (old: ${asField.isPrimaryKey}; new: ${deField.IsPrimaryKey}); Note: only first recognized difference is printed to log` ); return true; } return false; }); }) .map((key) => metadataMap[key].storageReferenceID.value) .filter(Boolean); return sharedDeIds; } else { // nothing to do - return empty array return []; } } /** * Builds map of metadata entries mapped to their keyfields * * @param {object} body json of response body * @param {string} [singleRetrieve] key of single item to filter by * @returns {MetadataTypeMap} keyField => metadata map */ static parseResponseBody(body, singleRetrieve) { const metadataCache = super.parseResponseBody(body); // make sure we add the entire list to cache before running postRetrieveTasks because of the self-references this type is using // usually, the cache is only written into after all postRetrieveTasks have been run cache.setMetadata(this.definition.type, metadataCache); const metadataStructure = super.parseResponseBody(body, singleRetrieve); return metadataStructure; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single metadata * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(metadata) { // folder if (metadata.storageLogicalType === 'DataExtension') { // attributeSet created for Group Connect do not have a folder super.setFolderPath(metadata); } // source switch (metadata.storageLogicalType) { case 'ExactTargetSchema': // synced / shared DEs case 'DataExtension': { // shared / local DEs try { metadata.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.storageReferenceID.value, 'ObjectID', 'CustomerKey' ); // TODO: check if fields in metadata.sendAttributeStorageName exist in data extension --> error // TODO: check if fields in data extension exist in metadata.sendAttributeStorageName --> warn delete metadata.storageReferenceID; delete metadata.storageName; delete metadata.storageObjectInformation; // type ExactTargetSchema only } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ ex.message }` ); } break; } case 'MobileAttributes': { // TODO: implement // "storageName": "_MobileAddress", break; } case 'EnterpriseAttributes': { // TODO: implement // "storageName": "_EnterpriseAttribute", break; } case 'PushAttributes': { // TODO: implement // "storageName": "_PushAddress", break; } } // relationships to attributeGroups & AttributeSet if (Array.isArray(metadata.relationships)) { for (const relationship of metadata.relationships) { for (const type of ['left', 'right']) { if ( relationship[type + 'Item']?.connectingID?.identifierType === 'FullyQualifiedName' ) { delete relationship[type + 'Item'].connectingID; } let relationshipObj = null; switch (relationship[type + 'Item'].relationshipType) { case 'AttributeGroup': { try { relationship[type + 'Item'].r__attributeGroup_key = cache.searchForField( 'attributeGroup', relationship[type + 'Item']?.identifier, 'definitionID', 'definitionKey' ); delete relationship[type + 'Item']?.identifier; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ metadata[this.definition.keyField] }: ${ex.message}` ); } // get relationship fieldnames relationshipObj = { valueDefinitions: this._getSystemValueDefinitions(), }; break; } case 'AttributeSet': { try { relationship[type + 'Item'].r__attributeSet_key = cache.searchForField( 'attributeSet', relationship[type + 'Item']?.identifier, 'definitionID', 'definitionKey' ); delete relationship[type + 'Item']?.identifier; // get relationship fieldnames // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet relationshipObj = relationship[type + 'Item'].r__attributeSet_key === metadata.definitionKey ? metadata : cache.getByKey( 'attributeSet', relationship[type + 'Item'].r__attributeSet_key ); } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ metadata[this.definition.keyField] }: ${ex.message}` ); } break; } } try { // get relationship fieldnames // resolve field values for (const attr of relationship.relationshipAttributes) { const id = attr[type + 'AttributeID']; const valueDefinition = relationshipObj.valueDefinitions.find( (item) => item.valueDefinitionID === id ); if (valueDefinition) { attr['c__' + type + 'FullyQualifiedName'] = valueDefinition.fullyQualifiedName; delete attr[type + 'AttributeID']; delete attr[type + 'ConnectingID']; } else { throw new Error( `Could not find ${type}AttributeID ${id} of relationship ${relationship.relationshipID}` ); } } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} / ${ metadata[this.definition.keyField] }: ${ex.message}` ); } } } } // Member ID delete metadata.customObjectOwnerMID; // remove duplicate ID fields (main field is definitionID) delete metadata.setDefinitionID; if (metadata.dataRetentionProperties?.setDefinitionID) { delete metadata.dataRetentionProperties?.setDefinitionID; } // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - to be sure we check it here and remove it if it's the case if (metadata.connectingID?.identifierType === 'FullyQualifiedName') { // remove useless field delete metadata.connectingID; } return metadata; } /** * helper for {@link AttributeSet.postRetrieveTasks} * * @returns {object[]} all system value definitions */ static _getSystemValueDefinitions() { this.systemValueDefinitions ||= {}; if (!this.systemValueDefinitions[this.buObject.mid]) { this.systemValueDefinitions[this.buObject.mid] = Object.values( cache.getCache()['attributeSet'] ) .flatMap((item) => { if (item.isSystemDefined) { return item.valueDefinitions; } }) .filter(Boolean); } return this.systemValueDefinitions[this.buObject.mid]; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; AttributeSet.definition = MetadataTypeDefinitions.attributeSet; export default AttributeSet; ================================================ FILE: lib/metadataTypes/Automation.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import Definitions from '../MetadataTypeDefinitions.js'; import cache from '../util/cache.js'; import pLimit from 'p-limit'; import Retriever from '../Retriever.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * @typedef {import('../../types/mcdev.d.js').AutomationItem} AutomationItem * @typedef {import('../../types/mcdev.d.js').AutomationItemObj} AutomationItemObj * @typedef {import('../../types/mcdev.d.js').AutomationMap} AutomationMap * @typedef {import('../../types/mcdev.d.js').AutomationMapObj} AutomationMapObj * @typedef {import('../../types/mcdev.d.js').AutomationSchedule} AutomationSchedule * @typedef {import('../../types/mcdev.d.js').AutomationScheduleSoap} AutomationScheduleSoap */ /** * Automation MetadataType * * @augments MetadataType */ class Automation extends MetadataType { static notificationUpdates = {}; static createdKeyMap; static _skipNotificationRetrieve = false; /** @type {AutomationMap} */ static _cachedMetadataMap; /** * Retrieves Metadata of Automation * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<AutomationMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { let metadataMap; if (key && this._cachedMetadataMap?.[key]) { metadataMap = { [key]: this._cachedMetadataMap[key] }; delete this._cachedMetadataMap; } else if (!key && this._cachedMetadataMap) { metadataMap = this._cachedMetadataMap; delete this._cachedMetadataMap; } else { /** @type {SoapRequestParams} */ let requestParams = null; const objectIds = []; if (key?.startsWith('id:')) { objectIds.push(key.slice(3)); } else if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } const results = await this.client.soap.retrieveBulk( 'Program', ['ObjectID'], requestParams ); if (results?.Results?.length) { objectIds.push(...results.Results.map((item) => item.ObjectID)); } // the API seems to handle 50 concurrent requests nicely const response = objectIds.length ? await this.retrieveRESTcollection( objectIds.map((objectID) => ({ id: objectID, uri: '/automation/v1/automations/' + objectID, })), 10, !key ) : null; metadataMap = response?.metadata || {}; } if (!this._skipNotificationRetrieve && Object.keys(metadataMap).length) { // attach notification and wait timezone information to each automation that has any await this.#getAutomationLegacyREST(metadataMap); } // * retrieveDir can be empty when we use it in the context of postDeployTasks if (retrieveDir) { this.retrieveDir = retrieveDir; const savedMetadataMap = await this.saveResults(metadataMap, retrieveDir, null, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadataMap).length})` + Util.getKeysString(key) ); if (Object.keys(savedMetadataMap).length) { await this.runDocumentOnRetrieve(key, savedMetadataMap); } else if (key) { this.postDeleteTasks(key); } } return { metadata: metadataMap, type: this.definition.type }; } /** * helper for {@link this.retrieveRESTcollection} * * @param {SDKError} ex exception * @param {string} key id or key of item * @param {string} url url to call for retry * @returns {Promise.<any>} can return retry-result */ static async handleRESTErrors(ex, key, url) { try { if (ex.message == 'socket hang up' || ex.code == 'ERR_BAD_RESPONSE') { // one more retry; it's a rare case but retrying again should solve the issue gracefully Util.logger.info( ` - Connection problem (Code: ${ex.code}). Retrying once ${ ex.endpoint ? Util.getGrayMsg( ' - ' + ex.endpoint.split('rest.marketingcloudapis.com')[1] ) : '' }` ); Util.logger.errorStack(ex); return await this.client.rest.get(url); } } catch { // no extra action needed, handled below } // if we do get here, we should log the error and continue instead of failing to download all automations Util.logger.error(` ☇ skipping ${this.definition.type} ${key}: ${ex.message} ${ex.code}`); return null; } /** * helper for {@link Automation.retrieve} to get Automation Notifications * * @param {MetadataTypeMap} metadataMap keyField => metadata map * @param {boolean} [skipNotification] skip notification retrieval * @returns {Promise.<object>} Promise of automation legacy api response */ static async #getAutomationLegacyREST(metadataMap, skipNotification = false) { Util.logger.info(Util.getGrayMsg(` Retrieving additional automation details...`)); // get list of keys that we retrieved so far const foundKeys = Object.keys(metadataMap); // get encodedAutomationID to retrieve notification information const iteratorBackup = this.definition.bodyIteratorField; this.definition.bodyIteratorField = 'entry'; const automationLegacyMapObj = await super.retrieveREST( undefined, `/legacy/v1/beta/bulk/automations/automation/definition/` ); this.definition.bodyIteratorField = iteratorBackup; // notification const notificationLegacyMap = Object.keys(automationLegacyMapObj.metadata) .filter((key) => foundKeys.includes(key)) // ! using the `id` field to retrieve notifications does not work. instead one needs to use the URL in the `notifications` field .map((key) => ({ id: automationLegacyMapObj.metadata[key].id, key, })); // created / modified / paused / wait activities const extendedDetailsLegacyMap = Object.keys(automationLegacyMapObj.metadata) .filter((key) => foundKeys.includes(key)) .map((key) => ({ id: automationLegacyMapObj.metadata[key].id, key, })); const rateLimit = pLimit(5); // get wait activities for automations using it await Promise.all( extendedDetailsLegacyMap.map((automationLegacy) => // notifications rateLimit(async () => { // this is a file so extended is at another endpoint try { /** @type {AutomationItem} */ const item = metadataMap[automationLegacy.key]; item.legacyId = automationLegacy.id; const extended = await this.client.rest.get( `/legacy/v1/beta/bulk/automations/automation/definition/` + automationLegacy.id ); // set those for {@link schedule} item.type ||= extended.automationType; item.status ||= extended.status; // created item.createdName = extended.createdBy?.name; item.createdDate = extended.createdDate; // last modified item.modifiedName = extended.lastSavedBy?.name; item.modifiedDate = extended.lastSaveDate; // last paused item.pausedName = extended.lastPausedBy?.name; item.pausedDate = extended.lastPausedDate; // schedule id for activating the schedule if (extended?.scheduleObject?.id && item.schedule) { // save schedule id in cached metadata for retrieval during scheduling item.schedule.id = extended.scheduleObject.id; item.schedule.description = extended.scheduleObject.description; item.schedule.icalRecur ||= extended.scheduleObject.iCalRecur; item.schedule.startDate ||= extended.scheduleObject.startDate; item.schedule.timezoneName ||= extended.scheduleObject.timeZone; } // add timezone to wait activities if (Array.isArray(extended?.processes)) { for (const step of extended.processes) { // steps if (!Array.isArray(step?.workers)) { continue; } for (const activity of step.workers) { // activties if ( activity.objectTypeId === 467 && activity.serializedObject ) { // wait activities const waitObj = JSON.parse(activity.serializedObject); if (waitObj.timeZone) { // add timezone to the wait activity item.steps[step.sequence].activities[ activity.sequence ].timeZone = waitObj.timeZone; } // * wait activities are not supported in the new API } } } } } catch (ex) { Util.logger.debug( ` ☇ issue retrieving extended details for automation ${automationLegacy.key}: ${ex.message} ${ex.code}` ); } }) ) ); if (skipNotification) { return; } // get notifications for each automation let found = 0; let skipped = 0; const notificationPromiseMap = await Promise.all( notificationLegacyMap.map((automationLegacy) => // notifications rateLimit(async () => { // this is a file so extended is at another endpoint try { const notificationsResult = await this.client.rest.get( '/legacy/v1/beta/automations/notifications/' + automationLegacy.id ); if (Array.isArray(notificationsResult?.workers)) { metadataMap[automationLegacy.key].notifications = notificationsResult.workers.map((n) => ({ email: n.definition.split(',').map((item) => item.trim()), message: n.body, type: n.notificationType, })); found++; } else { if ( !notificationsResult || typeof notificationsResult !== 'object' || Object.keys(notificationsResult).length !== 1 || !notificationsResult?.programId ) { throw new TypeError(JSON.stringify(notificationsResult)); } // * if there are no automation notifications, the API returns a single object with the programId } } catch (ex) { Util.logger.debug( ` ☇ issue retrieving Notifications for automation ${automationLegacy.key}: ${ex.message} ${ex.code}` ); skipped++; } }) ) ); Util.logger.info( Util.getGrayMsg(` Notifications found for ${found} automation${found === 1 ? '' : 's'}`) ); Util.logger.debug( `Notifications not found for ${skipped} automation${skipped === 1 ? '' : 's'}` ); return notificationPromiseMap; } /** * Retrieves Metadata of Automation * * @returns {Promise.<AutomationMapObj>} Promise of metadata */ static async retrieveChangelog() { const results = await this.client.soap.retrieveBulk('Program', ['ObjectID']); const details = []; for (const item of results.Results ? await Promise.all( results.Results.map((a) => this.client.soap.retrieveBulk( 'Automation', [ 'ProgramID', 'Name', 'CustomerKey', 'CategoryID', 'LastSaveDate', 'LastSavedBy', 'CreatedBy', 'CreatedDate', ], { filter: { leftOperand: 'ProgramID', operator: 'equals', rightOperand: a.ObjectID, }, } ) ) ) : []) { details.push(...item.Results); } details.map((item) => { item.key = item.CustomerKey; }); const parsed = this.parseResponseBody({ items: details }); return { metadata: parsed, type: this.definition.type }; } /** * Retrieves automation metadata for caching * * @returns {Promise.<AutomationMapObj>} Promise of metadata */ static async retrieveForCache() { let results = {}; if (this._cachedMetadataMap) { results.Results = Object.values(this._cachedMetadataMap); delete this._cachedMetadataMap; } else { // get automations for cache results = await this.client.soap.retrieveBulk('Program', [ 'ObjectID', 'CustomerKey', 'Name', ]); } /** @type {AutomationMap} */ const resultsConverted = {}; if (Array.isArray(results?.Results)) { // get encodedAutomationID to retrieve notification information const keyBackup = this.definition.keyField; const iteratorBackup = this.definition.bodyIteratorField; this.definition.keyField = 'key'; this.definition.bodyIteratorField = 'entry'; const automationsLegacy = await super.retrieveREST( undefined, `/legacy/v1/beta/bulk/automations/automation/definition/` ); this.definition.keyField = keyBackup; this.definition.bodyIteratorField = iteratorBackup; // merge encodedAutomationID into results for (const m of results.Results) { const key = m.CustomerKey || m.key; resultsConverted[key] = { id: m.ObjectID || m.id, key: key, name: m.Name || m.name, programId: automationsLegacy.metadata[key]?.id, status: automationsLegacy.metadata[key]?.status, }; } } return { metadata: resultsConverted, type: this.definition.type }; } /** * Retrieve a specific Automation Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<AutomationItemObj>} Promise of metadata */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); const results = await this.client.soap.retrieve('Program', ['ObjectID', 'Name'], { filter: { leftOperand: 'Name', operator: 'equals', rightOperand: name, }, }); if (Array.isArray(results?.Results)) { // eq-operator returns a similar, not exact match and hence might return more than 1 entry const metadata = results.Results.find((item) => item.Name === name); if (!metadata) { Util.logger.error(`${this.definition.type} '${name}' not found on server.`); return; } let details = await this.client.rest.get( '/automation/v1/automations/' + metadata.ObjectID ); const metadataMap = this.parseResponseBody({ items: [details] }); if (Object.keys(metadataMap).length) { // attach notification and wait timezone information to each automation that has any await this.#getAutomationLegacyREST(metadataMap); details = Object.values(metadataMap)[0]; } let val = null; let originalKey; // if parsing fails, we should just save what we get try { const parsedDetails = this.postRetrieveTasks(details); originalKey = parsedDetails[this.definition.keyField]; if (parsedDetails !== null) { val = JSON.parse( Util.replaceByObject(JSON.stringify(parsedDetails), templateVariables) ); } } catch { val = structuredClone(details); } if (val === null) { throw new Error( `Automations '${name}' was skipped and hence cannot be used for templating.` ); } // remove all fields not listed in Definition for templating this.keepTemplateFields(val); await File.writeJSONToFile( [templateDir, this.definition.type].join('/'), originalKey + '.' + this.definition.type + '-meta', val ); Util.logger.info(`- templated ${this.definition.type}: ${name}`); return { metadata: val, type: this.definition.type }; } else if (results) { Util.logger.error(`${this.definition.type} '${name}' not found on server.`); Util.logger.info(`Downloaded: automation (0)`); return { metadata: {}, type: this.definition.type }; } else { throw new Error(JSON.stringify(results)); } } /** * helper for {@link Automation.postRetrieveTasks} and {@link Automation.execute} * * @param {AutomationItem} metadata a single automation * @returns {boolean} true if the automation schedule is valid */ static #isValidSchedule(metadata) { if (metadata.type === 'scheduled' && metadata.schedule?.startDate) { try { if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) { // if we found the id in our list, remove the redundant data delete metadata.schedule.timezoneId; } } catch { Util.logger.debug( `- Schedule name '${metadata.schedule.timezoneName}' not found in definition.timeZoneMapping` ); } return true; } else { return false; } } /** * manages post retrieve steps * * @param {AutomationItem} metadata a single automation * @returns {AutomationItem | void} parsed item */ static postRetrieveTasks(metadata) { // folder this.setFolderPath(metadata); // automations are often skipped due to lack of support. if (metadata.type == 'automationtriggered' && metadata.automationTrigger) { const automationTrigger = metadata.automationTrigger; if (automationTrigger.fileTransferLocationId) { try { automationTrigger.r__fileLocation_name = cache.searchForField( 'fileLocation', automationTrigger.fileTransferLocationId, 'id', 'name' ); delete automationTrigger.fileTransferLocationId; } catch (ex) { Util.logger.warn(` - automation ${metadata.key}: ${ex.message}`); } } if (automationTrigger.fileNamePatternType) { try { automationTrigger.fileNamePatternType = Util.inverseGet( this.definition.fileNameOperatorMapping, automationTrigger.fileNamePatternType ); } catch { Util.logger.warn( ` - Unknown File naming Pattern '${automationTrigger.fileNamePatternType}' in Automation '${metadata.name}'` ); } } } try { if (metadata.type === 'scheduled' && metadata.schedule?.startDate) { // Starting Source == 'Schedule' if (!this.#isValidSchedule(metadata)) { return; } // type 'Running' is temporary status only, overwrite with Scheduled for storage. if (metadata.type === 'scheduled' && metadata.status === 'Running') { metadata.status = 'Scheduled'; } } else if (metadata.type === 'triggered' && metadata.fileTrigger) { // Starting Source == 'File Drop' // Do nothing for now } if (metadata.steps) { let i = 0; for (const step of metadata.steps) { i++; const stepNumber = step.stepNumber || step.step || i; delete step.stepNumber; delete step.step; for (const activity of step.activities) { try { // get metadata type of activity activity.r__type = Util.inverseGet( this.definition.activityTypeMapping, activity.objectTypeId ); delete activity.objectTypeId; } catch { Util.logger.warn( ` - Unknown activity type '${activity.objectTypeId}'` + ` in step ${stepNumber}.${activity.displayOrder}` + ` of Automation '${metadata.name}'` ); continue; } // if no activityObjectId then either serialized activity // (config in Automation ) or unconfigured so no further action to be taken if ( activity.activityObjectId === '00000000-0000-0000-0000-000000000000' || activity.activityObjectId == null ) { Util.logger.debug( ` - skipping ${ metadata[this.definition.keyField] } activity ${stepNumber}.${ activity.displayOrder } due to missing activityObjectId: ${JSON.stringify(activity)}` ); // empty if block continue; } else if (this.definition.customDeployTypes.includes(activity.r__type)) { if (activity.r__type === 'wait') { // convert 12 to 24 hrs system let waitTime24; const [waitDuration, waitUnit] = activity.name.split(' '); if (waitUnit === 'AM' || waitUnit === 'PM') { waitTime24 = waitDuration; if (waitUnit === 'PM') { waitTime24 = (Number(waitTime24.split(':')[0]) + 12).toString() + ':00'; } activity.name = waitTime24; } } continue; } else if (!this.definition.dependencies.includes(activity.r__type)) { Util.logger.debug( ` - skipping ${ metadata[this.definition.keyField] } activity ${stepNumber}.${ activity.displayOrder } because the type ${ activity.r__type } is not set up as a dependency for ${this.definition.type}` ); continue; } // / if managed by cache we can update references to support deployment if ( Definitions[activity.r__type]?.['idField'] && cache.getCache()[activity.r__type] ) { try { activity.r__key = cache.searchForField( activity.r__type, activity.activityObjectId, Definitions[activity.r__type].idField, Definitions[activity.r__type].keyField ); delete activity.name; } catch (ex) { // getFromCache throws error where the dependent metadata is not found Util.logger.warn( ` - Missing ${activity.r__type} activity '${activity.name}'` + ` in step ${stepNumber}.${activity.displayOrder}` + ` of Automation '${metadata.name}' (${ex.message})` ); } } else { Util.logger.warn( ` - Missing ${activity.r__type} activity '${activity.name}'` + ` in step ${stepNumber}.${activity.displayOrder}` + ` of Automation '${metadata.name}' (Not Found in Cache)` ); } } // In some cases the displayOrder and array order are not equal which leads to a different order every time we retrieve & deployed the automation. To prevent that, we sort the activities by displayOrder on retrieve step.activities.sort((a, b) => a.displayOrder - b.displayOrder); } } return structuredClone(metadata); } catch (ex) { Util.logger.warn( ` - ${this.definition.typeName} '${metadata[this.definition.nameField]}': ${ ex.message }` ); return null; } } /** * a function to active the schedule of an automation * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static async schedule(keyArr) { return this.#schedulePause('schedule', keyArr); } /** * a function to pause the schedule of an automation * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static async pause(keyArr) { return this.#schedulePause('pause', keyArr); } /** * a function to active the schedule of an automation * * @param {'schedule'|'pause'} mode what to do * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static async #schedulePause(mode, keyArr) { const metadataMap = {}; for (const key of keyArr) { metadataMap[key] = { key, schedule: {} }; } await this.#getAutomationLegacyREST(metadataMap, true); for (const key of keyArr) { const item = metadataMap[key]; if (!item.type) { Util.logger.error( ` ☇ skipping ${Util.getTypeKeyName(this.definition, item)}: automation not found.` ); delete metadataMap[key]; } else if (item.type !== 'scheduled') { Util.logger.error( ` ☇ skipping ${Util.getTypeKeyName(this.definition, item)}: cannot ${mode} an automation of type '${item.type}'.` ); delete metadataMap[key]; } } if (!Object.keys(metadataMap).length) { Util.logger.error(`No ${this.definition.type} to ` + mode); return []; } Util.logger.info(`${mode === 'schedule' ? 'Activating' : 'Pausing'} automations`); const promiseResults = []; for (const key of Object.keys(metadataMap)) { /** @type {AutomationItem} */ const item = metadataMap[key]; if (item.status === (mode === 'schedule' ? 'Scheduled' : 'PausedSchedule')) { // schedule Util.logger.info( ` ☇ skipping ${Util.getTypeKeyName(this.definition, item)}: already ${mode === 'schedule' ? 'activated' : 'paused'}.` ); continue; } if (mode === 'schedule') { try { this._checkSchedule(item.schedule, true); } catch (ex) { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key} (${item.schedule.description}): ${ex.message}` ); continue; } } // schedule promiseResults.push( this.#schedulePauseItem( mode, key, item.legacyId, item.schedule.id, item.schedule.description ) ); } const results = await Promise.all(promiseResults); const updatedKeyArr = results .filter(Boolean) .filter((r) => r.response?.id) .map((r) => r.key); Util.logger.info( `${mode === 'schedule' ? 'Activated' : 'Paused'} ${updatedKeyArr.length} of ${keyArr.length} items` ); if (updatedKeyArr.length) { Util.logger.info( Util.getGrayMsg( `Caching ${this.definition.type} post-${mode === 'schedule' ? 'activation' : 'pausing'} to update local files.` ) ); // re-retrieve the items that were activated / paused const retriever = new Retriever(this.properties, this.buObject); try { await retriever.retrieve([this.definition.type], updatedKeyArr); } catch (ex) { Util.logger.warn( `Could not re-retrieve ${mode === 'schedule' ? 'activated' : 'paused'} ${this.definition.type}s: ${ex.message}` ); } } return updatedKeyArr; } /** * helper for {@link Automation.schedule} * * @param {'schedule'|'pause'} mode what to do * @param {string} key automation key * @param {string} automationLegacyId automation id * @param {string} [scheduleLegacyId] schedule id * @param {string} [description] schedule description * @returns {Promise.<{key:string, response:object}>} metadata key and API response */ static async #schedulePauseItem(mode, key, automationLegacyId, scheduleLegacyId, description) { if (!scheduleLegacyId) { const extended = await this.client.rest.get( `/legacy/v1/beta/bulk/automations/automation/definition/` + automationLegacyId ); /** @type {AutomationSchedule} */ const scheduleObjectLegacy = extended.scheduleObject; if (scheduleObjectLegacy?.id) { scheduleLegacyId = scheduleObjectLegacy.id; if (mode === 'schedule') { // convert legacy API schedule to new schedule /** @type {AutomationSchedule} */ const scheduleObject = { id: scheduleObjectLegacy.id, typeId: null, endDate: null, startDate: scheduleObjectLegacy.startDate, timezoneName: scheduleObjectLegacy.timeZone, icalRecur: scheduleObjectLegacy.iCalRecur, }; try { this._checkSchedule(scheduleObject); } catch (ex) { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}: ${ex.message}` ); return null; } } description = scheduleObjectLegacy.description; } else { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}: no valid schedule settings found.` ); return null; } } let response; try { response = await this.client.rest.post( '/legacy/v1/beta/bulk/automations/automation/definition/?action=' + (mode === 'schedule' ? 'schedule' : 'pauseSchedule'), { id: automationLegacyId, scheduleObject: { id: scheduleLegacyId, }, } ); if (response?.id === automationLegacyId) { const item = { [this.definition.keyField]: key }; Util.logger.info( ` - ${mode === 'schedule' ? '✅ activated' : '🛑 paused'} scheduled ${Util.getTypeKeyName(this.definition, item)}${mode === 'schedule' ? ' (' + description + ')' : ''}` ); } } catch (ex) { Util.logger.error( ` ☇ error ${mode === 'schedule' ? 'activating' : 'pausing'} ${this.definition.type} ${key} (${description}): ${ex.message}` ); } return { key, response }; } /** * a function to start query execution via API * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed */ static async execute(keyArr) { /** @type {AutomationMap} */ const metadataMap = {}; for (const key of keyArr) { // runOnce const objectId = await this.#getObjectIdForSingleRetrieve(key); /** @type {AutomationItem} */ metadataMap[key] = { key, id: objectId }; } if (!Object.keys(metadataMap).length) { Util.logger.error(`No ${this.definition.type} to execute`); return; } Util.logger.info( `Starting automations to run once (use --schedule or --execute=schedule to schedule instead): ${Object.keys(metadataMap).length}` ); const promiseResults = []; for (const key of Object.keys(metadataMap)) { // schedule + runOnce promiseResults.push(super.executeSOAP(metadataMap[key])); } const results = await Promise.all(promiseResults); const executedKeyArr = results .filter(Boolean) .filter((r) => r.response.OverallStatus === 'OK') .map((r) => r.key); Util.logger.info(`Executed ${executedKeyArr.length} of ${keyArr.length} items`); return executedKeyArr; } /** * Standardizes a check for multiple messages but adds query specific filters to error texts * * @param {object} ex response payload from REST API * @returns {string[]} formatted Error Message */ static getErrorsREST(ex) { const errors = super.getErrorsREST(ex); if (errors?.length > 0) { return errors.map((msg) => msg .split('403 Forbidden') .join('403 Forbidden: Please check if the automation is currently running.') ); } return errors; } /** * Creates a single automation * * @param {AutomationItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata) { const uri = '/automation/v1/automations/'; return super.createREST(metadata, uri); } /** * Updates a single automation * * @param {AutomationItem} metadata single metadata entry * @param {AutomationItem} metadataBefore metadata mapped by their keyField * @returns {Promise} Promise */ static update(metadata, metadataBefore) { if (metadataBefore.status === 'Running') { Util.logger.error( ` ☇ error updating ${this.definition.type} ${ metadata[this.definition.keyField] || metadata[this.definition.nameField] } / ${ metadata[this.definition.nameField] }: You cannot update an automation that's currently running. Please wait a bit and retry.` ); return null; } const uri = '/automation/v1/automations/' + metadata.id; return super.updateREST(metadata, uri); } /** * helper for {@link Automation.preDeployTasks} and {@link Automation.execute} * * @param {AutomationItem} metadata metadata mapped by their keyField */ static #preDeploySchedule(metadata) { delete metadata.schedule.rangeTypeId; delete metadata.schedule.pattern; delete metadata.schedule.scheduledTime; delete metadata.schedule.scheduledStatus; if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) { metadata.schedule.timezoneId = this.definition.timeZoneMapping[metadata.schedule.timezoneName]; } else { Util.logger.error( `Could not find timezone ${metadata.schedule.timezoneName} in definition.timeZoneMapping` ); } // the upsert API needs this to be named scheduleTypeId; the retrieve API returns it as typeId metadata.schedule.scheduleTypeId = metadata.schedule.typeId; delete metadata.schedule.typeId; // prep startSource metadata.startSource = { schedule: metadata.schedule, typeId: 1 }; } /** * Gets executed before deploying metadata * * @param {AutomationItem} metadata metadata mapped by their keyField * @returns {Promise.<AutomationItem>} Promise */ static async preDeployTasks(metadata) { if (metadata.notifications) { this.notificationUpdates[metadata.key] = metadata.notifications; } else { const cached = cache.getByKey(this.definition.type, metadata.key); if (cached?.notifications) { // if notifications existed but are no longer present in the deployment package, we need to run an empty update call to remove them this.notificationUpdates[metadata.key] = []; } } if (metadata.type == 'automationtriggered' && metadata.automationTrigger) { const automationTrigger = metadata.automationTrigger; if (automationTrigger.r__fileLocation_name) { automationTrigger.fileTransferLocationId = cache.searchForField( 'fileLocation', automationTrigger.r__fileLocation_name, 'name', 'id' ); delete automationTrigger.r__fileLocation_name; } if ( automationTrigger.fileNamePatternType && typeof automationTrigger.fileNamePatternType === 'string' ) { automationTrigger.fileNamePatternType = this.definition.fileNameOperatorMapping[automationTrigger.fileNamePatternType]; } } if (this.validateDeployMetadata(metadata)) { // folder this.setFolderId(metadata); if (metadata.type === 'scheduled' && metadata?.schedule?.startDate) { // Starting Source == 'Schedule' this.#preDeploySchedule(metadata); // * run _buildSchedule here but only to check if things look ok - do not use the returned schedule object for deploy this._checkSchedule(metadata.schedule); delete metadata.schedule.timezoneName; delete metadata.startSource.schedule.timezoneName; } else if (metadata.type === 'triggered' && metadata.fileTrigger) { // Starting Source == 'File Drop' // prep startSource metadata.startSource = { fileDrop: { fileNamePattern: metadata.fileTrigger.fileNamingPattern, fileNamePatternTypeId: metadata.fileTrigger.fileNamePatternTypeId, folderLocation: metadata.fileTrigger.folderLocationText, queueFiles: metadata.fileTrigger.queueFiles, }, typeId: 2, }; delete metadata.fileTrigger; } delete metadata.schedule; delete metadata.type; let i = 0; if (metadata.steps) { for (const step of metadata.steps) { let displayOrder = 0; for (const activity of step.activities) { activity.displayOrder = ++displayOrder; if ( activity.r__key && this.definition.dependencies.includes(activity.r__type) ) { // automations can have empty placeholder for activities with only their type defined activity.activityObjectId = cache.searchForField( activity.r__type, activity.r__key, Definitions[activity.r__type].keyField, Definitions[activity.r__type].idField ); activity.name = cache.searchForField( activity.r__type, activity.r__key, Definitions[activity.r__type].keyField, Definitions[activity.r__type].nameField ); } if (activity.r__type === 'wait') { const [waitDuration, waitUnit] = activity.name.split(' '); const waitDurationNumber = Number(waitDuration); const allowedWaitUnits = [ 'Minutes', 'Hours', 'Days', 'Weeks', 'Months', 'Years', ]; if ( waitDurationNumber && waitUnit && allowedWaitUnits.includes(waitUnit) ) { // @ts-expect-error - serializedObject is only used to create/update wait activities activity.serializedObject = JSON.stringify({ duration: waitDurationNumber, durationUnits: waitUnit, }); } else if (!waitUnit) { // // convert 24 hrs based time in waitDuration back into 12 hrs based time // let waitTime12 = waitDuration; // waitTime12 = // Number(waitTime12) > 12 // ? (Number(waitTime12) - 12).toString() + ' AM' // : waitTime12 + ' PM'; // @ts-expect-error - serializedObject is only used to create/update wait activities activity.serializedObject = JSON.stringify({ specifiedTime: waitDuration, timeZone: activity.timeZone || 'GMT Standard Time', }); } } activity.objectTypeId = this.definition.activityTypeMapping[activity.r__type]; delete activity.r__key; delete activity.r__type; } step.annotation = step.name; step.stepNumber = i; delete step.name; delete step.step; i++; } } if (!Util.OPTIONS.matchName) { // make sure the name is unique const thisCache = cache.getCache()[this.definition.type]; const relevantNames = Object.keys(thisCache).map((key) => ({ type: null, key: key, name: thisCache[key][this.definition.nameField], })); // if the name is already in the folder for a different key, add a number to the end metadata[this.definition.nameField] = this.findUniqueName( metadata[this.definition.keyField], metadata[this.definition.nameField], relevantNames ); } return metadata; } else { return null; } } /** * Validates the automation to be sure it can be deployed. * Whitelisted Activites are deployed but require configuration * * @param {AutomationItem} metadata single automation record * @returns {boolean} result if automation can be deployed based on steps */ static validateDeployMetadata(metadata) { let deployable = true; const errors = []; if (metadata.steps) { let stepNumber = 0; for (const step of metadata.steps) { stepNumber++; let displayOrder = 0; for (const activity of step.activities) { displayOrder++; // check if manual deploy required. if so then log warning if (this.definition.manualDeployTypes.includes(activity.r__type)) { Util.logger.warn( `- ${this.definition.type} '${metadata.name}' requires additional manual configuration: '${activity.r__key || activity.name}' in step ${stepNumber}.${displayOrder}` ); } // cannot deploy because it is not supported else if ( !this.definition.customDeployTypes.includes(activity.r__type) && !this.definition.dependencies.includes(activity.r__type) ) { errors.push( ` • not supported ${activity.r__type} activity '${activity.r__key || activity.name}' in step ${stepNumber}.${displayOrder}` ); deployable = false; } } } } if (!deployable) { Util.logger.error( ` ☇ skipping ${this.definition.type} ${metadata[this.definition.keyField]} / ${ metadata[this.definition.nameField] }:` ); for (const error of errors) { Util.logger.error(error); } } return deployable; } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @returns {Promise.<void>} - */ static async _postChangeKeyTasks(metadataEntry) { super._postChangeKeyTasks(metadataEntry, true); } /** * Gets executed after deployment of metadata type * * @param {AutomationMap} metadataMap metadata mapped by their keyField * @returns {Promise.<void>} - */ static async postDeployTasks(metadataMap) { for (const key in metadataMap) { const item = metadataMap[key]; const oldKey = Util.changedKeysMap?.[this.definition.type]?.[key] || key; delete Util.changedKeysMap?.[this.definition.type]?.[key]; if (!item.type) { // create response does not return the type attribute if (item.startSource?.schedule) { // rewrite upsert reponse into retrieve format item.schedule = item.startSource.schedule; delete item.startSource; } const scheduleHelper = item.schedule; // el.type item.type = scheduleHelper ? 'scheduled' : item.fileTrigger ? 'triggered' : undefined; // el.schedule.timezoneName if (item.type === 'scheduled') { // not existing for triggered automations scheduleHelper.timezoneName ||= Util.inverseGet( this.definition.timeZoneMapping, scheduleHelper.timezoneId ); } // @ts-expect-error - string vs enum item.status ||= Util.inverseGet(this.definition.statusMapping, item.statusId); } // need to put schedule on here if status is scheduled if (Util.OPTIONS.schedule) { await Automation.#schedulePauseItem( 'schedule', oldKey || key, metadataMap[key]?.legacyId ); } // need to update notifications separately if there are any await Automation.#updateNotificationInfoREST(metadataMap, key); // rewrite upsert to retrieve fields if (item.steps) { for (const step of item.steps) { step.name = step.annotation; delete step.annotation; } } } if (Util.OPTIONS.execute) { Util.logger.info(`Executing: ${this.definition.type}`); await this.execute(Object.keys(metadataMap)); } Util.logger.debug( `Caching all ${this.definition.type} post-deploy to ensure we have all fields` ); // post-deploy re-retrieve // dont use retrieveForCache here because that is simplified for automations const typeCache = await this.retrieve(); // update values in upsertResults with retrieved values before saving to disk for (const key of Object.keys(metadataMap)) { if (typeCache.metadata[key]) { metadataMap[key] = typeCache.metadata[key]; } } } /** * helper for {@link Automation.postDeployTasks} * * @param {AutomationMap} metadataMap metadata mapped by their keyField * @param {string} key current customer key * @returns {Promise.<void>} - */ static async #updateNotificationInfoREST(metadataMap, key) { if (this.notificationUpdates[key]) { // create & update automation calls return programId as 'legacyId'; retrieve does not return it const programId = metadataMap[key]?.legacyId; if (programId) { const notificationBody = { programId, workers: this.notificationUpdates[key].map((notification) => ({ programId, notificationType: notification.type, definition: Array.isArray(notification.email) ? notification.email.join(',') : notification.email, body: notification.message, channelType: 'Account', })), }; try { const result = await this.client.rest.post( '/legacy/v1/beta/automations/notifications/' + programId, notificationBody ); if (result) { // should be empty if all OK throw new Error(result); } } catch (ex) { Util.logger.error( `Error updating notifications for automation '${metadataMap[key].name}': ${ex.message} (${ex.code}))` ); } Util.logger.info( Util.getGrayMsg( ` - updated notifications for automation '${metadataMap[key].name}'` ) ); } } } /** * generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single script activity definition */ static setFolderPath(metadata) { const folderIdField = metadata[this.definition.folderIdField] ? this.definition.folderIdField : 'CategoryID'; try { metadata.r__folder_Path = cache.searchForField( 'folder', metadata[folderIdField], 'ID', 'Path' ); delete metadata[folderIdField]; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find folder (${ex.message})` ); } } /** * Builds a schedule object to be used for scheduling an automation * based on combination of ical string and start/end dates. * * @param {AutomationSchedule} scheduleObject child of automation metadata used for scheduling * @param {boolean} [errorOnNotSchedulable] used if run for schedule command * @returns {void} throws and error in case of problems */ static _checkSchedule(scheduleObject, errorOnNotSchedulable = false) { // build recurrence const recurHelper = {}; // ical values are split by ; then have key values split by = for (const obj of scheduleObject.icalRecur.split(';')) { const a = obj.split('='); recurHelper[a[0]] = a[1]; } if (recurHelper.INTERVAL) { recurHelper.INTERVAL = Number.parseInt(recurHelper.INTERVAL); } if (recurHelper.FREQ === 'MINUTELY' && recurHelper.INTERVAL && recurHelper.INTERVAL < 5) { throw new Error( 'The smallest interval you can configure is 5 minutes. Please adjust your schedule.' ); } if (this.definition.timeZoneMapping[scheduleObject.timezoneName]) { scheduleObject.timezoneId = this.definition.timeZoneMapping[scheduleObject.timezoneName]; } else { throw new Error( `Could not find timezone ${scheduleObject.timezoneName} in definition.timeZoneMapping` ); } if (recurHelper.COUNT == 1) { const timezoneString = this.definition.timeZoneDifference[scheduleObject.timezoneId]; // add tz to input date to ensure Date() creates a date object with the right tz const inputStartDateString = scheduleObject.startDate + timezoneString; if (new Date(inputStartDateString) > new Date()) { const msg = 'The automation will run only once. Please make sure this is intended and that the start date is in the future.'; if (errorOnNotSchedulable) { throw new Error(msg); } else { Util.logger.warn(msg); } } else { const msg = `The automation will run only once but its start date is in the past. While this can be saved, it cannot be scheduled.`; if (errorOnNotSchedulable) { throw new Error(msg); } else { Util.logger.warn(msg); } } } } /** * used to convert dates to the system timezone required for startDate * * @param {number} offsetServer stack4: US Mountain time (UTC-7); other stacks: US Central (UTC-6) * @param {string|Date} dateInput date in ISO format (2021-12-05T20:00:00.983) * @param {string} [offsetInput] timzone difference (+02:00) * @returns {string} date in server */ static _calcTime(offsetServer, dateInput, offsetInput) { // get UTC time in msec const utc = 'string' === typeof dateInput ? new Date(dateInput + offsetInput).getTime() : dateInput.getTime(); // create new Date object reflecting SFMC's servertime const dateServer = new Date(utc + 3600000 * offsetServer); // return time as a string without trailing "Z" and without miliseconds (separated by .) return dateServer.toISOString().slice(0, -1).split('.')[0]; } /** * Experimental: Only working for DataExtensions: * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {AutomationItem} json dataextension * @param {object[][]} tabled prepped array for output in tabular format * @returns {string} file content */ static _generateDocMd(json, tabled) { let output = `## ${json.key}\n\n`; if (json.key !== json.name) { output += `**Name** (not equal to External Key)**:** ${json.name}\n\n`; } output += `**Description:** ${json.description || 'n/a'}\n\n` + `**Folder:** ${ json.r__folder_Path || '_Hidden! Could not find folder with ID ' + json.categoryId + '_' }/\n\n`; const automationType = { scheduled: 'Schedule', triggered: 'File Drop' }; output += `**Started by:** ${automationType[json.type] || 'Not defined'}\n\n`; output += `**Status:** ${json.status}\n\n`; if (json.type === 'scheduled' || json.schedule) { const tz = this.definition.timeZoneDifference[ this.definition.timeZoneMapping[json?.schedule?.timezoneName] ]; if (json.schedule?.icalRecur) { output += `**Schedule:**\n\n`; output += `* Start: ${json.schedule.startDate.split('T').join(' ')} ${tz}\n`; output += `* End: ${json.schedule.endDate.split('T').join(' ')} ${tz}\n`; output += `* Timezone: ${json.schedule.timezoneName}\n`; const ical = {}; for (const item of json.schedule.icalRecur.split(';')) { const temp = item.split('='); ical[temp[0]] = temp[1]; } const frequency = ical.FREQ.slice(0, -2).toLowerCase(); output += `* Recurrence: `; output += ical.COUNT == 1 ? 'run only once' : `every${ical.INTERVAL > 1 ? ' ' + ical.INTERVAL : ''} ${ frequency === 'dai' ? 'day' : frequency }${ical.INTERVAL > 1 ? 's' : ''}${ ical.COUNT ? ` for ${ical.COUNT} times` : ical.UNTIL ? ' until end date' : '' }`; output += '\n'; } else if (json.schedule) { output += `**Schedule:** Not defined\n`; } } else if (json.type === 'triggered' && json.fileTrigger) { output += `**File Trigger:**\n\n`; output += `* Queue Files: ${json.fileTrigger.queueFiles}\n`; output += `* Published: ${json.fileTrigger.isPublished}\n`; output += `* Pattern: ${json.fileTrigger.fileNamingPattern}\n`; output += `* Folder: ${json.fileTrigger.folderLocationText}\n`; } // add empty line to ensure the following notifications are rendered properly output += '\n'; if (json.notifications?.length) { output += `**Notifications:**\n\n`; // ensure notifications are sorted by type regardless of how the API returns it const notifications = {}; for (const n of json.notifications) { notifications[n.type] = (Array.isArray(n.email) ? n.email.join(',') : n.email) + (n.message ? ` ("${n.message}")` : ''); } if (notifications.Complete) { output += `* Complete: ${notifications.Complete}\n`; } if (notifications.Error) { output += `* Error: ${notifications.Error}\n`; } } else { output += `**Notifications:** _none_\n\n`; } // show table with automation steps if (tabled && tabled.length) { // add empty line to ensure the following table is rendered properly output += '\n'; let tableSeparator = ''; const row1 = []; for (const column of tabled[0]) { row1.push( `| ${column.title}${ column.description ? `<br>_<small>${column.description.replaceAll('\n', '<br>')}</small>_` : '' } ` ); tableSeparator += '| --- '; } output += row1.join('') + `|\n${tableSeparator}|\n`; for (let i = 1; i < tabled.length; i++) { for (const activity of tabled[i]) { output += activity ? `| _${activity.i}: ${activity.type}_<br>${activity.key} ` : '| - '; } output += '|\n'; } } return output; } /** * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {string} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {AutomationItem} json dataextension.columns * @param {'html'|'md'} mode html or md * @returns {Promise.<void>} Promise of success of saving the file */ static async _writeDoc(directory, filename, json, mode) { await File.ensureDir(directory); const tabled = []; if (json.steps && json.steps.length) { tabled.push( json.steps.map((step, index) => ({ title: `Step ${index + 1}`, description: step.name || '-', })) ); let maxActivities = 0; for (const step of json.steps) { if (step.activities.length > maxActivities) { maxActivities = step.activities.length; } } for (let activityIndex = 0; activityIndex < maxActivities; activityIndex++) { tabled.push( json.steps.map((step, stepIndex) => step.activities[activityIndex] ? { i: stepIndex + 1 + '.' + (activityIndex + 1), key: step.activities[activityIndex].r__key || (step.activities[activityIndex].timeZone ? `${step.activities[activityIndex].name}<br>${step.activities[activityIndex].timeZone}` : step.activities[activityIndex].name), type: step.activities[activityIndex].r__type, } : null ) ); } } let output; if (mode === 'md') { output = this._generateDocMd(json, tabled); try { // write to disk await File.writeToFile(directory, filename + '.automation-doc', mode, output); } catch (ex) { Util.logger.error(`Automation.writeDeToX(${mode}):: error | ` + ex.message); } } } /** * Parses metadata into a readable Markdown/HTML format then saves it * * @param {AutomationMap} [metadata] a list of dataExtension definitions * @returns {Promise.<void>} - */ static async document(metadata) { if (['md', 'both'].includes(this.properties.options.documentType)) { if (!metadata) { metadata = ( await this.readBUMetadataForType( File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, ]), true ) ).automation; } const docPath = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); if (!metadata || !Object.keys(metadata).length) { // as part of retrieve & manual execution we could face an empty folder return; } const docLimit = pLimit(100); await Promise.all( Object.keys(metadata).map((key) => docLimit(() => this._writeDoc(docPath + '/', key, metadata[key], 'md')) ) ); } } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { if (this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)) { // document automation is active. assume we want to commit the MD file as well const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-doc.md`]), ]); return fileList; } else { // document automation is not active upon retrieve, run default method instead return super.getFilesToCommit(keyArr); } } /** * helper to allow us to select single metadata entries via REST * * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static async #getObjectIdForSingleRetrieve(key) { const response = await this.client.soap.retrieve('Program', ['ObjectID'], { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }); return response?.Results?.length ? response.Results[0].ObjectID : null; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(key) { // the delete endpoint returns a general exception if the automation does not exist; handle it gracefully instead by adding a retrieve first const objectId = key ? await this.#getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeySOAP(key, 'CustomerKey'); } /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static async postDeleteTasks(customerKey) { // delete local copy: retrieve/cred/bu/.../...-meta.json // delete local copy: retrieve/cred/bu/.../...-doc.md await super.postDeleteTasks(customerKey, [`${this.definition.type}-doc.md`]); } /** * helper for {@link MetadataType.getNestedValue} - adjusted for automation activities * * @param {any} obj the metadataItem to search in (or the result) * @param {string[]} nestedKeyParts key in dot-notation split into parts * @param {string} dependentType used for types that need custom handling * @returns {(string) | (string)[]} result */ static getNestedValueHelper(obj, nestedKeyParts, dependentType) { if (nestedKeyParts.length == 0) { // key was found; append '' to ensure we always return a string return obj + ''; } // get most left key const key = nestedKeyParts.shift(); if (!obj[key]) { // key was not found return; } if (Array.isArray(obj[key])) { return obj[key].flatMap((x) => this.getNestedValueHelper(x, [...nestedKeyParts], dependentType) ); } else { if (nestedKeyParts.length == 0) { // key was found if length is 0 and search field (r__type) is equal the current type, else, keep going return obj[key] === dependentType ? obj.r__key : undefined; } else { return this.getNestedValueHelper(obj[key], [...nestedKeyParts], dependentType); } } } } // Assign definition to static attributes Automation.definition = Definitions.automation; export default Automation; ================================================ FILE: lib/metadataTypes/Campaign.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * Campaign MetadataType * * @augments MetadataType */ class Campaign extends MetadataType { /** * Retrieves Metadata of campaigns. Afterwards, starts metadata retrieval for their campaign assets * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { const res = await super.retrieveREST( retrieveDir, '/legacy/v1/beta2/data/campaign/', null, key ); // get assignments Util.logger.info(`Retrieving: campaignAsset`); const campaignAssets = await Promise.all( Object.keys(res.metadata).map((key) => this.getAssetTags(retrieveDir, res.metadata[key].campaignId, key) ) ); Util.logger.info( `Downloaded: campaignAsset (${campaignAssets.flat().length})` + Util.getKeysString(key) ); return res; } /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache() { return super.retrieveREST(null, '/legacy/v1/beta2/data/campaign/'); } /** * Parses campaign asset response body and returns metadata entries mapped to their id * * @param {string} retrieveDir folder where to save * @param {string} campaignId of camapaign to retrieve * @param {string} name of camapaign for saving * @returns {Promise.<MetadataTypeMapObj>} Campaign Asset Object */ static async getAssetTags(retrieveDir, campaignId, name) { const res = await this.client.rest.getBulk(`/hub/v1/campaigns/${campaignId}/assets`); for (const asset of res.items) { await File.writeJSONToFile( `${retrieveDir}/campaign/${name}/assets/`, asset.id + '.campaignAsset-meta', asset ); } return res.items; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Campaign.definition = MetadataTypeDefinitions.campaign; export default Campaign; ================================================ FILE: lib/metadataTypes/ContentArea.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ContentArea MetadataType * * @augments MetadataType */ class ContentArea extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { Util.logger.warn( ' - Classic Content Areas are deprecated and will be discontinued by SFMC in the near future. Ensure that you migrate any existing Content Areas to Content Builder as soon as possible.' ); /** @type {SoapRequestParams} */ let requestParams = null; if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } // !dont activate `await File.initPrettier('html');` as we only want to retrieve for migration and formatting might mess with the outcome return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single script activity definition */ static setFolderPath(metadata) { try { metadata.r__folder_Path = cache.searchForField( 'folder', metadata[this.definition.folderIdField], 'ID', 'Path' ); delete metadata[this.definition.folderIdField]; } catch (ex) { Util.logger.debug( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find folder (${ex.message})` ); // classic content blocks that reside in the main folder are // saved with CategoryID=0, instead of to the actual ID of // their parent root folder. metadata.r__folder_Path = 'my contents'; } } /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed item */ static postRetrieveTasks(metadata) { // folder this.setFolderPath(metadata); // extract code const codeArr = [ { subFolder: null, fileName: metadata.CustomerKey, fileExt: 'html', content: metadata.Content, }, ]; delete metadata.Content; return { json: metadata, codeArr: codeArr, subFolder: null }; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; ContentArea.definition = MetadataTypeDefinitions.contentArea; export default ContentArea; ================================================ FILE: lib/metadataTypes/DataExtension.js ================================================ 'use strict'; import jsonToTable from 'json-to-table'; import MetadataType from './MetadataType.js'; import AttributeSet from './AttributeSet.js'; import DataExtensionField from './DataExtensionField.js'; import Folder from './Folder.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import auth from '../util/auth.js'; import cache from '../util/cache.js'; import pLimit from 'p-limit'; import { checkbox } from '@inquirer/prompts'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldItem} DataExtensionFieldItem * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldMap} DataExtensionFieldMap * @typedef {import('../../types/mcdev.d.js').DataExtensionItem} DataExtensionItem * @typedef {import('../../types/mcdev.d.js').DataExtensionMap} DataExtensionMap */ /** * DataExtension MetadataType * * @augments MetadataType */ class DataExtension extends MetadataType { /** @type {Object.<string, DataExtensionFieldMap>} key: deKey, value: deFieldMap */ static oldFields; /** * Upserts dataExtensions after retrieving them from source and target to compare * if create or update operation is needed. * * @param {DataExtensionMap} metadataMap dataExtensions mapped by their customerKey * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<MetadataTypeMap>} keyField => metadata map */ static async upsert(metadataMap, deployDir) { /** @type {object[]} */ const metadataToCreate = []; /** @type {object[]} */ const metadataToUpdate = []; let filteredByPreDeploy = 0; for (const metadataKey in metadataMap) { try { metadataMap[metadataKey] = await this.validation( 'deploy', metadataMap[metadataKey], deployDir ); if (!metadataMap[metadataKey]) { filteredByPreDeploy++; continue; } metadataMap[metadataKey] = await this.preDeployTasks(metadataMap[metadataKey]); await this.createOrUpdate( metadataMap, metadataKey, false, metadataToUpdate, metadataToCreate ); } catch (ex) { // output error & remove from deploy list Util.logger.error( ` ☇ skipping ${this.definition.type} ${ metadataMap[metadataKey][this.definition.keyField] } / ${metadataMap[metadataKey][this.definition.nameField]}: ${ex.message}` ); delete metadataMap[metadataKey]; // skip rest of handling for this DE filteredByPreDeploy++; continue; } } const createLimit = pLimit(10); const createResults = ( await Promise.allSettled( metadataToCreate .filter((r) => r !== undefined && r !== null) .map((metadataEntry) => createLimit(() => this.create(metadataEntry))) ) ) .filter((r) => r !== undefined && r !== null) .filter(this.#filterUpsertResults); if (Util.OPTIONS.noUpdate && metadataToUpdate.length > 0) { Util.logger.info( ` ☇ skipping update of ${metadataToUpdate.length} ${this.definition.type}${metadataToUpdate.length == 1 ? '' : 's'}: --noUpdate flag is set` ); } const updateLimit = pLimit(10); const updateResults = Util.OPTIONS.noUpdate ? [] : ( await Promise.allSettled( metadataToUpdate .filter((r) => r !== undefined && r !== null) .map((metadataEntry) => updateLimit(() => this.update(metadataEntry.after)) ) ) ) .filter((r) => r !== undefined && r !== null) .filter(this.#filterUpsertResults); const successfulResults = [...createResults, ...updateResults]; Util.logger.info( `${this.definition.type} upsert: ${createResults.length} of ${metadataToCreate.length} created / ${updateResults.length} of ${metadataToUpdate.length} updated` + (filteredByPreDeploy > 0 ? ` / ${filteredByPreDeploy} filtered` : '') ); let upsertResults; if (successfulResults.length > 0) { const metadataResults = successfulResults .map((r) => (r.status === 'fulfilled' ? r.value.Results[0].Object : null)) .filter(Boolean) .map((r) => { // if only one fields added will return object otherwise array if (Array.isArray(r?.Fields?.Field)) { r.Fields = r.Fields.Field; } else if (r?.Fields?.Field) { r.Fields = [r.Fields.Field]; } return r; }); upsertResults = super.parseResponseBody({ Results: metadataResults }); } else { upsertResults = {}; } await this.postDeployTasks(upsertResults, metadataMap, { created: createResults.length, updated: updateResults.length, }); return upsertResults; } /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadataMap list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create * @returns {Promise.<'create'|'update'|'skip'>} action to take */ static async createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ) { const action = await super.createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ); if (action === 'update') { // Update dataExtension + Columns if they already exist; Create them if not // Modify columns for update call DataExtensionField.client = this.client; DataExtensionField.properties = this.properties; DataExtensionField.buObject = this.buObject; DataExtension.oldFields ||= {}; DataExtension.oldFields[metadataMap[metadataKey][this.definition.keyField]] = await DataExtensionField.prepareDeployColumnsOnUpdate( metadataMap[metadataKey].Fields, Util.matchedByName?.[this.definition.type]?.[metadataKey] || metadataKey ); if ( metadataMap[metadataKey][this.definition.keyField] !== metadataKey && metadataMap[metadataKey].Fields.length ) { // changeKeyValue / changeKeyField used Util.logger.warn( ` - ${this.definition.type} ${metadataKey}: Cannot change fields while updating the key. Skipping field update in favor of key update.` ); metadataMap[metadataKey].Fields.length = 0; } // convert simple array into object.Array.object format to cope with how the XML body in the SOAP call needs to look like: // <Fields> // <Field> // <CustomerKey>SubscriberKey</CustomerKey> // .. // </Field> // </Fields> metadataMap[metadataKey].Fields = { Field: metadataMap[metadataKey].Fields }; } else if (action === 'create') { this.#cleanupRetentionPolicyFields(metadataMap[metadataKey]); // convert simple array into object.Array.object format to cope with how the XML body in the SOAP call needs to look like: // <Fields> // <Field> // <CustomerKey>SubscriberKey</CustomerKey> // .. // </Field> // </Fields> metadataMap[metadataKey].Fields = { Field: metadataMap[metadataKey].Fields }; } return action; } /** * helper for {@link DataExtension.upsert} * * @param {object} res - * @returns {boolean} true: keep, false: discard */ static #filterUpsertResults(res) { if (res.status === 'rejected') { // promise rejects, whole request failed Util.logger.error('- error upserting dataExtension: ' + res.reason); return false; } else if (res.value == undefined || Object.keys(res.value).length === 0) { // in case of returning empty result handle gracefully // TODO: consider if SOAP handler for this should really return empty object return false; } else if (res.value.results) { Util.logger.error( '- error upserting dataExtension: ' + (res.value.Results[0].Object ? res.value.Results[0].Object.Name : '') + '. ' + res.value.Results[0].StatusMessage ); return false; } else if (res.status === 'fulfilled' && res?.value?.faultstring) { // can happen that the promise does not reject, but that it resolves an error Util.logger.error('- error upserting dataExtension: ' + res.value.faultstring); return false; } else { return true; } } /** * Create a single dataExtension. Also creates their columns in 'dataExtension.columns' * * @param {DataExtensionItem} metadata single metadata entry * @returns {Promise} Promise */ static async create(metadata) { return super.createSOAP(metadata); } /** * SFMC saves a date in "RetainUntil" under certain circumstances even * if that field duplicates whats in the period fields * during deployment, that extra value is not accepted by the APIs which is why it needs to be removed * * @param {DataExtensionItem} metadata single metadata entry * @returns {void} */ static #cleanupRetentionPolicyFields(metadata) { if ( metadata.DataRetentionPeriodLength && metadata.DataRetentionPeriodUnitOfMeasure && metadata.RetainUntil !== '' ) { metadata.RetainUntil = ''; Util.logger.warn( ` - RetainUntil date was reset automatically because RetentionPeriod info was found in: ${metadata.CustomerKey}` ); } } /** * Updates a single dataExtension. Also updates their columns in 'dataExtension.columns' * * @param {DataExtensionItem} metadata single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise} Promise */ static async update(metadata, handleOutside) { return super.updateSOAP(metadata, handleOutside); } /** * Gets executed after deployment of metadata type * * @param {DataExtensionMap} upsertedMetadata metadata mapped by their keyField * @param {DataExtensionMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static async postDeployTasks(upsertedMetadata, originalMetadata, createdUpdated) { for (const key in upsertedMetadata) { const item = upsertedMetadata[key]; const oldKey = Util.changedKeysMap?.[this.definition.type]?.[key] || key; delete Util.changedKeysMap?.[this.definition.type]?.[key]; const cachedVersion = createdUpdated.updated ? cache.getByKey(this.definition.type, key) : null; if (cachedVersion) { // UPDATE const existingFields = DataExtension.oldFields[item[this.definition.keyField]]; // @ts-expect-error Fields is a special case that cannot be properly typed; emtpy string is required for SOAP API if (item.Fields === '') { // if no fields were updated, we need to set Fields to "empty string" for the API to work // reset here to get the correct field list item.Fields = Object.keys(existingFields) .map((el) => existingFields[el]) .toSorted((a, b) => a.Ordinal - b.Ordinal); } else if (existingFields) { // get list of updated fields /** @type {DataExtensionFieldItem[]} */ // @ts-ignore Fields.Field is a special case that cannot be properly typed; only required for SOAP API const updatedFieldsArr = originalMetadata[oldKey].Fields.Field.filter( (field) => field.ObjectID && field.ObjectID !== '' ); // convert existing fields obj into array and sort /** @type {DataExtensionFieldItem[]} */ const finalFieldsArr = Object.keys(existingFields) .map((el) => { /** @type {DataExtensionFieldItem} */ const existingField = existingFields[el]; // check if the current field was updated and then override with it. otherwise use existing value const field = updatedFieldsArr.find( (field) => field.ObjectID === existingField.ObjectID ) || existingField; // field does not have a ordinal value because we rely on array order field.Ordinal = existingField.Ordinal; // updating FieldType is not supported by API and hence removed field.FieldType = existingField.FieldType; return field; }) .toSorted((a, b) => a.Ordinal - b.Ordinal); // get list of new fields /** @type {DataExtensionFieldItem[]} */ // @ts-ignore Fields.Field is a special case that cannot be properly typed; only required for SOAP API const newFieldsArr = originalMetadata[oldKey].Fields.Field.filter( (field) => !field.ObjectID ); // push new fields to end of list if (newFieldsArr.length) { finalFieldsArr.push(...newFieldsArr); } // sort Fields entry to the end of the object for saving in .json delete item.Fields; item.Fields = finalFieldsArr; } } // UPDATE + CREATE for (const field of item.Fields) { DataExtensionField.postRetrieveTasksDE(field); } } await this.#fixShared(upsertedMetadata, originalMetadata, createdUpdated); } /** * takes care of updating attribute groups on child BUs after an update to Shared DataExtensions * helper for {@link DataExtension.postDeployTasks} * fixes an issue where shared data extensions are not visible in data designer on child BU; SF known issue: https://issues.salesforce.com/#q=W-11031095 * * @param {DataExtensionMap} upsertedMetadata metadata mapped by their keyField * @param {DataExtensionMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static async #fixShared(upsertedMetadata, originalMetadata, createdUpdated) { if (this.buObject.eid !== this.buObject.mid) { // only if we were executing a deploy on parent bu could we be deploying shared data extensions Util.logger.debug(`Skipping fixShared logic because we are not executing on Parent BU`); return; } if (createdUpdated.updated === 0) { // only if updates were made could the issue in https://issues.salesforce.com/#q=W-11031095 affect data designer Util.logger.debug(`Skipping fixShared logic because nothing was updated`); return; } // find all shared data extensions if (!this.deployedSharedKeys?.length) { Util.logger.debug( `Skipping fixShared logic because no Shared Data Extensions were updated` ); return; } const sharedDataExtensionsKeys = this.deployedSharedKeys; this.deployedSharedKeys = null; if (Util.OPTIONS.fixShared) { // select which BUs to run this for const selectedBuNames = await this.#fixShared_getBUs(); // backup settings const buObjectBak = this.buObject; const clientBak = this.client; // get dataExtension ID-Key relationship /** @type {Object.<string, string>} */ const sharedDataExtensionMap = {}; for (const key of sharedDataExtensionsKeys) { try { const id = cache.searchForField( 'dataExtension', key, 'CustomerKey', 'ObjectID', this.buObject.eid ); sharedDataExtensionMap[id] = key; } catch { continue; } } // run the fix-data-model logic Util.logger.info( `Fixing Shared Data Extensions details in data models of child BUs` + Util.getKeysString(sharedDataExtensionsKeys) ); for (const buName of selectedBuNames) { await this.#fixShared_onBU(buName, buObjectBak, clientBak, sharedDataExtensionMap); } Util.logger.info(`Finished fixing Shared Data Extensions details in data models`); // restore settings this.buObject = buObjectBak; this.client = clientBak; } else { Util.logger.warn( 'Shared Data Extensions were updated but --fixShared option is not set. This can result in your changes not being visible in attribute groups on child BUs.' ); Util.logger.info( 'We recommend to re-run your deployment with the --fixShared option unless you are sure your Shared Data Extension is not used in attribute groups on any child BU.' ); } } /** * helper for {@link DataExtension.#fixShared} * * @returns {Promise.<string[]>} list of selected BU names */ static async #fixShared_getBUs() { const buListObj = this.properties.credentials[this.buObject.credential].businessUnits; const fixBuPreselected = []; const availableBuNames = Object.keys(buListObj).filter( (buName) => buName !== Util.parentBuName ); if (typeof Util.OPTIONS.fixShared === 'string') { if (Util.OPTIONS.fixShared === '*') { // pre-select all BUs fixBuPreselected.push(...availableBuNames); } else { // pre-select BUs from comma-separated list fixBuPreselected.push( ...Util.OPTIONS.fixShared .split(',') .filter(Boolean) .map((bu) => bu.trim()) .filter((bu) => availableBuNames.includes(bu)) ); } } if (Util.skipInteraction && fixBuPreselected.length) { // assume programmatic use case or user that wants to skip the wizard. Use pre-selected BUs return fixBuPreselected; } const buList = availableBuNames.map((name) => ({ name, value: name, checked: fixBuPreselected.includes(name), })); let answer = null; try { answer = await checkbox({ message: 'Please select BUs that have access to the updated Shared Data Extensions:', pageSize: 10, choices: buList, }); } catch (ex) { Util.logger.info(ex); } return answer; } /** * helper for {@link DataExtension.#fixShared} * * @param {string} childBuName name of child BU to fix * @param {BuObject} buObjectParent bu object for parent BU * @param {object} clientParent SDK for parent BU * @param {Object.<string, string>} sharedDataExtensionMap ID-Key relationship of shared data extensions * @returns {Promise.<string[]>} updated shared DE keys on BU */ static async #fixShared_onBU( childBuName, buObjectParent, clientParent, sharedDataExtensionMap ) { /** @type {BuObject} */ const buObjectChildBu = { eid: this.properties.credentials[buObjectParent.credential].eid, mid: this.properties.credentials[buObjectParent.credential].businessUnits[childBuName], businessUnit: childBuName, credential: this.buObject.credential, }; const clientChildBu = auth.getSDK(buObjectChildBu); try { // check if shared data Extension is used in an attributeSet on current BU AttributeSet.properties = this.properties; AttributeSet.buObject = buObjectChildBu; AttributeSet.client = clientChildBu; const sharedDeIdsUsedOnBU = await AttributeSet.fixShared_retrieve( sharedDataExtensionMap, DataExtensionField.fixShared_fields ); if (sharedDeIdsUsedOnBU.length) { let sharedDataExtensionsKeys = sharedDeIdsUsedOnBU.map( (deId) => sharedDataExtensionMap[deId] ); Util.logger.info( ` - Fixing dataExtensions on BU ${childBuName} ` + Util.getKeysString(sharedDataExtensionsKeys) ); for (const deId of sharedDeIdsUsedOnBU) { // dont use Promise.all to ensure order of execution; otherwise, switched BU contexts in one step will affect the next const fixed = await this.#fixShared_item( deId, sharedDataExtensionMap[deId], buObjectChildBu, clientChildBu, buObjectParent, clientParent ); if (!fixed) { // remove from list of shared DEs that were fixed sharedDataExtensionsKeys = sharedDataExtensionsKeys.filter( (key) => key !== sharedDataExtensionMap[deId] ); } } if (sharedDataExtensionsKeys.length) { Util.logger.debug( ` - Fixed ${sharedDataExtensionsKeys.length}/${ sharedDeIdsUsedOnBU.length }: ${sharedDataExtensionsKeys.join(', ')}` ); } return sharedDataExtensionsKeys; } else { Util.logger.info( Util.getGrayMsg( ` - No matching attributeSet found for given Shared Data Extensions keys found on BU ${childBuName}` ) ); return []; } } catch (ex) { Util.logger.error(ex.message); return []; } } /** * method that actually takes care of triggering the update for a particular BU-sharedDe combo * helper for {@link DataExtension.#fixShared_onBU} * * @param {string} deId data extension ObjectID * @param {string} deKey dataExtension key * @param {BuObject} buObjectChildBu BU object for Child BU * @param {object} clientChildBu SDK for child BU * @param {BuObject} buObjectParent BU object for Parent BU * @param {object} clientParent SDK for parent BU * @returns {Promise.<boolean>} flag that signals if the fix was successful */ static async #fixShared_item( deId, deKey, buObjectChildBu, clientChildBu, buObjectParent, clientParent ) { try { // add field via child BU const randomSuffix = await DataExtension.#fixShared_item_addField( buObjectChildBu, clientChildBu, deKey, deId ); // get field ID from parent BU (it is not returned on child BU) const fieldObjectID = await DataExtension.#fixShared_item_getFieldId( randomSuffix, buObjectParent, clientParent, deKey ); // delete field via child BU await DataExtension.#fixShared_item_deleteField( randomSuffix, buObjectChildBu, clientChildBu, deKey, fieldObjectID ); Util.logger.info( ` - Fixed dataExtension ${deKey} on BU ${buObjectChildBu.businessUnit}` ); return true; } catch (ex) { Util.logger.error( `- error fixing dataExtension ${deKey} on BU ${buObjectChildBu.businessUnit}: ${ex.message}` ); return false; } } /** * add a new field to the shared DE to trigger an update to the data model * helper for {@link DataExtension.#fixShared_item} * * @param {BuObject} buObjectChildBu BU object for Child BU * @param {object} clientChildBu SDK for child BU * @param {string} deKey dataExtension key * @param {string} deId dataExtension ObjectID * @returns {Promise.<string>} randomSuffix */ static async #fixShared_item_addField(buObjectChildBu, clientChildBu, deKey, deId) { this.buObject = buObjectChildBu; this.client = clientChildBu; const randomSuffix = Util.OPTIONS._runningTest ? '_randomNumber_' : Math.floor(Math.random() * 9999999999).toString(); // add a new field to the shared DE to trigger an update to the data model const soapType = this.definition.soapType || this.definition.type; const payload = { CustomerKey: deKey, ObjectID: deId, Fields: { Field: [ { Name: 'TriggerUpdate' + randomSuffix, IsRequired: false, IsPrimaryKey: false, FieldType: 'Boolean', ObjectID: null, }, ], }, }; await this.client.soap.update(Util.capitalizeFirstLetter(soapType), payload, null); return randomSuffix; } /** * get ID of the field added by {@link DataExtension.#fixShared_item_addField} on the shared DE via parent BU * helper for {@link DataExtension.#fixShared_item} * * @param {string} randomSuffix - * @param {BuObject} buObjectParent BU object for Parent BU * @param {object} clientParent SDK for parent BU * @param {string} deKey dataExtension key * @returns {Promise.<string>} fieldObjectID */ static async #fixShared_item_getFieldId(randomSuffix, buObjectParent, clientParent, deKey) { DataExtensionField.buObject = buObjectParent; DataExtensionField.client = clientParent; const fieldKey = `[${deKey}].[TriggerUpdate${randomSuffix}]`; const fieldResponse = await DataExtensionField.retrieveForCacheDE( { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: fieldKey, }, }, ['Name', 'ObjectID'] ); const fieldObjectID = fieldResponse.metadata[fieldKey]?.ObjectID; return fieldObjectID; } /** * delete the field added by {@link DataExtension.#fixShared_item_addField} * helper for {@link DataExtension.#fixShared_item} * * @param {string} randomSuffix - * @param {BuObject} buObjectChildBu BU object for Child BU * @param {object} clientChildBu SDK for child BU * @param {string} deKey dataExtension key * @param {string} fieldObjectID field ObjectID * @returns {Promise} - */ static async #fixShared_item_deleteField( randomSuffix, buObjectChildBu, clientChildBu, deKey, fieldObjectID ) { DataExtensionField.buObject = buObjectChildBu; DataExtensionField.client = clientChildBu; await DataExtensionField.deleteByKeySOAP( deKey + '.TriggerUpdate' + randomSuffix, fieldObjectID ); } /** * Retrieves dataExtension metadata. Afterwards starts retrieval of dataExtensionColumn metadata retrieval * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {void | string[]} [_] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: DataExtensionMap, type: string}>} Promise of item map */ static async retrieve(retrieveDir, additionalFields, _, key) { /** @type {SoapRequestParams} */ let requestParams = null; /** @type {SoapRequestParams} */ let fieldOptions = null; if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; fieldOptions = { filter: { leftOperand: 'DataExtension.CustomerKey', operator: 'equals', rightOperand: key, }, }; } let metadataMap = await this._retrieveAll(additionalFields, requestParams); // in case of cache dont get fields if (metadataMap && retrieveDir) { // get fields from API await this.attachFields(metadataMap, fieldOptions, additionalFields); } if (!retrieveDir && this.buObject.eid !== this.buObject.mid) { const metadataParentBu = await this.retrieveSharedForCache(additionalFields); // make sure to overwrite parent bu DEs with local ones metadataMap = { ...metadataParentBu, ...metadataMap }; } if (retrieveDir) { const savedMetadata = await super.saveResults(metadataMap, retrieveDir, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(key) ); if (Object.keys(savedMetadata).length > 0) { await this.runDocumentOnRetrieve(key, savedMetadata); } else if (key) { this.postDeleteTasks(key); } } return { metadata: metadataMap, type: 'dataExtension' }; } /** * get shared dataExtensions from parent BU and merge them into the cache * helper for {@link DataExtension.retrieve} and for AttributeSet.fixShared_retrieve * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<DataExtensionMap>} keyField => metadata map */ static async retrieveSharedForCache(additionalFields = []) { // for caching, we want to retrieve shared DEs as well from the instance parent BU Util.logger.info(' - Caching dependent Metadata: dataExtension (shared via _ParentBU_)'); const buObjectBak = this.buObject; const clientBak = this.client; /** @type {BuObject} */ const buObjectParentBu = { eid: this.properties.credentials[this.buObject.credential].eid, mid: this.properties.credentials[this.buObject.credential].eid, businessUnit: Util.parentBuName, credential: this.buObject.credential, }; try { this.buObject = buObjectParentBu; this.client = auth.getSDK(buObjectParentBu); } catch (ex) { Util.logger.error(ex.message); return; } const metadataParentBu = await this._retrieveAll(additionalFields); // get shared folders to match our shared / synched Data Extensions const subTypeArr = this.definition.dependencies .filter((item) => item.startsWith('folder-')) .map((item) => item.slice(7)) .filter((item) => Folder.definition.folderTypesFromParent.includes(item)); Util.logger.info(' - Caching dependent Metadata: folder (shared via _ParentBU_)'); Util.logSubtypes(subTypeArr, ' '); Folder.client = this.client; Folder.buObject = this.buObject; Folder.properties = this.properties; const result = await Folder.retrieveForCache(null, subTypeArr); cache.mergeMetadata('folder', result.metadata, this.buObject.eid); // get the types and clean out non-shared ones const folderTypesFromParent = MetadataTypeDefinitions.folder.folderTypesFromParent; for (const metadataEntry in metadataParentBu) { try { // get the data extension type from the folder const folderContentType = cache.searchForField( 'folder', metadataParentBu[metadataEntry].CategoryID, 'ID', 'ContentType', this.buObject.eid ); if (!folderTypesFromParent.includes(folderContentType)) { // Util.logger.verbose( // `removing ${metadataEntry} because r__folder_ContentType '${folderContentType}' identifies this DE as not being shared` // ); delete metadataParentBu[metadataEntry]; } } catch (ex) { Util.logger.debug( `removing dataExtension ${metadataEntry} because of error while retrieving r__folder_ContentType: ${ex.message}` ); delete metadataParentBu[metadataEntry]; } } // revert client to current default this.client = clientBak; this.buObject = buObjectBak; Folder.client = clientBak; Folder.buObject = buObjectBak; return metadataParentBu; } /** * helper to retrieve all dataExtension fields and attach them to the dataExtension metadata * * @param {DataExtensionMap} metadata already cached dataExtension metadata * @param {SoapRequestParams} [fieldOptions] optionally filter results * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<void>} - */ static async attachFields(metadata, fieldOptions, additionalFields) { const fieldsObj = await this._retrieveFields(fieldOptions, additionalFields); const fieldKeys = Object.keys(fieldsObj); // add fields to corresponding DE for (const key of fieldKeys) { const field = fieldsObj[key]; if (metadata[field?.DataExtension?.CustomerKey]) { metadata[field.DataExtension.CustomerKey].Fields.push(field); } else { // field was retrieved for which we do not have the right dataExtension. This might be due to us having to resort to not using a DE filter to avoid the "String or binary data would be truncated." error } } // sort fields by Ordinal value (API returns field unsorted) for (const metadataEntry in metadata) { metadata[metadataEntry].Fields.sort(DataExtensionField.sortDeFields); } // remove attributes that we do not want to retrieve // * do this after sorting on the DE's field list for (const key of fieldKeys) { DataExtensionField.postRetrieveTasksDE(fieldsObj[key]); } } /** * Retrieves dataExtension metadata. Afterwards starts retrieval of dataExtensionColumn metadata retrieval * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<{metadata: DataExtensionMap, type: string}>} Promise of item map */ static async retrieveChangelog(additionalFields) { const metadata = await this._retrieveAll(additionalFields); return { metadata: metadata, type: 'dataExtension' }; } /** * manages post retrieve steps * * @param {DataExtensionItem} metadata a single dataExtension * @returns {Promise.<DataExtensionItem>} metadata */ static async postRetrieveTasks(metadata) { // Error during deploy if SendableSubscriberField.Name = '_SubscriberKey' even though it is retrieved like that // Therefore map it to 'Subscriber Key'. Retrieving afterward still results in '_SubscriberKey' if (metadata.SendableSubscriberField?.Name === '_SubscriberKey') { metadata.SendableSubscriberField.Name = 'Subscriber Key'; } this.setFolderPath(metadata); // DataExtensionTemplate if (metadata.Template?.CustomerKey) { try { metadata.r__dataExtensionTemplate_name = cache.searchForField( 'dataExtensionTemplate', metadata.Template.CustomerKey, 'CustomerKey', 'Name' ); delete metadata.Template; } catch (ex) { Util.logger.debug(ex.message); // Let's allow retrieving such DEs but warn that they cannot be deployed to another BU. // Deploying to same BU still works! // A workaround exists but it's likely not beneficial to explain to users: // Create a DE based on the not-supported template on the target BU, retrieve it, copy the Template.CustomerKey into the to-be-deployed DE (or use mcdev-templating), done Util.logger.warn( ` - Issue with dataExtension '${ metadata[this.definition.nameField] }': Could not find specified DataExtension Template. Please note that DataExtensions based on SMSMessageTracking and SMSSubscriptionLog cannot be deployed automatically across BUs at this point.` ); } } // remove the date fields manually here because we need them in the changelog but not in the saved json delete metadata.CreatedDate; delete metadata.ModifiedDate; // Retention policy if ( metadata.RowBasedRetention === false && metadata.DeleteAtEndOfRetentionPeriod === false && metadata.RetainUntil === '' ) { // Note: RetainUntil expected to NOT have a value metadata.c__retentionPolicy = 'none'; delete metadata.RetainUntil; delete metadata.ResetRetentionPeriodOnImport; } else if ( metadata.RowBasedRetention === false && metadata.DeleteAtEndOfRetentionPeriod === false ) { // Note: RetainUntil expected to have a value metadata.c__retentionPolicy = 'allRecordsAndDataextension'; } else if ( metadata.RowBasedRetention === false && metadata.DeleteAtEndOfRetentionPeriod === true ) { // Note: RetainUntil expected to have a value metadata.c__retentionPolicy = 'allRecords'; } else if ( metadata.RowBasedRetention === true && metadata.DeleteAtEndOfRetentionPeriod === false ) { // Note: RetainUntil expected to NOT have a value metadata.c__retentionPolicy = 'individialRecords'; delete metadata.RetainUntil; } delete metadata.RowBasedRetention; delete metadata.DeleteAtEndOfRetentionPeriod; if (metadata.RetainUntil) { const retainUntil = new Date(metadata.RetainUntil); metadata.c__retainUntil = `${retainUntil.getFullYear()}-${retainUntil.getMonth() + 1}-${retainUntil.getDate()}`; } delete metadata.RetainUntil; if (metadata.DataRetentionPeriodUnitOfMeasure) { metadata.c__dataRetentionPeriodUnitOfMeasure = Util.inverseGet( this.definition.dataRetentionPeriodUnitOfMeasureMapping, metadata.DataRetentionPeriodUnitOfMeasure ); delete metadata.DataRetentionPeriodUnitOfMeasure; } return metadata; } /** * Helper to retrieve Data Extension Fields * * @private * @param {SoapRequestParams} [options] options (e.g. continueRequest) * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<DataExtensionFieldMap>} Promise of items */ static async _retrieveFields(options, additionalFields) { if (!options) { // dont print this during updates or templating which retrieves fields DE-by-DE Util.logger.info(' - Caching dependent Metadata: dataExtensionField'); } DataExtensionField.client = this.client; DataExtensionField.properties = this.properties; const response = await DataExtensionField.retrieveForCacheDE(options, additionalFields); return response.metadata; } /** * helps retrieving fields during templating and deploy where we dont want the full list * * @private * @param {DataExtensionMap} metadata list of DEs * @param {string} customerKey external key of single DE * @returns {Promise.<void>} - */ static async _retrieveFieldsForSingleDe(metadata, customerKey) { /** @type {SoapRequestParams} */ const fieldOptions = { filter: { leftOperand: 'DataExtension.CustomerKey', operator: 'equals', rightOperand: customerKey, }, }; const fieldsObj = await this._retrieveFields(fieldOptions); DataExtensionField.client = this.client; DataExtensionField.properties = this.properties; const fieldArr = DataExtensionField.convertToSortedArray(fieldsObj); // remove attributes that we do not want to retrieve // * do this after sorting on the DE's field list for (const field of fieldArr) { DataExtensionField.postRetrieveTasksDE(field); } metadata[customerKey].Fields = fieldArr; } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @returns {Promise.<void>} - */ static async _postChangeKeyTasks(metadataEntry) { return super._postChangeKeyTasks(metadataEntry, true); } /** * prepares a DataExtension for deployment * * @param {DataExtensionItem} metadata a single data Extension * @returns {Promise.<DataExtensionItem>} Promise of updated single DE */ static async preDeployTasks(metadata) { if (metadata.Name?.startsWith('_')) { throw new Error(`Cannot Upsert Strongly Typed Data Extensions`); } if ( !Util.OPTIONS._fixSharedOnBu && this.buObject.eid !== this.buObject.mid && metadata.r__folder_Path?.startsWith('Shared Items') ) { throw new Error(`Cannot Create/Update a Shared Data Extension from the Child BU`); } if (metadata.r__folder_ContentType === 'shared_dataextension') { this.deployedSharedKeys ||= []; this.deployedSharedKeys.push(metadata.CustomerKey); } if (metadata.r__folder_Path?.startsWith('Synchronized Data Extensions')) { throw new Error( `Cannot Create/Update a Synchronized Data Extension. Please use Contact Builder to maintain these` ); } // folder super.setFolderId(metadata); // DataExtensionTemplate if (metadata.r__dataExtensionTemplate_name) { // remove templated fields for (const templateField of this.definition.templateFields[ metadata.r__dataExtensionTemplate_name ]) { for (let index = 0; index < metadata.Fields.length; index++) { const element = metadata.Fields[index]; if (element.Name === templateField) { metadata.Fields.splice(index, 1); Util.logger.debug(`Removed template field: ${templateField}`); break; } } } // get template's CustomerKey try { metadata.Template = { CustomerKey: cache.searchForField( 'dataExtensionTemplate', metadata.r__dataExtensionTemplate_name, 'Name', 'CustomerKey' ), }; delete metadata.r__dataExtensionTemplate_name; } catch (ex) { Util.logger.debug(ex.message); // It is assumed that non-supported types would not have been converted to r__dataExtensionTemplate_name upon retrieve. // Deploying to same BU therefore still works! // A workaround for cross-BU deploy exists but it's likely not beneficial to explain to users: // Create a DE based on the not-supported template on the target BU, retrieve it, copy the Template.CustomerKey into the to-be-deployed DE (or use mcdev-templating), done throw new Error( `Could not find specified DataExtension Template. Please note that DataExtensions based on SMSMessageTracking and SMSSubscriptionLog cannot be deployed automatically across BUs at this point.`, { cause: ex } ); } } // contenttype delete metadata.r__folder_ContentType; // Error if SendableSubscriberField.Name = '_SubscriberKey' even though it is retrieved like that // Therefore map it to 'Subscriber Key'. Retrieving afterward still results in '_SubscriberKey' // TODO remove from preDeploy with release of version 4, keep until then to help with migration of old metadata if ( metadata.SendableSubscriberField && metadata.SendableSubscriberField.Name === '_SubscriberKey' ) { metadata.SendableSubscriberField.Name = 'Subscriber Key'; } // Retention policy switch (metadata.c__retentionPolicy) { case 'none': { metadata.RowBasedRetention = false; metadata.DeleteAtEndOfRetentionPeriod = false; metadata.ResetRetentionPeriodOnImport = false; break; } case 'allRecordsAndDataextension': { metadata.RowBasedRetention = false; metadata.DeleteAtEndOfRetentionPeriod = false; break; } case 'allRecords': { metadata.RowBasedRetention = false; metadata.DeleteAtEndOfRetentionPeriod = true; break; } case 'individialRecords': { metadata.RowBasedRetention = true; metadata.DeleteAtEndOfRetentionPeriod = false; break; } default: { Util.logger.debug( ` - dataExtension '${ metadata[this.definition.nameField] }': Unknown retention policy: ${metadata.c__retentionPolicy}` ); } } delete metadata.c__retentionPolicy; if (metadata.c__retainUntil) { const retainUntil = new Date(metadata.c__retainUntil); metadata.RetainUntil = `${retainUntil.getMonth() + 1}/${retainUntil.getDate()}/${retainUntil.getFullYear()} 12:00:00 AM`; delete metadata.c__retainUntil; } else { metadata.RetainUntil = ''; } if (metadata.c__dataRetentionPeriodUnitOfMeasure) { metadata.DataRetentionPeriodUnitOfMeasure = this.definition.dataRetentionPeriodUnitOfMeasureMapping[ metadata.c__dataRetentionPeriodUnitOfMeasure ]; delete metadata.c__dataRetentionPeriodUnitOfMeasure; } return metadata; } /** * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {DataExtensionItem} json single dataextension * @param {object[][]} tabled prepped array for output in tabular format * @returns {string} file content */ static _generateDocHtml(json, tabled) { let output = '<html> <head> <style> html, table { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; } td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } tbody>tr:hover { background-color: #EBECF0; } </style> </head> <body></body>'; output += `<h2>${json.CustomerKey}</h2>`; if (json.CustomerKey !== json.Name) { output += `<p><b>Error - Name not equal to External Key:</b> ${json.Name}</p>`; } output += `<p><b>Description:</b> ${json.Description || 'n/a'}</p>`; output += `<p><b>Folder:</b> ${ json.r__folder_Path || '<i>Hidden! Could not find folder with ID ' + json.CategoryID + '</i>' }</p>`; output += `<p><b>Fields in table:</b> ${tabled.length - 1}</p>`; output += '<p><b>Sendable:</b> '; output += json.IsSendable === true ? 'Yes (<i>' + json.SendableDataExtensionField.Name + '</i> to <i>' + json.SendableSubscriberField.Name + '</i>)</p>\n\n' : `No</p>\n\n`; output += `<p><b>Testable:</b> ${json.IsTestable === true ? 'Yes' : 'No'}</p>\n\n`; if (json.r__dataExtensionTemplate_name) { output += `<p><b>Template:</b> ${json.r__dataExtensionTemplate_name}</p>`; } output += '<table><thead><tr>'; for (const element of tabled[0]) { output += '<th>' + element + '</th>'; } output += '</tr><thead><tbody>'; for (let i = 1; i < tabled.length; i++) { output += '<tr>'; for (const field of tabled[i]) { output += `<td>${field}</td>`; } output += '</tr>'; } output += '</tbody></table>'; return output; } /** * Experimental: Only working for DataExtensions: * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {DataExtensionItem} json dataextension * @param {object[][]} tabled prepped array for output in tabular format * @returns {string} file content */ static _generateDocMd(json, tabled) { let output = `## ${json.CustomerKey}\n\n`; if (json.CustomerKey !== json.Name) { output += `**Name** (not equal to External Key)**:** ${json.Name}\n\n`; } output += `**Description:** ${json.Description || 'n/a'}\n\n` + `**Folder:** ${ json.r__folder_Path || '_Hidden! Could not find folder with ID ' + json.CategoryID + '_' }/\n\n` + `**Fields in table:** ${tabled.length - 1}\n\n`; output += '**Sendable:** '; output += json.IsSendable === true ? 'Yes (`' + json.SendableDataExtensionField.Name + '` to `' + json.SendableSubscriberField.Name + '`)\n\n' : `No\n\n`; output += `**Testable:** ${json.IsTestable === true ? 'Yes' : 'No'}\n\n`; if (json.r__dataExtensionTemplate_name) { output += `**Template:** ${json.r__dataExtensionTemplate_name}\n\n`; } // Retention output += `**Retention Policy:** ${json.c__retentionPolicy}\n\n`; switch (json.c__retentionPolicy) { case 'allRecords': case 'allRecordsAndDataextension': { if (json.DataRetentionPeriodLength) { // if period length was selected, show it plus the optional reset-on-import; the retain-until date IS returned by the api but does not matter for documentation output += `- **Retention Period:** ${json.DataRetentionPeriodLength} ${json.c__dataRetentionPeriodUnitOfMeasure}\n`; output += `- **Reset Retention Period on import:** ${json.ResetRetentionPeriodOnImport ? 'yes' : 'no'}\n`; } else { // if a date was selected instead, the GUI auto-deselects reset-on-import output += `- **Retain Until:** ${json.c__retainUntil}\n`; } // add empty line after retention: output += `\n`; break; } case 'individialRecords': { output += `- **Retention Period:** ${json.DataRetentionPeriodLength} ${json.c__dataRetentionPeriodUnitOfMeasure}\n`; output += `- **Reset Retention Period on import:** ${json.ResetRetentionPeriodOnImport ? 'yes' : 'no'}\n`; // add empty line after retention: output += `\n`; break; } case 'none': { // nothing else to do break; } } let tableSeparator = ''; for (const column of tabled[0]) { output += `| ${column} `; tableSeparator += '| --- '; } output += `|\n${tableSeparator}|\n`; for (let i = 1; i < tabled.length; i++) { for (const field of tabled[i]) { output += `| ${field} `; } output += '|\n'; } return output; } /** * Saves json content to a html table in the local file system. Will create the parent directory if it does not exist. * The json's first level of keys must represent the rows and the secend level the columns * * @private * @param {string} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {DataExtensionItem} json dataextension.columns * @param {'html'|'md'} mode html or md * @param {string[]} [fieldsToKeep] list of keys(columns) to show. This will also specify * @returns {Promise.<void>} Promise of success of saving the file */ static async _writeDoc(directory, filename, json, mode, fieldsToKeep) { let fieldsJson = Object.values(json.Fields); if (fieldsToKeep) { /** @type {DataExtensionFieldItem[]} */ const newJson = []; for (const element of fieldsJson) { const newJsonElement = {}; for (const field of fieldsToKeep) { if (field === 'MaxLength' && element.FieldType === 'Decimal') { newJsonElement.MaxLength = `${element.MaxLength},${element.Scale}`; } else { newJsonElement[field] = element[field]; } } // @ts-ignore for document the fields have less values and that leads to an error here. newJson.push(newJsonElement); } fieldsJson = newJson; } const tabled = jsonToTable(fieldsJson); let output; if (mode === 'html') { output = DataExtension._generateDocHtml(json, tabled); } else if (mode === 'md') { output = DataExtension._generateDocMd(json, tabled); } try { // write to disk await File.writeToFile(directory, filename + '.dataExtension-doc', mode, output); } catch (ex) { Util.logger.error(`DataExtension.writeDeToX(${mode}):: error | ` + ex.message); } } /** * Parses metadata into a readable Markdown/HTML format then saves it * * @param {DataExtensionMap} [metadataMap] a list of dataExtension definitions * @returns {Promise.<any>} - */ static async document(metadataMap) { try { if (!metadataMap) { metadataMap = ( await this.readBUMetadataForType( File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, ]), true ) ).dataExtension; } } catch (ex) { Util.logger.error(ex.message); return; } const docPath = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); if (!metadataMap || !Object.keys(metadataMap).length) { // as part of retrieve & manual execution we could face an empty folder return; } const columnsToIterateThrough = ['IsNullable', 'IsPrimaryKey']; const columnsToPrint = [ 'Name', 'FieldType', 'MaxLength', 'IsPrimaryKey', 'IsNullable', 'DefaultValue', ]; const docLimit = pLimit(100); return Promise.all( Object.keys(metadataMap).map((key) => { if (metadataMap[key]?.Fields?.length) { for (const field of metadataMap[key].Fields) { field.IsNullable = !Util.isTrue(field.IsRequired); for (const prop of columnsToIterateThrough) { if (Util.isTrue(field[prop])) { field[prop] = '+'; } else if (Util.isFalse(field[prop])) { field[prop] = '-'; } } } if (['html', 'both'].includes(this.properties.options.documentType)) { return docLimit(() => this._writeDoc( docPath + '/', key, metadataMap[key], 'html', columnsToPrint ) ); } if (['md', 'both'].includes(this.properties.options.documentType)) { return docLimit(() => this._writeDoc( docPath + '/', key, metadataMap[key], 'md', columnsToPrint ) ); } } }) ); } /** * Delete a metadata item from the specified business unit * * @param {string} customerKey Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(customerKey) { return super.deleteByKeySOAP(customerKey, undefined, 310007); } /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - promise */ static async postDeleteTasks(customerKey) { // delete local copy: retrieve/cred/bu/dataExtension/...-meta.json // delete local copy: doc/dataExtension/cred/bu/...md await super.postDeleteTasks(customerKey, [`${this.definition.type}-doc.md`]); } /** * Retrieves folder metadata into local filesystem. Also creates a uniquePath attribute for each folder. * * @returns {Promise.<{metadata: DataExtensionMap, type: string}>} Promise */ static async retrieveForCache() { return this.retrieve(null, ['ObjectID', 'CustomerKey', 'Name']); } /** * Retrieves dataExtension metadata in template format. * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata item * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<{metadata: DataExtensionItem, type: string}>} Promise of items */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); /** @type {SoapRequestParams} */ const options = { filter: { leftOperand: 'Name', operator: 'equals', rightOperand: name, }, }; const metadata = await this._retrieveAll(null, options); if (!Object.keys(metadata).length) { Util.logger.error(`${this.definition.type} '${name}' not found on server.`); Util.logger.info('Downloaded: dataExtension (0)'); return { metadata: null, type: 'dataExtension' }; } const customerKey = Object.keys(metadata)[0]; await this._retrieveFieldsForSingleDe(metadata, customerKey); for (const key in metadata) { try { // API returns field unsorted metadata[key].Fields.sort((a, b) => a.Ordinal - b.Ordinal); const originalKey = key; const metadataCleaned = structuredClone( await this.postRetrieveTasks(metadata[key]) ); this.keepTemplateFields(metadataCleaned); const metadataTemplated = JSON.parse( Util.replaceByObject(JSON.stringify(metadataCleaned), templateVariables) ); await File.writeJSONToFile( [templateDir, this.definition.type].join('/'), originalKey + '.' + this.definition.type + '-meta', metadataTemplated ); } catch (ex) { Util.metadataLogger('error', this.definition.type, 'retrieve', ex, key); } } Util.logger.info(`- templated ${this.definition.type}: ${customerKey}`); return { metadata: metadata[customerKey], type: 'dataExtension' }; } /** * dataExtension logic that retrieves the folder path from cache and updates the given metadata with it after retrieve * it also sets the content type which is basically the subtype * * @param {MetadataTypeItem} metadata a single script activity definition */ static setFolderPath(metadata) { let error = false; let verbose = false; // data extension type (from folder) try { metadata.r__folder_ContentType = cache.searchForField( 'folder', metadata[this.definition.folderIdField], 'ID', 'ContentType' ); } catch (ex) { if (/(_Salesforce)(_\d\d?\d?)?$/.test(metadata.Name)) { verbose = true; metadata.r__folder_ContentType = 'synchronizeddataextension'; } else { error = true; Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find folder (${ex.message})` ); } } // folder try { metadata.r__folder_Path = cache.searchForField( 'folder', metadata[this.definition.folderIdField], 'ID', 'Path' ); delete metadata[this.definition.folderIdField]; } catch (ex) { if (/(_Salesforce)(_\d\d?\d?)?$/.test(metadata.Name)) { metadata.r__folder_Path = 'Synchronized Data Extensions'; delete metadata[this.definition.folderIdField]; if (!verbose) { Util.logger.verbose( `Synchronized Data Extension of other BU found: '${metadata.Name}'. Setting folder to 'Synchronized Data Extensions'` ); } } else if (!error) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): ${ex.message}` ); } } } /** * Retrieves dataExtension metadata and cleans it * * @private * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {SoapRequestParams} [options] e.g. filter * @returns {Promise.<DataExtensionMap>} keyField => metadata map */ static async _retrieveAll(additionalFields, options) { const { metadata } = await super.retrieveSOAP(null, options, null, additionalFields); for (const key in metadata) { // some system data extensions do not have CategoryID which throws errors in other places. These do not need to be parsed if (metadata[key].CategoryID) { metadata[key].Fields = []; } else { delete metadata[key]; } } return metadata; } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { if (this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)) { // document dataExtension is active. assume we want to commit the MD file as well const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-doc.md`]), ]); return fileList; } else { // document dataExtension is not active upon retrieve, run default method instead return super.getFilesToCommit(keyArr); } } /** * Hook called when dependency keys were not found in the child BU retrieve folder. * Checks the `_ParentBU_` folder for shared or synchronized dataExtensions and emits * readable warnings. Does NOT add the found items to the deployment package. * Only active when running on a child BU (eid !== mid). * Used by {@link MetadataType.getDependentFiles}. * * @param {string[]} notFound keys that were not found in the child BU retrieve folder * @returns {Promise.<string[]>} keys that should still trigger the default "not found" warning */ static async handleNotFoundDependencies(notFound) { // on parent BU, shared DE check is not applicable if (this.buObject.eid === this.buObject.mid) { return notFound; } const parentBUPath = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, Util.parentBuName, this.definition.type, ]); const stillNotFound = []; for (const key of notFound) { const filePath = File.normalizePath([ parentBUPath, File.filterIllegalFilenames(key) + '.' + this.definition.type + '-meta.json', ]); let metadataItem; try { metadataItem = await File.readJson(filePath); } catch { stillNotFound.push(key); continue; } const contentType = metadataItem.r__folder_ContentType; if (contentType === 'shared_dataextension') { Util.logger.warn( `dataExtension '${key}' is a shared dataExtension stored in _ParentBU_. It cannot be included in the child BU deployment package.` ); Util.logger.warn( `References to it may need to be changed during deployment via mcdev templating or manually. To update the shared dataExtension itself, run build for the parent BU and deploy it separately.` ); } else if (contentType === 'synchronizeddataextension') { Util.logger.warn( `dataExtension '${key}' is a synchronized dataExtension stored in _ParentBU_. It cannot be included in the child BU deployment package.` ); Util.logger.warn( `The reference to it likely needs to be changed during deployment via mcdev templating or manually.` ); } else { // regular dataExtension found on parent BU cannot be used from a child BU; treat as not found stillNotFound.push(key); } } return stillNotFound; } /** * helper for {@link MetadataType.createOrUpdate} * * @param {MetadataTypeItem} metadataItem to be deployed item * @returns {MetadataTypeItem} cached item or undefined */ static getCacheMatchedByName(metadataItem) { let cacheMatchedByName; if (Util.OPTIONS.matchName) { // make sure to run the search ONLY if OPTIONS.matchName is true and definition.allowMatchingByName signals support const typeCache = cache.getCache()?.[this.definition.type]; const potentials = []; for (const key in typeCache) { const cachedItem = typeCache[key]; if ( cachedItem[this.definition.nameField] === metadataItem[this.definition.nameField] ) { potentials.push(cachedItem); } } if (potentials.length > 1) { // ! SFMC disallows having 2 dataExtensions with the same name because that would cause a conflict in queries and in ampscript/ssjs which all use dataExtension NAMES instead of keys in their scripts // ! When trying to create a duplicate it results in the error Code 310007 ("A data extension named xyz already exists.") Util.logger.debug(` - Multiple name matches found? This should never happen.`); } else if (potentials.length === 1) { // only one item found, confirm that it's in the same folder const deployFolderPath = cache.searchForField( 'folder', metadataItem[this.definition.folderIdField], 'ID', 'Path' ); if ( potentials[0][this.definition.folderIdField] === metadataItem[this.definition.folderIdField] ) { cacheMatchedByName = potentials[0]; Util.logger.info( Util.getGrayMsg( ` - found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" and folder "${deployFolderPath}": ${cacheMatchedByName[this.definition.keyField]}` ) ); } else if ( Util.OPTIONS.ignoreFolder && potentials[0][this.definition.folderIdField] !== metadataItem[this.definition.folderIdField] ) { cacheMatchedByName = potentials[0]; const cacheFolderPath = cache.searchForField( 'folder', potentials[0][this.definition.folderIdField], 'ID', 'Path' ); Util.logger.info( Util.getGrayMsg( ` - found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" and but folder is different (--ignoreFolder). New folder: "${deployFolderPath}". Old: "${cacheFolderPath}"` ) ); } else { const cacheFolderPath = cache.searchForField( 'folder', potentials[0][this.definition.folderIdField], 'ID', 'Path' ); throw new Error( `found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name but folder is different. New folder: "${deployFolderPath}". Old: "${cacheFolderPath}": Identified key: ${potentials[0][this.definition.keyField]}` ); } } else { Util.logger.debug( ` - no name-match found for ${this.definition.type} ${metadataItem[this.definition.keyField]}. Creating new ${this.definition.type} instead.` ); } } return cacheMatchedByName; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DataExtension.definition = MetadataTypeDefinitions.dataExtension; export default DataExtension; ================================================ FILE: lib/metadataTypes/DataExtensionField.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import DataExtension from './DataExtension.js'; import { confirm } from '@inquirer/prompts'; import auth from '../util/auth.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldMap} DataExtensionFieldMap * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldItem} DataExtensionFieldItem */ /** * DataExtensionField MetadataType * * @augments MetadataType */ class DataExtensionField extends MetadataType { static fixShared_fields; /** * Retrieves all records and saves it to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<{metadata: DataExtensionFieldMap, type: string}>} Promise of items */ static async retrieve(retrieveDir, additionalFields) { return super.retrieveSOAP(retrieveDir, null, null, additionalFields); } /** * Retrieves all records and saves it to disk * * @returns {Promise.<MetadataTypeMapObj>} Promise of items */ static async retrieveForCache() { const cachedDEs = cache.getCache().dataExtension; if (cachedDEs) { await DataExtension.attachFields(cachedDEs); } return; } /** * helps retrieving fields for a single DE. Use when needing field data for one DE only. * * @param {string} customerKey external key of single DE * @returns {Promise.<object>} Promise of items */ static async retrieveFieldsForSingleDe(customerKey) { /** @type {SoapRequestParams} */ const fieldOptions = { filter: { leftOperand: 'DataExtension.CustomerKey', operator: 'equals', rightOperand: customerKey, }, }; const response = await DataExtensionField.retrieveForCacheDE(fieldOptions); return DataExtensionField.convertToSortedArray(response.metadata).reduce((acc, field) => { acc[field.CustomerKey] = field; return acc; }, {}); } /** * determines if a dataExtension is shared (from parent BU) by checking its folder's ContentType in the parent BU folder cache * * @param {string} customerKey external key of single DE * @returns {boolean} true if the DE is shared (stored on parent BU) */ static isSharedDe(customerKey) { if (this.buObject.eid === this.buObject.mid) { // already on parent BU, no shared DEs possible return false; } const categoryId = cache.getCache().dataExtension?.[customerKey]?.CategoryID; if (!categoryId) { return false; } try { const contentType = cache.searchForField( 'folder', categoryId, 'ID', 'ContentType', this.buObject.eid ); return MetadataTypeDefinitions.folder.folderTypesFromParent.includes(contentType); } catch { // folder not found in parent BU cache → local DE return false; } } /** * helps retrieving fields for a single DE from parent BU. * Use when the DE is shared (stored on parent BU) and its fields are not in the current BU's cache. * * @param {string} customerKey external key of single DE * @returns {Promise.<object>} Promise of items */ static async retrieveFieldsForSingleSharedDe(customerKey) { if (this.buObject.eid === this.buObject.mid) { // already on parent BU, shared retrieval is not needed - all DEs are local here Util.logger.debug( `DataExtensionField.retrieveFieldsForSingleSharedDe: already on parent BU, skipping for ${customerKey}` ); return {}; } if (!this.properties.credentials[this.buObject.credential]) { Util.logger.error( `DataExtensionField.retrieveFieldsForSingleSharedDe: credential '${this.buObject.credential}' not found in properties` ); return {}; } const buObjectBak = this.buObject; const clientBak = this.client; /** @type {BuObject} */ const buObjectParentBu = { eid: this.properties.credentials[this.buObject.credential].eid, mid: this.properties.credentials[this.buObject.credential].eid, businessUnit: Util.parentBuName, credential: this.buObject.credential, }; try { this.buObject = buObjectParentBu; this.client = auth.getSDK(buObjectParentBu); } catch (ex) { Util.logger.error(ex.message); this.buObject = buObjectBak; this.client = clientBak; return {}; } const fields = await this.retrieveFieldsForSingleDe(customerKey); // revert client to current default this.buObject = buObjectBak; this.client = clientBak; return fields; } /** * Routes field retrieval to the correct method depending on whether the DE is local or shared. * Use this instead of duplicating the isSharedDe() check at each call site. * * @param {string} customerKey external key of single DE * @returns {Promise.<object>} Promise of items */ static async retrieveFieldsForSingleDeAuto(customerKey) { return this.isSharedDe(customerKey) ? this.retrieveFieldsForSingleSharedDe(customerKey) : this.retrieveFieldsForSingleDe(customerKey); } /** * Retrieves all records for caching * * @param {SoapRequestParams} [requestParams] required for the specific request (filter for example) * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<{metadata: DataExtensionFieldMap, type: string}>} Promise of items */ static async retrieveForCacheDE(requestParams, additionalFields) { let response; response = await super.retrieveSOAP(null, requestParams, null, additionalFields); if (!response) { // try again but without filters as a workaround for the "String or binary data would be truncated." issue response = await super.retrieveSOAP(null, {}, null, additionalFields); } return response; } /** * helper for DataExtension.retrieveFieldsForSingleDe that sorts the fields into an array * * @param {DataExtensionFieldMap} fieldsObj customerKey-based list of fields for one dataExtension * @returns {DataExtensionFieldItem[]} sorted array of field objects */ static convertToSortedArray(fieldsObj) { return ( Object.keys(fieldsObj) .map((field) => fieldsObj[field]) // the API returns the fields not sorted .toSorted(this.sortDeFields) ); } /** * sorting method to ensure `Ordinal` is respected * * @param {DataExtensionFieldItem} a - * @param {DataExtensionFieldItem} b - * @returns {number} sorting based on Ordinal */ static sortDeFields(a, b) { return a.Ordinal - b.Ordinal; } /** * manages post retrieve steps; only used by DataExtension class * * @param {DataExtensionFieldItem} metadata a single item * @returns {DataExtensionFieldItem} metadata */ static postRetrieveTasksDE(metadata) { // remove fields according to definition this.keepRetrieveFields(metadata); // remove fields that we do not need after association to a DE delete metadata.CustomerKey; delete metadata.DataExtension; delete metadata.Ordinal; if (metadata.FieldType !== 'Decimal') { // remove scale - it's only used for "Decimal" to define the digits behind the decimal delete metadata.Scale; } return metadata; } /** * Mofifies passed deployColumns for update by mapping ObjectID to their target column's values. * Removes FieldType field if its the same in deploy and target column, because it results in an error even if its of the same type * * @param {DataExtensionFieldItem[]} deployColumns Columns of data extension that will be deployed * @param {string} deKey external/customer key of Data Extension * @returns {Promise.<DataExtensionFieldMap>} existing fields by their original name to allow re-adding FieldType after update */ static async prepareDeployColumnsOnUpdate(deployColumns, deKey) { // create list of DE keys that had changes to their fields to be able to use it as a filter in the --fixShared logic this.fixShared_fields ||= {}; this.fixShared_fields[deKey] ||= {}; // get row count to know which field restrictions apply let hasData = false; try { const rowset = await this.client.rest.get( `/data/v1/customobjectdata/key/${deKey}/rowset?$page=1&$pagesize=1` ); const rowCount = rowset.count; hasData = rowCount > 0; Util.logger.debug(`dataExtension ${deKey} row count: ${rowCount}`); } catch (ex) { Util.logger.debug(`Could not retrieve rowcount for ${deKey}: ${ex.message}`); } // retrieve existing fields to enable updating them const response = await this.retrieveForCacheDE( { filter: { leftOperand: 'DataExtension.CustomerKey', operator: 'equals', rightOperand: deKey, }, }, ['Name', 'ObjectID'] ); const fieldsObj = response.metadata; // ensure fields can be updated properly by their adding ObjectId based on Name-matching /** @type {DataExtensionFieldMap} */ const existingFieldByName = {}; for (const key of Object.keys(fieldsObj)) { // make sure we stringify the name in case it looked numeric and then lowercase it for easy comparison as the server is comparing field names case-insensitive existingFieldByName[(fieldsObj[key].Name + '').toLowerCase()] = fieldsObj[key]; } // capture field names from deploy payload before the loop modifies them (for renamed fields, the original name is used) const deployColumnNames = new Set( deployColumns.map((item) => (item.Name + '').toLowerCase()) ); for (let i = deployColumns.length - 1; i >= 0; i--) { const item = deployColumns[i]; // make sure we stringify the name in case it looked numeric and then lowercase it for easy comparison as the server is comparing field names case-insensitive const itemOld = existingFieldByName[(item.Name + '').toLowerCase()]; if (itemOld) { // field is getting updated --- // Updating to a new FieldType will result in an error; warn & afterwards remove it if (itemOld.FieldType !== item.FieldType) { // applicable: with or without data but simply ignored by API Util.logger.error( ` - The Field Type of an existing field cannot be changed. [${deKey}].[${item.Name}]: '${itemOld.FieldType}'` ); } if (item.FieldType !== 'Decimal') { // remove scale - it's only used for "Decimal" to define the digits behind the decimal delete item.Scale; } delete item.FieldType; if (itemOld.MaxLength > item.MaxLength) { // applicable: with or without data (Code 310007) Util.logger.error( ` - The length of an existing field cannot be decreased. [${deKey}].[${item.Name}]: '${itemOld.MaxLength}'` ); } if (Util.isFalse(itemOld.IsRequired) && Util.isTrue(item.IsRequired)) { // applicable: with or without data (Code 310007) Util.logger.error( ` - A field cannot be changed to be required on update after it was created to allow nulls. [${deKey}].[${item.Name}]` ); } // enable renaming if (item.Name_new) { Util.logger.info( ` - Found Name_new='${item.Name_new}' for field ${deKey}.${item.Name} - trying to rename.` ); item.Name = item.Name_new; delete item.Name_new; } // check if any changes were found let changeFound = false; for (const key of Object.keys(item)) { if (item[key] !== itemOld[key]) { changeFound = true; } } // share fields with fixShared logic this.fixShared_fields[deKey][item.Name] = structuredClone(item); this.fixShared_fields[deKey][item.Name].FieldType = itemOld.FieldType; if (!changeFound) { deployColumns.splice(i, 1); Util.logger.verbose(`no change - removed field [${deKey}].[${item.Name}]`); continue; } // set the ObjectId for clear identification during update item.ObjectID = itemOld.ObjectID; } else { // field is getting added --- if (hasData && Util.isTrue(item.IsRequired) && item.DefaultValue === '') { // applicable: with data only if (Util.isFalse(item.IsPrimaryKey)) { Util.logger.warn( ` - Adding new fields to an existing table requires that these fields are either not-required (nullable) or have a default value set. Changing [${deKey}].[${item.Name}] to be not-required` ); item.IsRequired = false; } else { Util.logger.error( `- You cannot add a new primary key field to an existing table that has data. [${deKey}].[${item.Name}]` ); } } if (item.Name_new) { Util.logger.info( ` - Found Name_new='${item.Name_new}' for field ${deKey}.${item.Name} but could not find a corresponding DE field on the server - adding new field instead of updating.` ); delete item.Name_new; } // Field doesn't exist in target, therefore Remove ObjectID if present delete item.ObjectID; this.fixShared_fields[deKey][item.Name] = structuredClone(item); } if (Util.isTrue(item.IsPrimaryKey) && Util.isFalse(item.IsRequired)) { // applicable: with or without data Util.logger.warn( `- Primary Key field [${deKey}].[${item.Name}] cannot be not-required (nullable). Changing field to be required!` ); item.IsRequired = true; } // filter bad manual changes to the json if (!Util.isTrue(item.IsRequired) && !Util.isFalse(item.IsRequired)) { Util.logger.error( `- Invalid value for 'IsRequired' of [${deKey}].[${item.Name}]. Found '${item.IsRequired}' instead of 'true'/'false'.` ); } if (!Util.isTrue(item.IsPrimaryKey) && !Util.isFalse(item.IsPrimaryKey)) { Util.logger.error( `- Invalid value for 'IsPrimaryKey' of [${deKey}].[${item.Name}]. Found '${item.IsPrimaryKey}' instead of 'true'/'false'.` ); } } Util.logger.info( Util.getGrayMsg( ` - Found ${deployColumns.length} added/updated Fields for ${deKey}${ deployColumns.length ? ': ' : '' }` + deployColumns.map((item) => item.Name).join(', ') ) ); // warn about fields that exist on the server but are not in the deploy payload // these fields are NOT auto-deleted to prevent unintended data loss const removedFieldNames = Object.values(existingFieldByName) .filter((field) => !deployColumnNames.has((field.Name + '').toLowerCase())) .map((field) => field.Name) .toSorted(); if (removedFieldNames.length > 0) { Util.logger.warn( ` - dataExtension ${deKey}: found ${removedFieldNames.length} field${removedFieldNames.length > 1 ? 's' : ''} on the server but not in the deploy payload. Fields cannot be auto-deleted due to potential data loss. To delete them, please run:` ); Util.logger.info( Util.getGrayMsg( `mcdev delete ${this.buObject.credential}/${this.buObject.businessUnit} -m ` + removedFieldNames .map((name) => `dataExtensionField:"${deKey}.${name}"`) .join(' ') ) ); } return existingFieldByName; } /** * Delete a metadata item from the specified business unit * * @param {string} customerKey Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(customerKey) { return this.deleteByKeySOAP(customerKey); } /** * Delete a data extension from the specified business unit * * @param {string} customerKey Identifier of metadata * @param {string} [fieldId] for programmatic deletes only one can pass in the ID directly * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKeySOAP(customerKey, fieldId) { const [deKey, fieldName] = customerKey.split('.'); customerKey = `[${deKey}].[${fieldName}]`; let fieldObjectID = fieldId; let deletionQueue; // get the object id if (!fieldObjectID) { if (deKey === '*') { const response = await this.retrieveForCacheDE( { filter: { leftOperand: 'Name', operator: 'equals', rightOperand: fieldName, }, }, ['Name', 'ObjectID', 'DataExtension.CustomerKey'] ); deletionQueue = Object.values(response.metadata).map((item) => ({ fieldObjectID: item.ObjectID, fieldName: fieldName, deKey: item.DataExtension.CustomerKey, })); Util.logger.info( ` - Found ${deletionQueue.length} Data Extensions with field ${fieldName} in your BU:\n - ${deletionQueue .map((item) => item.deKey) .toSorted() .join('\n - ')}` ); if (deletionQueue.length > 0 && !Util.skipInteraction) { const massDelete = await confirm({ message: `Do you really want to delete that field from all of the above Data Extensions?`, default: false, }); if (!massDelete) { Util.logger.info( ` ☇ skipping deletion of ${fieldName} based on user-choice.` ); return false; } } } else { const response = await this.retrieveForCacheDE( { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: customerKey, }, }, ['Name', 'ObjectID'] ); fieldObjectID = response.metadata[customerKey]?.ObjectID; } } if (!fieldObjectID && !deletionQueue) { Util.logger.error(`Could not find ${customerKey} on your BU`); return false; } else if (!deletionQueue) { deletionQueue = [ { fieldObjectID: fieldObjectID, fieldName: fieldName, deKey: deKey, }, ]; } let success = true; const fieldDeletedFromDEKeys = []; for (const item of deletionQueue) { // normal code const keyObj = { CustomerKey: item.deKey, Fields: { Field: { ObjectID: item.fieldObjectID, }, }, }; try { // ! we really do need to delete from DataExtension not DataExtensionField here! await this.client.soap.delete('DataExtension', keyObj, null); if (!fieldId) { Util.logger.info( ` - deleted ${this.definition.type}: ${item.deKey}.${item.fieldName}` ); } fieldDeletedFromDEKeys.push(item.deKey); // return true; } catch (ex) { const errorMsg = ex?.results?.length ? `${ex.results[0].StatusMessage} (Code ${ex.results[0].ErrorCode})` : ex?.json?.Results?.length ? `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})` : ex.message; Util.logger.error( `- error deleting ${this.definition.type} ${item.deKey}.${item.fieldName}: ${errorMsg}` ); success = false; } } const uniqueDEKeys = [...new Set(fieldDeletedFromDEKeys)]; if (uniqueDEKeys.length > 0) { Util.logger.info( Util.getGrayMsg( `To refresh your local files, run mcdev r ${this.buObject.credential}/${this.buObject.businessUnit} -m ${uniqueDEKeys .map((key) => 'dataExtension:"' + key + '"') .toSorted() .join(' ')}` ) ); } return success; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; import cache from '../util/cache.js'; DataExtensionField.definition = MetadataTypeDefinitions.dataExtensionField; export default DataExtensionField; ================================================ FILE: lib/metadataTypes/DataExtensionTemplate.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DataExtensionTemplate MetadataType * * @augments MetadataType */ class DataExtensionTemplate extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = null; if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } return super.retrieveSOAP(retrieveDir, requestParams, key); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DataExtensionTemplate.definition = MetadataTypeDefinitions.dataExtensionTemplate; export default DataExtensionTemplate; ================================================ FILE: lib/metadataTypes/DataExtract.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DataExtract MetadataType * * @augments MetadataType */ class DataExtract extends MetadataType { /** * Retrieves Metadata of Data Extract Activity. * Endpoint /automation/v1/dataextracts/ returns all Data Extracts * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { return super.retrieveREST(retrieveDir, '/automation/v1/dataextracts/', null, key); } /** * Retrieves Metadata of Data Extract Activity for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieveForCache() { return super.retrieveREST(null, '/automation/v1/dataextracts/'); } /** * Retrieve a specific dataExtract Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise of metadata */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); const res = await this.client.rest.get( '/automation/v1/dataextracts/?$filter=name%20eq%20' + encodeURIComponent(name) ); if (Array.isArray(res.items) && res.items.length) { // eq-operator returns a similar, not exact match and hence might return more than 1 entry const metadata = res.items.find((item) => item.name === name); if (!metadata) { Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`); return; } // get full definition const extended = await this.client.rest.get( '/automation/v1/dataextracts/' + metadata[this.definition.idField] ); const originalKey = extended[this.definition.keyField]; const val = JSON.parse( Util.replaceByObject( JSON.stringify(this.postRetrieveTasks(extended)), templateVariables ) ); // remove all fields listed in Definition for templating this.keepTemplateFields(val); await File.writeJSONToFile( [templateDir, this.definition.type].join('/'), originalKey + '.' + this.definition.type + '-meta', JSON.parse(Util.replaceByObject(JSON.stringify(val), templateVariables)) ); Util.logger.info(`- templated ${this.definition.type}: ${name}`); return { metadata: val, type: this.definition.type }; } else if (res?.items) { Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`); } else { throw new Error( `Encountered unknown error when retrieveing ${ this.definition.typeName } "${name}": ${JSON.stringify(res)}` ); } } /** * Creates a single Data Extract * * @param {MetadataTypeItem} dataExtract a single Data Extract * @returns {Promise} Promise */ static create(dataExtract) { return super.createREST(dataExtract, '/automation/v1/dataextracts/'); } /** * Updates a single Data Extract * * @param {MetadataTypeItem} dataExtract a single Data Extract * @returns {Promise} Promise */ static update(dataExtract) { return super.updateREST( dataExtract, '/automation/v1/dataextracts/' + dataExtract.dataExtractDefinitionId ); } /** * prepares a dataExtract for deployment * * @param {MetadataTypeItem} metadata a single dataExtract activity definition * @returns {MetadataTypeItem} metadata object */ static preDeployTasks(metadata) { // dataExtension if (metadata.r__dataExtension_key) { const deField = metadata.dataFields.find((field) => field.name === 'DECustomerKey'); if (deField) { deField.value = cache.searchForField( 'dataExtension', metadata.r__dataExtension_key, 'CustomerKey', 'CustomerKey' ); delete metadata.r__dataExtension_key; } } // dataExtractType metadata.dataExtractTypeId = cache.searchForField( 'dataExtractType', metadata.r__dataExtractType_name, 'name', 'extractId' ); delete metadata.r__dataExtractType_name; return metadata; } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static async postDeployTasks(upsertResults) { // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present) Util.logger.debug( `Caching all ${this.definition.type} post-deploy to ensure we have all fields` ); const typeCache = await this.retrieveForCache(); // update values in upsertResults with retrieved values before saving to disk for (const key of Object.keys(upsertResults)) { if (typeCache.metadata[key]) { upsertResults[key] = typeCache.metadata[key]; } } } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(metadata) { // user try { metadata.createdBy = cache.searchForField( 'user', metadata.createdBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } try { metadata.modifiedBy = cache.searchForField( 'user', metadata.modifiedBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } // dataExtension const deField = metadata.dataFields.find((field) => field.name === 'DECustomerKey'); if (deField && deField.value) { try { metadata.r__dataExtension_key = cache.searchForField( 'dataExtension', deField.value, 'CustomerKey', 'CustomerKey' ); delete deField.value; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ex.message}` ); } } // dataExtractType try { metadata.r__dataExtractType_name = cache.searchForField( 'dataExtractType', metadata.dataExtractTypeId, 'extractId', 'name' ); delete metadata.dataExtractTypeId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ex.message}` ); } return metadata; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static async _getObjectIdForSingleRetrieve(key) { const name = key.startsWith('name:') ? key.slice(5) : null; const filter = name ? '?$filter=name%20eq%20' + encodeURIComponent(name) : ''; const results = await this.client.rest.get('/automation/v1/dataextracts/' + filter); const items = results?.items || []; const found = items.find((item) => name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key ); return found?.dataExtractDefinitionId || null; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/automation/v1/dataextracts/' + objectId, key); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DataExtract.definition = MetadataTypeDefinitions.dataExtract; export default DataExtract; ================================================ FILE: lib/metadataTypes/DataExtractType.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DataExtractType MetadataType * Only for Caching No retrieve/upsert is required * as this is a configuration in the EID * * @augments MetadataType */ class DataExtractType extends MetadataType { /** * Retrieves Metadata of Data Extract Type. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { return super.retrieveREST(retrieveDir, '/automation/v1/dataextracttypes/', null, key); } /** * Retrieves Metadata of Data Extract Type for caching. * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache() { return super.retrieveREST(null, '/automation/v1/dataextracttypes/'); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DataExtractType.definition = MetadataTypeDefinitions.dataExtractType; export default DataExtractType; ================================================ FILE: lib/metadataTypes/DataFilter.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; import DataExtensionField from './DataExtensionField.js'; import Folder from './Folder.js'; import { XMLBuilder, XMLParser } from 'fast-xml-parser'; import File from '../util/file.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').DataFilterItem} DataFilterItem * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldMap} DataExtensionFieldMap * @typedef {import('../../types/mcdev.d.js').DataExtensionFieldItem} DataExtensionFieldItem * @typedef {import('../../types/mcdev.d.js').DataFilterMap} DataFilterMap * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').FilterConditionSet} FilterConditionSet * @typedef {import('../../types/mcdev.d.js').FilterCondition} FilterCondition */ /** * DataFilter (FilterDefinition) MetadataType * * @augments MetadataType */ class DataFilter extends MetadataType { static cache = {}; // type internal cache for various things static deIdKeyMap; static hidden = false; /** * Retrieves all records and saves it to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [_] unused parameter * @param {string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: DataFilterMap, type: string}>} Promise of items */ static async retrieve(retrieveDir, _, __, key) { Util.logBeta(this.definition.type); /** @type {DataFilterMap} */ const filterDefinitionMap = {}; const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (objectId) { const metadataMapSingle = await super.retrieveREST( null, '/email/v1/filters/filterdefinition/' + objectId, null, key ); Object.assign(filterDefinitionMap, metadataMapSingle.metadata); } else { const filterFolders = await this._getFilterFolderIds(); for (const folderId of filterFolders) { const metadataMapFolder = await super.retrieveREST( null, 'email/v1/filters/filterdefinition/category/' + folderId + '?derivedFromType=1,2,3,4&', null, key ); if (Object.keys(metadataMapFolder.metadata).length) { Object.assign(filterDefinitionMap, metadataMapFolder.metadata); if (filterDefinitionMap[key]) { // if key was found we can stop checking other folders break; } } } } // /** @type {DataFilterMap} */ // const filterDefinitionMap = metadataTypeMapObj.metadata; for (const item of Object.values(filterDefinitionMap)) { // description is not returned when empty item.description ||= ''; } if (retrieveDir) { // custom dataExtensionField caching await this._cacheDeFields(filterDefinitionMap, 'retrieve'); // await this._cacheContactAttributes(filterDefinitionMap); // await this._cacheMeasures(filterDefinitionMap); const savedMetadata = await this.saveResults(filterDefinitionMap, retrieveDir); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(key) ); } return { metadata: filterDefinitionMap, type: this.definition.type }; } /** * helper for {@link DataFilter.retrieve} * * @param {boolean} [recached] indicates if this is a recursive call after cache refresh * @returns {Promise.<number[]>} Array of folder IDs */ static async _getFilterFolderIds(recached = false) { const fromCache = this.cache[this.buObject.mid]?.folderFilter || cache.getCache().folder ? Object.values( this.cache[this.buObject.mid]?.folderFilter || cache.getCache().folder ) .filter((item) => item.ContentType === 'filterdefinition') .filter( (item) => (!this.hidden && item.Path.startsWith('Data Filters')) || (this.hidden && !item.Path.startsWith('Data Filters')) ) // only retrieve from Data Filters folder .map((item) => item.ID) : []; if (fromCache.length) { return fromCache; } if (recached) { Util.logger.debug('_getFilterFolderIds: could not find filterdefinition folders'); return []; } const subTypeArr = ['hidden', 'filterdefinition']; Util.logger.info(` - Caching dependent Metadata: folder`); Util.logSubtypes(subTypeArr); Folder.client = this.client; Folder.buObject = this.buObject; Folder.properties = this.properties; this.cache[this.buObject.mid] ||= {}; this.cache[this.buObject.mid].folderFilter = ( await Folder.retrieveForCache(null, subTypeArr) ).metadata; return this._getFilterFolderIds(true); } /** * helper for {@link DataFilter._cacheMeasures} * * @returns {Promise.<number[]>} Array of folder IDs */ static async _getMeasureFolderIds() { const fromCache = this.cache[this.buObject.mid]?.folderMeasure || cache.getCache().folder ? Object.values( this.cache[this.buObject.mid]?.folderMeasure || cache.getCache().folder ) .filter((item) => item.ContentType === 'measure') .map((item) => item.ID) : []; if (fromCache.length) { return fromCache; } const subTypeArr = ['measure']; Util.logger.info(` - Caching dependent Metadata: folder`); Util.logSubtypes(subTypeArr); Folder.client = this.client; Folder.buObject = this.buObject; Folder.properties = this.properties; this.cache[this.buObject.mid] ||= {}; this.cache[this.buObject.mid].folderMeasure ||= {}; this.cache[this.buObject.mid].folderMeasure = ( await Folder.retrieveForCache(null, subTypeArr) ).metadata; return this._getMeasureFolderIds(); } /** * helper for {@link DataFilter.retrieve}. uses cached dataExtensions to resolve dataExtensionFields * * @param {DataFilterMap} metadataTypeMap - * @param {'retrieve'|'deploy'} [mode] - */ static async _cacheDeFields(metadataTypeMap, mode) { const deKeys = mode === 'retrieve' ? Object.values(metadataTypeMap) .filter((item) => item.derivedFromObjectTypeName === 'DataExtension') .filter((item) => item.derivedFromObjectId) .map((item) => { try { const deKey = cache.searchForField( 'dataExtension', item.derivedFromObjectId, 'ObjectID', 'CustomerKey' ); if (deKey) { this.deIdKeyMap ||= {}; this.deIdKeyMap[item.derivedFromObjectId] = deKey; return deKey; } } catch { return null; } }) .filter(Boolean) : Object.values(metadataTypeMap) .filter((item) => item.r__source_dataExtension_key) .map((item) => item.r__source_dataExtension_key) .filter( (deKey) => !this.cache[this.buObject.mid]?.dataExtensionField || !this.cache[this.buObject.mid]?.dataExtensionField[deKey] ) .filter(Boolean); if (deKeys.length) { const deKeysUnique = [...new Set(deKeys)]; Util.logger.info(' - Caching dependent Metadata: dataExtensionField'); // only proceed with the download if we have dataExtension keys const fieldOptions = {}; for (const deKey of deKeysUnique) { fieldOptions.filter = fieldOptions.filter ? { leftOperand: { leftOperand: 'DataExtension.CustomerKey', operator: 'equals', rightOperand: deKey, }, operator: 'OR', rightOperand: fieldOptions.filter, } : { leftOperand: 'DataExtension.CustomerKey', operator: 'equals', rightOperand: deKey, }; } DataExtensionField.buObject = this.buObject; DataExtensionField.client = this.client; DataExtensionField.properties = this.properties; this.saveDataExtensionFieldCacheToMap( (await DataExtensionField.retrieveForCacheDE(fieldOptions, ['Name', 'ObjectID'])) .metadata ); } } /** * helper for {@link DataFilter._cacheDeFields} * * @param {DataExtensionFieldMap} deFieldCache - */ static saveDataExtensionFieldCacheToMap(deFieldCache) { this.cache[this.buObject.mid] ||= {}; this.cache[this.buObject.mid].dataExtensionField ||= {}; if (!deFieldCache) { return; } for (const field of Object.values(deFieldCache)) { if (!field?.DataExtension?.CustomerKey) { continue; } if ( !this.cache[this.buObject.mid].dataExtensionField[field.DataExtension.CustomerKey] ) { /** @type {Object.<string, DataExtensionFieldItem[]>} */ this.cache[this.buObject.mid].dataExtensionField[field.DataExtension.CustomerKey] = []; } this.cache[this.buObject.mid].dataExtensionField[field.DataExtension.CustomerKey].push( field ); } } /** * helper for {@link DataFilter.retrieve} * * @param {DataFilterMap} metadataTypeMap - */ static async _cacheContactAttributes(metadataTypeMap) { if (this.cache[this.buObject.mid]?.contactAttributes) { return; } const subscriberFilters = Object.values(metadataTypeMap) .filter((item) => item.derivedFromObjectTypeName === 'SubscriberAttributes') .filter((item) => item.derivedFromObjectId); if (subscriberFilters.length) { Util.logger.info(' - Caching dependent Metadata: contactAttributes'); const response = await this.client.rest.get('/email/v1/Contacts/Attributes/'); const keyFieldBackup = this.definition.keyField; this.definition.keyField = 'id'; this.cache[this.buObject.mid] ||= {}; this.cache[this.buObject.mid].contactAttributes = this.parseResponseBody(response); this.definition.keyField = keyFieldBackup; } } /** * helper for {@link DataFilter.retrieve} * * @param {DataFilterMap} metadataTypeMap - */ static async _cacheMeasures(metadataTypeMap) { if (this.cache?.[this.buObject.mid]?.measures) { return; } const subscriberFilters = Object.values(metadataTypeMap) .filter((item) => item.derivedFromObjectTypeName === 'SubscriberAttributes') .filter((item) => item.derivedFromObjectId); const measureFolders = await this._getMeasureFolderIds(); if (subscriberFilters.length) { Util.logger.info(' - Caching dependent Metadata: measure'); const response = { items: [] }; for (const folderId of measureFolders) { const metadataMapFolder = await this.client.rest.getBulk( 'email/v1/Measures/category/' + folderId + '/', 250 // 250 is what the GUI is using ); if (Object.keys(metadataMapFolder.items).length) { response.items.push(...metadataMapFolder.items); } } const keyFieldBackup = this.definition.keyField; this.definition.keyField = 'measureID'; this.cache[this.buObject.mid] ||= {}; this.cache[this.buObject.mid].measures = this.parseResponseBody(response); this.definition.keyField = keyFieldBackup; } } /** * Retrieves all records for caching * * @returns {Promise.<{metadata: DataFilterMap, type: string}>} Promise of items */ static async retrieveForCache() { return this.retrieve(null); } /** * parses retrieved Metadata before saving * * @param {DataFilterItem} metadata a single record * @returns {Promise.<DataFilterItem>} parsed metadata definition */ static async postRetrieveTasks(metadata) { // if (metadata.derivedFromType > 4) { // // GUI only shows types 1,2,3,4; lets mimic that here. // // type 6 seems to be journey related. Maybe we need to change that again in the future // return; // } // folder super.setFolderPath(metadata); // parse XML filter for further processing in JSON format const xmlToJson = new XMLParser({ preserveOrder: false, // XML parser returns undefined if this is true ignoreAttributes: false, allowBooleanAttributes: true, }); metadata.c__filterDefinition = xmlToJson.parse( metadata.filterDefinitionXml )?.FilterDefinition; delete metadata.filterDefinitionXml; switch (metadata.derivedFromType) { case 1: { // if (metadata.c__filterDefinition['@_Source'] === 'SubscriberAttribute') { // if ( // metadata.derivedFromObjectId && // metadata.derivedFromObjectId !== '00000000-0000-0000-0000-000000000000' // ) { // // Lists // try { // metadata.r__source_list_PathName = cache.getListPathName( // metadata.derivedFromObjectId, // 'ObjectID' // ); // } catch { // Util.logger.warn( // ` - skipping ${this.definition.type} ${metadata.key}: list ${metadata.derivedFromObjectId} not found on current or Parent BU` // ); // } // } else { // // SubscriberAttributes // // - nothing to do // } // } // // SubscriberAttributes // this._postRetrieve_resolveAttributeIds(metadata); // delete metadata.derivedFromObjectId; // delete metadata.derivedFromObjectName; // delete metadata.derivedFromObjectTypeName; // delete metadata.derivedFromType; // delete metadata.c__filterDefinition['@_Source']; break; } case 2: { // DataExtension + XXX? if ( metadata.c__filterDefinition['@_Source'] === 'Meta' || metadata.derivedFromObjectId === '00000000-0000-0000-0000-000000000000' ) { // TODO - weird so far not understood case of Source=Meta // sample: <FilterDefinition Source=\"Meta\"><Include><ConditionSet Operator=\"OR\" ConditionSetName=\"Individual Filter Grouping\"><Condition ID=\"55530cec-1df4-e611-80cc-1402ec7222b4\" isParam=\"false\" isPathed=\"true\" pathAttrGroupID=\"75530cec-1df4-e611-80cc-1402ec7222b4\" Operator=\"Equal\"><Value><![CDATA[994607]]></Value></Condition><Condition ID=\"55530cec-1df4-e611-80cc-1402ec7222b4\" isParam=\"false\" isPathed=\"true\" pathAttrGroupID=\"75530cec-1df4-e611-80cc-1402ec7222b4\" Operator=\"Equal\"><Value><![CDATA[3624804]]></Value></Condition></ConditionSet></Include><Exclude></Exclude></FilterDefinition> } else if (metadata.c__filterDefinition['@_Source'] === 'DataExtension') { // DataExtension try { metadata.r__source_dataExtension_key = this.deIdKeyMap?.[metadata.derivedFromObjectId] || cache.searchForField( 'dataExtension', metadata.derivedFromObjectId, 'ObjectID', 'CustomerKey' ); delete metadata.derivedFromObjectName; delete metadata.derivedFromObjectTypeName; } catch { Util.logger.debug( ` - skipping ${this.definition.type} ${metadata.key}: dataExtension ${metadata.derivedFromObjectId} not found on BU` ); return; } this._resolveFields(metadata, 'postRetrieve'); delete metadata.derivedFromObjectId; delete metadata.derivedFromType; delete metadata.c__filterDefinition['@_Source']; delete metadata.c__filterDefinition['@_SourceID']; } break; } } return metadata; } /** * helper for {@link postRetrieveTasks} * * @param {DataFilterItem} metadata - * @param {'postRetrieve'|'preDeploy'} mode - * @param {DataExtensionFieldItem[]} [fieldCache] - * @param {FilterConditionSet} [filter] - * @returns {void} */ static _resolveFields(metadata, mode, fieldCache, filter) { if (!filter) { return this._resolveFields( metadata, mode, this.cache[this.buObject.mid].dataExtensionField[ metadata.r__source_dataExtension_key ], metadata.c__filterDefinition?.ConditionSet ); } if (filter.Condition) { const conditionsArr = Array.isArray(filter.Condition) ? filter.Condition : [filter.Condition]; if (mode === 'postRetrieve') { for (const condition of conditionsArr) { this._postRetrieve_resolveFieldIdsCondition(metadata, condition, fieldCache); } } else if (mode === 'preDeploy') { for (const condition of conditionsArr) { this._preDeploy_resolveFieldNamesCondition(metadata, condition, fieldCache); } } } if (filter.ConditionSet) { const conditionSet = Array.isArray(filter.ConditionSet) ? filter.ConditionSet : [filter.ConditionSet]; for (const cs of conditionSet) { this._resolveFields(metadata, mode, fieldCache, cs); } } } /** * helper for {@link _resolveFields} * * @param {DataFilterItem} metadata - * @param {FilterCondition} condition - * @param {DataExtensionFieldItem[]} fieldCache - * @returns {void} */ static _postRetrieve_resolveFieldIdsCondition(metadata, condition, fieldCache) { condition.r__dataExtensionField_name = fieldCache.find( (field) => field.ObjectID === condition['@_ID'] )?.Name; if (condition.r__dataExtensionField_name) { delete condition['@_ID']; } else { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: could not resolve dataExtensionField with ID ${condition['@_ID']} in condition` ); } if (['IsEmpty', 'IsNotEmpty'].includes(condition['@_Operator'])) { delete condition.Value; } } /** * helper for {@link _resolveFields} * * @param {DataFilterItem} metadata - * @param {FilterCondition} condition - * @param {DataExtensionFieldItem[]} fieldCache - * @returns {void} */ static _preDeploy_resolveFieldNamesCondition(metadata, condition, fieldCache) { condition['@_ID'] = fieldCache.find( (field) => field.Name === condition.r__dataExtensionField_name )?.ObjectID; if (condition['@_ID']) { delete condition.r__dataExtensionField_name; } else { throw new Error( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: could not resolve dataExtensionField with Name ${condition.r__dataExtensionField_name} in condition` ); } if (['IsEmpty', 'IsNotEmpty'].includes(condition['@_Operator'])) { condition.Value ||= ''; } else if (condition?.Value && typeof condition.Value !== 'object') { // allow adding cdata // @ts-ignore condition.Value = { cdata: condition.Value }; } } /** * helper for {@link postRetrieveTasks} * * @param {DataFilterItem} metadata - * @param {object} [filter] - * @returns {void} */ static _postRetrieve_resolveAttributeIds(metadata, filter) { if (!filter) { return this._postRetrieve_resolveAttributeIds( metadata, metadata.c__filterDefinition?.ConditionSet ); } const contactAttributes = this.cache[this.buObject.mid]?.contactAttributes; const measures = this.cache[this.buObject.mid]?.measures; const conditionsArr = Array.isArray(filter.Condition) ? filter.Condition : [filter.Condition]; for (const condition of conditionsArr) { condition['@_ID'] += ''; if (condition['@_SourceType'] === 'Measure' && measures[condition['@_ID']]) { condition.r__measure = measures[condition['@_ID']]?.name; delete condition['@_ID']; } else if ( condition['@_SourceType'] !== 'Measure' && contactAttributes[condition['@_ID']] ) { condition.r__contactAttribute = contactAttributes[condition['@_ID']]?.name; delete condition['@_ID']; } if (['IsEmpty', 'IsNotEmpty'].includes(condition['@_Operator'])) { delete condition.Value; } } if (filter.ConditionSet) { this._postRetrieve_resolveAttributeIds(metadata, filter.ConditionSet); } } /** * prepares a item for deployment * * @param {DataFilterItem} metadata a single record * @returns {Promise.<DataFilterItem>} Promise of updated single item */ static async preDeployTasks(metadata) { // folder super.setFolderId(metadata); // disable updates to r__source_dataExtension_key // the API and GUI prevent changes to the source data extensions. // to avoid confusion and accidental changes, we will reset the values from cache before deployment const normalizedKey = File.reverseFilterIllegalFilenames( metadata[this.definition.keyField] ); const cachedVersion = cache.getByKey(this.definition.type, normalizedKey); // DataExtension if (metadata.r__source_dataExtension_key) { metadata.derivedFromObjectId = cache.searchForField( 'dataExtension', metadata.r__source_dataExtension_key, 'CustomerKey', 'ObjectID' ); if ( cachedVersion && cachedVersion.derivedFromObjectId !== metadata.derivedFromObjectId ) { throw new Error( `Updating r__source_dataExtension_key is not allowed. You need to delete and re-create the dataFilter to change this.` ); } metadata.derivedFromObjectName = cache.searchForField( 'dataExtension', metadata.r__source_dataExtension_key, 'CustomerKey', 'Name' ); metadata.derivedFromObjectTypeName = 'DataExtension'; metadata.derivedFromType = 2; metadata.c__filterDefinition['@_Source'] = 'DataExtension'; metadata.c__filterDefinition['@_SourceID'] = metadata.derivedFromObjectId; this._resolveFields(metadata, 'preDeploy'); delete metadata.r__source_dataExtension_key; } const jsonToXml = new XMLBuilder({ preserveOrder: false, // XML Builder returns undefined if this is true ignoreAttributes: false, cdataPropName: 'cdata', }); metadata.filterDefinitionXml = jsonToXml.build({ FilterDefinition: metadata.c__filterDefinition, }); delete metadata.c__filterDefinition; return metadata; } /** * MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {boolean} [runUpsertSequentially] when a type has self-dependencies creates need to run one at a time and created/changed keys need to be cached to ensure following creates/updates have thoses keys available * @returns {Promise.<MetadataTypeMap>} keyField => metadata map */ static async upsert(metadataMap, deployDir, runUpsertSequentially = false) { Util.logBeta(this.definition.type); await this._cacheDeFields(metadataMap, 'deploy'); return super.upsert(metadataMap, deployDir, runUpsertSequentially); } /** * Creates a single item * * @param {DataFilterItem} metadata a single item * @returns {Promise.<DataFilterItem>} Promise */ static create(metadata) { return super.createREST(metadata, '/email/v1/filters/filterdefinition/'); } /** * Updates a single item * * @param {DataFilterItem} metadata a single item * @returns {Promise.<DataFilterItem>} Promise */ static update(metadata) { return super.updateREST( metadata, '/email/v1/filters/filterdefinition/' + metadata[this.definition.idField] ); } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or empty string */ static async _getObjectIdForSingleRetrieve(key) { const name = key.startsWith('name:') ? key.slice(5) : null; const response = await this.client.soap.retrieve(this.definition.soapType, ['ObjectID'], { filter: { leftOperand: name ? 'Name' : 'CustomerKey', operator: 'equals', rightOperand: name || key, }, }); return response?.Results?.length ? response.Results[0].ObjectID : null; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/email/v1/filters/filterdefinition/' + objectId, key); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DataFilter.definition = MetadataTypeDefinitions.dataFilter; export default DataFilter; ================================================ FILE: lib/metadataTypes/DataFilterHidden.js ================================================ 'use strict'; // const TYPE = require('../../types/mcdev.d'); import DataFilter from './DataFilter.js'; /** * DataFilterHidden (FilterDefinitionHidden) MetadataType * * @augments DataFilter */ class DataFilterHidden extends DataFilter { static hidden = true; } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DataFilterHidden.definition = MetadataTypeDefinitions.dataFilterHidden; export default DataFilterHidden; ================================================ FILE: lib/metadataTypes/DeliveryProfile.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * DeliveryProfile MetadataType * * @augments MetadataType */ class DeliveryProfile extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] not used * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { return super.retrieveREST( retrieveDir, '/legacy/v1/beta/messaging/deliverypolicy/', null, key ); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DeliveryProfile.definition = MetadataTypeDefinitions.deliveryProfile; export default DeliveryProfile; ================================================ FILE: lib/metadataTypes/Discovery.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ImportFile MetadataType * * @augments MetadataType */ class Discovery extends MetadataType { /** * Retrieves API endpoint * documentation: https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/routes.htm * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] not used * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { if (key) { Util.logger.error('Discovery.retrieve() does not support key parameter'); } if (this.buObject.eid === this.buObject.mid) { const res = await this.client.rest.getCollection( Object.keys(this.definition.endPointMapping).map( (endpoint) => this.definition.endPointMapping[endpoint] ) ); const metadataStructure = {}; for (const [i, v] of res.entries()) { v.key = Object.keys(this.definition.endPointMapping)[i]; metadataStructure[v.key] = v; } await super.saveResults(metadataStructure, retrieveDir, null); Util.logger.info('Downloaded: ' + this.definition.type); return { metadata: metadataStructure, type: this.definition.type }; } else { // don't run for BUs other than Parent BU Util.logger.warn(' - Skipping Discovery retrieval on non-parent BU'); return; } } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Discovery.definition = MetadataTypeDefinitions.discovery; export default Discovery; ================================================ FILE: lib/metadataTypes/DomainVerification.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').DomainVerificationItem} DomainVerificationItem */ /** * DomainVerification MetadataType * * @augments MetadataType */ class DomainVerification extends MetadataType { /** * Retrieves Metadata ofDomainVerification. * Endpoint /automation/v1/dataextracts/ returns all items * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { return super.retrieveREST(retrieveDir, '/messaging/v1/domainverification/', null, key); } /** * Retrieves Metadata of DomainVerification for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieveForCache() { return super.retrieveREST(null, '/messaging/v1/domainverification/'); } /** * Creates a single item * * @param {DomainVerificationItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem) { return metadataItem.domain === 'bulk' && (Array.isArray(metadataItem.addresses) || (metadataItem.deTable && metadataItem.deColumn)) ? this.createRESTBulk(metadataItem, '/messaging/v1/domainverification/') // bulk/insert : super.createREST(metadataItem, '/messaging/v1/domainverification/'); } /** * Creates a multiple metadata entries via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for POST * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async createRESTBulk(metadataEntry, uri) { if (metadataEntry.deTable || metadataEntry.deColumn) { Util.logger.error( 'It seems the deTable/deColumn approach does not work. Supply emails via addresses-array instead' ); return; } const createResults = {}; for (const address of metadataEntry.addresses) { if (cache.getByKey(this.definition.type, address)) { Util.logger.warn(` - ${this.definition.type} ${address} already exists`); continue; } const item = { domain: address }; if (await this.createREST(item, uri)) { createResults[address] = true; } } if (Object.keys(createResults).length) { // trigger re-retrieve to get all fields await this.postDeployTasks(createResults); await this.saveResults( createResults, [ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, ].join('/'), null ); } Util.logger.info( `${this.definition.type} bulk load: ${Object.keys(createResults).length} of ${metadataEntry.addresses.length} created` ); if (Object.keys(createResults).length) { Util.logger.warn('Please ignore the next message about filtering 1 item'); return `bulk successfully added.`; } else { return null; } } /** * helper for {@link MetadataType.createREST} * * @param {DomainVerificationItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<DomainVerificationItem>} apiResponse */ static async postCreateTasks(metadataEntry, apiResponse) { if (apiResponse && apiResponse === `${metadataEntry.domain} successfully added.`) { return metadataEntry; } else { throw new Error(apiResponse); } } /** * helper for {@link update} * * @param {DomainVerificationItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<DomainVerificationItem>} apiResponse, potentially modified */ static async postUpdateTasks(metadataEntry, apiResponse) { if (apiResponse && apiResponse === `1 records successfully updated!`) { metadataEntry.domain = metadataEntry.emailAddress; return metadataEntry; } else { throw new Error(apiResponse); } } /** * Updates a single item; replaces super.updateREST because we need to send metadataItem as an array for some reason and also get an array back * * @param {DomainVerificationItem} metadataItem a single item * @returns {Promise.<DomainVerificationItem>} Promise */ static async update(metadataItem) { const uri = '/messaging/v1/domainverification/update'; this.removeNotUpdateableFields(metadataItem); try { // set to empty object in case API returned nothing to be able to update it in helper classes let response = (await this.client.rest.post(uri, [metadataItem])) || {}; this.getErrorsREST(response); response = await this.postUpdateTasks(metadataItem, response); // some times, e.g. automation dont return a key in their update response and hence we need to fall back to name Util.logger.info(` - updated ${Util.getTypeKeyName(this.definition, metadataItem)}`); return metadataItem; } catch (ex) { const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error updating ${Util.getTypeKeyName(this.definition, metadataItem)}:` ); for (const msg of parsedErrors) { Util.logger.error(' • ' + msg); } return null; } } /** * manages post retrieve steps * * @param {DomainVerificationItem} metadataItem a single item * @returns {DomainVerificationItem|void} metadata */ static postRetrieveTasks(metadataItem) { if (typeof metadataItem === 'string' && metadataItem === 'bulk successfully added.') { // this is a hack for bulk-creation only return; } if (metadataItem.status !== 'Verified') { Util.logger.warn( Util.getMsgPrefix(this.definition, metadataItem) + ` is not verified. Current status: ${metadataItem.status}` ); } if (!metadataItem.isSendable) { Util.logger.warn( Util.getMsgPrefix(this.definition, metadataItem) + ` is not sendable.` ); } return metadataItem; } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static async postDeployTasks(upsertResults) { // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present) if (!Object.keys(upsertResults).length) { return; } Util.logger.debug( `Caching all ${this.definition.type} post-deploy to ensure we have all fields` ); const typeCache = await this.retrieveForCache(); // update values in upsertResults with retrieved values before saving to disk for (const key of Object.keys(upsertResults)) { if (typeCache.metadata[key]) { upsertResults[key] = typeCache.metadata[key]; } } } /** * prepares a single item for deployment * * @param {DomainVerificationItem} metadata a single item * @returns {Promise.<DomainVerificationItem>} Promise */ static async preDeployTasks(metadata) { if (metadata.domainType && metadata.domainType !== 'UserDomain') { throw new Error( `Can only delete entries of type 'UserDomain'. Found: ${metadata.domainType}` ); } // prep for update which uses emailAddress instead of domain metadata.emailAddress = metadata.domain; return metadata; } /** * Gets executed before deleting a list of keys for the current type * * @returns {Promise.<void>} - */ static async preDeleteTasks() { if (!cache.getCache()) { cache.initCache(this.buObject); } if (!cache.getCache()?.[this.definition.type]) { const cached = await this.retrieveForCache(); if (cached) { cache.setMetadata(this.definition.type, cached?.metadata); } } } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { const metadataItem = cache.getByKey(this.definition.type, key); if (!metadataItem) { await this.deleteNotFound(key); return false; } if (metadataItem.domainType !== 'UserDomain') { Util.logger.error( ` - ${this.definition.type} ${key}: Can only delete entries of type UserDomain. Found: ${metadataItem.domainType}` ); return false; } try { const response = await this.client.rest.post( '/messaging/v1/domainverification/delete', [ { emailAddress: metadataItem.domain, domainType: metadataItem.domainType, }, ] ); if (response === '1 records successfully updated!') { Util.logger.info(` - deleted ${this.definition.type}: ${key}`); this.postDeleteTasks(key); return true; } else { Util.logger.error( ` - Deleting ${this.definition.type} '${key}' failed: ` + response ); return false; } } catch (ex) { Util.logger.errorStack(ex, ` - Deleting ${this.definition.type} '${key}' failed`); return false; } } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; DomainVerification.definition = MetadataTypeDefinitions.domainVerification; export default DomainVerification; ================================================ FILE: lib/metadataTypes/Email.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * Email MetadataType * * @augments MetadataType */ class Email extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = null; if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } // !dont activate `await File.initPrettier('html');` as we only want to retrieve for migration and formatting might mess with the outcome return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * Helper for writing Metadata to disk, used for Retrieve and deploy * * @param {MetadataTypeMap} results metadata results from deploy * @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve * @param {string} [overrideType] for use when there is a subtype (such as folder-queries) * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMap>} Promise of saved metadata */ static async saveResults(results, retrieveDir, overrideType, templateVariables) { if (Object.keys(results).length) { // only execute the following if records were found Util.logger.warn( ' - Classic E-Mails are deprecated and will be discontinued by SFMC in the near future. Ensure that you migrate any existing E-Mails to Content Builder as soon as possible.' ); } return super.saveResults(results, retrieveDir, overrideType, templateVariables); } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single query * @returns {MetadataTypeItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata) { // folder super.setFolderPath(metadata); // extract code const codeArr = [ { subFolder: null, fileName: metadata.CustomerKey, fileExt: 'html', content: metadata.HTMLBody, }, ]; delete metadata.HTMLBody; return { json: metadata, codeArr: codeArr, subFolder: null }; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Email.definition = MetadataTypeDefinitions.email; export default Email; ================================================ FILE: lib/metadataTypes/EmailSend.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MessageSendActivity MetadataType * * @augments MetadataType */ class EmailSend extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = { filter: { leftOperand: { // somehow that parameter controls visible (non deleted?) email send activities leftOperand: 'IsPlatformObject', operator: 'equals', rightOperand: false, }, operator: 'AND', rightOperand: { leftOperand: 'Description', operator: 'notEquals', rightOperand: 'SFSendDefinition', }, }, }; if (key) { // move original filter down one level into rightOperand and add key filter into leftOperand requestParams = { filter: { leftOperand: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, operator: 'AND', rightOperand: requestParams.filter, }, }; } return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * Updates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static update(metadataItem) { return super.updateSOAP(metadataItem); } /** * Creates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem) { return super.createSOAP(metadataItem); } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(key) { return super.deleteByKeySOAP(key, undefined, 42002); } /** * prepares a single item for deployment * * @param {MetadataTypeItem} metadata a single script activity definition * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata) { // re-add IsPlatformObject, required for visibility metadata.IsPlatformObject = false; // folder super.setFolderId(metadata); // email; in case we still have Email.ID, keep it but warn metadata.Email ||= {}; if (metadata.r__email_name) { // classic metadata.Email.ID = cache.searchForField('email', metadata.r__email_name, 'Name', 'ID'); delete metadata.r__email_name; } else if (metadata.r__asset_key) { // content builder // * this ignores r__asset_name_readOnly on purpose\ as that is only unique per parent folder but useful during PR reviews // will try to find the key with the bu mid at the end, if unable, will try to find the key without it try { // check asset key as provided metadata.Email.ID = cache.searchForField( 'asset', metadata.r__asset_key, 'customerKey', 'legacyData.legacyId' ); delete metadata.r__asset_key; delete metadata.r__asset_name_readOnly; } catch { // if we deploy to another BU, try applying the BU's MID to the end, which we do in preDeployTasks for assets // get suffix to update customer key at the end const suffix = '-' + this.buObject.mid; metadata.Email.ID = cache.searchForField( 'asset', metadata.r__asset_key.slice(0, Math.max(0, 36 - suffix.length)) + suffix, 'customerKey', 'legacyData.legacyId' ); delete metadata.r__asset_key; delete metadata.r__asset_name_readOnly; } } else if (metadata.Email.ID) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Email.ID was provided manually in your deployment file. We recommend using r__asset_key instead.` ); try { // content builder - test only cache.searchForField( 'asset', metadata.Email.ID, 'legacyData.legacyId', 'customerKey' ); } catch { try { // classic - test only cache.searchForField('email', metadata.Email.ID, 'ID', 'Name'); } catch { throw new Error( ` ☇ skipping ${this.definition.type} ${metadata.Name} (${metadata.CustomerKey}): Could not find email with ID ${metadata.Email.ID} in Content Builder or Classic Emails.` ); } } } // Target Audience DataExtension // normalize first because this can be an array if (!metadata.SendDefinitionList) { metadata.SendDefinitionList = []; } else if (!Array.isArray(metadata.SendDefinitionList)) { metadata.SendDefinitionList = [metadata.SendDefinitionList]; } // Target Audience source // - DataSourceTypeID=CustomObject --> DataExtension is source; list is also defined // - DataSourceTypeID=List --> List is source; DE is not defined for (const sdl of metadata.SendDefinitionList) { // get DataExtension (optional) if (sdl.r__dataExtension_key) { if (sdl.DataSourceTypeID !== 'CustomObject') { throw new Error( `Expecting DataSourceTypeID to equal 'CustomObject' when r__dataExtension_key is defined; Found '${sdl.DataSourceTypeID}'` ); } sdl.CustomObjectID = cache.searchForField( 'dataExtension', sdl.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); delete sdl.r__dataExtension_key; } else if (sdl.DataSourceTypeID === 'CustomObject') { throw new Error( `Expecting r__dataExtension_key to be defined if DataSourceTypeID='CustomObject'` ); } if (!sdl.SalesForceObjectID || sdl.SalesForceObjectID === '') { // otherwise this causes error 42117 / invalid ObjectID delete sdl.SalesForceObjectID; } // get List (required) if (sdl.r__list_PathName) { sdl.List = { ID: cache.getListObjectId(sdl.r__list_PathName, 'ID'), }; delete sdl.r__list_PathName; } else if (sdl.SendDefinitionListType === 'SourceList') { // dont throw an error for type 'ExclusionList' throw new Error( `Field SendDefinitionList.r__list_PathName was not defined. Please try re-retrieving this ESD from your source BU.` ); } } // sender profile if (metadata.r__senderProfile_key) { cache.searchForField( 'senderProfile', metadata.r__senderProfile_key, 'CustomerKey', 'CustomerKey' ); metadata.SenderProfile = { CustomerKey: metadata.r__senderProfile_key, }; delete metadata.r__senderProfile_key; } // send classification if (metadata.r__sendClassification_key) { cache.searchForField( 'sendClassification', metadata.r__sendClassification_key, 'CustomerKey', 'CustomerKey' ); metadata.SendClassification = { CustomerKey: metadata.r__sendClassification_key, }; delete metadata.r__sendClassification_key; } // delivery profile if (metadata.r__deliveryProfile_key) { cache.searchForField('deliveryProfile', metadata.r__deliveryProfile_key, 'key', 'key'); metadata.DeliveryProfile = { CustomerKey: metadata.r__deliveryProfile_key, }; delete metadata.r__deliveryProfile_key; } return metadata; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single query * @returns {MetadataTypeItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata) { // remove IsPlatformObject, always has to be 'false' delete metadata.IsPlatformObject; // folder super.setFolderPath(metadata); // email if (metadata.Email?.ID) { try { // content builder const contentBuilderEmailName = cache.searchForField( 'asset', metadata.Email.ID, 'legacyData.legacyId', 'name' ); metadata.r__asset_name_readOnly = contentBuilderEmailName; const contentBuilderEmailKey = cache.searchForField( 'asset', metadata.Email.ID, 'legacyData.legacyId', 'customerKey' ); metadata.r__asset_key = contentBuilderEmailKey; delete metadata.Email; } catch { try { // classic const classicEmail = cache.searchForField( 'email', metadata.Email.ID, 'ID', 'Name' ); metadata.r__email_name = classicEmail; delete metadata.Email; } catch { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Could not find email with ID ${ metadata.Email.ID } Content Builder or Classic Emails.` ); } } } // Target Audience DataExtension // normalize first because this can be an array if (!metadata.SendDefinitionList) { metadata.SendDefinitionList = []; } else if (!Array.isArray(metadata.SendDefinitionList)) { metadata.SendDefinitionList = [metadata.SendDefinitionList]; } // Target Audience DataExtension for (const sdl of metadata.SendDefinitionList) { // get DataExtension keys if (sdl.CustomObjectID) { try { sdl.r__dataExtension_key = cache.searchForField( 'dataExtension', sdl.CustomObjectID, 'ObjectID', 'CustomerKey' ); delete sdl.CustomObjectID; } catch { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Could not find Target Audience (DataExtension) with ObjectID ${ sdl.CustomObjectID }.` ); } } // List if (sdl.List?.ID) { try { sdl.r__list_PathName = cache.getListPathName(sdl.List.ID, 'ID'); delete sdl.List; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}` ); } } if (!sdl.SalesForceObjectID) { // otherwise this causes error 42117 / invalid ObjectID delete sdl.SalesForceObjectID; } } // sender profile if (metadata.SenderProfile?.CustomerKey) { try { cache.searchForField( 'senderProfile', metadata.SenderProfile.CustomerKey, 'CustomerKey', 'CustomerKey' ); metadata.r__senderProfile_key = metadata.SenderProfile.CustomerKey; delete metadata.SenderProfile; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}` ); } } // send classification if (metadata.SendClassification?.CustomerKey) { try { cache.searchForField( 'sendClassification', metadata.SendClassification.CustomerKey, 'CustomerKey', 'CustomerKey' ); metadata.r__sendClassification_key = metadata.SendClassification.CustomerKey; delete metadata.SendClassification; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}` ); } } // delivery profile if (metadata.DeliveryProfile?.CustomerKey) { try { cache.searchForField( 'deliveryProfile', metadata.DeliveryProfile.CustomerKey, 'key', 'key' ); metadata.r__deliveryProfile_key = metadata.DeliveryProfile.CustomerKey; delete metadata.DeliveryProfile; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}` ); } } return metadata; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; EmailSend.definition = MetadataTypeDefinitions.emailSend; export default EmailSend; ================================================ FILE: lib/metadataTypes/Event.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; import deepEqual from 'deep-equal'; import pLimit from 'p-limit'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * * @typedef {import('../../types/mcdev.d.js').ReferenceObject} ReferenceObject * @typedef {import('../../types/mcdev.d.js').SfObjectField} SfObjectField * @typedef {import('../../types/mcdev.d.js').configurationArguments} configurationArguments * @typedef {import('../../types/mcdev.d.js').Conditions} Conditions * @typedef {import('../../types/mcdev.d.js').DataExtensionItem} DataExtensionItem */ /** * Event MetadataType * * @augments MetadataType */ class Event extends MetadataType { static reCacheDataExtensions = []; static createdKeys = []; /** * Retrieves Metadata of Event Definition. * Endpoint /interaction/v1/eventDefinitions return all Event Definitions with all details. * Currently it is not needed to loop over Imports with endpoint /interaction/v1/eventDefinitions/{id} * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { try { return await super.retrieveREST( retrieveDir, `/interaction/v1/eventDefinitions${ key ? '/key:' + encodeURIComponent(key) : '' }?extras=all`, null, key ); } catch (ex) { // if the event does not exist, the API returns the error "Request failed with status code 400 (ERR_BAD_REQUEST)" which would otherwise bring execution to a hold if (key && ex.code === 'ERR_BAD_REQUEST') { Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString(key)}` ); this.postDeleteTasks(key); } else { throw ex; } } return; } /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache() { return this.retrieve(null); } /** * Retrieve a specific Event Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise of metadata */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); const res = await this.client.rest.get( '/interaction/v1/eventDefinitions?name=' + encodeURIComponent(name) ); const event = res.items.filter((item) => item.name === name); try { if (!event || event.length === 0) { throw new Error(`No Event Definitions Found with name "${name}"`); } else if (event.length > 1) { throw new Error( `Multiple Event Definitions with name "${name}"` + `please rename to be unique to avoid issues` ); } else if (event?.length === 1) { const originalKey = event[0][this.definition.keyField]; const metadataItemTemplated = Util.replaceByObject( await this.postRetrieveTasks(event[0]), templateVariables ); if (!metadataItemTemplated.r__dataExtension_key) { throw new Error( `Event.postRetrieveTasks:: No Data Extension found for ${this.definition.type}: ${metadataItemTemplated.name}. This cannot be templated.` ); } // remove all fields listed in Definition for templating this.keepTemplateFields(metadataItemTemplated); await File.writeJSONToFile( [templateDir, this.definition.type].join('/'), originalKey + '.' + this.definition.type + '-meta', metadataItemTemplated ); Util.logger.info(` - templated ${this.definition.type}: ${name}`); return { metadata: metadataItemTemplated, type: this.definition.type }; } else { throw new Error( `Encountered unknown error when retrieveing ${ this.definition.typeName } "${name}": ${JSON.stringify(res.body)}` ); } } catch (ex) { Util.logger.error('Event.retrieveAsTemplate:: ' + ex); return null; } } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(key) { return await super.deleteByKeyREST( '/interaction/v1/eventDefinitions/key:' + encodeURIComponent(key), key, 30000 ); } /** * Deploys metadata - merely kept here to be able to print {@link Util.logBeta} once per deploy * * @param {MetadataTypeMap} metadata metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {string} retrieveDir directory where metadata after deploy should be saved * @returns {Promise.<MetadataTypeMap>} Promise of keyField => metadata map */ static async deploy(metadata, deployDir, retrieveDir) { Util.logBeta(this.definition.type); const metadataMap = await super.deploy(metadata, deployDir, retrieveDir); this.createdKeys.length = 0; // reset createdKeys after deploy to ensure it's not used in future retrieves return metadataMap; } /** * Creates a single Event Definition * * @param {MetadataTypeItem} metadata a single Event Definition * @returns {Promise} Promise */ static create(metadata) { this.createdKeys.push(metadata[this.definition.keyField]); return super.createREST(metadata, '/interaction/v1/eventDefinitions/'); } /** * Updates a single Event Definition (using PUT method since PATCH isn't supported) * * @param {MetadataTypeItem} metadataEntry a single Event Definition * @returns {Promise} Promise */ static async update(metadataEntry) { return super.updateREST( metadataEntry, '/interaction/v1/eventDefinitions/key:' + encodeURIComponent(metadataEntry[this.definition.keyField]), 'put' ); } /** * prepares an event definition for deployment * * @param {MetadataTypeItem} metadata a single eventDefinition * @returns {Promise.<MetadataTypeItem>} parsed version */ static async preDeployTasks(metadata) { // Note: lots has to be done in createOrUpdate based on what action is required metadata.arguments ||= {}; metadata.arguments.eventDefinitionKey = metadata.eventDefinitionKey; // standard values metadata.isVisibleInPicker ||= false; if (metadata.isVisibleInPicker && !metadata.sourceApplicationExtensionId) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: isVisibleInPicker is true but sourceApplicationExtensionId is missing. Setting isVisibleInPicker to false.` ); metadata.isVisibleInPicker = false; } metadata.isPlatformObject ||= false; metadata.mode ||= 'Production'; switch (metadata.type) { case 'APIEvent': { metadata.entrySourceGroupConfigUrl ||= 'jb:///data/entry/api-event/entrysourcegroupconfig.json'; metadata.iconUrl ||= '/images/icon_journeyBuilder-event-api-blue.svg'; break; } case 'SalesforceObjectTriggerV2': { metadata.iconUrl ||= '/events/js/salesforce-event/images/SF-Event-Icon.svg'; break; } case 'AutomationAudience': { metadata.iconUrl ||= '/images/icon-data-extension.svg'; break; } } // filter if (!metadata.filterDefinitionId) { metadata.filterDefinitionId = '00000000-0000-0000-0000-000000000000'; } // automation if (metadata.r__automation_key) { metadata.automationId = cache.searchForField( 'automation', metadata.r__automation_key, 'key', 'id' ); if (metadata.arguments) { metadata.arguments.automationId = metadata.automationId; } } else if (!metadata.automationId) { // if no automation was linked during retrieve we remove the field and hence need to re-set it before deployment metadata.automationId = '00000000-0000-0000-0000-000000000000'; if (metadata.arguments) { metadata.arguments.automationId = metadata.automationId; } } // dataExteension // is resolved in createOrUpdate const warnings = await this.preDeployTasks_SalesforceEntryEvents( metadata.type, metadata.configurationArguments ); if (warnings) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): ${warnings}` ); } await this.compareSalesforceEntryEvents_dataExtension( metadata.type, metadata.configurationArguments?.eventDataSummary, metadata.r__dataExtension_key ); return metadata; } /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadataMap list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create * @returns {Promise.<'create'|'update'|'skip'>} action to take */ static async createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ) { const createOrUpdateAction = await super.createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ); const metadataItem = metadataMap[metadataKey]; if (createOrUpdateAction === 'update') { if (metadataItem.r__dataExtension_key) { metadataItem.dataExtensionId = cache.searchForField( 'dataExtension', metadataItem.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); metadataItem.dataExtensionName = cache.searchForField( 'dataExtension', metadataItem.r__dataExtension_key, 'CustomerKey', 'Name' ); metadataItem.arguments.dataExtensionId = metadataItem.dataExtensionId; if (metadataItem.schema) { metadataItem.schema.id = metadataItem.dataExtensionId; metadataItem.schema.name = metadataItem.dataExtensionName; } } if (metadataItem.schema?.fields?.length) { const normalizedKey = File.reverseFilterIllegalFilenames( metadataMap[metadataKey][this.definition.keyField] ); const cachedVersion = cache.getByKey(this.definition.type, normalizedKey); if (cachedVersion?.schema?.fields?.length) { const cacheClone = structuredClone(cachedVersion); cacheClone.schema.fields = cacheClone.schema.fields.map((field) => { delete field.isDevicePreference; return field; }); if (!deepEqual(metadataItem?.schema?.fields, cacheClone?.schema?.fields)) { Util.logger.warn( ` - ${this.definition.type} ${metadataItem[this.definition.keyField]}: schema fields differ from server version. Resetting as this will not be reflected on dataExtension.` ); metadataItem.schema.fields = cacheClone.schema.fields; } } } } else if (createOrUpdateAction === 'create') { let deFound; try { if (metadataItem.r__dataExtension_key) { metadataItem.dataExtensionId = cache.searchForField( 'dataExtension', metadataItem.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); metadataItem.dataExtensionName = cache.searchForField( 'dataExtension', metadataItem.r__dataExtension_key, 'CustomerKey', 'Name' ); if (metadataItem.schema) { Util.logger.info( ` - ${this.definition.type} ${metadataItem[this.definition.keyField]}: dataExtension ${metadataItem.r__dataExtension_key} found, ignoring schema-section in ${this.definition.type} json` ); } deFound = true; } else { deFound = false; } } catch { deFound = false; } if (!deFound) { if (metadataItem.r__dataExtension_key) { if (!metadataItem.schema) { // make sure we skip this item this.removeFromDeployment(metadataKey, metadataToUpdate, metadataToCreate); throw new Error( `related dataExtension ${metadataItem.r__dataExtension_key} not found` ); } metadataItem.schema.name = metadataItem.r__dataExtension_key; } if (!metadataItem.schema) { this.removeFromDeployment(metadataKey, metadataToUpdate, metadataToCreate); throw new Error(`no related dataExtension and no schema found`); } Util.logger.warn( `Data Extension ${metadataItem.schema.name || metadataItem[this.definition.keyField]} not found on BU. Creating it automatically based on schema-definition.` ); // we want the event api to create the DE for us based on the schema this.reCacheDataExtensions.push({ eventKey: metadataItem[this.definition.keyField], deKey: metadataItem.schema.name || metadataItem[this.definition.keyField], }); } } return createOrUpdateAction; } /** * helper for {@link createOrUpdate} * * @param {string} metadataKey key of item we are looking at * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create */ static removeFromDeployment(metadataKey, metadataToUpdate, metadataToCreate) { const removeUpdate = metadataToUpdate.findIndex( (el) => el.after[this.definition.keyField] === metadataKey ); if (removeUpdate !== -1) { metadataToUpdate.splice(removeUpdate, 1); } const removeCreate = metadataToCreate.findIndex( (el) => el[this.definition.keyField] === metadataKey ); if (removeCreate !== -1) { metadataToCreate.splice(removeCreate, 1); } } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @param {MetadataTypeMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static async postDeployTasks(upsertResults, originalMetadata, createdUpdated) { // CREATE ONLY - if dataExtensions were auto-created if (this.reCacheDataExtensions.length && createdUpdated.created > 0) { Util.logger.warn(' - Re-caching dependent Metadata: dataExtension'); const deRetrieve = await DataExtension.retrieveForCache(); cache.setMetadata('dataExtension', deRetrieve.metadata); const reDownloadDeKeys = []; // try to update key & name of the auto-generated dataExtension for (const { eventKey, deKey } of this.reCacheDataExtensions) { if (!upsertResults[eventKey]) { continue; } const eventItem = upsertResults[eventKey]; const newDeKey = cache.searchForField( 'dataExtension', eventItem.dataExtensionId, 'ObjectID', 'CustomerKey' ); // get dataExtension from cache which conveniently already has the ObjectID set const deObj = cache.getByKey('dataExtension', newDeKey); const oldName = deObj[DataExtension.definition.nameField]; // prepare a clone of the DE to update name & key to match the event const clone = structuredClone(deObj); clone[DataExtension.definition.keyField] = deKey; clone[DataExtension.definition.nameField] = deKey; try { // update DE on server await DataExtension.update(clone, true); Util.logger.info( ` - changed dataExtension ${newDeKey} (${oldName}) key/name to ${deKey}` ); // update cache deObj[DataExtension.definition.keyField] = deKey; deObj[DataExtension.definition.nameField] = deKey; reDownloadDeKeys.push(deObj[DataExtension.definition.keyField]); } catch { // fallback, set DE key to value of DE name const clone = structuredClone(deObj); clone[DataExtension.definition.keyField] = oldName; try { // update DE on server await DataExtension.update(clone, true); Util.logger.info( ` - changed dataExtension ${newDeKey} (${oldName}) key to ${oldName}` ); // update cache deObj[DataExtension.definition.keyField] = deObj[DataExtension.definition.nameField]; reDownloadDeKeys.push(deObj[DataExtension.definition.keyField]); } catch { Util.logger.debug( ` - failed to change dataExtension ${newDeKey} (${oldName}) key/name` ); } } } this.reCacheDataExtensions.length = 0; // ensure we have downloaded auto-created DEs if (reDownloadDeKeys.length) { const retriever = new Retriever(this.properties, this.buObject); await retriever.retrieve(['dataExtension'], reDownloadDeKeys); } } // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present) Util.logger.debug( `Caching all ${this.definition.type} post-deploy to ensure we have all fields` ); const typeCache = await this.retrieveForCache(); // update values in upsertResults with retrieved values before saving to disk for (const key of Object.keys(upsertResults)) { if (typeCache.metadata[key]) { upsertResults[key] = typeCache.metadata[key]; } } } /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single event definition * @returns {Promise.<MetadataTypeItem>} parsed metadata */ static async postRetrieveTasks(metadata) { try { metadata.createdBy = cache.searchForField( 'user', metadata.createdBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } try { metadata.modifiedBy = cache.searchForField( 'user', metadata.modifiedBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } // filter if ( metadata?.filterDefinitionId && metadata.filterDefinitionId === '00000000-0000-0000-0000-000000000000' ) { // if no filter is linked this placeholder value is set which holds no value delete metadata.filterDefinitionId; } // automation if (metadata?.automationId) { if (metadata?.automationId === '00000000-0000-0000-0000-000000000000') { // if no automation is linked this placeholder value is set which holds no value delete metadata.automationId; } else { try { metadata.r__automation_key = cache.searchForField( 'automation', metadata.automationId, 'id', 'key' ); delete metadata.automationId; delete metadata.arguments?.automationId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } } } // dataExtension try { metadata.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.dataExtensionId, 'ObjectID', 'CustomerKey' ); delete metadata.dataExtensionId; delete metadata.dataExtensionName; delete metadata.arguments.dataExtensionId; if (metadata.schema) { delete metadata.schema.id; } } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } if (!metadata.isPlatformObject) { delete metadata.isPlatformObject; } if (metadata.mode === 'Production') { delete metadata.mode; } if (!this.createdKeys.includes(metadata[this.definition.keyField])) { if (metadata.interactionCount === 0 && metadata.publishedInteractionCount === 0) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): is not used and could therefore be deleted. Associated Journeys: ${metadata.interactionCount}. Active Journeys: ${metadata.publishedInteractionCount}.` ); } else if (metadata.publishedInteractionCount === 0) { Util.logger.info( Util.getGrayMsg( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): is currently inactive. Associated Journeys: ${metadata.interactionCount}. Active Journeys: ${metadata.publishedInteractionCount}.` ) ); } } try { await this.postRetrieveTasks_SalesforceEntryEvents( metadata.type, metadata.configurationArguments, metadata.eventDefinitionKey, metadata.publishedInteractionCount >= 1 ); } catch (ex) { const msg = ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}) with ${metadata.publishedInteractionCount} active journeys: ${ex.message}`; Util.logger.warn(metadata.publishedInteractionCount === 0 ? Util.getGrayMsg(msg) : msg); } try { await this.compareSalesforceEntryEvents_dataExtension( metadata.type, metadata.configurationArguments?.eventDataSummary, metadata.r__dataExtension_key ); } catch (ex) { const msg = ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}) with ${metadata.publishedInteractionCount} active journeys: ${ex.message}`; Util.logger.warn(metadata.publishedInteractionCount === 0 ? Util.getGrayMsg(msg) : msg); } return metadata; } static sfObjects = { /** @type {string[]} */ workflowObjects: null, /** @type {Object.<string, ReferenceObject[]>} object-name > object data */ referencedObjects: {}, /** @type {Object.<string, Object.<string, SfObjectField>>} object-name > field-name > field data */ objectFields: {}, /** @type {Object.<string, Promise.<any>>} */ loadingFields: {}, /** @type {Object.<string, Promise.<any>>} */ loadingRelatedObjects: {}, /** @type {Promise.<any>} */ loadingWorkflowObjects: null, }; /** * helper for {@link checkSalesforceEntryEvents} that retrieves information about SF object fields * * @param {string} objectAPIName salesforce object api name */ static async getSalesforceObjects(objectAPIName) { if (!objectAPIName) { return; } // 1 get all available Salesforce objects // similar response to /jbint/getWorkflowObjects if (!this.sfObjects.workflowObjects) { if (!this.sfObjects.loadingWorkflowObjects) { this.sfObjects.loadingWorkflowObjects = this._getWorkflowObjects(); } await this.sfObjects.loadingWorkflowObjects; } // 2 get objects related to the selected object // same response as /jbint/getRelatedObjects?type=<objectAPIName> if (!this.sfObjects.referencedObjects?.[objectAPIName]) { if (!this.sfObjects.loadingRelatedObjects[objectAPIName]) { this.sfObjects.loadingRelatedObjects[objectAPIName] = this._getRelatedSfObjects(objectAPIName); } await this.sfObjects.loadingRelatedObjects[objectAPIName]; // 3 get fields const rateLimit = pLimit(20); const uniqueSfObjectNames = this.sfObjects.referencedObjects[objectAPIName] ? [ ...new Set( Object.values(this.sfObjects.referencedObjects[objectAPIName]) .map((el) => el.referenceObjectName) .toSorted() ), ] : []; await Promise.all( uniqueSfObjectNames.map((objectAPIName) => rateLimit(async () => { this.sfObjects.loadingFields[objectAPIName] ||= this._getSalesforceObjectFields(objectAPIName); return this.sfObjects.loadingFields[objectAPIName]; }) ) ); // 4 create Common fields const contactLeadName = 'Contacts and Leads'; if ( this.sfObjects.objectFields['Contact'] && this.sfObjects.objectFields['Lead'] && !this.sfObjects.workflowObjects.includes(contactLeadName) ) { Util.logger.verbose( Util.getGrayMsg(' - Constructing Common / Contacts and Leads object') ); // add fake entry to workflowObjects to allow testing for this easily this.sfObjects.workflowObjects.push(contactLeadName); // construct fields object for it this.sfObjects.objectFields[contactLeadName] = {}; const contactFieldNames = Object.keys(this.sfObjects.objectFields['Contact']); const leadFieldNames = Object.keys(this.sfObjects.objectFields['Lead']); for (const fieldName of contactFieldNames.filter((item) => leadFieldNames.includes(item) )) { // copy the value from contact - while thats not perfectly correct it will hopefully be sufficient for what we need to check this.sfObjects.objectFields[contactLeadName][fieldName] = structuredClone( this.sfObjects.objectFields['Contact'][fieldName] ); this.sfObjects.objectFields[contactLeadName][fieldName].objectname = 'Common'; // do not delete fields from Contact or Lead because it depends on the environment where we have to look for those } // create duplicate to also reference this via "Common" this.sfObjects.objectFields['Common'] = this.sfObjects.objectFields[contactLeadName]; } } return; } /** * helper that allows skipping to run this again in multi-key retrieval */ static async _getWorkflowObjects() { Util.logger.info(Util.getGrayMsg(' - Caching Salesforce Objects')); const workflowObjectsResponse = await this.client.rest.get( `/data/v1/integration/member/salesforce/workflowobjects` ); this.sfObjects.workflowObjects = workflowObjectsResponse ? workflowObjectsResponse.map((o) => o.apiname) : []; } /** * helper that allows skipping to run this again in multi-key retrieval * * @param {string} objectAPIName SF entry object of the current event */ static async _getRelatedSfObjects(objectAPIName) { Util.logger.info( Util.getGrayMsg(' - Caching Related Salesforce Objects for ' + objectAPIName) ); try { const referenceObjectsResponse = await this.client.rest.get( `/data/v1/integration/member/salesforce/object/${objectAPIName}/referenceobjects` ); // add itself first so that we get the fields for objectAPIName as well const selfReference = { referenceObjectName: objectAPIName, relationshipName: objectAPIName, }; this.sfObjects.referencedObjects[objectAPIName] = referenceObjectsResponse ? [selfReference, ...referenceObjectsResponse] : [selfReference]; if ( referenceObjectsResponse.some((el) => el.referenceObjectName === 'Lead') && referenceObjectsResponse.some((el) => el.referenceObjectName === 'Contact') ) { // add fake object "Common" to referenced objects for testing this.sfObjects.referencedObjects[objectAPIName].push({ displayname: 'Common', relationshipIdName: 'Id', relationshipName: 'Common', isPolymorphic: false, referenceObjectName: 'Common', }); } } catch (ex) { if (ex.code === 'ERR_BAD_RESPONSE') { throw new Error( `Could not find Salesforce entry object ${objectAPIName} on connected org.`, { cause: ex } ); } } } /** * helper that allows skipping to run this again in multi-key retrieval * * @param {string} objectAPIName SF object for which to get the fields */ static async _getSalesforceObjectFields(objectAPIName) { if (this.sfObjects.objectFields[objectAPIName] || objectAPIName === 'Common') { return; } Util.logger.verbose( Util.getGrayMsg(' - Caching Fields for Salesforce Object ' + objectAPIName) ); const referenceObjectsFieldsResponse = await this.client.rest.get( `/legacy/v1/beta/integration/member/salesforce/object/${objectAPIName}` ); if (referenceObjectsFieldsResponse?.sfobjectfields?.length) { Util.logger.debug( `Found ${referenceObjectsFieldsResponse?.sfobjectfields?.length} fields for Salesforce Object ${objectAPIName}` ); this.sfObjects.objectFields[objectAPIName] = {}; // !add default fields that are somehow not always returned by this legacy beta API for (const field of this.defaultSalesforceFields) { // @ts-expect-error hack to work around shortcomings of legacy beta API this.sfObjects.objectFields[objectAPIName][field] = { label: field, name: field, }; } // add fields returned by API for (const field of referenceObjectsFieldsResponse.sfobjectfields) { this.sfObjects.objectFields[objectAPIName][field.name] = field; } } else { Util.logger.warn( `Could not cache fields for Salesforce Object '${objectAPIName}'. This is likely caused by insufficient access of your MC-Connect integration user. Please check assigned permission sets / the profile.` ); } return; } static defaultSalesforceFields = [ 'Id', 'Name', 'FirstName', 'LastName', 'Phone', 'CreatedById', 'CreatedDate', 'IsDeleted', 'LastModifiedById', 'LastModifiedDate', 'SystemModstamp', ]; /** * * @param {configurationArguments} ca trigger[0].configurationArguments * @param {boolean} isPublished if the current item is published it means we do not need to do contact vs common checks * @returns {string} warnings or null */ static checkSalesforceEntryEvents(ca, isPublished) { // 1 check eventDataConfig const edcObjects = ca.eventDataConfig.objects.toSorted((a, b) => a.dePrefix.localeCompare(b.dePrefix) ); const warnings = []; const errors = []; const dePrefixFields = {}; const dePrefixRelationshipMap = {}; const dePrefixReferenceObjectMap = {}; // SFMC only uses "Common" to aggreagate Contacts and Leads if that was actively selected in the entry event. Also, already published journeys/events continue to work even if fields would later be changed, leading to a shift from or to the "common" fake-object. const checkCommon = ca.whoToInject === 'Contact ID/Lead ID (Contacts and Leads)' && !isPublished; for (const object of edcObjects) { // create secondary object to quickly check eventDataSummary against dePrefixFields[object.dePrefix] = object.fields; // if the current object is the entry object then relationshipName and referenceObject are set to empty strings because it's not "referencing" a "relationship" but just listing its own fields dePrefixRelationshipMap[object.dePrefix] = object.relationshipName === '' ? object.dePrefix.split(':')[0] : object.relationshipName; dePrefixReferenceObjectMap[object.dePrefix] = object.referenceObject === '' ? object.dePrefix.split(':')[0] : object.referenceObject; // 1.1 check if fields in eventDataConfig exist in Salesforce // if it has no value this is the entry-source object itself const referencedObject = object.referenceObject === '' ? ca.objectAPIName : object.referenceObject; // sort list of fields alphabetically object.fields.sort(); // check if object was cached earlier if (!this.sfObjects.workflowObjects.includes(referencedObject)) { errors.push(`Salesforce object ${referencedObject} not found on connected org.`); } else if ( !this.sfObjects.objectFields[referencedObject] || !Object.keys(this.sfObjects.objectFields[referencedObject]).length ) { // check if we found fields for the object const msg = `Fields for Salesforce object ${referencedObject} could not be checked. Fields selected in entry event: ` + object.fields.join(', '); if (Util.OPTIONS.ignoreSfFields) { warnings.push(` (--ignoreSfFields) ` + msg); } else { errors.push( msg + ` (you can use --ignoreSfFields to skip this error in case you are convinced it is a false positive)` ); } } else { // check if the fields selected in the eventDefinition are actually available for (const fieldName of object.fields) { if ( checkCommon && (referencedObject === 'Contact' || referencedObject === 'Lead') && this.sfObjects.objectFields['Common'][fieldName] ) { errors.push( `Salesforce object field ${referencedObject}.${fieldName} needs to be referenced as Common.${fieldName}` ); } else if (!this.sfObjects.objectFields[referencedObject][fieldName]) { // TODO reactivate after switch to new API // errors.push( // `Salesforce object field ${referencedObject}.${fieldName} not available on connected org.` // ); } // 1.2 check if all fields in eventDataConfig are listed in the eventDataSummary if (!ca.eventDataSummary.includes(object.dePrefix + fieldName)) { // we could auto-create eventDataSummary but frankly this is good for code reviews and for searching for fields errors.push( `Field ${object.dePrefix + fieldName} is listed under eventDataConfig${object.referenceObject ? ` for referenceObject ` + object.referenceObject : ''} but not in eventDataSummary` ); } } } } // 2 compare eventDataConfig with eventDataSummary // check if all fields in eventDataSummary are listed in the eventDataConfig for (let fieldName of ca.eventDataSummary) { // we could auto-create eventDataSummary but frankly this is good for code reviews and for searching for fields const fieldPath = fieldName.split(':'); fieldName = fieldPath.pop(); const dePrefix = fieldPath.join(':') + ':'; if (!dePrefixFields[dePrefix]) { errors.push( `Field ${dePrefix + fieldName} is listed under eventDataSummary but object ${dePrefix} was not found in eventDataConfig` ); } else if (!dePrefixFields[dePrefix]?.includes(fieldName)) { errors.push( `Field ${dePrefix + fieldName} is listed under eventDataSummary but not in eventDataConfig` ); } } // 3 check contactKey // check against referencedObjects const referencedContactObj = this.sfObjects.referencedObjects[ca.objectAPIName].find( (el) => el.relationshipName === (ca.contactKey.relationshipName == '' ? ca.contactKey.referenceObjectName : ca.contactKey.relationshipName) ); if (referencedContactObj) { if ( ca.contactKey.isPolymorphic && referencedContactObj.isPolymorphic !== ca.contactKey.isPolymorphic ) { errors.push( `configurationArguments.contactKey states an incorrect isPolimorphic value. Should be ${referencedContactObj.isPolymorphic}` ); } if (referencedContactObj.referenceObjectName !== ca.contactKey.referenceObjectName) { errors.push( `configurationArguments.contactKey states an incorrect referenceObjectName value. Should be ${referencedContactObj.referenceObjectName}` ); } // * if contactKey uses "Common" then there is no fieldName attribute but instead relationshipIdName needs to be checked if ( checkCommon && ca.contactKey.referenceObjectName === 'Contact' && this.sfObjects.objectFields['Common'][ ca.contactKey.fieldName || ca.contactKey.relationshipIdName ] ) { errors.push( `configurationArguments.contactKey should be referencing Common instead of Contact` ); } else if ( !this.sfObjects.objectFields[ca.contactKey.referenceObjectName]?.[ ca.contactKey.fieldName || ca.contactKey.relationshipIdName ] ) { errors.push( `configurationArguments.contactKey states the invalid fieldName '${ca.contactKey.fieldName || ca.contactKey.relationshipIdName}' value that does not exist on ${ca.contactKey.referenceObjectName}` ); } } else { errors.push( `configurationArguments.contactKey references ${ ca.contactKey.relationshipName == '' ? ca.contactKey.referenceObjectName : ca.contactKey.relationshipName } which is not found in related salesforce objects` ); } // 4 check passThroughArgument const dePrefixCommon = ca.objectAPIName + ':Common'; for (const key of Object.keys(ca.passThroughArgument.fields)) { const fieldPath = ca.passThroughArgument.fields[key].split(':'); const fieldName = fieldPath.pop(); const dePrefix = fieldPath.join(':') + ':'; // it seems these fields do NOT need to be in the eventDataConfig const relationshipName = dePrefixRelationshipMap[dePrefix]; const referenceObject = dePrefixReferenceObjectMap[dePrefix]; if (!this.sfObjects.objectFields[referenceObject]?.[fieldName]) { errors.push( `Field ${dePrefix + fieldName} is listed under passThroughArgument.fields.${key} but is not available on connected org.` ); } else if ( checkCommon && (relationshipName === 'Contact' || relationshipName === 'Lead') && this.sfObjects.objectFields['Common']?.[fieldName] ) { errors.push( `Field ${dePrefix + fieldName} is listed under passThroughArgument.fields.${key} but needs to be referenced as ${dePrefixCommon}.${fieldName}` ); } } // 5.a check primaryObjectFilterCriteria this.checkSfFilterFieldsExist( ca.primaryObjectFilterCriteria.conditions, errors, 'primaryObjectFilterCriteria' ); // 5.b check relatedObjectFilterCriteria this.checkSfFilterFieldsExist( ca.relatedObjectFilterCriteria.conditions, errors, 'relatedObjectFilterCriteria' ); // 6.a remove primaryObjectFilterSummary (and auto-generate it again in preDeploy from primaryObjectFilterCriteria) // TODO // 6.b remove relatedObjectFilterSummary (and auto-generate it again in preDeploy from relatedObjectFilterCriteria) // TODO // 7 remove eventDataSummary (and auto-generate it again in preDeploy from eventDataConfig) // TODO // 8 remove evaluationCriteriaSummary (and auto-generate it again in preDeploy from salesforceTriggerCriteria) // TODO // throw error if problems were found if (errors?.length) { // add a line break if (errors.length > 1) { errors.unshift(``); } throw new Error(errors.join('\n · ')); } if (warnings?.length) { // add a line break if (warnings.length > 1) { warnings.unshift(``); } return warnings.join('\n · '); } else { return null; } } /** * * @param {object[]} conditions - * @param {string[]} errors list of errors * @param {'primaryObjectFilterCriteria'|'relatedObjectFilterCriteria'} context used to improve error logs */ static checkSfFilterFieldsExist(conditions, errors, context) { for (const condition of conditions) { if ( condition.fieldName & condition.referenceObjectName && !this.sfObjects.objectFields[condition.referenceObjectName]?.[condition.fieldName] ) { errors.push( `Field ${condition.referenceObjectName}.${condition.fieldName} is listed under ${context} but is not available on connected org.` ); } else if (condition.conditions) { this.checkSfFilterFieldsExist(condition.conditions, errors, context); } } } static requiredConfigurationArguments = [ 'applicationExtensionKey', 'contactKey', 'contactPersonType', 'eventDataConfig', 'objectAPIName', 'passThroughArgument', 'primaryObjectFilterCriteria', 'relatedObjectFilterCriteria', 'salesforceTriggerCriteria', 'version', 'whoToInject', ]; /** * * @param {string} triggerType e.g. SalesforceObjectTriggerV2, APIEvent, ... * @param {configurationArguments} ca trigger[0].configurationArguments * @param {string} key of event / journey * @param {boolean} isPublished if the current item is published it means we do not need to do contact vs common checks * @param {string} [type] optionally provide metadatype for error on missing configurationArguments attributes * @returns {Promise.<void>} - */ static async postRetrieveTasks_SalesforceEntryEvents(triggerType, ca, key, isPublished, type) { if (triggerType !== 'SalesforceObjectTriggerV2' || !ca) { return; } // normalize payload because these fields are sometimes set as strings and sometimes as objects // @ts-expect-error journeys SOMETIMES spell it "Api" and this script aims to auto-correct that if (ca.objectApiName) { // on event only the uppercase version is used. lets make sure we normalize that here. // @ts-expect-error journeys SOMETIMES spell it "Api" and this script aims to auto-correct that ca.objectAPIName = ca.objectApiName; // @ts-expect-error journeys SOMETIMES spell it "Api" and this script aims to auto-correct that delete ca.objectApiName; } // check if everything important is there or else MC Connect cannot publish this AND other journeys for (const attribute of this.requiredConfigurationArguments) { if (!ca[attribute]) { Util.logger.error( ` - ${type || this.definition.type} ${key}: required field configurationArguments.${attribute} not set` ); } } // normalize payload because these fields are sometimes set as strings and sometimes as objects ca.contactKey = 'string' === typeof ca.contactKey ? JSON.parse(ca.contactKey) : ca.contactKey; ca.eventDataConfig = 'string' === typeof ca.eventDataConfig ? JSON.parse(ca.eventDataConfig) : ca.eventDataConfig; ca.eventDataSummary = 'string' === typeof ca.eventDataSummary ? // @ts-expect-error transforming this from API-string-format to from mcdev-format ca.eventDataSummary.split('; ').filter(Boolean).toSorted() : ca.eventDataSummary; ca.passThroughArgument = 'string' === typeof ca.passThroughArgument ? JSON.parse(ca.passThroughArgument) : ca.passThroughArgument; ca.primaryObjectFilterCriteria = 'string' === typeof ca.primaryObjectFilterCriteria ? JSON.parse(ca.primaryObjectFilterCriteria) : ca.primaryObjectFilterCriteria; ca.relatedObjectFilterCriteria = 'string' === typeof ca.relatedObjectFilterCriteria ? JSON.parse(ca.relatedObjectFilterCriteria) : ca.relatedObjectFilterCriteria; // get info about salesforce objects if not already cached // * SF product team actually sometimes sets this field with uppercase "API" and sometimes with "Api"... Great job, guys! await this.getSalesforceObjects(ca.objectAPIName); // check if whats on the journey matches what SF Core offers this.checkSalesforceEntryEvents(ca, isPublished); } /** * * @param {string} triggerType e.g. SalesforceObjectTriggerV2, APIEvent, ... * @param {string[]} eventDataSummary eventDataConfig in simplified string-form * @param {string} deKey key of associated dataExtension * @returns {Promise.<void>} - */ static async compareSalesforceEntryEvents_dataExtension( triggerType, eventDataSummary, deKey ) { if (triggerType !== 'SalesforceObjectTriggerV2' || !eventDataSummary) { return; } /** @type {DataExtensionItem} */ const deItem = deKey ? cache.getByKey('dataExtension', deKey) : null; if (!deItem) { return; } eventDataSummary = 'string' === typeof eventDataSummary ? // @ts-expect-error transforming this from API-string-format to from mcdev-format eventDataSummary.split('; ').filter(Boolean).toSorted() : eventDataSummary; const errors = []; for (const fieldName of eventDataSummary) { if (!deItem.Fields.find((field) => field.Name === fieldName)) { errors.push( `Field ${fieldName} was not found in associated dataExtension ${deKey}` ); } } if (errors?.length) { // add a line break if (errors.length > 1) { errors.unshift(``); } throw new Error(errors.join('\n · ')); } } /** * * @param {string} triggerType e.g. SalesforceObjectTriggerV2, APIEvent, ... * @param {configurationArguments} ca trigger[0].configurationArguments * @returns {Promise.<string>} - */ static async preDeployTasks_SalesforceEntryEvents(triggerType, ca) { if (triggerType !== 'SalesforceObjectTriggerV2' || !ca) { return; } // check if everything important is there or else MC Connect cannot publish this AND other journeys const missingFields = []; for (const attribute of this.requiredConfigurationArguments) { if (!ca[attribute]) { missingFields.push(attribute); } } if (missingFields.length) { throw new Error( `required field not set: \n -` + missingFields .map((attribute) => `configurationArguments.${attribute}`) .join('\n - ') ); } // get info about salesforce objects if not already cached await this.getSalesforceObjects(ca.objectAPIName); // check if whats on the journey matches what SF Core offers const warnings = this.checkSalesforceEntryEvents(ca, false); // normalize payload because these fields are sometimes set as strings and sometimes as objects // @ts-expect-error reverting this back from mcdev-format to API format ca.contactKey = 'object' === typeof ca.contactKey ? JSON.stringify(ca.contactKey) : ca.contactKey; // @ts-expect-error reverting this back from mcdev-format to API format ca.eventDataConfig = 'object' === typeof ca.eventDataConfig ? JSON.stringify(ca.eventDataConfig) : ca.eventDataConfig; // @ts-expect-error reverting this back from mcdev-format to API format ca.eventDataSummary = Array.isArray(ca.eventDataSummary) ? ca.eventDataSummary.join('; ') + '; ' : ca.eventDataSummary; // @ts-expect-error reverting this back from mcdev-format to API format ca.passThroughArgument = 'object' === typeof ca.passThroughArgument ? JSON.stringify(ca.passThroughArgument) : ca.passThroughArgument; // @ts-expect-error reverting this back from mcdev-format to API format ca.primaryObjectFilterCriteria = 'object' === typeof ca.primaryObjectFilterCriteria ? JSON.stringify(ca.primaryObjectFilterCriteria) : ca.primaryObjectFilterCriteria; // @ts-expect-error reverting this back from mcdev-format to API format ca.relatedObjectFilterCriteria = 'object' === typeof ca.relatedObjectFilterCriteria ? JSON.stringify(ca.relatedObjectFilterCriteria) : ca.relatedObjectFilterCriteria; // @ts-expect-error journeys SOMETIMES spell it "Api" and this script aims to auto-correct that if (ca.objectApiName) { // on event only the uppercase version is used. lets make sure we normalize that here. // @ts-expect-error journeys SOMETIMES spell it "Api" and this script aims to auto-correct that ca.objectAPIName = ca.objectApiName; // @ts-expect-error journeys SOMETIMES spell it "Api" and this script aims to auto-correct that delete ca.objectApiName; } return warnings; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; import DataExtension from './DataExtension.js'; import Retriever from './../Retriever.js'; Event.definition = MetadataTypeDefinitions.event; export default Event; ================================================ FILE: lib/metadataTypes/FileLocation.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ImportFile MetadataType * * @augments MetadataType */ class FileLocation extends MetadataType { static cache = {}; /** * Retrieves Metadata of FileLocation * Endpoint /automation/v1/ftplocations/ return all FileLocations * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { try { const dataItems = await super.retrieveREST( null, '/data/v1/filetransferlocation' + (key ? '/' + encodeURIComponent(key) : 's'), null, key ); this.cache[this.buObject.mid] ||= {}; this.cache[this.buObject.mid].dataItems = dataItems.metadata; } catch (ex) { if (ex.code === 'ERR_BAD_REQUEST') { // if retrieve-by-key comes up empty, the data-endpoint returns a code 400 Util.logger.debug(ex.message); } else { Util.logger.warn(ex.message); } } const items = await super.retrieveREST( retrieveDir, '/automation/v1/ftplocations/', null, key ); return items; } /** * Retrieves folder metadata into local filesystem. Also creates a uniquePath attribute for each folder. * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieveForCache() { return this.retrieve(null); } /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} Promise */ static create(metadata) { return this.createREST(metadata, '/data/v1/filetransferlocation'); } /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} Promise */ static update(metadata) { return this.updateREST( metadata, '/data/v1/filetransferlocation/' + encodeURIComponent(metadata[this.definition.keyField]) ); } /** * helper for {@link MetadataType.parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword * * @param {MetadataTypeItem} metadata single item */ static createCustomKeyField(metadata) { if (metadata.fileTransferLocation) { const fileTransferLocation = metadata.fileTransferLocation; for (const key of Object.keys(metadata)) { delete metadata[key]; } Object.assign(metadata, fileTransferLocation); } else { if (!metadata.customerKey && this.cache[this.buObject.mid]?.dataItems) { const nameMatch = Object.values(this.cache[this.buObject.mid].dataItems).find( (item) => item.name === metadata.name ); if (nameMatch) { Object.assign(metadata, nameMatch); } } if (!this.definition.locationTypeIdMappingDeployable[metadata.locationTypeId]) { // old file location types are only returned by the automation-endpoint which does not return customerKey field - but also these are not updatable and hence we can improvise here metadata.customerKey ||= metadata.name; } } } /** * Creates a single metadata entry via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for POST * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async createREST(metadataEntry, uri, handleOutside) { this.removeNotCreateableFields(metadataEntry); const createPayload = { fileTransferLocation: metadataEntry }; try { // set to empty object in case API returned nothing to be able to update it in helper classes let response = (await this.client.rest.post(uri, createPayload)) || {}; response = await this.postCreateTasks(metadataEntry, response); if (!handleOutside) { Util.logger.info( ` - created ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } return response; } catch (ex) { const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error creating ${Util.getTypeKeyName(this.definition, metadataEntry)}:` ); if (parsedErrors.length) { for (const msg of parsedErrors) { Util.logger.error(' • ' + msg); } } else if (ex?.message) { Util.logger.debug(ex.message); } return null; } } /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} _ a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static async postCreateTasks(_, apiResponse) { return apiResponse?.fileTransferLocation || apiResponse; } /** * Updates a single metadata entry via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for PATCH * @param {'patch'|'post'|'put'} [httpMethod] defaults to 'patch'; some update requests require PUT instead of PATCH * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async updateREST(metadataEntry, uri, httpMethod = 'patch', handleOutside) { this.removeNotUpdateableFields(metadataEntry); const updatePayload = { fileTransferLocation: metadataEntry }; try { // set to empty object in case API returned nothing to be able to update it in helper classes let response = (await this.client.rest[httpMethod](uri, updatePayload)) || {}; await this._postChangeKeyTasks(metadataEntry); this.getErrorsREST(response); response = await this.postUpdateTasks(metadataEntry, response); // some times, e.g. automation dont return a key in their update response and hence we need to fall back to name if (!handleOutside) { Util.logger.info( ` - updated ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } return response; } catch (ex) { const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error updating ${Util.getTypeKeyName(this.definition, metadataEntry)}:` ); for (const msg of parsedErrors) { Util.logger.error(' • ' + msg); } return null; } } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} _ a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(_, apiResponse) { return apiResponse?.fileTransferLocation || apiResponse; } /** * prepares a import definition for deployment * * @param {MetadataTypeItem} metadata a single importDef * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata) { if (metadata.c__locationType) { metadata.locationTypeId = this.definition.locationTypeMapping[metadata.c__locationType]; if (this.definition.locationTypeMappingDeployable[metadata.c__locationType]) { metadata.locationType = this.definition.locationTypeMappingDeployable[metadata.c__locationType]; } else { throw new Error( `Only FileLocations of types ${Object.keys(this.definition.locationTypeMappingDeployable).join(', ')} can be deployed via mcdev.` ); } } return metadata; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata) { if (metadata.locationTypeId !== undefined) { try { metadata.c__locationType = Util.inverseGet( this.definition.locationTypeMapping, metadata.locationTypeId ); delete metadata.locationTypeId; } catch { Util.logger.info( 'Please report this new & unknown locationTypeId to the mcdev developer team via github: ' + metadata.locationTypeId ); } } else if (metadata.locationType) { // assuming create/update of new types metadata.c__locationType = Util.inverseGet( this.definition.locationTypeMappingDeployable, metadata.locationType ); } return metadata; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { return super.deleteByKeyREST( '/data/v1/filetransferlocation/' + encodeURIComponent(key), key, 400 ); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; FileLocation.definition = MetadataTypeDefinitions.fileLocation; export default FileLocation; ================================================ FILE: lib/metadataTypes/FileTransfer.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * FileTransfer MetadataType * * @augments MetadataType */ class FileTransfer extends MetadataType { /** * Retrieves Metadata of FileTransfer Activity. * Endpoint /automation/v1/filetransfers/ returns all File Transfers * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { return super.retrieveREST(retrieveDir, '/automation/v1/filetransfers/', null, key); } /** * Retrieves Metadata of FileTransfer Activity for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieveForCache() { return super.retrieveREST(null, '/automation/v1/filetransfers/'); } /** * Retrieve a specific File Transfer Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); const res = await this.client.rest.get( '/automation/v1/filetransfers/?$filter=name%20eq%20' + encodeURIComponent(name) ); if (Array.isArray(res?.items) && res?.items?.length) { // eq-operator returns a similar, not exact match and hence might return more than 1 entry const metadata = res.items.find((item) => item.name === name); if (!metadata) { Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`); return; } // get full definition const extended = await this.client.rest.get( '/automation/v1/filetransfers/' + metadata[this.definition.idField] ); const originalKey = extended[this.definition.keyField]; const val = JSON.parse( Util.replaceByObject( JSON.stringify(this.postRetrieveTasks(extended)), templateVariables ) ); // remove all fields listed in Definition for templating this.keepTemplateFields(val); await File.writeJSONToFile( [templateDir, this.definition.type].join('/'), originalKey + '.' + this.definition.type + '-meta', JSON.parse(Util.replaceByObject(JSON.stringify(val), templateVariables)) ); Util.logger.info(`- templated ${this.definition.type}: ${name}`); return { metadata: val, type: this.definition.type }; } else if (res?.items) { Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`); } else { throw new Error( `Encountered unknown error when retrieveing ${ this.definition.typeName } "${name}": ${JSON.stringify(res)}` ); } } /** * Creates a single File Transfer * * @param {MetadataTypeItem} fileTransfer a single File Transfer * @returns {Promise} Promise */ static create(fileTransfer) { return super.createREST(fileTransfer, '/automation/v1/filetransfers/'); } /** * Updates a single File Transfer * * @param {MetadataTypeItem} fileTransfer a single File Transfer * @returns {Promise} Promise */ static update(fileTransfer) { return super.updateREST(fileTransfer, '/automation/v1/filetransfers/' + fileTransfer.id); } /** * prepares a fileTransfer for deployment * * @param {MetadataTypeItem} metadata a single fileTransfer activity definition * @returns {Promise} Promise */ static async preDeployTasks(metadata) { if (metadata.r__fileLocation_name) { metadata.fileTransferLocationId = cache.searchForField( 'fileLocation', metadata.r__fileLocation_name, 'name', 'id' ); delete metadata.r__fileLocation_name; } else { throw new Error( 'r__fileLocation_name not set. Please ensure the source is properly set up and re-retrieve it first.' ); } return metadata; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single fileTransfer activity definition * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata) { try { metadata.r__fileLocation_name = cache.searchForField( 'fileLocation', metadata.fileTransferLocationId, 'id', 'name' ); delete metadata.fileTransferLocationId; } catch (ex) { Util.logger.warn( ` - FileTransfer '${metadata[this.definition.keyField]}': ${ex.message}` ); } return metadata; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static async _getObjectIdForSingleRetrieve(key) { const name = key.startsWith('name:') ? key.slice(5) : null; const filter = name ? '?$filter=name%20eq%20' + encodeURIComponent(name) : ''; const results = await this.client.rest.get('/automation/v1/filetransfers/' + filter); const items = results?.items || []; const found = items.find((item) => name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key ); return found?.id || null; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/automation/v1/filetransfers/' + objectId, key); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; FileTransfer.definition = MetadataTypeDefinitions.fileTransfer; export default FileTransfer; ================================================ FILE: lib/metadataTypes/Filter.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; import File from '../util/file.js'; const dataTypes = { 1: 'List', 2: 'DataExtension', 3: 'Group Wizard', 4: 'Behavioral Data', }; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').FilterItem} FilterItem */ /** * Filter MetadataType * * @augments MetadataType */ class Filter extends MetadataType { /** * Retrieves Metadata of Filter. * Endpoint /automation/v1/filters/ returns all Filters, * but only with some of the fields. So it is needed to loop over * Filters with the endpoint /automation/v1/filters/{id} * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : ''; return super.retrieveREST(retrieveDir, '/automation/v1/filters/' + objectId, null, key); } /** * parses retrieved Metadata before saving * * @param {FilterItem} metadata a single record * @returns {FilterItem} parsed metadata definition */ static postRetrieveTasks(metadata) { // folder super.setFolderPath(metadata); try { // filterDefinition metadata.r__dataFilter_key = cache.searchForField( 'dataFilter', metadata.filterDefinitionId, 'id', 'key' ); delete metadata.filterDefinitionId; } catch { try { // filterDefinitionHidden - auto-generated for filtered dataExtensions metadata.r__dataFilter_key = cache.searchForField( 'dataFilterHidden', metadata.filterDefinitionId, 'id', 'key' ); delete metadata.filterDefinitionId; } catch { // ignore } } // rest API does not return description property when it's empty but we always want this as part of our json metadata.description ||= ''; this._postRetrieve_dataTypeMapping('source', metadata); this._postRetrieve_dataTypeMapping('destination', metadata); return metadata; } /** * helper for postRetrieveTasks to map data types * * @param {'source'|'destination'} target we are processing source and destinations * @param {FilterItem} metadata single record */ static _postRetrieve_dataTypeMapping(target, metadata) { try { switch (metadata[`${target}TypeId`]) { // case 1: { // // List // // TODO // break; case 2: { // dataExtension metadata[`r__${target}_dataExtension_key`] = cache.searchForField( 'dataExtension', metadata[`${target}ObjectId`], 'ObjectID', 'CustomerKey' ); delete metadata[`${target}ObjectId`]; delete metadata[`${target}TypeId`]; break; } // case 3: { // // GroupWizard // // TODO // break; // } // case 4: { // // BehavioralData // // TODO // break; // } default: { Util.logger.warn( ` - Filter '${metadata.name}' (${ metadata.customerKey }): Unsupported ${target} type '${dataTypes[metadata[`${target}TypeId`]]}'` ); } } } catch (ex) { Util.logger.warn( ` - filter '${metadata.name}' (${metadata.customerKey}): ${target} not found (${ex.message})` ); } } /** * helper for preDeployTasks to map data types * * @param {'source'|'destination'} target we are processing source and destinations * @param {FilterItem} metadata single record * @param {FilterItem} cachedVersion cached version of the metadata */ static _preDeploy_dataTypeMapping(target, metadata, cachedVersion) { // TODO List / TypeId==1 // dataExtension if (metadata[`r__${target}_dataExtension_key`]) { metadata[`${target}TypeId`] = 2; metadata[`${target}ObjectId`] = cache.searchForField( 'dataExtension', metadata[`r__${target}_dataExtension_key`], 'CustomerKey', 'ObjectID' ); if ( cachedVersion && cachedVersion[`${target}ObjectId`] !== metadata[`${target}ObjectId`] ) { throw new Error( `Updating r__${target}_dataExtension_key is not allowed. You need to delete and re-create the filter to change this.` ); // metadata[`${target}ObjectId`] = cachedVersion[`${target}ObjectId`]; } if (target === 'source') { // this seems to be duplicated in update calls from the GUI metadata.filterDefinitionSourceTypeId = metadata[`${target}TypeId`]; metadata.sourceId = null; } else if (target === 'destination') { const deItem = cache.getByKey( 'dataExtension', metadata[`r__${target}_dataExtension_key`] ); metadata.resultDEDescription = deItem?.Description || ''; metadata.resultDEName = deItem?.Name || ''; metadata.resultDEKey = deItem?.CustomerKey || ''; metadata.resultGroupFolderId = null; metadata.resultGroupName = null; } delete metadata[`r__${target}_dataExtension_key`]; } // TODO GroupWizard / TypeId==3 // TODO BehavioralData / TypeId==4 } /** * Creates a single item * this uses soap API because the rest api does not allow hotlinking to an existing target DE * * @param {FilterItem} item a single item * @returns {Promise} Promise */ static async create(item) { // create: POST automation/v1/filters/ // {"filterDefinitionId":"4b9adc79-8f56-488c-9910-ab7ad7afc13a","name":"jb_talent_flat_2_gui","description":"","categoryId":"5319","sourceId":null,"resultGroupFolderId":null,"resultGroupName":null,"filterDefinitionSourceTypeId":2,"folderLocationText":"Filter","customerKey":"jb_talent_flat_2_gui","resultDEName":"jb_talent_flat_2_gui","resultDEKey":"jb_talent_flat_2_gui","resultDEDescription":""} // return super.createREST(item, '/automation/v1/filters/'); let response = null; try { response = await super.createSOAP(this.preCreateSOAPItem(item), true); Util.logger.info(` - created ${Util.getTypeKeyName(this.definition, item)}`); } catch (ex) { this._handleSOAPErrors(ex, 'creating', item, false); } return this.postCreateTasks(item, response); } /** * helper that converts the rest item into a soap item * * @param {FilterItem} item a single item * @returns {object} SOAP formatted filter item */ static preCreateSOAPItem(item) { return { FilterDefinitionID: item.filterDefinitionId, Name: item.name, Description: item.description || '', // CategoryID: item.categoryId, CustomerKey: item.customerKey, DestinationTypeID: item.destinationTypeId, DestinationObjectID: item.destinationObjectId, SourceTypeID: item.sourceTypeId, SourceObjectID: item.sourceObjectId, }; } /** * helper that runs update on all create calls to ensure all fields are set * * @param {FilterItem} restItem original rest item * @param {object} response SOAP response * @returns {Promise.<FilterItem>} created item */ static async postCreateTasks(restItem, response) { Util.logger.debug( ` - running post create tasks for ${Util.getTypeKeyName(this.definition, restItem)} to set the folder ID` ); if (!response) { return response; } const soapItem = response.Results?.[0].Object; restItem.filterActivityId = soapItem.FilterActivityID; return super.updateREST( restItem, '/automation/v1/filters/' + restItem[this.definition.idField], undefined, true ); } /** * Updates a single item * * @param {MetadataTypeItem} item a single item * @returns {Promise} Promise */ static update(item) { return super.updateREST(item, '/automation/v1/filters/' + item[this.definition.idField]); } /** * prepares a record for deployment * * @param {FilterItem} metadata a single record * @returns {Promise.<FilterItem>} Promise of updated single record */ static async preDeployTasks(metadata) { // folder super.setFolderId(metadata); // disable updates to r__dataFilter_key, r__source_dataExtension_key, r__destination_dataExtension_key // technically, the API allows changing the reference to the dataFilter but the GUI does not. // the API and GUI prevent changes to the source & destination data extensions. // to avoid confusion and accidental changes, we will reset the values from cache before deployment const normalizedKey = File.reverseFilterIllegalFilenames( metadata[this.definition.keyField] ); const cachedVersion = cache.getByKey(this.definition.type, normalizedKey); // filterDefinition if (metadata.r__dataFilter_key) { metadata.filterDefinitionId = cache.searchForField( 'dataFilter', metadata.r__dataFilter_key, 'key', 'id' ); if (cachedVersion && cachedVersion.filterDefinitionId !== metadata.filterDefinitionId) { throw new Error( `Updating r__dataFilter_key is not allowed. You need to delete and re-create the filter to change this.` ); } delete metadata.r__dataFilter_key; } if (!metadata.description) { metadata.description = ''; } metadata.resultGroupFolderId = null; metadata.sourceId = null; this._preDeploy_dataTypeMapping('source', metadata, cachedVersion); this._preDeploy_dataTypeMapping('destination', metadata, cachedVersion); return metadata; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or empty string */ static async _getObjectIdForSingleRetrieve(key) { const name = key.startsWith('name:') ? key.slice(5) : null; const response = await this.client.soap.retrieve(this.definition.soapType, ['ObjectID'], { filter: { leftOperand: name ? 'Name' : 'CustomerKey', operator: 'equals', rightOperand: name || key, }, }); return response?.Results?.length ? response.Results[0].ObjectID : ''; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/automation/v1/filters/' + objectId, key); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Filter.definition = MetadataTypeDefinitions.filter; export default Filter; ================================================ FILE: lib/metadataTypes/Folder.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import toposort from 'toposort'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * * @typedef {import('../../types/mcdev.d.js').ListItem} ListItem * @typedef {import('../../types/mcdev.d.js').ListMap} ListMap * @typedef {import('../../types/mcdev.d.js').ListIdMap} ListIdMap */ /** * Folder MetadataType * * @augments MetadataType */ class Folder extends MetadataType { /** * Retrieves metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] content type of folder * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: ListMap, type: string}>} Promise */ static async retrieve(retrieveDir, additionalFields, subTypeArr, key) { if (key) { Util.logger.error(`Folder.retrieve() does not support key parameter`); } /** @type {ListItem[]} */ const queryAllFolders = await this.retrieveHelper(additionalFields, false, subTypeArr); if (this.buObject.eid !== this.buObject.mid) { const selectedParentTypes = subTypeArr?.length ? subTypeArr.filter((item) => this.definition.folderTypesFromParent.includes(item)) : subTypeArr; if (!subTypeArr?.length || selectedParentTypes.length) { queryAllFolders.push( ...(await this.retrieveHelper(additionalFields, true, selectedParentTypes)) ); } } const sortPairs = toposort(queryAllFolders.map((a) => [a.ParentFolder.ID, a.ID])); /** @type {ListIdMap} */ const idMap = {}; for (const val of queryAllFolders) { // Contact Builder Lists create a folder called "Audiences" with the same Customer Key as the // main data extension folder. We restrict this from deploy so setting customer key to allow retrieve if (val.CustomerKey === 'dataextension_default' && val.Name === 'Audiences') { val.CustomerKey = 'dataextension_audiences'; } // by default folders do not have an external key, we set this to ID plus EID as this will be unique else if (!val.CustomerKey) { val.CustomerKey = [this.buObject.eid, val.ID].join('-'); } // ensure name is a string and not a number (SFMC-SDK workaround) val.Name = val.Name + ''; idMap[val.ID] = val; } // create root node for attaching, but will be deleted later // @ts-expect-error we set an incomplete ListItem for ID==0 which is flagged by ts idMap[0] = { Name: '<ROOT>', }; for (const id of sortPairs) { if (!idMap[id]) { Util.logger.debug(`id ${id} not found in idMap-obj but in sortPairs-array.`); } else if ( idMap[id].ParentFolder && Number.isSafeInteger(idMap[id].ParentFolder.ID) && idMap[id].Name !== '<ROOT>' ) { // if the parent folder can be found by ID if (idMap[idMap[id].ParentFolder.ID]) { // if the parent folder has a Path if (idMap[idMap[id].ParentFolder.ID].Path) { const parent = idMap[idMap[id].ParentFolder.ID]; // we use / here not system separator as it is important to keep metadata consistent // replace '/' in folder names with escape char to avoid confusion with the path separator idMap[id].Path = [ parent.Path, idMap[id].Name.replaceAll('/', Util.folderNameSlashEscapeChar), ].join(Util.standardizedSplitChar); idMap[id].ParentFolder.Path = parent.Path; } else { // replace '/' in folder names with escape char to avoid confusion with the path separator idMap[id].Path = idMap[id].Name.replaceAll( '/', Util.folderNameSlashEscapeChar ); } } else { Util.logger.info( Util.getGrayMsg( ` ☇ skipping folder ${idMap[id].Name} (${id}, type: ${idMap[id].ContentType}): Cannot find parent folder (${idMap[id].ParentFolder.ID})` ) ); delete idMap[id]; } } // All folders except the artificial root have ParentFolder attribute. If they dont something else is wrong else if (idMap[id].Name !== '<ROOT>') { idMap[id].Path = ''; Util.logger.warn( ` ☇ skipping folder ${idMap[id].Name} (${id}, type: ${idMap[id].ContentType}): Does not have a parent folder` ); delete idMap[id]; } } // helper for error warning const buMapping = {}; for (const cred in this.properties.credentials) { const buObj = this.properties.credentials[cred].businessUnits; for (const bu in buObj) { buMapping[buObj[bu]] = `${cred}/${bu}`; } } // build a new map using the customer key instead of id /** @type {ListMap} */ const metadata = {}; for (const id in idMap) { // remove keys which are listed in other BUs and skip root if ( idMap[id].Client?.ID && (this.buObject.mid == idMap[id].Client.ID || this.definition.folderTypesFromParent.includes( idMap[id].ContentType.toLowerCase() )) ) { if (metadata[idMap[id].CustomerKey]) { // check the shortest path as this is likely the more important folder. if (metadata[idMap[id].CustomerKey].Path.length > idMap[id].Path.length) { Util.logger.debug( `MetadataType[folder-${ idMap[id].ContentType }].retrieve:: Duplicate CustomerKey on Folder. Keeping: ${ idMap[id].Path }, Overwriting: ${metadata[idMap[id].CustomerKey].Path}` ); metadata[idMap[id].CustomerKey] = idMap[id]; } else { Util.logger.debug( `MetadataType[folder-${ idMap[id].ContentType }].retrieve:: Duplicate CustomerKey on Folder. Keeping: ${ metadata[idMap[id].CustomerKey].Path }, Ignoring: ${idMap[id].Path}` ); } } else { metadata[idMap[id].CustomerKey] = idMap[id]; } } else { delete idMap[id]; } } if (retrieveDir) { const savedMetadata = await this.saveResults(metadata, retrieveDir); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` ); } return { metadata, type: this.definition.type }; } /** * Retrieves folder metadata for caching * * @param {void | string[]} [_] parameter not used * @param {string[]} [subTypeArr] content type of folder * @returns {Promise.<{metadata: ListMap, type: string}>} Promise */ static retrieveForCache(_, subTypeArr) { return this.retrieve(null, null, subTypeArr, null); } /** * Folder upsert (copied from Metadata Upsert), after retrieving from target * and comparing to check if create or update operation is needed. * Copied due to having a dependency on itself, meaning the created need to be serial * * @param {ListMap} metadata metadata mapped by their keyField * @returns {Promise.<ListMap>} Promise of saved metadata */ static async upsert(metadata) { const orignalMetadata = structuredClone(metadata); let updateCount = 0; let updateFailedCount = 0; let createCount = 0; let createFailedCount = 0; let filteredByPreDeploy = 0; /** @type {ListMap} */ const upsertResults = {}; const sortPairs = toposort( Object.keys(metadata).map((customerKey) => [ metadata[customerKey].ParentFolder.Path, metadata[customerKey].Path, ]) ); // loop of loops to find a match between two arrays for (const folderPath of sortPairs) { for (const metadataKey in metadata) { if (metadata[metadataKey].Path === folderPath) { try { // preDeployTasks parsing const deployableMetadata = await this.preDeployTasks(metadata[metadataKey]); // if preDeploy returns nothing then it cannot be deployed so skip deployment if (deployableMetadata) { const normalizedKey = File.reverseFilterIllegalFilenames(metadataKey); let existingId; try { // perform a secondary check based on path // do not allow mapping folders from other BUs to avoid // treating a same-path folder from another BU as already existing const cachedVersion = cache.getFolderByPath( deployableMetadata.Path, undefined, false ); existingId = cachedVersion?.ID; if ( existingId && !this.hasChangedGeneric( cachedVersion, metadata[metadataKey], 'Path', true ) ) { Util.logger.verbose( ` - skipping ${this.definition.type} ${ cachedVersion?.Path || metadata[metadataKey][this.definition.nameField] }: no change detected` ); filteredByPreDeploy++; continue; } } catch { // In case no path matching, then try to use CustomerKey const cachedVersion = cache.getByKey('folder', normalizedKey); existingId = cachedVersion?.ID; if ( existingId && !this.hasChangedGeneric( cachedVersion, metadata[metadataKey], 'Path', true ) ) { Util.logger.verbose( ` - skipping ${this.definition.type} ${ cachedVersion?.Path || metadata[metadataKey][this.definition.nameField] }: no change detected` ); filteredByPreDeploy++; continue; } } if (existingId && Util.OPTIONS.noUpdate) { Util.logger.verbose( ` - skipping ${this.definition.type} ${ deployableMetadata?.Path || deployableMetadata[this.definition.nameField] }: --noUpdate flag is set` ); continue; } let result; // since deployableMetadata will be modified for deploy, make a copy for reference const beforeMetadata = structuredClone(deployableMetadata); if (existingId) { // if an existing folder exists with the same name/path then use that deployableMetadata.ID = existingId; result = await this.update(deployableMetadata); if (result) { updateCount++; } else { updateFailedCount++; } } else { result = await this.create(deployableMetadata); if (result) { createCount++; } else { createFailedCount++; } } if (result?.Results) { const parsed = this.parseResponseBody({ Results: [result.Results[0].Object], }); if (!result.Results[0].Object.CustomerKey && parsed['undefined']) { // when inserting folders without specifying a CustomerKey, this happens in parseResponseBody() parsed[normalizedKey] = parsed['undefined']; delete parsed['undefined']; } const newObject = { [normalizedKey]: Object.assign( beforeMetadata, parsed[normalizedKey] ), }; cache.mergeMetadata('folder', newObject); upsertResults[metadataKey] = beforeMetadata; } else { Util.logger.debug(result); throw new Error( `'${beforeMetadata.Path}' was not deployed correctly` ); } } } catch (ex) { Util.logger.errorStack(ex, `Upserting ${this.definition.type} failed`); } } } } // Logging Util.logger.info( `${this.definition.type} upsert: ${createCount} of ${ createCount + createFailedCount } created / ${updateCount} of ${updateCount + updateFailedCount} updated` + (filteredByPreDeploy > 0 ? ` / ${filteredByPreDeploy} filtered` : '') ); if (updateCount) { Util.logger.warn( ` - Folders are recognized for updates based on their CustomerKey or, if that is not given, their folder-path.` ); } await this.postDeployTasks(upsertResults, orignalMetadata, { created: createCount, updated: updateCount, }); return upsertResults; } /** * creates a folder based on metatadata * * @param {ListItem} metadataEntry metadata of the folder * @returns {Promise.<any>} Promise of api response */ static async create(metadataEntry) { if (metadataEntry?.ParentFolder?.ID === 0) { Util.logger.debug( `${this.definition.type}-${metadataEntry.ContentType}.create:: Cannot create Root Folder: ${metadataEntry.Name}` ); return {}; } const path = metadataEntry.Path; let apiTypeSoap = false; try { if (this.definition.deployFolderTypesEmailRest.includes(metadataEntry.ContentType)) { // * The SOAP endpoint for creating folders does not support folders for automations nor journeys. The Rest endpoint on the other hand errors out on certain characters in the folder names that are actually valid. We therefore only use Rest for the folder types that are not supported by SOAP. const restPayload = { parentCatId: metadataEntry.ParentFolder.ID, name: metadataEntry.Name, catType: metadataEntry.ContentType, }; const response = await super.createREST(restPayload, '/email/v1/category', true); if (response?.categoryId) { // convert the response to the same format as the SOAP response // set the new folder ID metadataEntry.ID = response.categoryId; // set the client ID to ensure we can find the newly created folders as parents for folders created afterwards inside of it metadataEntry.Client = { ID: metadataEntry.Client?.ID || this.buObject.mid, }; // the following is a bit of a hack to make the response look like the SOAP response; not sure if we actually need that anywhere like this --> future developers feel free to double check const returnObject = { Results: [ { Object: metadataEntry, }, ], }; Util.logger.info(` - created folder: ${path}`); return returnObject; } else { throw new Error(JSON.stringify(response)); } } else if ( this.definition.deployFolderTypesAssetRest.includes(metadataEntry.ContentType) ) { // * The SOAP endpoint for creating folders does not support folders for automations nor journeys. The Rest endpoint on the other hand errors out on certain characters in the folder names that are actually valid. We therefore only use Rest for the folder types that are not supported by SOAP. const restPayload = { parentId: metadataEntry.ParentFolder.ID, categoryType: metadataEntry.ContentType, extendable: 1, editable: 1, name: metadataEntry.Name, description: '', }; const response = await super.createREST( restPayload, '/asset/v1/content/categories', true ); if (response?.id) { // convert the response to the same format as the SOAP response // set the new folder ID metadataEntry.ID = response.id; // set the client ID to ensure we can find the newly created folders as parents for folders created afterwards inside of it metadataEntry.Client = { ID: metadataEntry.Client?.ID || this.buObject.mid, }; // the following is a bit of a hack to make the response look like the SOAP response; not sure if we actually need that anywhere like this --> future developers feel free to double check const returnObject = { Results: [ { Object: metadataEntry, }, ], }; Util.logger.info(` - created folder: ${path}`); return returnObject; } else { throw new Error(JSON.stringify(response)); } } else { apiTypeSoap = true; const response = await super.createSOAP(metadataEntry, true); if (response) { // set the client ID to ensure we can find the newly created folders as parents for folders created afterwards inside of it metadataEntry.Client = { ID: metadataEntry.Client?.ID || this.buObject.mid, }; // set the new folder ID metadataEntry.ID = response.Results[0].NewID; response.Results[0].Object = metadataEntry; delete response.Results[0].Object.$; Util.logger.info(` - created folder: ${path}`); return response; } } } catch (ex) { if (apiTypeSoap) { this._handleSOAPErrors(ex, 'creating', metadataEntry, false, 'Name'); } else { if (ex?.results) { Util.logger.error( `${this.definition.type}-${metadataEntry.ContentType}.create:: error creating: '${path}'. ${ex.results[0].StatusMessage}` ); } else if (ex) { Util.logger.error( `${this.definition.type}-${metadataEntry.ContentType}.create:: error creating: '${path}'. ${ex.message}` ); } } } } /** * Updates a single Folder. * * @param {MetadataTypeItem} metadataEntry single metadata entry * @returns {Promise.<any>} Promise of api response */ static async update(metadataEntry) { if (metadataEntry?.ParentFolder?.ID === 0) { Util.logger.debug( `${this.definition.type}-${metadataEntry.ContentType}.create:: Cannot create Root Folder: ${metadataEntry.Name}` ); return {}; } const path = metadataEntry.Path; let apiTypeSoap = false; try { let response; if (this.definition.deployFolderTypesAssetRest.includes(metadataEntry.ContentType)) { // * The SOAP endpoint for creating folders does not support folders for automations nor journeys. The Rest endpoint on the other hand errors out on certain characters in the folder names that are actually valid. We therefore only use Rest for the folder types that are not supported by SOAP. const restPayload = { id: metadataEntry.ID, parentId: metadataEntry.ParentFolder.ID, // categoryType: metadataEntry.ContentType, extendable: 1, // ? editable: 1, // ? name: metadataEntry.Name, description: '', }; response = await super.updateREST( restPayload, '/asset/v1/content/categories/' + metadataEntry.ID, 'put', true ); if (response?.id) { // convert the response to the same format as the SOAP response // set the client ID to ensure we can find the newly created folders as parents for folders created afterwards inside of it metadataEntry.Client = { ID: metadataEntry.Client?.ID || this.buObject.mid, }; // the following is a bit of a hack to make the response look like the SOAP response; not sure if we actually need that anywhere like this --> future developers feel free to double check const returnObject = { Results: [ { Object: metadataEntry, }, ], }; Util.logger.info(` - updated folder: ${path}`); return returnObject; } else { throw new Error(JSON.stringify(response)); } } else { apiTypeSoap = true; response = await super.updateSOAP(metadataEntry, true); if (response.Results?.[0]?.StatusCode === 'OK') { response.Results[0].Object = metadataEntry; response.Results[0].Object.CustomerKey = metadataEntry.CustomerKey; delete response.Results[0].Object.$; Util.logger.info(` - updated folder: ${path}`); return response; } } } catch (ex) { if (apiTypeSoap) { this._handleSOAPErrors(ex, 'updating', metadataEntry, false, 'Name'); } else { if (ex?.results) { Util.logger.error( `${this.definition.type}-${metadataEntry.ContentType}.update:: error updating: '${path}'. ${ex.results[0].StatusMessage}` ); } else if (ex) { Util.logger.error( `${this.definition.type}-${metadataEntry.ContentType}.update:: error updating: '${path}'. ${ex.message}` ); } } } } /** * prepares a folder for deployment * * @param {ListItem} metadata a single folder definition * @returns {Promise.<ListItem>} Promise of parsed folder metadata */ static async preDeployTasks(metadata) { if (!this.definition.deployFolderTypes.includes(metadata.ContentType.toLowerCase())) { Util.logger.warn( ` - Folder ${metadata.Name} is of a type which does not support deployment (Type: ${metadata.ContentType}). Please create this manually in the Web-Interface.` ); return; } // skip certain folders by name else if (this.definition.deployFolderBlacklist.includes(metadata.Name.toLowerCase())) { Util.metadataLogger( 'debug', 'folder', 'preDeployTasks', `Folder ${metadata.Name} is blacklisted for deployment due to it being a reserved name or that folder cannot be deployed` ); return; } // skip when metadata isnt editable else if (!metadata.IsEditable) { Util.metadataLogger( 'warn', 'folder', 'preDeployTasks', `Folders with IsEditable (such as ${metadata.Name}) are skipped in deployment to avoid overwriting system folder` ); return; } // retrieve ID based on the matching Path of the parent folder else if (metadata?.ParentFolder?.Path) { // do not allow mapping folders to other BUs during deploy metadata.ParentFolder.ID = cache.getFolderId( metadata.ParentFolder.Path, undefined, false ); return metadata; } else { Util.metadataLogger( 'warn', 'folder', 'preDeployTasks', `skipping root folder '${metadata.Name}' (no need to include this in deployment)` ); return; } } /** * Returns file contents mapped to their filename without '.json' ending * * @param {string} dir directory with json files, e.g. /retrieve/cred/bu/folder, /deploy/cred/bu/folder, /template/folder * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {Promise.<ListMap>} fileName => fileContent map */ static async getJsonFromFS(dir, listBadKeys) { try { /** @type {ListMap} */ const fileName2FileContent = {}; const directories = File.readDirectoriesSync(dir, 10, true); let newCounter = 0; if (!Array.isArray(directories)) { return fileName2FileContent; } for (const subdir of directories) { // standardise to / and then remove the stem up until folder as this // should not be in the path for the metadata. In case no split then return empty as this is root const standardSubDir = File.reverseFilterIllegalFilenames( subdir.replaceAll('\\', '/').split(/folder\//)[1] || '' ); for (const fileName of await File.readdir(subdir)) { try { if (fileName.endsWith('meta.json')) { const fileContent = await File.readJSONFile(subdir, fileName, false); const fileNameWithoutEnding = File.reverseFilterIllegalFilenames( fileName.split(/\.(\w|-)+-meta.json/)[0] ); if (fileContent.Name === fileNameWithoutEnding) { // replace '/' in folder names with escape char to match how paths are built during retrieve fileContent.Path = (standardSubDir ? standardSubDir + '/' : '') + fileNameWithoutEnding.replaceAll( '/', Util.folderNameSlashEscapeChar ); fileContent.ParentFolder = { Path: standardSubDir, }; const key = fileContent.CustomerKey || `new-${++newCounter}`; if (fileName2FileContent[key]) { Util.logger.error( `Your have multiple folder-JSONs with the same CustomerKey '${key}' - skipping ${fileName}` ); } else { fileName2FileContent[key] = fileContent; } } else if (!listBadKeys) { Util.metadataLogger( 'error', this.definition.type, 'getJsonFromFS', 'Name of the Folder and the Filename must match', JSON.stringify({ Filename: fileNameWithoutEnding, MetadataName: fileContent.Name, }) ); } } } catch (ex) { // by catching this in the loop we gracefully handle the issue and move on to the next file Util.metadataLogger('debug', this.definition.type, 'getJsonFromFS', ex); } } } return fileName2FileContent; } catch (ex) { Util.metadataLogger('error', this.definition.type, 'getJsonFromFS', ex); throw ex; } } /** * Helper to retrieve the folders as promise * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {boolean} [queryAllAccounts] which queryAllAccounts setting to use * @param {string[]} [contentTypeList] content type of folder * @returns {Promise.<ListItem[]>} soap object */ static async retrieveHelper(additionalFields, queryAllAccounts, contentTypeList) { const options = { QueryAllAccounts: !!queryAllAccounts }; if (contentTypeList) { const newFilter = { leftOperand: 'ContentType', operator: contentTypeList.length === 1 ? 'equals' : 'IN', rightOperand: contentTypeList.length === 1 ? contentTypeList[0] : contentTypeList.toSorted(), }; options.filter = options.filter ? { leftOperand: newFilter, operator: 'OR', rightOperand: options.filter, } : newFilter; } const response = await this.client.soap.retrieveBulk( 'DataFolder', this.getFieldNamesToRetrieve(additionalFields).filter( (field) => !field.includes('Path') ), options ); return response.Results ?? []; } /** * Gets executed after retreive of metadata type * * @param {ListItem} metadata metadata mapped by their keyField * @returns {ListItem} cloned metadata */ static postRetrieveTasks(metadata) { return structuredClone(metadata); } /** * Helper for writing Metadata to disk, used for Retrieve and deploy * * @param {ListMap} results metadata results from deploy * @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve * @returns {Promise.<ListMap>} Promise of saved metadata */ static async saveResults(results, retrieveDir) { /** @type {ListMap} */ const savedResults = {}; for (const metadataEntry in results) { try { // skip saving shared folders as they technically live in parent. if ( results[metadataEntry].Client && this.buObject.mid != results[metadataEntry].Client.ID ) { // deploy: folders auto-generated by deploy do not have .Client set and hence this check will be skipped // retrieve: Client.ID is set to the MID of the BU that the folder belongs to; we only want folders of the current BU saved here continue; } else if ( results[metadataEntry] && (this.isFiltered(results[metadataEntry], true) || this.isFiltered(results[metadataEntry], false)) ) { // if current metadata entry is filtered skip writeJSONToFile() continue; } // get subfolder into which we need to save this JSON // * cannot use split('/') here due to the "A/B Testing" folder const stem = results[metadataEntry].Path.slice( 0, -results[metadataEntry].Name.length ); // we dont store Id on local disk, but we need it for caching logic, // so its in retrieve but not in save. Here we put into the clone so that the original // object used for caching doesnt have the Id removed. const tempHolder = this.postRetrieveTasks(results[metadataEntry]); this.keepRetrieveFields(tempHolder); delete tempHolder.ParentFolder; delete tempHolder.Client; if (!this.definition.keepId) { delete tempHolder.ID; } savedResults[metadataEntry] = tempHolder; // need to {await} writeJSONToFile() here because sometimes SFMC allows the same folder to be created twice and then we run into race conditions, causing bad JSON to be saved await File.writeJSONToFile( // manage subtypes [retrieveDir, 'folder', stem], tempHolder.Name + '.folder-meta', tempHolder ); } catch (ex) { Util.metadataLogger( 'error', this.definition.type, 'saveResults', ex, metadataEntry ); } } return savedResults; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Folder.definition = MetadataTypeDefinitions.folder; export default Folder; ================================================ FILE: lib/metadataTypes/ImportFile.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError */ /** * ImportFile MetadataType * * @augments MetadataType */ class ImportFile extends MetadataType { /** * Retrieves Metadata of Import File. * Endpoint /automation/v1/imports/ return all Import Files with all details. * Currently it is not needed to loop over Imports with endpoint /automation/v1/imports/{id} * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { let objectId = null; if (key) { // using '?$filter=customerKey%20eq%20' + encodeURIComponent(key) would also work but that just retrieves more data for no reason objectId = await this._getObjectIdForSingleRetrieve(key); if (!objectId) { // avoid running the rest request below by returning early Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString(key)}` ); this.postDeleteTasks(key); return { metadata: {}, type: this.definition.type }; } } Util.logger.debug(' - retrieving extended metadata for SMS imports'); const smsImportResults = await this.client.rest.getBulk( '/legacy/v1/beta/mobile/imports/', 50 ); this.smsImports = {}; if (smsImportResults.totalResults > 0 && smsImportResults.entry.length > 0) { if (smsImportResults.entry.filter((item) => !!item.sourceObjectId).length > 0) { // imports from data extensions require additional information (item.sourceFile != '_CustomObject' and item.sourceObjectId is not set) Util.logger.info( Util.getGrayMsg( ` - Caching dependent Metadata: dataExtension (source for SMS imports)` ) ); } const sourceObject = {}; for (const item of smsImportResults.entry) { // this api does not show the key but the name is assumed to be unique this.smsImports[item.name] = item; if (!item.sourceObjectId) { continue; } try { if (!sourceObject[item.sourceObjectId]) { sourceObject[item.sourceObjectId] = await this.client.rest.get( '/legacy/v1/beta/object/' + item.sourceObjectId ); } item.sourceObjectKey = sourceObject[item.sourceObjectId].key; } catch { Util.logger.warn( `endpoint /legacy/v1/beta/object/${item.sourceObjectId} does not exist` ); } } } return super.retrieveREST( retrieveDir, '/automation/v1/imports/' + (objectId || ''), null, key ); } /** * helper for {@link MetadataType.retrieveRESTcollection} * * @param {SDKError} ex exception * @param {string} key id or key of item * @param {string} url url to call for retry * @returns {Promise.<any>} can return retry-result */ static async handleRESTErrors(ex, key, url) { try { if (ex.code == 'ERR_BAD_RESPONSE') { // one more retry; it's a rare case but retrying again should solve the issue gracefully Util.logger.info( ` - Connection problem (Code: ${ex.code}). Retrying once${ ex.endpoint ? Util.getGrayMsg( ' - ' + ex.endpoint.split('rest.marketingcloudapis.com')[1] ) : '' }` ); Util.logger.errorStack(ex); return await this.client.rest.get(url); } } catch { // no extra action needed, handled below } // if we do get here, we should log the error and continue instead of failing to download all automations Util.logger.error(` ☇ skipping ${this.definition.type} ${key}: ${ex.message} ${ex.code}`); return null; } /** * Retrieves import definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static retrieveForCache(_, __, key) { return this.retrieve(null, null, null, key); } /** * Retrieve a specific Import Definition by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); // using '?$filter=name%20eq%20' + encodeURIComponent(name) would also work but that just retrieves more data for no reason const cache = await this.retrieveForCache(null, null, 'name:' + name); const metadataArr = Object.values(cache?.metadata); if (Array.isArray(metadataArr) && metadataArr.length) { // eq-operator returns a similar, not exact match and hence might return more than 1 entry const metadata = metadataArr.find((item) => item.name === name); if (!metadata) { Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`); return; } const originalKey = metadata[this.definition.keyField]; const val = JSON.parse( Util.replaceByObject( JSON.stringify(this.postRetrieveTasks(metadata)), templateVariables ) ); // remove all fields listed in Definition for templating this.keepTemplateFields(val); await File.writeJSONToFile( [templateDir, this.definition.type].join('/'), originalKey + '.' + this.definition.type + '-meta', JSON.parse(Util.replaceByObject(JSON.stringify(val), templateVariables)) ); Util.logger.info(`- templated ${this.definition.type}: ${name}`); return { metadata: val, type: this.definition.type }; } else if (metadataArr) { Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`); } else { throw new Error( `Encountered unknown error when retrieveing ${ this.definition.typeName } "${name}": ${JSON.stringify(metadataArr)}` ); } } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static async _getObjectIdForSingleRetrieve(key) { const response = await this.client.soap.retrieve('ImportDefinition', ['ObjectID'], { filter: key.startsWith('name:') ? { leftOperand: 'Name', operator: 'equals', rightOperand: key.slice(5), } : { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }); return response?.Results?.length ? response.Results[0].ObjectID : null; } /** * Creates a single Import File * * @param {MetadataTypeItem} importFile a single Import File * @returns {Promise} Promise */ static create(importFile) { return super.createREST(importFile, '/automation/v1/imports/'); } /** * Updates a single Import File * * @param {MetadataTypeItem} importFile a single Import File * @returns {Promise} Promise */ static update(importFile) { return super.updateREST( importFile, '/automation/v1/imports/' + importFile.importDefinitionId ); } /** * Deploys metadata * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {string} retrieveDir directory where metadata after deploy should be saved * @returns {Promise.<MetadataTypeMap>} Promise of keyField => metadata map */ static async deploy(metadataMap, deployDir, retrieveDir) { if ( Object.values(metadataMap).filter((item) => item.destination.c__type === 'SMS').length > 0 ) { Util.logger.info(`Caching dependent Metadata: dataExtension (source for SMS imports)`); const dataExtensionLegacyResult = await this.client.rest.getBulk( '/legacy/v1/beta/object/', 500 ); this.dataExtensionsLegacy = {}; if (dataExtensionLegacyResult?.entry?.length) { for (const item of dataExtensionLegacyResult.entry) { this.dataExtensionsLegacy[item.key] = item; } } } return super.deploy(metadataMap, deployDir, retrieveDir); } /** * prepares a import definition for deployment * * @param {MetadataTypeItem} metadata a single importDef * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata) { if (metadata.source?.r__fileLocation_name) { const fileLocation = cache.getByKey( 'fileLocation', metadata.source?.r__fileLocation_name ); if (!fileLocation) { throw new Error( `fileLocation ${metadata.source?.r__fileLocation_name} not found in cache` ); } metadata.fileTransferLocationId = fileLocation.id; metadata.fileTransferLocationTypeId = fileLocation.locationTypeId; delete metadata.source.r__fileLocation_name; } switch (metadata.destination.c__type) { case 'DataExtension': { if (metadata.destination.r__dataExtension_key) { metadata.destinationObjectId = cache.searchForField( 'dataExtension', metadata.destination.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); delete metadata.destination.r__dataExtension_key; } else { throw new Error('Import Destination DataExtension not defined'); } if (metadata.source.c__type === 'DataExtension' && metadata.r__dataExtension_key) { // only happens for dataimport activities (summer24 release) metadata.source.sourceCustomObjectId = cache.searchForField( 'dataExtension', metadata.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); metadata.source.sourceDataExtensionName = cache.searchForField( 'dataExtension', metadata.r__dataExtension_key, 'CustomerKey', 'Name' ); delete metadata.r__dataExtension_key; } break; } case 'List': { if (metadata.destination.r__list_PathName) { metadata.destinationObjectId = cache.getListObjectId( metadata.destination.r__list_PathName, 'ObjectID' ); // destinationId is also needed for List types metadata.destinationId = cache.getListObjectId( metadata.destination.r__list_PathName, 'ID' ); delete metadata.destination.r__list_PathName; } else { throw new Error('Import Destination List not defined'); } break; } case 'SMS': { if (metadata.destination.r__mobileKeyword_key) { // code const codeObj = cache.getByKey( 'mobileCode', metadata.destination.r__mobileKeyword_key.split('.')[0] ); if (!codeObj) { throw new Error( `mobileCode ${metadata.destination.r__mobileKeyword_key} not found in cache` ); } metadata.code = codeObj; // keyword const keywordObj = cache.getByKey( 'mobileKeyword', metadata.destination.r__mobileKeyword_key ); if (!keywordObj) { throw new Error( `mobileKeyword ${metadata.destination.r__mobileKeyword_key} not found in cache` ); } metadata.keyword = keywordObj; } else { Util.logger.error( ` - importFile ${metadata[this.definition.keyField]}: No code or keyword info found. Please re-download this from the source.` ); } // destination metadata.destinationObjectId = '00000000-0000-0000-0000-000000000000'; metadata.destinationObjectType = 'MobileSubscription'; // source if (this.dataExtensionsLegacy[metadata.source.r__dataExtension_key]) { metadata.sourceObjectId = this.dataExtensionsLegacy[metadata.source.r__dataExtension_key].id; metadata.sourceObjectName = this.dataExtensionsLegacy[ metadata.source.r__dataExtension_key ].dataExtensionName; delete metadata.source.r__dataExtension_key; } throw new Error( `Import Destination Type ${metadata.destination.c__type} not fully supported.` ); } default: { // e.g. WhatsApp throw new Error( `Import Destination Type ${metadata.destination.c__type} not fully supported.` ); } } if (metadata.c__blankFileProcessing) { // omit this if not set metadata.blankFileProcessingType = this.definition.blankFileProcessingTypeMapping[metadata.c__blankFileProcessing]; } // When the destinationObjectTypeId is 584 it refers to Mobile Connect which is not supported as an Import Type metadata.destinationObjectTypeId = this.definition.destinationObjectTypeMapping[metadata.destination.c__type]; metadata.subscriberImportTypeId = this.definition.subscriberImportTypeMapping[metadata.c__subscriberImportType]; metadata.updateTypeId = this.definition.updateTypeMapping[metadata.c__dataAction]; delete metadata.destination; delete metadata.source; return metadata; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata) { metadata.destination = { // * When the destinationObjectTypeId is 584 it refers to Mobile Connect which is not supported as an Import Type c__type: Util.inverseGet( this.definition.destinationObjectTypeMapping, metadata.destinationObjectTypeId ), }; // destination.c__type SMS & DataExtension both set fileNamingPattern to _CustomObject and they both define a DE as source metadata.source = { c__type: metadata.fileNamingPattern === '_CustomObject' || metadata.fileSpec === '_CustomObject' ? 'DataExtension' : 'File Location', }; if (metadata.fileTransferLocationId !== '00000000-0000-0000-0000-000000000000') { try { metadata.source.r__fileLocation_name = cache.searchForField( 'fileLocation', metadata.fileTransferLocationId, 'id', 'name' ); delete metadata.fileTransferLocationId; } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } } switch (metadata.destination.c__type) { case 'DataExtension': { try { metadata.destination.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.destinationObjectId, 'ObjectID', 'CustomerKey' ); delete metadata.destinationObjectId; } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } if ( metadata.source.c__type === 'DataExtension' && metadata.sourceCustomObjectId !== '' ) { // only happens for dataimport activities (summer24 release) try { metadata.source.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.sourceCustomObjectId, 'ObjectID', 'CustomerKey' ); delete metadata.sourceCustomObjectId; delete metadata.sourceDataExtensionName; } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } } break; } case 'List': { try { metadata.destination.r__list_PathName = cache.getListPathName( metadata.destinationObjectId, 'ObjectID' ); delete metadata.destinationObjectId; } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } break; } case 'SMS': { if (this.smsImports[metadata.name]) { const smsImport = this.smsImports[metadata.name]; // code try { cache.searchForField('mobileCode', smsImport.code?.code, 'code', 'code'); } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } // keyword try { cache.searchForField( 'mobileKeyword', smsImport.keyword?.keyword, 'c__codeKeyword', 'c__codeKeyword' ); } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } // code + keyword metadata.destination.r__mobileKeyword_key = smsImport.code?.code + '.' + smsImport.keyword?.keyword; // source dataExtension if (smsImport.sourceObjectKey) { metadata.source.r__dataExtension_key = smsImport.sourceObjectKey; } } else { Util.logger.warn( ` - importFile ${metadata.customerKey}: Could not find mobile code and keyword nor source for this SMS import activity.` ); } // remove empty desitination delete metadata.destinationObjectId; break; } case 'WhatsApp': { if ( metadata.source.c__type === 'DataExtension' && metadata.sourceCustomObjectId !== '' ) { // only happens for dataimport activities (summer24 release) try { metadata.source.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.sourceCustomObjectId, 'ObjectID', 'CustomerKey' ); delete metadata.sourceCustomObjectId; delete metadata.sourceDataExtensionName; } catch (ex) { Util.logger.warn(` - importFile ${metadata.customerKey}: ${ex.message}`); } } break; } default: { Util.logger.debug( ` - importFile ${metadata.customerKey}: Destination Type ${metadata.destinationObjectTypeId} not fully supported. Deploy might fail.` ); } } delete metadata.destinationObjectTypeId; if (metadata.blankFileProcessingType !== undefined) { // omit this if not set metadata.c__blankFileProcessing = Util.inverseGet( this.definition.blankFileProcessingTypeMapping, metadata.blankFileProcessingType ); delete metadata.blankFileProcessingType; } metadata.c__subscriberImportType = Util.inverseGet( this.definition.subscriberImportTypeMapping, metadata.subscriberImportTypeId ); delete metadata.subscriberImportTypeId; metadata.c__dataAction = Util.inverseGet( this.definition.updateTypeMapping, metadata.updateTypeId ); delete metadata.updateTypeId; return metadata; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/automation/v1/imports/' + objectId, key); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; ImportFile.definition = MetadataTypeDefinitions.importFile; export default ImportFile; ================================================ FILE: lib/metadataTypes/Journey.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import TransactionalEmail from './TransactionalEmail.js'; import DataExtensionField from './DataExtensionField.js'; import TriggeredSend from './TriggeredSend.js'; import Event from './Event.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; import File from '../util/file.js'; import ReplaceCbReference from '../util/replaceContentBlockReference.js'; import Retriever from '../Retriever.js'; import pLimit from 'p-limit'; import yoctoSpinner from 'yocto-spinner'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * Journey MetadataType * id: A unique id of the journey assigned by the journey’s API during its creation * key: A unique id of the journey within the MID. Can be generated by the developer * definitionId: A unique UUID provided by Salesforce Marketing Cloud. Each version of a journey has a unique DefinitionID while the Id and Key remain the same. Version 1 will have id == definitionId * * @augments MetadataType */ class Journey extends MetadataType { /** * Retrieves Metadata of Journey * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { const extrasDefault = 'activities'; let singleKey = ''; let mode = 'all'; const additionalParams = new URLSearchParams(); if (Util.OPTIONS.onlyPublished) { Util.logger.info(' - Retrieving only published versions of journeys'); additionalParams.set('status', 'Published'); } if (key) { if (key.startsWith('%23')) { // correct the format key = 'id:' + key.slice(3); } if (key.startsWith('id:')) { // ! allow selecting journeys by ID because that's what users see in the URL // if the key started with %23 assume an ID was copied from the URL but the user forgot to prefix it with id: // remove id: or %23 singleKey = key.slice(3); if (singleKey.startsWith('%23')) { // in the journey URL the Id is prefixed with an HTML-encoded "#" which could accidentally be copied by users // despite the slicing above, this still needs testing here because users might have prefixed the ID with id: but did not know to remove the #23 singleKey = singleKey.slice(3); // correct the format to ensure we show sth readable in the "Downloaded" log key = 'id:' + singleKey; } if (singleKey.includes('/')) { // in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the ID for the retrieve as we always aim to retrieve the latest version only singleKey = singleKey.split('/')[0]; } mode = 'id'; } else if (key.startsWith('name:')) { additionalParams.set('nameOrDescription', key.slice(5)); mode = 'name'; } else { // assume actual key was provided singleKey = 'key:' + encodeURIComponent(key); mode = 'key'; } } try { const uri = `/interaction/v1/interactions/`; if ( (!Util.OPTIONS.onlyPublished && singleKey && (mode === 'key' || mode === 'id')) || !retrieveDir ) { // full details for retrieve, only base data for caching; reduces caching time from minutes to seconds const extras = retrieveDir && singleKey ? extrasDefault : ''; // caching or single retrieve return await super.retrieveREST( retrieveDir, `${uri}${singleKey}?extras=${extras}${key && key.includes('/') ? '&versionNumber=' + key.split('/')[1] : ''}`, null, key ); } else { const url = uri + (additionalParams.size > 0 ? '?' + additionalParams.toString() : ''); // retrieve all const results = this.definition.restPagination ? await this.client.rest.getBulk(url, this.definition.restPageSize || 500) : await this.client.rest.get(url); if (results.items?.length) { // empty results will come back without "items" defined Util.logger.info( Util.getGrayMsg( ` - ${results.items?.length} ${this.definition.type}s found. Retrieving details...` ) ); } // full details for retrieve const extras = extrasDefault; let details = []; let parsed; if (retrieveDir) { const searchName = mode === 'name' ? key.slice(5) : null; const foundKey = []; let journey; // get extra details for saving this if (Util.OPTIONS.onlyPublished && mode === 'key') { journey = results.items.find( (a) => a[this.definition.keyField] === singleKey.slice(4) ); } else if (Util.OPTIONS.onlyPublished && mode === 'id') { journey = results.items.find( (a) => a[this.definition.idField] === singleKey ); } else { details = results.items ? await Promise.all( results.items.map(async (a) => { if (mode === 'name') { // when filtering by name, the API in fact does a LIKE search with placeholders left and right of the search term - and also searches the description field. if (searchName === a[this.definition.nameField]) { foundKey.push(a[this.definition.keyField]); } else { // skip because the name does not match return null; } } try { return await this.client.rest.get( `${uri}key:${a[this.definition.keyField]}?extras=${extras}` + `&versionNumber=${a.version}` ); } catch (ex) { // if we do get here, we should log the error and continue instead of failing to download all automations Util.logger.warn( ` ☇ skipping ${this.definition.type} ${ a[this.definition.nameField] } (${a[this.definition.keyField]}): ${ex.message} (${ ex.code })${ ex.endpoint ? Util.getGrayMsg( ' - ' + ex.endpoint.split( 'rest.marketingcloudapis.com' )[1] ) : '' }` ); return null; } }) ) : []; } if (Util.OPTIONS.onlyPublished && journey) { details.push( await this.client.rest.get( `${uri}${singleKey}?extras=${extras}` + `&versionNumber=${journey.version}` ) ); } parsed = this.parseResponseBody({ items: details.filter(Boolean) }); // * retrieveDir is mandatory in this method as it is not used for caching (there is a seperate method for that) const savedMetadata = await this.saveResults(parsed, retrieveDir, null, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString( mode === 'name' ? `${foundKey.join(', ')} (${key})` : key ) ); } else { // limit to main details for caching parsed = this.parseResponseBody(results); } return { metadata: parsed, type: this.definition.type, }; } } catch (ex) { // if the interaction does not exist, the API returns an error code which would otherwise bring execution to a hold if ( [ 'Interaction matching key not found.', // might be outdated 'Interaction matching criteria not found.', // seen in 2025-05 'Must provide a valid ID or Key parameter', ].includes(ex.message) || (key && ex.code === 'ERR_BAD_REQUEST') ) { Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString( mode === 'id' ? singleKey : key, mode === 'id' )}` ); if (mode === 'key') { this.postDeleteTasks(key); } } else { throw ex; } } } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(key) { let version; let id; let cachedJourney; if (key.startsWith('id:') || key.startsWith('%23')) { // ! allow selecting journeys by ID because that's what users see in the URL // if the key started with %23 assume an ID was copied from the URL but the user forgot to prefix it with id: // remove id: or %23 id = key.slice(3); if (id.startsWith('%23')) { // in the journey URL the Id is prefixed with an HTML-encoded "#" which could accidentally be copied by users // despite the slicing above, this still needs testing here because users might have prefixed the ID with id: but did not know to remove the #23 id = id.slice(3); } if (id.includes('/')) { // in the journey URL the version is appended after the ID, separated by a forward-slash. [id, version] = id.split('/'); } try { const response = await this.client.rest.get( `/interaction/v1/interactions/${encodeURIComponent(id)}?extras=activities` ); const results = this.parseResponseBody(response, key); cachedJourney = results[key]; } catch { // handle below } } else { if (key.includes('/')) { // in the journey URL the version is appended after the ID, separated by a forward-slash. [key, version] = key.split('/'); } // delete by key with specified version does not work, therefore we need to get the ID first try { const response = await this.client.rest.get( `/interaction/v1/interactions/key:${encodeURIComponent(key)}?extras=activities` ); const results = this.parseResponseBody(response, key); cachedJourney = results[key]; id = cachedJourney?.id; } catch { // handle below } } if (!cachedJourney?.key) { await this.deleteNotFound(key); return false; } switch (cachedJourney.definitionType) { case 'Multistep': { if (version && version !== '*' && version > cachedJourney.version) { Util.logger.error( `The chosen version (${version}) is higher than the latest known version (${cachedJourney.version}). Please choose a lower version.` ); return false; } if (version !== '*') { if (!/^\d+$/.test(version)) { Util.logger.error( 'Version is required for deleting journeys to avoid accidental deletion of the wrong item. Please append it at the end of the key or id, separated by forward-slash. Example for deleting version 4: ' + key + '/4' ); return false; } Util.logger.warn( `Deleting Journeys via this command breaks following retrieve-by-key/id requests until you've deployed/created a new draft version! You can get still get the latest available version of your journey by retrieving all journeys on this BU.` ); } return super.deleteByKeyREST( '/interaction/v1/interactions/' + id + (version === '*' ? '' : `?versionNumber=${version}`), key ); // break; } case 'Quicksend': { // Quicksend doesnt have versions const isDeleted = await super.deleteByKeyREST( '/interaction/v1/interactions/' + id, key ); return isDeleted; } case 'Transactional': { // Transactional dont have versions const isDeleted = await super.deleteByKeyREST( '/interaction/v1/interactions/' + id, key ); const transactionalEmailKey = cachedJourney.activities[0]?.configurationArguments?.triggeredSendKey; if (isDeleted) { const msg = []; if (cachedJourney.activities[0]?.configurationArguments?.triggeredSendKey) { msg.push( `transactionalEmail "${cachedJourney.activities[0].configurationArguments.triggeredSendKey}"` ); } } if (isDeleted && transactionalEmailKey) { Util.logger.info( ` - deleted ${TransactionalEmail.definition.type}: ${transactionalEmailKey} (SFMC auto-deletes the related transactionalEmail of ${this.definition.type} ${key})` ); TransactionalEmail.buObject = this.buObject; TransactionalEmail.properties = this.properties; TransactionalEmail.client = this.client; TransactionalEmail.postDeleteTasks(transactionalEmailKey); } return isDeleted; } } } /** * Deploys metadata * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {string} retrieveDir directory where metadata after deploy should be saved * @returns {Promise.<MetadataTypeMap>} Promise of keyField => metadata map */ static async deploy(metadataMap, deployDir, retrieveDir) { Util.logBeta(this.definition.type); let needTransactionalEmail = false; for (const key in metadataMap) { if (metadataMap[key].definitionType == 'Transactional') { needTransactionalEmail = true; break; } } if (needTransactionalEmail && !cache.getCache()?.transactionalEmail) { // ! interaction and transactionalEmail both link to each other. caching transactionalEmail here "manually", assuming that it's quicker than the other way round Util.logger.info(' - Caching dependent Metadata: transactionalEmail'); TransactionalEmail.buObject = this.buObject; TransactionalEmail.client = this.client; TransactionalEmail.properties = this.properties; const result = await TransactionalEmail.retrieveForCache(); cache.setMetadata('transactionalEmail', result.metadata); } return super.deploy(metadataMap, deployDir, retrieveDir); } /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata) { return super.updateREST( metadata, '/interaction/v1/interactions/key:' + metadata.key, 'put' ); } /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata) { return super.createREST(metadata, '/interaction/v1/interactions/'); } /** * Helper for writing Metadata to disk, used for Retrieve and deploy * * @param {MetadataTypeMap} results metadata results from deploy * @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve * @param {string} [overrideType] for use when there is a subtype (such as folder-queries) * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMap>} Promise of saved metadata */ static async saveResults(results, retrieveDir, overrideType, templateVariables) { if (Object.keys(results).length) { // only execute the following if records were found await this._postRetrieveTasksBulk(results); } return super.saveResults(results, retrieveDir, overrideType, templateVariables); } /** * helper for Journey's {@link Journey.saveResults}. Gets executed after retreive of metadata type and * * @param {MetadataTypeMap} metadataMap key=customer key, value=metadata */ static async _postRetrieveTasksBulk(metadataMap) { let needTransactionalEmail = false; for (const key in metadataMap) { if (metadataMap[key].definitionType == 'Transactional') { needTransactionalEmail = true; break; } } if (needTransactionalEmail && !cache.getCache()?.transactionalEmail) { // ! interaction and transactionalEmail both link to each other. caching transactionalEmail here "manually", assuming that it's quicker than the other way round Util.logger.info(' - Caching dependent Metadata: transactionalEmail'); TransactionalEmail.buObject = this.buObject; TransactionalEmail.client = this.client; TransactionalEmail.properties = this.properties; const result = await TransactionalEmail.retrieveForCache(); cache.setMetadata('transactionalEmail', result.metadata); } } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} Array with one metadata object */ static async postRetrieveTasks(metadata) { // folder if (metadata.r__folder_Path && Util.OPTIONS.publish) { // if we re-retrieve this as part of deploy with --publish then the cached version will already have been processed return metadata; } super.setFolderPath(metadata); switch (metadata.definitionType) { case 'Quicksend': // Single Send Journey case 'Multistep': { // Single Send Journey // ~~~ TRIGGERS ~~~~ // event && triggers[].type === 'ContactAudience' // Multi-Step Journey // ~~~ TRIGGERS ~~~~ // event / definitionType==='Multistep' && channel==='' && triggers[].type === 'EmailAudience'|'APIEvent' if (metadata.triggers?.length > 0) { const search = ['arguments', 'metaData']; for (const area of search) { const config = metadata.triggers[0][area]; if (config?.eventDefinitionId) { // trigger found; there can only be one entry in this array try { const edKey = cache.searchForField( 'event', config.eventDefinitionId, 'id', 'eventDefinitionKey' ); if (config.eventDefinitionKey !== edKey) { Util.logger.debug( `eventDefinitionKey not matching eventDefinitionId. Overwriting '${config.eventDefinitionKey}' with the correct key '${edKey}'.` ); } config.r__event_key = edKey; delete config.eventDefinitionKey; delete config.eventDefinitionId; } catch (ex) { const msg = ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }) ${metadata.status}: ${ex.message}.`; Util.logger.warn( metadata.status === 'Published' ? msg : Util.getGrayMsg(msg) ); } } if (config?.dataExtensionId) { try { config.r__dataExtension_key = cache.searchForField( 'dataExtension', config.dataExtensionId, 'ObjectID', 'CustomerKey' ); delete config.dataExtensionId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } } } try { await Event.postRetrieveTasks_SalesforceEntryEvents( metadata.triggers[0].type, metadata.triggers[0].configurationArguments, metadata.key, metadata.status === 'Published', this.definition.type ); } catch (ex) { const msg = ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}) ${metadata.status}: ${ex.message}`; Util.logger.warn( metadata.status === 'Published' ? msg : Util.getGrayMsg(msg) ); } } // ~~~ ACTIVITIES ~~~~ await this._postRetrieveTasks_activities(metadata); // TODO: journey template id? / metaData.templateId break; } case 'Transactional': { // Transactional Send Journey // ~~~ TRIGGERS ~~~~ // ! journeys so far only supports transactional EMAIL messages. SMS and Push do not create their own journey. // ! transactional (email) journeys only have a dummy trigger without real content. // transactionalEmail / definitionType==='Transactional' && channel==='email' && triggers[].type === 'transactional-api' // --> nothing to do here // ~~~ ACTIVITIES ~~~~ // ! transactional (email) journeys only have one activity (type=EMAILV2) which links back to the transactionalEmail () switch (metadata.channel) { case 'email': { if (metadata.activities?.length > 0) { const activity = metadata.activities[0]; // trigger found; there can only be one entry in this array if (activity.configurationArguments?.triggeredSendId) { try { const tEmailKey = cache.searchForField( 'transactionalEmail', activity.configurationArguments?.triggeredSendId, 'definitionId', 'definitionKey' ); if ( activity.configurationArguments?.triggeredSendKey && tEmailKey != activity.configurationArguments?.triggeredSendKey ) { Util.logger.debug( `triggeredSendKey not matching triggeredSendId. Overwriting '${activity.configurationArguments.triggeredSendKey}' with the correct key '${tEmailKey}'.` ); } activity.configurationArguments.r__transactionalEmail_key = tEmailKey; delete activity.configurationArguments.triggeredSendKey; delete activity.configurationArguments.triggeredSendId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ metadata[this.definition.nameField] } (${metadata[this.definition.keyField]}): ${ex.message}.` ); } } if ( activity.metaData?.highThroughput?.definitionKey && activity.configurationArguments?.r__transactionalEmail_key && activity.metaData?.highThroughput?.definitionKey != activity.configurationArguments.r__transactionalEmail_key ) { Util.logger.warn( ` - ${this.definition.type} ${ metadata[this.definition.nameField] } (${metadata[this.definition.keyField]}): activities[0].metaData.highThroughput.definitionKey not matching key in activities[0].configurationArguments.r__transactionalEmail_key.` ); } else if ( activity.configurationArguments?.r__transactionalEmail_key && metadata.status === 'Published' ) { // as long as status is Draft, we wont have r__transactionalEmail_key set as that record will not have been created delete activity.metaData.highThroughput.definitionKey; } await this._postRetrieveTasks_activities(metadata); if (activity.metaData?.highThroughput?.dataExtensionId) { try { activity.metaData.highThroughput.r__dataExtension_key = cache.searchForField( 'dataExtension', activity.metaData.highThroughput.dataExtensionId, 'ObjectID', 'CustomerKey' ); delete activity.metaData.highThroughput.dataExtensionId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ metadata[this.definition.nameField] } (${metadata[this.definition.keyField]}): ${ex.message}.` ); } } } break; } default: { // it is expected that we'll see 'sms' and 'push' here in the future Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): channel ${ metadata.channel } is not supported yet. Please open a ticket at https://github.com/Accenture/sfmc-devtools/issues/new/choose to request it` ); } } break; } default: { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): definitionType ${ metadata.definitionType } is not supported yet. Please open a ticket at https://github.com/Accenture/sfmc-devtools/issues/new/choose to request it` ); } } return metadata; } /** * helper for {@link Journey.postRetrieveTasks} * * @private * @param {MetadataTypeItem} metadata a single item */ static async _postRetrieveTasks_activities(metadata) { if (!metadata.activities) { return; } for (const activity of metadata.activities) { switch (activity.type) { case 'EMAILV2': { // triggeredSend + email+asset const configurationArguments = activity.configurationArguments; if (configurationArguments) { try { // configurationArguments.triggeredSendKey && configurationArguments.triggeredSendId are only set on a running journey; if a journey is new, they do not exist if (configurationArguments.triggeredSendId) { // triggeredSendKey is not always set but triggeredSendId is const tsKey = cache.searchForField( 'triggeredSend', configurationArguments.triggeredSendId, 'ObjectID', 'CustomerKey' ); if (configurationArguments.triggeredSendKey != tsKey) { Util.logger.debug( `triggeredSendKey not matching triggeredSendId. Overwriting '${configurationArguments.triggeredSendKey}' with the correct key '${tsKey}'.` ); configurationArguments.triggeredSendKey = tsKey; } configurationArguments.r__triggeredSend_key = configurationArguments.triggeredSendKey; delete configurationArguments.triggeredSendKey; delete configurationArguments.triggeredSendId; } else if (configurationArguments.triggeredSendKey) { // very rare case but it's been seen that no triggeredSendId was saved Util.logger.debug( `triggeredSendKey found on activity but no triggeredSendId present on journey. Checking key directly...` ); configurationArguments.r__triggeredSend_key = cache.searchForField( 'triggeredSend', configurationArguments.triggeredSendKey, 'CustomerKey', 'CustomerKey' ); delete configurationArguments.triggeredSendKey; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } } if ( configurationArguments?.triggeredSend && 'string' === typeof configurationArguments?.triggeredSend ) { // sometimes, the API returns this object as a string for unknown reasons. Good job, product team! configurationArguments.triggeredSend = JSON.parse( configurationArguments?.triggeredSend ); } const triggeredSend = configurationArguments?.triggeredSend; if (triggeredSend) { // this section is likely only relevant for QuickSends and not for Multi-Step Journeys // triggeredSend key if (configurationArguments.r__transactionalEmail_key) { const linkedTE = cache.getByKey( 'transactionalEmail', configurationArguments.r__transactionalEmail_key ); if (linkedTE) { if (linkedTE.subscriptions) { triggeredSend.autoAddSubscribers = linkedTE.subscriptions.autoAddSubscriber; triggeredSend.autoUpdateSubscribers = linkedTE.subscriptions.updateSubscriber; // List if (linkedTE.subscriptions?.list) { triggeredSend.publicationListId = cache.searchForField( 'list', linkedTE.subscriptions.list, 'CustomerKey', 'ID' ); } else if (linkedTE.subscriptions.r__list_PathName) { delete triggeredSend.publicationListId; triggeredSend.r__list_PathName = { publicationList: linkedTE.subscriptions.r__list_PathName, }; } // dataExtension if (linkedTE.subscriptions.dataExtension) { try { activity.metaData.highThroughput.r__dataExtension_key = cache.searchForField( 'dataExtension', linkedTE.subscriptions.dataExtension, 'CustomerKey', 'CustomerKey' ); delete activity.metaData.highThroughput.dataExtensionId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ metadata[this.definition.nameField] } (${metadata[this.definition.keyField]}): ${ex.message}.` ); } } else if (linkedTE.subscriptions.r__dataExtension_key) { activity.metaData.highThroughput.r__dataExtension_key = linkedTE.subscriptions.r__dataExtension_key; delete activity.metaData.highThroughput.dataExtensionId; } } if (linkedTE.options) { triggeredSend.isTrackingClicks = linkedTE.options.trackLinks || false; triggeredSend.ccEmail = linkedTE.options.cc || ''; triggeredSend.bccEmail = linkedTE.options.bcc || ''; } // send classification if (linkedTE.classification) { try { const scKey = cache.searchForField( 'sendClassification', linkedTE.classification, 'CustomerKey', 'CustomerKey' ); triggeredSend.r__sendClassification_key = scKey; delete triggeredSend.sendClassificationId; } catch (ex) { Util.logger.warn( ` - transactionalEmail ${linkedTE.definitionKey}: ${ex.message} (sendClassification key ${linkedTE.classification})` ); } } else if (linkedTE.r__sendClassification_key) { triggeredSend.r__sendClassification_key = linkedTE.r__sendClassification_key; } // senderProfile + deliveryProfile from sendClassification if (triggeredSend.r__sendClassification_key) { const sc = cache.getByKey( 'sendClassification', triggeredSend.r__sendClassification_key ); if (sc.SenderProfile?.ObjectID) { triggeredSend.r__senderProfile_key = cache.searchForField( 'senderProfile', sc.SenderProfile.ObjectID, 'ObjectID', 'CustomerKey' ); delete triggeredSend.senderProfileId; } else if (sc.r__senderProfile_key) { triggeredSend.r__senderProfile_key = sc.r__senderProfile_key; delete triggeredSend.senderProfileId; } if (sc.DeliveryProfile?.ObjectID) { triggeredSend.r__deliveryProfile_key = cache.searchForField( 'deliveryProfile', sc.DeliveryProfile.ObjectID, 'ObjectID', 'key' ); delete triggeredSend.deliveryProfileId; } else if (sc.r__deliveryProfile_key) { triggeredSend.r__deliveryProfile_key = sc.r__deliveryProfile_key; delete triggeredSend.deliveryProfileId; } } } } else if (configurationArguments.r__triggeredSend_key) { // if we have a key set outside of this detailed triggeredSend config then lets overwrite what we've got here with what we cached from the related TS as it will be more current; but we cannot retrieve all info unfortunately triggeredSend.r__triggeredSend_key = configurationArguments.r__triggeredSend_key; delete triggeredSend.id; delete triggeredSend.key; const linkedTS = cache.getByKey( 'triggeredSend', configurationArguments.r__triggeredSend_key ); if (linkedTS) { triggeredSend.emailId = linkedTS.Email?.ID; triggeredSend.dynamicEmailSubject = linkedTS.DynamicEmailSubject; triggeredSend.emailSubject = linkedTS.EmailSubject; // only the bccEmail field can be retrieved for triggeredSends, not the ccEmail field; for some reason BccEmail can be retrieved but does not return a value even if stored correctly in the journey. // triggeredSend.bccEmail = linkedTS.BccEmail; triggeredSend.isMultipart = linkedTS.IsMultipart; triggeredSend.autoAddSubscribers = linkedTS.AutoAddSubscribers; triggeredSend.autoUpdateSubscribers = linkedTS.AutoUpdateSubscribers; triggeredSend.isTrackingClicks = !linkedTS.SuppressTracking; triggeredSend.suppressTracking = linkedTS.SuppressTracking; triggeredSend.triggeredSendStatus = linkedTS.TriggeredSendStatus; // from name & email are set in the senderProfile, not in the triggeredSend // triggeredSend.fromName = linkedTS.FromName; // triggeredSend.fromAddress = linkedTS.FromAddress; // List if (linkedTS.List?.ID) { triggeredSend.publicationListId = linkedTS.List.ID; } else if (linkedTS.r__list_PathName) { delete triggeredSend.publicationListId; triggeredSend.r__list_PathName = { publicationList: linkedTS.r__list_PathName, }; } if (linkedTS.SenderProfile?.CustomerKey) { try { const spKey = cache.searchForField( 'senderProfile', linkedTS.SenderProfile.ObjectID, 'ObjectID', 'CustomerKey' ); triggeredSend.r__senderProfile_key = spKey; delete triggeredSend.senderProfileId; } catch (ex) { Util.logger.warn( ` - triggeredSend ${linkedTS.CustomerKey}: ${ex.message} (senderProfile key ${linkedTS.SenderProfile.CustomerKey})` ); } } else if (linkedTS.r__senderProfile_key) { triggeredSend.r__senderProfile_key = linkedTS.r__senderProfile_key; } // send classification if (linkedTS.SendClassification?.CustomerKey) { try { const scKey = cache.searchForField( 'sendClassification', linkedTS.SendClassification.ObjectID, 'ObjectID', 'CustomerKey' ); triggeredSend.r__sendClassification_key = scKey; delete triggeredSend.sendClassificationId; } catch (ex) { Util.logger.warn( ` - triggeredSend ${linkedTS.CustomerKey}: ${ex.message} (sendClassification key ${linkedTS.SendClassification.CustomerKey})` ); } } else if (linkedTS.r__sendClassification_key) { triggeredSend.r__sendClassification_key = linkedTS.r__sendClassification_key; } if (linkedTS.c__priority) { delete triggeredSend.priority; triggeredSend.c__priority = linkedTS.c__priority; } if (linkedTS.Email?.ID) { triggeredSend.emailId = linkedTS.Email.ID; } else if (linkedTS.r__asset_key) { delete triggeredSend.emailId; triggeredSend.r__asset_name_readOnly = linkedTS.r__asset_name_readOnly; triggeredSend.r__asset_key = linkedTS.r__asset_key; } } } else if (triggeredSend.id) { // triggeredSendKey is not always set but id is const tsKey = cache.searchForField( 'triggeredSend', triggeredSend.id, 'ObjectID', 'CustomerKey' ); if (triggeredSend.key != tsKey) { Util.logger.debug( `key not matching id. Overwriting '${triggeredSend.key}' with the correct key '${tsKey}'.` ); triggeredSend.key = tsKey; } triggeredSend.r__triggeredSend_key = triggeredSend.key; delete triggeredSend.key; delete triggeredSend.id; } else if (triggeredSend.key) { // very rare case but it's been seen that no id was saved Util.logger.debug( `key found on triggeredSend but no id present on journey activity. Checking key directly...` ); triggeredSend.r__triggeredSend_key = cache.searchForField( 'triggeredSend', triggeredSend.key, 'CustomerKey', 'CustomerKey' ); delete triggeredSend.key; } if (typeof triggeredSend.ccEmail === 'string') { triggeredSend.ccEmail = triggeredSend.ccEmail .split(';') .filter((el) => el !== ''); } if (typeof triggeredSend.bccEmail === 'string') { triggeredSend.bccEmail = triggeredSend.bccEmail .split(';') .filter((el) => el !== ''); } // List (optional) triggeredSend.r__list_PathName ||= {}; if (triggeredSend.publicationListId) { try { triggeredSend.r__list_PathName.publicationList = cache.getListPathName(triggeredSend.publicationListId, 'ID'); delete triggeredSend.publicationListId; } catch (ex) { Util.logger.warn( ` - ${this.definition.typeName} '${metadata.name}'/'${metadata.key}': ${ex.message}` ); // save this TSD because it could be fixed by the user } } if ( triggeredSend.suppressionLists && Array.isArray(triggeredSend.suppressionLists) && triggeredSend.suppressionLists.length ) { triggeredSend.r__list_PathName.suppressionLists = triggeredSend.suppressionLists.map((sList) => { try { return cache.getListPathName(sList.id, 'ID'); } catch (ex) { Util.logger.warn( ` - ${this.definition.typeName} '${metadata.name}'/'${metadata.key}': ${ex.message}` ); // save this TSD because it could be fixed by the user } }); delete triggeredSend.suppressionLists; } if (!Object.keys(triggeredSend.r__list_PathName).length) { // in case we found no linked lists, remove this empty shell delete triggeredSend.r__list_PathName; } // DataExtension (optional) triggeredSend.r__dataExtension_key = {}; if ( triggeredSend.domainExclusions && Array.isArray(triggeredSend.domainExclusions) && triggeredSend.domainExclusions.length ) { let errors = 0; triggeredSend.r__dataExtension_key.domainExclusions = triggeredSend.domainExclusions.map((de) => { try { return cache.searchForField( 'dataExtension', de.id, 'ObjectID', 'CustomerKey' ); } catch (ex) { errors++; Util.logger.warn( ` - ${this.definition.typeName} '${metadata.name}'/'${metadata.key}': ${ex.message}` ); // save this TSD because it could be fixed by the user } }); if (!errors) { delete triggeredSend.domainExclusions; // array with id & name of DE } } if (!Object.keys(triggeredSend.r__dataExtension_key).length) { // in case we found no linked dataExtensions, remove this empty shell delete triggeredSend.r__dataExtension_key; } // sender profile if (triggeredSend.senderProfileId) { try { triggeredSend.r__senderProfile_key = cache.searchForField( 'senderProfile', triggeredSend.senderProfileId, 'ObjectID', 'CustomerKey' ); delete triggeredSend.senderProfileId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): ${ex.message}` ); } } // send classification if (triggeredSend.sendClassificationId) { try { triggeredSend.r__sendClassification_key = cache.searchForField( 'sendClassification', triggeredSend.sendClassificationId, 'ObjectID', 'CustomerKey' ); delete triggeredSend.sendClassificationId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): ${ex.message}` ); } } // delivery profile if (triggeredSend.deliveryProfileId) { try { triggeredSend.r__deliveryProfile_key = cache.searchForField( 'deliveryProfile', triggeredSend.deliveryProfileId, 'ObjectID', 'key' ); delete triggeredSend.deliveryProfileId; } catch { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Dependent deliveryProfile was not found. Please note that this can only be resolved if you have at least ONE Send Classification set up on the target BU that uses this Delivery Profile.` ); } } // message priority if (triggeredSend.priority) { triggeredSend.c__priority = Util.inverseGet( this.definition.priorityMapping, triggeredSend.priority ); delete triggeredSend.priority; } // email if (triggeredSend.emailId) { try { // content builder triggeredSend.r__asset_name_readOnly = cache.searchForField( 'asset', triggeredSend.emailId, 'legacyData.legacyId', 'name' ); triggeredSend.r__asset_key = cache.searchForField( 'asset', triggeredSend.emailId, 'legacyData.legacyId', 'customerKey' ); delete triggeredSend.emailId; } catch { try { // classic triggeredSend.r__email_name = cache.searchForField( 'email', triggeredSend.emailId, 'ID', 'Name' ); delete triggeredSend.emailId; } catch { const msg = ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find email with ID ${triggeredSend.emailId} in Classic nor in Content Builder.`; Util.logger.warn( metadata.status === 'Published' ? msg : Util.getGrayMsg(msg) ); } } } // sort attributes of triggeredSend alphabetically to allow for easier pull request reviews configurationArguments.triggeredSend = Util.sortObjectAttributes(triggeredSend); } break; } case 'SMSSYNC': { const configurationArguments = activity.configurationArguments; if (configurationArguments) { // mobileMessage try { if (configurationArguments.messageId) { configurationArguments.r__mobileMessage_key = cache.searchForField( 'mobileMessage', configurationArguments.messageId, 'id', 'id' ); delete configurationArguments.messageId; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } // mobileKeyword configurationArguments.r__mobileKeyword_key = {}; try { if (configurationArguments.keywordId) { configurationArguments.r__mobileKeyword_key.current = cache.searchForField( 'mobileKeyword', configurationArguments.keywordId, 'id', 'c__codeKeyword' ); delete configurationArguments.keywordId; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } try { if (configurationArguments.nextKeywordId) { configurationArguments.r__mobileKeyword_key.next = cache.searchForField( 'mobileKeyword', configurationArguments.nextKeywordId, 'id', 'c__codeKeyword' ); delete configurationArguments.nextKeywordId; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } if (!Object.keys(configurationArguments.r__mobileKeyword_key).length) { // in case we found no linked dataExtensions, remove this empty shell delete configurationArguments.r__mobileKeyword_key; } // mobileCode try { if (configurationArguments.codeId) { configurationArguments.r__mobileCode_key = cache.searchForField( 'mobileCode', configurationArguments.codeId, 'id', 'code' ); delete configurationArguments.codeId; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } try { // asset-asset: jsonmessage if (configurationArguments.assetId) { configurationArguments.r__asset_name_readOnly = cache.searchForField( 'asset', configurationArguments.assetId, 'id', 'name' ); configurationArguments.r__asset_key = cache.searchForField( 'asset', configurationArguments.assetId, 'id', 'customerKey' ); delete configurationArguments.assetId; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } // applicationExtensionId always equal "00000000-0000-0000-0000-000000000000" delete configurationArguments.applicationExtensionId; } break; } case 'UPDATECONTACTDATA': { const contactFields = activity?.arguments?.activityData?.updateContactFields ?? []; let tempCachedFields = false; for (const contactField of contactFields) { try { contactField.r__dataExtension_key = cache.searchForField( 'dataExtension', contactField.dataExtensionId, 'ObjectID', 'CustomerKey' ); delete contactField.dataExtensionId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); continue; } // Don't replace the field Id with the name if DE CustomerKey was not found try { DataExtensionField.buObject = this.buObject; DataExtensionField.client = this.client; DataExtensionField.properties = this.properties; let alreadyFetchedDe = false; if (!cache.getCache().dataExtensionField) { // no dataExtensionField cache yet: retrieve fields for this specific DE tempCachedFields = true; alreadyFetchedDe = true; const fields = await DataExtensionField.retrieveFieldsForSingleDeAuto( contactField.r__dataExtension_key ); cache.setMetadata('dataExtensionField', fields); } let fieldName; try { fieldName = cache.searchForField( 'dataExtensionField', contactField.field, 'ObjectID', 'Name' ); } catch (ex) { if (alreadyFetchedDe) { throw ex; } // field not in existing cache - retrieve fields for this specific DE const fields = await DataExtensionField.retrieveFieldsForSingleDeAuto( contactField.r__dataExtension_key ); if (Object.keys(fields).length > 0) { cache.mergeMetadata('dataExtensionField', fields); } // throws if still not found, handled by outer catch fieldName = cache.searchForField( 'dataExtensionField', contactField.field, 'ObjectID', 'Name' ); } contactField.r__dataExtensionField_name = fieldName; delete contactField.field; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }) activity-key=${activity.key}: ${ex.message}` ); } } if (tempCachedFields) { // reset dataExtensionField caching to trigger re-caching cache.clearCache(this.buObject.mid, 'dataExtensionField'); } } } } // apply sorting by activity key to work around the API shuffling activities around metadata.activities = metadata.activities.toSorted((a, b) => a.key.localeCompare(b.key)); } /** * prepares a TSD for deployment * ! BETA RELEASE of journey support (v4.3.0); it so far only resolves a limited amount of dependencies and will likely break during cross-BU deployments! * * @param {MetadataTypeItem} metadata of a single TSD * @returns {Promise.<MetadataTypeItem>} metadata object */ static async preDeployTasks(metadata) { if (metadata.status !== 'Draft') { metadata.status = 'Draft'; } // folder super.setFolderId(metadata); switch (metadata.definitionType) { case 'Quicksend': case 'Multistep': { // Multi-Step Journey // ~~~ TRIGGERS ~~~~ // event / definitionType==='Multistep' && channel==='' && triggers[].type === 'EmailAudience'|'APIEvent' if (metadata.triggers?.length > 0) { const search = ['arguments', 'metaData']; for (const area of search) { const config = metadata.triggers[0][area]; if (config?.r__event_key) { // trigger found; there can only be one entry in this array config.eventDefinitionId = cache.searchForField( 'event', config.r__event_key, 'eventDefinitionKey', 'id' ); config.eventDefinitionKey = config.r__event_key; delete config.r__event_key; } if (config?.r__dataExtension_key) { // trigger found; there can only be one entry in this array config.dataExtensionId = cache.searchForField( 'dataExtension', config.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); delete config.r__dataExtension_key; } } const warnings = await Event.preDeployTasks_SalesforceEntryEvents( metadata.triggers[0].type, metadata.triggers[0].configurationArguments ); if (warnings) { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): ${warnings}` ); } } // transactionalEmail / definitionType==='Transactional' && channel==='email' && triggers[].type === 'transactional-api' // ~~~ ACTIVITIES ~~~~ await this._preDeployTasks_activities(metadata); break; } case 'Transactional': { const cachedVersion = cache.getByKey('journey', metadata.key); if (cachedVersion?.status === 'Published') { if (Util.OPTIONS.publish) { Util.logger.info( ` - ${this.definition.type} ${metadata.key}: --publish option used. Automatically pausing journey to allow for updates.` ); const pausedKeys = await this.pause([metadata.key], { metadata: cache.getCache().journey, type: this.definition.type, }); if (!pausedKeys?.length || pausedKeys[0] !== metadata.key) { Util.logger.error( ` - failed to pause ${this.definition.typeName}: ${metadata.key}` ); throw new Error( `Cannot update transactional-send journey in Published status. Automatic pausing failed.` ); } cachedVersion.status = 'Paused'; } else { throw new Error( `Cannot update transactional-send journey in Published status. Run deploy with --publish to auto-pause & republish the journey.` ); } } // Transactional Send Journey // ~~~ TRIGGERS ~~~~ // ! journeys so far transactional EMAIL messages. SMS and Push do not create their own journey. // ! transactional (email) journeys only have a dummy trigger without real content. // transactionalEmail / definitionType==='Transactional' && channel==='email' && triggers[].type === 'transactional-api' // --> nothing to do here // ~~~ ACTIVITIES ~~~~ // ! transactional (email) journeys only have one activity (type=EMAILV2) which links back to the transactionalEmail () switch (metadata.channel) { case 'email': { const activity = metadata.activities[0]; if (activity.configurationArguments?.r__transactionalEmail_key) { // trigger found; there can only be one entry in this array try { activity.configurationArguments.triggeredSendId = cache.searchForField( 'transactionalEmail', activity.configurationArguments.r__transactionalEmail_key, 'definitionKey', 'definitionId' ); activity.configurationArguments.triggeredSendKey = activity.configurationArguments.r__transactionalEmail_key; } catch (ex) { const isCreateMode = !cachedVersion; if ( (isCreateMode && !Util.OPTIONS.publish) || (!isCreateMode && cachedVersion.status === 'Draft') ) { // no need to add a log entry if the publish-option was provided Util.logger.info( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): To activate this transactional journey (and create the associated transactionalEmail record), please run 'mcdev publish ${this.buObject.credential}/${this.buObject.businessUnit} -m journey:"${metadata.key}" ' or click on "Activate" in the GUI.` ); } else if (!isCreateMode) { // block deployment if we are in update mode throw ex; } } if (activity.metaData?.highThroughput) { // this is crucial for pinging the /interaction/v1/interactions/transactional/create endpoint that creates the transactionalEmail activity.metaData.highThroughput.definitionKey = activity.configurationArguments.r__transactionalEmail_key; } delete activity.configurationArguments.r__transactionalEmail_key; } if (activity.metaData?.highThroughput?.r__dataExtension_key) { // if this is set during create, we expect that the DE is already present (part of current deployment or already existing) activity.metaData.highThroughput.dataExtensionId = cache.searchForField( 'dataExtension', activity.metaData.highThroughput.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); delete activity.metaData.highThroughput.r__dataExtension_key; } await this._preDeployTasks_activities(metadata); break; } default: { // it is expected that we'll see 'sms' and 'push' here in the future throw new Error( `channel ${metadata.channel} is not supported yet. Please open a ticket at https://github.com/Accenture/sfmc-devtools/issues/new/choose to request it` ); } } break; } default: { throw new Error( `definitionType ${metadata.definitionType} is not supported yet. Please open a ticket at https://github.com/Accenture/sfmc-devtools/issues/new/choose to request it` ); } } return metadata; } /** * helper for {@link Journey.preDeployTasks} * * @private * @param {MetadataTypeItem} metadata a single item */ static async _preDeployTasks_activities(metadata) { for (const activity of metadata.activities) { switch (activity.type) { case 'EMAILV2': { // triggeredSend + email+asset const configurationArguments = activity.configurationArguments; if (configurationArguments?.r__triggeredSend_key) { // triggeredSendKey is not always set but triggeredSendId is try { configurationArguments.triggeredSendId = cache.searchForField( 'triggeredSend', configurationArguments.r__triggeredSend_key, 'CustomerKey', 'ObjectID' ); configurationArguments.triggeredSendKey = configurationArguments.r__triggeredSend_key; delete configurationArguments.r__triggeredSend_key; } catch { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): Could not find triggeredSend with key ${configurationArguments.r__triggeredSend_key}. Attempting to let the API auto-create it` ); } } const triggeredSend = configurationArguments?.triggeredSend; if (triggeredSend) { // triggeredSend key if ( !configurationArguments.r__triggeredSend_key && triggeredSend.r__triggeredSend_key ) { try { // key is not always set but id is triggeredSend.id = cache.searchForField( 'triggeredSend', triggeredSend.r__triggeredSend_key, 'CustomerKey', 'ObjectID' ); triggeredSend.key = triggeredSend.r__triggeredSend_key; } catch { Util.logger.warn( ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): Could not find triggeredSend with key ${triggeredSend.r__triggeredSend_key}. Attempting to let the API auto-create it` ); } delete triggeredSend.r__triggeredSend_key; } if (triggeredSend.ccEmail !== undefined) { triggeredSend.ccEmail = Array.isArray(triggeredSend.ccEmail) ? triggeredSend.ccEmail?.join(';') : triggeredSend.ccEmail; } if (triggeredSend.bccEmail !== undefined) { triggeredSend.bccEmail = Array.isArray(triggeredSend.bccEmail) ? triggeredSend.bccEmail?.join(';') : triggeredSend.bccEmail; } // List (optional) if (triggeredSend.r__list_PathName) { if (triggeredSend.r__list_PathName.publicationList) { triggeredSend.publicationListId = cache.getListObjectId( triggeredSend.r__list_PathName.publicationList, 'ID' ); } if (triggeredSend.r__list_PathName.suppressionLists?.length) { triggeredSend.suppressionLists = triggeredSend.r__list_PathName.suppressionLists.map( (listPathName) => { const id = cache.getListObjectId(listPathName, 'ID'); const name = cache.getListObjectId( listPathName, 'ListName' ); return { id, name }; } ); } delete triggeredSend.r__list_PathName; } // DataExtension (optional) if (triggeredSend.r__dataExtension_key?.length) { triggeredSend.domainExclusions = triggeredSend.r__dataExtension_key.map( (key) => { const id = cache.searchForField( 'dataExtension', key, 'CustomerKey', 'ObjectID' ); const name = cache.searchForField( 'dataExtension', key, 'CustomerKey', 'Name' ); return { id, name }; } ); } // sender profile if (triggeredSend.r__senderProfile_key) { triggeredSend.senderProfileId = cache.searchForField( 'senderProfile', triggeredSend.r__senderProfile_key, 'CustomerKey', 'ObjectID' ); delete triggeredSend.r__senderProfile_key; } // send classification if (triggeredSend.r__sendClassification_key) { triggeredSend.sendClassificationId = cache.searchForField( 'sendClassification', triggeredSend.r__sendClassification_key, 'CustomerKey', 'ObjectID' ); delete triggeredSend.r__sendClassification_key; } // delivery profile if (triggeredSend.r__deliveryProfile_key) { // remove it because we cannot resolve it and it should be set by selecting the sendClassification try { triggeredSend.deliveryProfileId = cache.searchForField( 'deliveryProfile', triggeredSend.r__deliveryProfile_key, 'key', 'ObjectID' ); delete triggeredSend.r__deliveryProfile_key; } catch (ex) { Util.logger.error( `Could not find the ID for Delivery Profile '${triggeredSend.r__deliveryProfile_key}'. Please note that this can only be resolved if you have at least ONE Send Classification set up on the target BU that uses a Delivery Profile with this key.` ); throw ex; } } // message priority if (triggeredSend.c__priority) { triggeredSend.priority = this.definition.priorityMapping[triggeredSend.c__priority]; delete triggeredSend.c__priority; } // email if (triggeredSend.r__asset_key) { triggeredSend.emailId = cache.searchForField( 'asset', triggeredSend.r__asset_key, 'customerKey', 'legacyData.legacyId' ); delete triggeredSend.r__asset_key; delete triggeredSend.r__asset_name_readOnly; } else if (triggeredSend.r__email_name) { // classic triggeredSend.emailId = cache.searchForField( 'email', triggeredSend.r__email_name, 'Name', 'ID' ); delete triggeredSend.r__email_name; } } break; } case 'SMSSYNC': { const configurationArguments = activity.configurationArguments; if (configurationArguments) { // mobileMessage if (configurationArguments.r__mobileMessage_key) { configurationArguments.messageId = cache.searchForField( 'mobileMessage', configurationArguments.r__mobileMessage_key, 'id', 'id' ); delete configurationArguments.r__mobileMessage_key; } // mobileKeyword if (configurationArguments.r__mobileKeyword_key?.current) { configurationArguments.keywordId = cache.searchForField( 'mobileKeyword', configurationArguments.r__mobileKeyword_key.current, 'c__codeKeyword', 'id' ); } if (configurationArguments.r__mobileKeyword_key?.next) { configurationArguments.nextKeywordId = cache.searchForField( 'mobileKeyword', configurationArguments.r__mobileKeyword_key.next, 'c__codeKeyword', 'id' ); } delete configurationArguments.r__mobileKeyword_key; // mobileCode if (configurationArguments.r__mobileCode_key) { configurationArguments.codeId = cache.searchForField( 'mobileCode', configurationArguments.r__mobileCode_key, 'code', 'id' ); delete configurationArguments.r__mobileCode_key; } // asset-asset: jsonmessage if (configurationArguments.r__asset_key) { configurationArguments.assetId = cache.searchForField( 'asset', configurationArguments.r__asset_key, 'customerKey', 'id' ); delete configurationArguments.r__asset_key; delete configurationArguments.r__asset_name_readOnly; } // applicationExtensionId always equal "00000000-0000-0000-0000-000000000000" configurationArguments.applicationExtensionId = '00000000-0000-0000-0000-000000000000'; } break; } case 'UPDATECONTACTDATA': { const contactFields = activity?.arguments?.activityData?.updateContactFields ?? []; let tempCachedFields = false; for (const contactField of contactFields) { if (!contactField.r__dataExtension_key) { continue; } contactField.dataExtensionId = cache.searchForField( 'dataExtension', contactField.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); if (!contactField.r__dataExtensionField_name) { continue; } DataExtensionField.buObject = this.buObject; DataExtensionField.client = this.client; DataExtensionField.properties = this.properties; let alreadyFetchedDe = false; if (!cache.getCache().dataExtensionField) { // no dataExtensionField cache yet: retrieve fields for this specific DE tempCachedFields = true; alreadyFetchedDe = true; const fields = await DataExtensionField.retrieveFieldsForSingleDeAuto( contactField.r__dataExtension_key ); cache.setMetadata('dataExtensionField', fields); } let fieldObjectId; try { fieldObjectId = cache.searchForField( 'dataExtensionField', `[${contactField.r__dataExtension_key}].[${contactField.r__dataExtensionField_name}]`, 'CustomerKey', 'ObjectID' ); } catch (ex) { // field not in existing cache - retrieve fields for this specific DE if (alreadyFetchedDe) { throw ex; } const fields = await DataExtensionField.retrieveFieldsForSingleDeAuto( contactField.r__dataExtension_key ); if (Object.keys(fields).length > 0) { cache.mergeMetadata('dataExtensionField', fields); } // throws if still not found, handled by outer catch fieldObjectId = cache.searchForField( 'dataExtensionField', `[${contactField.r__dataExtension_key}].[${contactField.r__dataExtensionField_name}]`, 'CustomerKey', 'ObjectID' ); } contactField.field = fieldObjectId; delete contactField.r__dataExtensionField_name; delete contactField.r__dataExtension_key; } if (tempCachedFields) { // reset dataExtensionField caching to trigger re-caching cache.clearCache(this.buObject.mid, 'dataExtensionField'); } } } } } /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadataMap list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create * @returns {Promise.<'create'|'update'|'skip'>} action to take */ static async createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ) { const action = await super.createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ); if (action === 'update') { const normalizedKey = File.reverseFilterIllegalFilenames( metadataMap[metadataKey][this.definition.keyField] ); const cachedVersion = cache.getByKey(this.definition.type, normalizedKey); if (cachedVersion) { if ( cachedVersion.status === 'Draft' || cachedVersion.definitionType !== 'Multistep' ) { // we can update journeys either if there is a draft version or if the type is not multistep. transactional and quicksend journeys do not have versions. // add version to ensure we update the correct one metadataMap[metadataKey].version = cachedVersion.version; // update modifiedDate field to bypass API-error "Another user recently modified this journey. Refresh to edit the latest version." metadataMap[metadataKey].modifiedDate = cachedVersion.modifiedDate; } else { // remove last entry from metadataToUpdate again metadataToUpdate.pop(); Util.logger.info( Util.getGrayMsg( ` - Found ${this.definition.type} ${ metadataMap[metadataKey][this.definition.nameField] } (${ metadataMap[metadataKey][this.definition.keyField] }) on BU, but it is not in Draft status. Will create new version.` ) ); metadataToCreate.push(metadataMap[metadataKey]); return 'create'; } } } return action; } /** * * @param {MetadataTypeItem} item single metadata item * @param {string} [_] parameter not used * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem>} key of the item that was updated */ static async replaceCbReference(item, _, findAssetKeys) { const parentName = `${this.definition.type} ${item[this.definition.keyField]}`; let changes = false; let error; // *** type specific logic ** // find email activities with triggeredSend configurationArguments const activities = item.activities.filter((activity) => activity.type === 'EMAILV2'); if (!activities) { const ex = new Error('No changes made to the code.'); // @ts-expect-error custom error object ex.code = 200; throw ex; } for (const activity of activities) { if (activity.arguments) { try { activity.arguments.emailSubjectDataBound = ReplaceCbReference.replaceReference( activity.arguments.emailSubjectDataBound, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } } const triggeredSend = activity.configurationArguments?.triggeredSend; if (triggeredSend) { // the following is very similar but not equal to the variables in TriggeredSend.js if (triggeredSend.bccEmail !== undefined) { try { let bccEmail = Array.isArray(triggeredSend.bccEmail) ? triggeredSend.bccEmail.join(';') : triggeredSend.bccEmail; bccEmail = ReplaceCbReference.replaceReference( bccEmail, parentName, findAssetKeys ); triggeredSend.bccEmail = bccEmail.split(';').filter((el) => el !== ''); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } } if (triggeredSend.ccEmail !== undefined) { try { let ccEmail = Array.isArray(triggeredSend.ccEmail) ? triggeredSend.ccEmail?.join(';') : triggeredSend.ccEmail; ccEmail = ReplaceCbReference.replaceReference( ccEmail, parentName, findAssetKeys ); triggeredSend.ccEmail = ccEmail.split(';').filter((el) => el !== ''); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } } try { triggeredSend.dynamicEmailSubject = ReplaceCbReference.replaceReference( triggeredSend.dynamicEmailSubject, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { triggeredSend.emailSubject = ReplaceCbReference.replaceReference( triggeredSend.emailSubject, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { triggeredSend.preHeader = ReplaceCbReference.replaceReference( triggeredSend.preHeader, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { triggeredSend.exclusionFilter = ReplaceCbReference.replaceReference( triggeredSend.exclusionFilter, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } } } if (error) { throw error; } if (!changes) { const ex = new Error('No changes made to the code.'); // @ts-expect-error custom error object ex.code = 200; throw ex; } // *** finish *** // replaceReference will throw an error if nothing was updated which will end execution here // no error means we have a new item to deploy and need to update the item in our retrieve folder return item; } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create */ static async postDeployTasks(upsertResults) { if (!upsertResults || !Object.keys(upsertResults).length) { // nothing to do. skip here to avoid unnecessary logs / api calls return; } // override the response from update by createdDate from cache (the date from update-response is incorrect) for (const [key, journey] of Object.entries(upsertResults)) { const cachedJourney = cache.getByKey(this.definition.type, key); if (cachedJourney) { journey.createdDate = cachedJourney.createdDate; } } let postDeployFlags = 0; if (Util.OPTIONS.publish) { postDeployFlags++; } if (Util.OPTIONS.validate) { postDeployFlags++; } if (postDeployFlags > 1) { Util.logger.warn( `Please provide only one of the following options (--publish, --validate). Flags are processed in this order and only the first one found is executed.` ); } if (Util.OPTIONS.publish) { Util.logger.info(`Publishing: ${this.definition.type}`); // pubslih const idArr = Object.values(upsertResults).map( (item) => 'id:' + item.id + '/' + item.version ); await this.publish(idArr, upsertResults); } else if (Util.OPTIONS.validate) { Util.logger.info(`Validating: ${this.definition.type}`); // pubslih const idArr = Object.values(upsertResults).map( (item) => 'id:' + item.id + '/' + item.version ); await this.validate(idArr); } } /** * a function to publish the journey via API * * @param {string[]} keyArr keys or ids of the metadata * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField as returned by update/create; needs to be refreshed after publish * @returns {Promise.<string[]>} Returns list of updated keys/ids that were published. Success could only be seen with a delay in the UI because the publish-endpoint is async */ static async publish(keyArr, upsertResults) { const resultsTransactional = []; // works only with objectId const statusUrls = []; const executedKeyArr = []; const refreshTransactionalKeys = []; const metadataMap = upsertResults ? { metadata: upsertResults } : await this.retrieveForCache(); const publishedJourneyCounter = { multiStep: 0, transactional: 0, }; // does not matter definitionType we run first, but the logs look bad if we dont sort them const processingOrder = { Transactional: `Publishing transactional journey…`, Multistep: `Publishing multi-step journey…`, }; for (const definitionType of Object.keys(processingOrder)) { const spinner = yoctoSpinner({ text: processingOrder[definitionType], }); for (let key of keyArr) { let objectId; let version; let journey; if (!key) { continue; } if (key.startsWith('%23')) { // if the key started with %23 assume an ID was copied from the URL but the user forgot to prefix it with id: // correct the format key = 'id:' + key.slice(3); } if (key.startsWith('id:')) { // ! allow selecting journeys by ID because that's what users see in the URL // remove id objectId = key.slice(3); if (objectId.startsWith('%23')) { // in the journey URL the Id is prefixed with an HTML-encoded "#" which could accidentally be copied by users // despite the slicing above, this still needs testing here because users might have prefixed the ID with id: but did not know to remove the #23 objectId = objectId.slice(3); // correct the format to ensure we show sth readable in the "Downloaded" log // objectId = objectId; // update this here to show it in the log key = 'id:' + objectId; } if (objectId.includes('/')) { version = objectId.split('/')[1]; // in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the ID for caching as we always aim to retrieve the latest version only objectId = objectId.split('/')[0]; } else { // if we didn't find a version we need to cache this from the API after all if (key.includes('/')) { // in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the key for caching as we always aim to retrieve the latest version only key = key.split('/')[0]; } } journey = Object.values(metadataMap.metadata).find((el) => el.id === objectId); if (!journey) { Util.logger.info( ` ☇ skipping ${this.definition.type} ${key}: not found on server (1)` ); continue; } } else { // key assumed journey = metadataMap.metadata[key]; } if (journey && journey.definitionType !== definitionType) { // to allow consistent log output we enforce publishing is sorted by definitionType if (!processingOrder[journey.definitionType]) { throw new Error( `${this.definition.type} type ${journey.definitionType} not supported yet by publish method` ); } continue; } if (!journey) { Util.logger.info( ` ☇ skipping ${this.definition.type} ${key}: not found on server (2)` ); continue; } if (!version) { version = journey.version; } if (journey.status === 'Published') { // api would return error code 30000 and ask to open a support case when in fact we simply already have a transactionalEmail created based on this status if (journey.definitionType === 'Transactional') { Util.logger.info( ` ☇ skipping ${this.definition.type} ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}): already published. Queueing for refresh.` ); refreshTransactionalKeys.push(journey.key); } else { Util.logger.warn( ` ☇ skipping ${this.definition.type} ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}): already published.` ); } continue; } else if ( journey.status === 'Paused' && journey.definitionType === 'Transactional' ) { Util.logger.info( ` ☇ skipping ${this.definition.type} ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}): currently paused. Queueing for refresh.` ); refreshTransactionalKeys.push(journey.key); continue; } switch (journey.definitionType) { case 'Transactional': { resultsTransactional.push( (async () => { spinner.start(); try { const response = await this.client.rest.post( `/interaction/v1/interactions/transactional/create`, { definitionId: journey.id } ); if (response.errors?.length) { throw new Error(JSON.stringify(response)); } else { spinner.stop(); Util.logger.info( ` - published ${this.definition.type}: ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}) by creating the matching transactionalEmail` ); statusUrls.push({ key, statusUrl: response.statusUrl }); } spinner.start(); return journey[this.definition.keyField]; } catch (ex) { spinner.stop(); if ( ex.response.status === 400 && ex.response?.data?.errors?.length === 1 && ex.response?.data?.errors?.[0]?.errorCode === '121500' ) { Util.logger.error( `Failed to publish ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}): Make sure the Event Definition Key, Data Extension and E-Mail are saved to the journey` ); } else { Util.logger.error( `Failed to publish ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}): ${ex.message}` ); if (ex.response?.data?.errors?.length) { Util.logger.error( JSON.stringify(ex.response?.data?.errors, null, 2) ); } } spinner.start(); } })() ); break; } case 'Multistep': { // SF Event, Api Event Journeys // ! for SF-triggered journeys this cannot be asynchronous or it will cause a race-condition (see #1627 for details); the requests are accepted but then processed sequentually anyways, eliminating potential speed gains. // It is unknown if the same would happen for API-event journeys but given that it's the same endpoint, lets not risk it and run this sequentially let statusUrl; try { const response = await this.client.rest.post( `/interaction/v1/interactions/publishAsync/${journey.id}?versionNumber=${version}`, {} ); // payload is empty for this request if (response.statusUrl && response.statusId) { Util.logger.info( ` - ${this.definition.type} queued for publishing: ${journey[this.definition.keyField]}/${version} / ${journey[this.definition.nameField]}` ); statusUrl = response.statusUrl; } else { throw new Error(response); } if (Util.OPTIONS.skipStatusCheck) { Util.logger.warn( ` - Skipping status check for publishing journey ${key} due to --skipStatusCheck flag` ); } if (!Util.OPTIONS.skipStatusCheck && statusUrl) { spinner.start(); await Util.sleep(1000); executedKeyArr.push( await this._checkPublishStatus( statusUrl, journey[this.definition.keyField], journey[this.definition.nameField], spinner ) ); publishedJourneyCounter.multiStep++; } else { // no guarantees if the journey was actually published executedKeyArr.push(key); publishedJourneyCounter.multiStep++; } } catch (ex) { switch (ex.message) { case 'Cannot publish interaction in Published status.': { Util.logger.info( ` - ${this.definition.type} ${key}/${version} is already published.` ); break; } case 'Cannot publish interaction in Stopped status.': { Util.logger.warn( ` - ${this.definition.type} ${key}/${version} is stopped. Please create a new version and publish that.` ); break; } case 'Cannot publish interaction in Paused status.': { Util.logger.warn( ` - ${this.definition.type} ${key}/${version} is already published but currently paused. Run 'mcdev resume' instead.` ); break; } default: { Util.logger.error( `Failed to publish ${this.definition.type} ${key}: ${ex.message}` ); } } } break; } default: { throw new Error( `${this.definition.type} type ${journey.definitionType} not supported yet by publish method` ); } } } // for loop // when all relevant keys have been iterated over per definitionType, ensure we wait for async tasks and update the counter switch (definitionType) { case 'Transactional': { if (resultsTransactional.length) { const transactionalKeyArr = ( await Promise.all(resultsTransactional) ).filter(Boolean); spinner.stop(); // if all publish actions failed, we don't need to re-retrieve anything here if (transactionalKeyArr.length) { executedKeyArr.push(...transactionalKeyArr); publishedJourneyCounter.transactional = transactionalKeyArr.length; // reset transactionalEmail cache to trigger re-caching it. cache.clearCache(this.buObject.mid, 'transactionalEmail'); } } break; } case 'Multistep': { // all done; executed synchronously break; } } } // processing order // reload published journeys including their events/transactionalEmails await this._reRetrieve( executedKeyArr, publishedJourneyCounter.transactional, publishedJourneyCounter.multiStep, upsertResults ); Util.logger.info( `Published ${executedKeyArr.filter(Boolean).length} of ${keyArr.length} items` ); if (refreshTransactionalKeys.length) { // in case we tried to publish a transactional journey that was already published we will instead run a refresh for those executedKeyArr.push( ...(await this.refresh(refreshTransactionalKeys, null, upsertResults)) ); } // good practice to return the published keys in alphabetical order return executedKeyArr.filter(Boolean).toSorted(); } /** * * @param {string[]} executedKeyArr list of journey keys * @param {number} transactionalCounter how many transactiona-send journeys did we expect to refresh * @param {number} multiStepCounter how many multi-step journeys did we expect to refresh * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField returned by update/create; needs to be refreshed after publish * @returns {Promise.<void>} - */ static async _reRetrieve( executedKeyArr, transactionalCounter, multiStepCounter, upsertResults ) { if (!executedKeyArr.filter(Boolean).length) { return; } Util.logger.info('Re-retrieving published journeys'); const retriever = new Retriever(this.properties, this.buObject); try { // we need to retrieve the updated journeys and all dependencies const updatedJourneyRetrieve = await retriever.retrieve( ['journey'], executedKeyArr.filter(Boolean) ); /** @type {MetadataTypeItem[]} */ const updatedJourneys = updatedJourneyRetrieve?.journey?.length > 1 ? Object.values( updatedJourneyRetrieve?.journey.reduce( (previousValue, currentValue) => Object.assign(previousValue, currentValue), {} ) ) : Object.values(updatedJourneyRetrieve?.journey[0]); if (updatedJourneys) { // regardless of upsert vs publish-only mode, we need to retrieve the events/transactionalEmail and their dependencies const updatedEvents = []; const updatedTransactionalEmails = []; for (const journey of updatedJourneys) { if (upsertResults?.[journey[this.definition.keyField]]) { // update upsertResults with journeys retrieved here to ensure we save the right thing to disk - if it was provided to the method upsertResults[journey[this.definition.keyField]] = journey; } // multi-step journeys updatedEvents.push(journey.triggers?.[0]?.metaData?.r__event_key); // transactional-send journeys updatedTransactionalEmails.push( journey.activities?.[0]?.configurationArguments?.r__transactionalEmail_key ); } /** @type {TypeKeyCombo} */ const eventTransEmailCombo = {}; if (updatedEvents.filter(Boolean).length) { eventTransEmailCombo.event = updatedEvents.filter(Boolean); } else if (multiStepCounter) { Util.logger.error(`Could not find events for the published journeys`); } if (updatedTransactionalEmails.filter(Boolean).length) { eventTransEmailCombo.transactionalEmail = updatedTransactionalEmails.filter(Boolean); Util.logger.info('Retrieving relevant transactionalEmails'); } else if (transactionalCounter) { Util.logger.error( `Could not find transactional Emails for the published journeys` ); } const toBeRetrievedTypes = Object.keys(eventTransEmailCombo); if (toBeRetrievedTypes.length) { Util.logger.info( 'Retrieving relevant ' + toBeRetrievedTypes.map((item) => item + 's').join(', ') ); await retriever.retrieve(toBeRetrievedTypes, eventTransEmailCombo); // TODO find r__automation_key in events and retrieve these automations as well } } } catch (ex) { Util.logger.errorStack(ex, 'retrieve failed'); } } /** * helper for {@link Journey.publish} and {@link Journey.validate} * * @param {string} statusUrl URL to check the status of the publish request * @param {string} key journey-key or id for log messages * @param {string} name journey-name for log messages * @param {import('yocto-spinner').Spinner} spinner reference to spinner to allow stopping it when done * @param {number} [tries] number of tries used to check the status * @returns {Promise.<string>} key of the item that was published successfully */ static async _checkPublishStatus(statusUrl, key, name, spinner, tries = 1) { const action = statusUrl.includes('/validateStatus') ? 'validating' : 'publishing'; try { const response = await this.client.rest.get(statusUrl); switch (response.status) { case 'ValidateCompleted': case 'PublishCompleted': { spinner.stop(); const action = statusUrl.includes('/validateStatus') ? '🔎 validation successful -' : '🚀 published'; Util.logger.info(` - ${action} ${this.definition.type}: ${key} / ${name}`); this._showPublishStatusDetails(response); return key; } case 'ValidateInProcess': case 'PublishInProcess': { Util.logger.debug( ` - ${action} ${this.definition.type} still in progress: ${key} / ${name}` ); if (tries < 50) { await (tries < 10 ? Util.sleep(2000) : Util.sleep(5000)); return await this._checkPublishStatus( statusUrl, key, name, spinner, tries + 1 ); } else { return; } } case 'Error': { spinner.stop(); Util.logger.error( ` - ${action} ${this.definition.type} failed: ${key} / ${name}` ); this._showPublishStatusDetails(response); return; } // No default } } catch (ex) { Util.logger.error(`Failed to check status of ${key}: ${ex.message}`); } } /** * helper for {@link Journey._checkPublishStatus} * * @param {{status:string, errors:Array, warnings:Array}} response publishStatus response */ static _showPublishStatusDetails(response) { const types = { errors: 'Errors', warnings: 'Warnings' }; const messages = { errors: [], warnings: [] }; for (const type in types) { let counter = 1; if (response[type] && response[type].length) { messages[type].push(` ${types[type]}:`); for (const msg of response[type]) { messages[type].push( ` #${counter++}: ${msg.errorDetail.split(' EmailID: ').join('\n EmailID: ').split(' Personalization error: ').join('\n Personalization error: ')}`, Util.getGrayMsg(` Code: ${msg.errorCode}`) ); if (msg.additionalInfo && Object.keys(msg.additionalInfo).length) { messages[type].push(Util.getGrayMsg(` Additional Info:`)); for (const key in msg.additionalInfo) { messages[type].push( Util.getGrayMsg(` ${key}: ${msg.additionalInfo[key]}`) ); } } // add spacer line messages[type].push(''); } } } for (const msg of messages.errors) { Util.logger.error(msg); } for (const msg of messages.warnings) { Util.logger.warn(' ' + msg); } } /** * a function to validate the journey via API * * @param {string[]} keyArr keys or ids of the metadata * @returns {Promise.<string[]>} Returns list of updated keys/ids that were published. Success could only be seen with a delay in the UI because the publish-endpoint is async */ static async validate(keyArr) { // works only with objectId const executedKeyArr = []; const metadataMap = await this.retrieveForCache(); for (let key of keyArr) { let objectId; let version; let journey; if (!key) { continue; } if (key.startsWith('%23')) { // if the key started with %23 assume an ID was copied from the URL but the user forgot to prefix it with id: // correct the format key = 'id:' + key.slice(3); } if (key.startsWith('id:')) { // ! allow selecting journeys by ID because that's what users see in the URL // remove id objectId = key.slice(3); if (objectId.startsWith('%23')) { // in the journey URL the Id is prefixed with an HTML-encoded "#" which could accidentally be copied by users // despite the slicing above, this still needs testing here because users might have prefixed the ID with id: but did not know to remove the #23 objectId = objectId.slice(3); // correct the format to ensure we show sth readable in the "Downloaded" log // objectId = objectId; // update this here to show it in the log key = 'id:' + objectId; } if (objectId.includes('/')) { version = objectId.split('/')[1]; // in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the ID for caching as we always aim to retrieve the latest version only objectId = objectId.split('/')[0]; } else { // if we didn't find a version we need to cache this from the API after all if (key.includes('/')) { // in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the key for caching as we always aim to retrieve the latest version only key = key.split('/')[0]; } } journey = Object.values(metadataMap.metadata).find((el) => el.id === objectId); if (!journey) { Util.logger.info( ` ☇ skipping ${this.definition.type} ${key}: not found on server (1)` ); continue; } } else { // key assumed journey = metadataMap.metadata[key]; } if (!journey) { Util.logger.info( ` ☇ skipping ${this.definition.type} ${key}: not found on server (2)` ); continue; } if (!version) { version = journey.version; } if (journey.status === 'Published') { // api would return error code 30000 and ask to open a support case when in fact we simply already have a transactionalEmail created based on this status Util.logger.error( ` ☇ skipping ${this.definition.type} ${ journey[this.definition.nameField] } (${journey[this.definition.keyField]}): already published` ); continue; } switch (journey.definitionType) { case 'Multistep': { // SF Event, Api Event Journeys // ! for SF-triggered journeys this cannot be asynchronous or it will cause a race-condition (see #1627 for details); the requests are accepted but then processed sequentually anyways, eliminating potential speed gains. // It is unknown if the same would happen for API-event journeys but given that it's the same endpoint, lets not risk it and run this sequentially let statusUrl; try { const response = await this.client.rest.post( `/interaction/v1/interactions/validateAsync/${journey.id}?versionNumber=${version}`, {} ); // payload is empty for this request if (response.statusUrl && response.statusId) { Util.logger.info( ` - ${this.definition.type} queued for validating: ${journey[this.definition.keyField]}/${version} / ${journey[this.definition.nameField]}` ); statusUrl = response.statusUrl; } else { throw new Error(response); } const spinner = yoctoSpinner({ text: `Validating journey…`, }).start(); await Util.sleep(1000); executedKeyArr.push( await this._checkPublishStatus( statusUrl, journey[this.definition.keyField], journey[this.definition.nameField], spinner ) ); } catch (ex) { switch (ex.message) { case 'Cannot validate interaction in Published status.': { Util.logger.info( ` - ${this.definition.type} ${key}/${version} is already published. Can only validate Draft Journeys` ); break; } case 'Cannot validate interaction in Stopped status.': { Util.logger.warn( ` - ${this.definition.type} ${key}/${version} is stopped. Can only validate Draft Journeys.` ); break; } case 'Cannot validate interaction in Paused status.': { Util.logger.warn( ` - ${this.definition.type} ${key}/${version} is already published but currently paused. Can only validate Draft Journeys.` ); break; } default: { Util.logger.error( `Failed to validate ${this.definition.type} ${key}: ${ex.message}` ); } } } break; } default: { Util.logger.info( Util.getGrayMsg( ` ☇ skipping ${this.definition.type} ${key}: type ${journey.definitionType} not supported yet by validate method` ) ); continue; } } } // for loop Util.logger.info( `Validated ${executedKeyArr.filter(Boolean).length} of ${keyArr.length} items without errors` ); return executedKeyArr.filter(Boolean); } /** * audit latest or given journey version * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were paused */ static async audit(keyArr) { let version; const endpoint = '/interaction/v1/interactions/'; const auditedKeyArr = []; const apiLimit = pLimit(20); const journeyCache = await this.retrieveForCache(); const ignoredLogProperties = [ 'executionMode', 'id', 'originalDefinitionId', 'publishRequestId', ]; const preformatedProperties = [ 'action', 'description', 'errors', 'key', 'name', 'publishedVersion', 'publishStatus', 'timeStamp', 'user', 'versionNumber', ]; await Promise.allSettled( keyArr.map((key) => apiLimit(async () => { [key, version] = key.split('/'); if (!journeyCache.metadata[key]) { Util.logger.error( ` ☇ skipping audit log of ${this.definition.type} ${key}: not found on server` ); return; } const toBeAuditedVersions = []; if (version === '*' || !version) { switch (journeyCache.metadata[key].definitionType) { case 'Transactional': case 'Multistep': { // transactional send journeys technically only have one version, but if you delete them and then create one with the same key their version number goes up and old audit logs are still available // multi-step journey versions could be retrieved but then we lose info of any versions that might have been deleted. Therefore we add all versions starting with the latest and counting down to 1 for (let i = journeyCache.metadata[key].version; i > 0; i--) { toBeAuditedVersions.push(i); } } } } else { toBeAuditedVersions.push(version); } Util.logger.info( ` - Audit log for ${this.definition.type} ${key} / ${journeyCache.metadata[key].name}` ); const rateLimitActivities = pLimit(1); const auditedVersions = ( await Promise.all( toBeAuditedVersions.map((version) => rateLimitActivities(async () => { try { const response = await this.client.rest.getBulk( endpoint + journeyCache.metadata[key].id + `/audit/all?versionNumber=${version}` ); Util.logger.info( ` - Version ${version}:\n - ` + response.items .map((log) => { let msg = `${log.action} version ${log.versionNumber} - ${Util.getGrayMsg(log.timeStamp.replace('T', ' ').slice(0, 19))}: ${log.user.name}\n` + (log.publishedVersion ? ` Published Version: ` + log.publishedVersion + '\n' : '') + (log.publishStatus ? ` Publish Status: ` + log.publishStatus + '\n' : '') + (log.key === key ? '' : ` Key: ` + log.key + '\n') + (log.name === journeyCache.metadata[key].name ? '' : ` Key: ` + log.key + '\n') + (log.errors ? ` Errors:\n • ` + log.errors .map((error) => error.ErrorDetail.replaceAll( /[\r\n]/g, ' ' ) ) .join('\n • ') + '\n' : ''); for (const key in log) { if ( !ignoredLogProperties.includes( key ) && !preformatedProperties.includes(key) ) { msg += ` ${key}: ` + log[key] + '\n'; } } return msg; }) .join(' - ') ); // Util.logger.info(JSON.stringify(auditLog, null, 2)); return version; } catch (ex) { if (journeyCache.metadata[key].version > version) { Util.logger.error( ` - Retrieving audit log for ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} - Version ${version} failed: Version was not found. The highest available version seems to be ${journeyCache.metadata[key].version}` ); } else { Util.logger.error( ` - Retrieving audit log for ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} - Version ${version} failed: ${ex.message}` ); } return; } }) ) ) ).filter(Boolean); if (auditedVersions.length === toBeAuditedVersions.length) { auditedKeyArr.push(key); } }) ) ); return auditedKeyArr; } /** * stops latest journey version * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were paused */ static async stop(keyArr) { let version; const endpoint = '/interaction/v1/interactions/stop/'; const stoppedKeyArr = []; const stopTransactionalKeyArr = []; const apiLimit = pLimit(20); const journeyCache = await this.retrieveForCache(); const stoppableJourneyStatus = ['Paused', 'Published', 'Unpublished']; // 'Unpublished' is shown as 'Finishing' in the UI await Promise.allSettled( keyArr.map((key) => apiLimit(async () => { [key, version] = key.split('/'); if (journeyCache.metadata[key]) { switch (journeyCache.metadata[key].definitionType) { case 'Transactional': { // transactional send journeys cannot be "stopped" but only "paused" stopTransactionalKeyArr.push(key); break; } case 'Multistep': { const toBeStoppedVersions = []; if (version === '*') { const responseAllVersions = await this.client.rest.getBulk( '/interaction/v1/interactions/?id=' + journeyCache.metadata[key].id + '&mostRecentVersionOnly=false', this.definition.restPageSize || 500 ); if (responseAllVersions?.items?.length) { // find all active versions const allActiveVersions = responseAllVersions.items .filter((item) => stoppableJourneyStatus.includes(item.status) ) .map((item) => item.version); if (allActiveVersions.length) { toBeStoppedVersions.push(...allActiveVersions); } } if (!toBeStoppedVersions.length) { Util.logger.warn( ` ☇ skipping stop of ${this.definition.type} ${key}: no active versions found` ); } } else { if (!version) { version = journeyCache.metadata[key].version; Util.logger.info( Util.getGrayMsg( ` - ${this.definition.type} ${key}: no version provided. Will try to stop latest version: Version ${version}. To stop all versions, append /* after the key.` ) ); if ( !stoppableJourneyStatus.includes( journeyCache.metadata[key].status ) ) { Util.logger.warn( ` ☇ skipping stop of ${this.definition.type} ${key}: version ${version} has status "${journeyCache.metadata[key].status}" which cannot be stopped. To stop all versions, append /* after the key.` ); } } toBeStoppedVersions.push(version); } const rateLimitActivities = pLimit(2); const stoppedVersions = ( await Promise.all( toBeStoppedVersions.map((version) => rateLimitActivities(async () => { try { await this.client.rest.post( endpoint + journeyCache.metadata[key].id + `?versionNumber=${version}`, {} ); Util.logger.info( ` - ⛔ stopped ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} - Version ${version}` ); return version; } catch (ex) { Util.logger.error( ` - stopping ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} - Version ${version} failed: ${ex.message}` ); return; } }) ) ) ).filter(Boolean); if (stoppedVersions.length === toBeStoppedVersions.length) { stoppedKeyArr.push(key); } break; } default: { Util.logger.error( ` - Stopping ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: Unsupported definitionType '${journeyCache.metadata[key].definitionType}'` ); } } } else { Util.logger.error( ` ☇ skipping stop of ${this.definition.type} ${key}: not found on server` ); } }) ) ); stoppedKeyArr.push(...(await this.pause(stopTransactionalKeyArr))); return stoppedKeyArr; } /** * pauses selected journey versions * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [journeyCache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were paused */ static async pause(keyArr, journeyCache) { let version; const pausedKeyArr = []; const apiLimit = pLimit(20); journeyCache ||= await this.retrieveForCache(); await Promise.allSettled( keyArr.map((key) => apiLimit(async () => { [key, version] = key.split('/'); if (journeyCache.metadata[key]) { if ( (!version || journeyCache.metadata[key].version == version) && journeyCache.metadata[key].status === 'Paused' ) { Util.logger.info( ` ${this.definition.type} ${key} (${journeyCache.metadata[key].name}): already paused` ); // still add this key because technically this method is supposed to pause a journey and this journey is paused. mission accomplished. Also, we need that for _refreshItem() to function pausedKeyArr.push(key); return; } else if ( (!version || journeyCache.metadata[key].version == version) && journeyCache.metadata[key].status !== 'Published' ) { Util.logger.error( ` - Pausing ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: Cannot pause a journey in status ${journeyCache.metadata[key].status}` ); return; } switch (journeyCache.metadata[key].definitionType) { case 'Transactional': { try { const response = await this.client.rest.post( '/interaction/v1/interactions/transactional/pause', { definitionId: journeyCache.metadata[key].id } ); if (response.errors?.length) { throw new Error(JSON.stringify(response)); } else { Util.logger.info( ` - 🛑 paused ${this.definition.type} ${key} / ${journeyCache.metadata[key].name}` ); pausedKeyArr.push(key); } } catch (ex) { Util.logger.error( ` - Pausing ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: ${ex.message}` ); } break; } case 'Multistep': { version ||= journeyCache.metadata[key].version; try { await this.client.rest.post( '/interaction/v1/interactions/pause/' + journeyCache.metadata[key].id + (version === '*' ? '?allVersions=true' : `?versionNumber=${version}`), {} ); Util.logger.info( ` - 🛑 paused ${this.definition.type} ${key}/${version} / ${journeyCache.metadata[key].name}` ); pausedKeyArr.push(key); } catch (ex) { Util.logger.error( ` - Pausing ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: ${ex.message}` ); } break; } default: { Util.logger.error( ` - Pausing ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: Unsupported definitionType '${journeyCache.metadata[key].definitionType}'` ); } } } else { Util.logger.error( ` ☇ skipping pause of ${this.definition.type} ${key}: not found on server` ); } }) ) ); return pausedKeyArr; } /** * resumes selected journey versions * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [journeyCache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were resumed */ static async execute(keyArr, journeyCache) { let version; const endpoint = '/interaction/v1/interactions/resume/'; const resumedKeyArr = []; const apiLimit = pLimit(20); journeyCache ||= await this.retrieveForCache(); await Promise.allSettled( keyArr.map((key) => apiLimit(async () => { [key, version] = key.split('/'); if (journeyCache.metadata[key]) { if ( (!version || journeyCache.metadata[key].version == version) && journeyCache.metadata[key].status !== 'Paused' ) { Util.logger.error( ` - Resuming ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: Cannot pause a journey in status ${journeyCache.metadata[key].status}` ); return; } switch (journeyCache.metadata[key].definitionType) { case 'Transactional': { try { const response = await this.client.rest.post( '/interaction/v1/interactions/transactional/resume', { definitionId: journeyCache.metadata[key].id } ); if (response.errors?.length) { throw new Error(JSON.stringify(response)); } else { Util.logger.info( ` - ✅ resumed ${this.definition.type} ${key} / ${journeyCache.metadata[key].name}` ); resumedKeyArr.push(key); } } catch (ex) { Util.logger.error( ` - Resuming ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: ${ex.message}` ); } break; } case 'Multistep': { version ||= journeyCache.metadata[key].version; try { await this.client.rest.post( endpoint + journeyCache.metadata[key].id + (version === '*' ? '?allVersions=true' : `?versionNumber=${version}`), {} ); Util.logger.info( ` - ✅ resumed ${this.definition.type} ${key}/${version}` ); resumedKeyArr.push(key); } catch (ex) { Util.logger.error( ` - Resuming ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: ${ex.message}` ); } break; } default: { Util.logger.error( ` - Resuming ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: Unsupported definitionType '${journeyCache.metadata[key].definitionType}'` ); } } } else { Util.logger.error( ` ☇ skipping resume of ${this.definition.type} ${key}: not found on server` ); } }) ) ); return resumedKeyArr; } /** * TSD-specific refresh method that finds active TSDs and refreshes them * * @param {string[]} keyArr metadata keys * @param {boolean} [_] whether to check if the key is valid * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField as returned by update/create; needs to be refreshed after publish * @returns {Promise.<string[]>} Returns list of keys that were refreshed */ static async refresh(keyArr, _, upsertResults) { console.time('Time'); // eslint-disable-line no-console if (!Array.isArray(keyArr) || !keyArr.length) { Util.logger.error('No refresh-keys provided'); return []; // keyArr = await this.getKeysForValidTSDs((await this.findRefreshableItems()).metadata); // checkKey = false; } const journeyCache = upsertResults ? { metadata: upsertResults, type: this.definition.type } : await this.retrieveForCache(); // then executes pause, publish, start on them. Util.logger.info(`Refreshing ${keyArr.length} ${this.definition.typeName}...`); Util.logger.debug(`Refreshing keys: ${keyArr.join(', ')}`); const refreshedKeyArr = []; const tsKeys = []; const rateLimit = pLimit(10); const transactionalJourneyKeys = []; await Promise.all( keyArr.map((key) => rateLimit(async () => { if (!journeyCache.metadata[key]) { Util.logger.error( ` ☇ skipping refresh of ${this.definition.type} ${key}: not found on server` ); return; } switch (journeyCache.metadata[key].definitionType) { case 'Transactional': { if ( ['Paused', 'Published'].includes(journeyCache.metadata[key]?.status) ) { const result = await this._refreshItem(key, journeyCache); if (result) { refreshedKeyArr.push(key); transactionalJourneyKeys.push(key); } } else { Util.logger.error( ` ☇ skipping refresh of ${this.definition.type} ${key}: Can only refresh journeys with status 'Published'. Found status: ${journeyCache.metadata[key]?.status}` ); } break; } case 'Multistep': { // find all published & paused versions const responseAllVersions = await this.client.rest.getBulk( '/interaction/v1/interactions/?id=' + journeyCache.metadata[key].id + '&mostRecentVersionOnly=false', this.definition.restPageSize || 500 ); if (responseAllVersions?.items?.length) { const allActiveVersions = responseAllVersions.items .filter( (item) => item.status === 'Paused' || item.status === 'Published' ) .map((item) => item.version); if (allActiveVersions.length) { Util.logger.info( Util.getGrayMsg( ` - journey ${key} / ${journeyCache.metadata[key].name} Paused/Published version numbers: ` + allActiveVersions.join(', ') ) ); // get TS keys from email activities of paused/published versions const rateLimitActivities = pLimit(2); tsKeys.push( ...( await Promise.all( allActiveVersions.map((version) => rateLimitActivities(async () => { const journey = await this.client.rest.get( '/interaction/v1/interactions/' + journeyCache.metadata[key]?.id + '?extras=activities&versionNumber=' + version ); // return all triggeredSends // ! if somebody changed the key of the triggeredSend then the journey would have wrong info in triggeredSendKey. There is the alternative field triggeredSendId but that would be too costly to use here because we would need to retrieve all TSs to find the correct one. Also, changing TS keys is not a common practice. return journey.activities .filter( (activity) => activity.type === 'EMAILV2' && activity.configurationArguments ?.triggeredSendKey ) .map( (activity) => activity.configurationArguments ?.triggeredSendKey ); }) ) ) ).flat() ); refreshedKeyArr.push(key); } else { Util.logger.error( ` ☇ skipping refresh of ${this.definition.type} ${key}: no published/paused versions found` ); } } break; } default: { Util.logger.error( ` - Refreshing ${this.definition.type} ${key} / ${journeyCache.metadata[key].name} failed: Unsupported definitionType '${journeyCache.metadata[key].definitionType}'` ); } } }) ) ); if (tsKeys.length) { // refresh TriggeredSends TriggeredSend.buObject = this.buObject; TriggeredSend.client = this.client; TriggeredSend.properties = this.properties; // hard-refresh all triggeredSends even if the TS was paused (inactive) before await TriggeredSend.refresh(tsKeys, false); } else { Util.logger.info(Util.getGrayMsg('No triggeredSends found to refresh')); } // reload refreshed transactional journeys including their transactionalEmails if (transactionalJourneyKeys.length) { // reset transactionalEmail cache to trigger re-caching it. cache.clearCache(this.buObject.mid, 'transactionalEmail'); await this._reRetrieve(transactionalJourneyKeys, transactionalJourneyKeys.length, 0); } Util.logger.info( `Refreshed ${refreshedKeyArr.length} of ${keyArr.length} ${this.definition.type}` ); console.timeEnd('Time'); // eslint-disable-line no-console return refreshedKeyArr; } /** * helper for {@link Journey.refresh} that pauses, publishes and starts a triggered send * * @param {string} key external key of triggered send item * @param {MetadataTypeMapObj} journeyCache metadata cache * @returns {Promise.<boolean>} true if refresh was successful */ static async _refreshItem(key, journeyCache) { // pause const pausedKeys = await this.pause([key], journeyCache); if (!pausedKeys?.length || pausedKeys[0] !== key) { Util.logger.error(` - failed to pause ${this.definition.typeName}: ${key}`); return false; } // update cache or else resume (execute) will fail journeyCache.metadata[key].status = 'Paused'; // resume const resumedKeys = await this.execute([key], journeyCache); if (!resumedKeys?.length || resumedKeys[0] !== key) { Util.logger.error(` - failed to resume ${this.definition.typeName}: ${key}`); return false; } return true; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Journey.definition = MetadataTypeDefinitions.journey; export default Journey; ================================================ FILE: lib/metadataTypes/List.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import Folder from './Folder.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; import auth from '../util/auth.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * List MetadataType * * @augments MetadataType */ class List extends MetadataType { /** * Retrieves Metadata of Lists * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = null; if (key) { requestParams = { filter: { leftOperand: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, operator: 'OR', rightOperand: { // deviating from standard here by allowing to search without the rather weird key which includes the folder name! leftOperand: 'ListName', operator: 'equals', rightOperand: key, }, }, }; } const results = await super.retrieveSOAP(retrieveDir, requestParams, key); return await this._retrieveParentAllSubs(results); } /** * Gets metadata cache with limited fields and does not store value to disk * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieveForCache() { const results = await this.retrieve(); const subTypeArr = [ 'list', 'mysubs', 'suppression_list', 'publication', 'contextual_suppression_list', ]; Util.logger.debug('folders not cached but required for list'); Util.logger.info(' - Caching dependent Metadata: folder'); Util.logSubtypes(subTypeArr); Folder.client = this.client; Folder.buObject = this.buObject; Folder.properties = this.properties; const result = await Folder.retrieveForCache(null, subTypeArr); if (cache.getCache()?.folder) { cache.mergeMetadata('folder', result.metadata); } else { cache.setMetadata('folder', result.metadata); } for (const metadataEntry in results.metadata) { this.parseMetadata(results.metadata[metadataEntry], true); } return results; } /** * helper for {@link retrieveForCache} and {@link retrieve} * * @private * @param {MetadataTypeMapObj} results metadata from retrieve for current BU * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async _retrieveParentAllSubs(results) { if (this.buObject.eid !== this.buObject.mid) { // for caching, we want to get the All Subscriber List from the Parent Account Util.logger.debug(' - Checking MasterUnsubscribeBehavior for current BU'); /** @type {BuObject} */ const buObjectParentBu = { eid: this.properties.credentials[this.buObject.credential].eid, mid: this.properties.credentials[this.buObject.credential].eid, businessUnit: Util.parentBuName, credential: this.buObject.credential, }; const clientBackup = this.client; const buObjectBackup = this.buObject; try { this.client = auth.getSDK(buObjectParentBu); } catch (ex) { Util.logger.error(ex.message); return; } this.buObject = buObjectParentBu; const buResult = await this.client.soap.retrieve( 'BusinessUnit', ['MasterUnsubscribeBehavior'], { QueryAllAccounts: true, filter: { leftOperand: 'ID', operator: 'equals', rightOperand: this.properties.credentials[this.buObject.credential].eid, }, } ); const masterUnsubscribeBehavior = buResult.Results[0]?.MasterUnsubscribeBehavior; if (masterUnsubscribeBehavior === 'ENTIRE_ENTERPRISE') { Util.logger.debug(` - BU uses ParentBU's All Subscriber List`); Util.logger.info( ' - Caching dependent Metadata: All Subscriber list (on _ParentBU_)' ); // do not use retrieveForCache here because (a) it does not support key-filtering and (b) it would cache folders on top which we do not need for the global all subscriber list const metadataParentBu = await this.retrieve(null, null, null, 'All Subscribers'); // manually set folder path of parent's All Subscriber List to avoid retrieving folders for (const key of Object.keys(metadataParentBu.metadata)) { metadataParentBu.metadata[key].r__folder_Path = 'my subscribers'; } // find & delete local All Subscriber list to avoid referencing the wrong one for (const key of Object.keys(results.metadata)) { if (results.metadata[key].ListName === 'All Subscribers') { delete results.metadata[key]; break; } } // revert to current default this.client = clientBackup; this.buObject = buObjectBackup; // make sure to overwrite parent bu DEs with local ones return { metadata: { ...metadataParentBu.metadata, ...results.metadata }, type: results.type, }; } else if (masterUnsubscribeBehavior === 'BUSINESS_UNIT_ONLY') { // revert client to current default this.client = clientBackup; Util.logger.debug(' - BU uses own All Subscriber List'); } } return results; } /** * Delete a metadata item from the specified business unit * * @param {string} customerKey Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(customerKey) { return super.deleteByKeySOAP(customerKey); } /** * manages post retrieve steps * * @param {MetadataTypeItem} list a single list * @returns {MetadataTypeItem} metadata */ static postRetrieveTasks(list) { return this.parseMetadata(list); } /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single list definition * @param {boolean} [parseForCache] if set to true, the Category ID is kept * @returns {MetadataTypeItem} Array with one metadata object and one sql string */ static parseMetadata(metadata, parseForCache) { if (!metadata.r__folder_Path) { // if we cached all subs from parent bu, we don't need to parse the folder path again here try { metadata.r__folder_Path = cache.searchForField( 'folder', metadata.Category, 'ID', 'Path' ); if (!parseForCache) { delete metadata.Category; } } catch (ex) { Util.logger.warn( ` - List ${metadata.ID}: '${metadata.CustomerKey}': ${ex.message}` ); } } return metadata; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; List.definition = MetadataTypeDefinitions.list; export default List; ================================================ FILE: lib/metadataTypes/MetadataType.js ================================================ 'use strict'; /* eslint no-unused-vars:off */ /* * README no-unused-vars is reduced to WARNING here as this file is a template * for all metadata types and methods often define params that are not used * in the generic version of the method */ import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; import deepEqual from 'deep-equal'; import pLimit from 'p-limit'; import Mustache from 'mustache'; import MetadataTypeInfo from '../MetadataTypeInfo.js'; import validationsRules from '../util/validations.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('sfmc-sdk').default} SDK * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError * @typedef {import('../../types/mcdev.d.js').SOAPError} SOAPError * @typedef {import('../../types/mcdev.d.js').RestError} RestError * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * ensure that Mustache does not escape any characters * * @param {string} text - * @returns {string} text */ Mustache.escape = function (text) { return text; }; /** * MetadataType class that gets extended by their specific metadata type class. * Provides default functionality that can be overwritten by child metadata type classes * */ class MetadataType { /** * Returns file contents mapped to their filename without '.json' ending * * @param {string} dir directory with json files, e.g. /retrieve/cred/bu/event, /deploy/cred/bu/event, /template/event * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @param {string[]} [selectedSubType] asset, message, ... * @returns {Promise.<MetadataTypeMap>} fileName => fileContent map */ static async getJsonFromFS(dir, listBadKeys, selectedSubType) { const fileName2FileContent = {}; try { const files = await File.readdir(dir); for (const fileName of files) { try { if (fileName.endsWith('.json')) { const fileContent = await File.readJSONFile(dir, fileName, false); // ! convert numbers to string to allow numeric keys to be checked properly const key = Number.isInteger(fileContent[this.definition.keyField]) ? fileContent[this.definition.keyField].toString() : fileContent[this.definition.keyField]; // ensure filename includes extended metadata extension const regex = new RegExp(/\.(\w|-)+-meta.json/); const errorDir = dir.split('\\').join('/'); if (regex.test(fileName)) { const fileNameWithoutEnding = File.reverseFilterIllegalFilenames( fileName.split(regex)[0] ); // We always store the filename using the External Key (CustomerKey or key) to avoid duplicate names. // to ensure any changes are done to both the filename and external key do a check here if (key === fileNameWithoutEnding || listBadKeys) { fileName2FileContent[fileNameWithoutEnding] = fileContent; } else { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}: Name of the metadata file and the JSON-key (${this.definition.keyField}) must match. Expected: ${key}.${this.definition.type}-meta.json. Actual: ` + Util.getGrayMsg(`${errorDir}/`) + fileName ); } } else { Util.logger.error( ` ☇ skipping ${this.definition.type} ${key}: Name of the metadata file must end on the extended metadata suffix. Expected: ${key}.${this.definition.type}-meta.json. Actual: ` + Util.getGrayMsg(`${errorDir}/`) + fileName ); } } } catch (ex) { // by catching this in the loop we gracefully handle the issue and move on to the next file Util.metadataLogger('debug', this.definition.type, 'getJsonFromFS', ex); } } } catch (ex) { // this will catch issues with readdirSync Util.metadataLogger('debug', this.definition.type, 'getJsonFromFS', ex); throw ex; } return fileName2FileContent; } /** * Returns fieldnames of Metadata Type. 'this.definition.fields' variable only set in child classes. * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {boolean} [isCaching] if true, then check if field should be skipped for caching * @returns {string[]} Fieldnames */ static getFieldNamesToRetrieve(additionalFields, isCaching) { const fieldNames = []; for (const fieldName in this.definition.fields) { if ( additionalFields?.includes(fieldName) || (this.definition.fields[fieldName].retrieving && !(isCaching && this.definition.fields[fieldName].skipCache)) ) { fieldNames.push(fieldName); } } if (!fieldNames.includes(this.definition.idField)) { // Always retrieve the ID because it may be used in references fieldNames.push(this.definition.idField); } return fieldNames; } /** * Deploys metadata * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved, ending on cred/bu * @param {string} retrieveDir directory where metadata after deploy should be saved, ending on cred/bu * @returns {Promise.<MetadataTypeMap>} Promise of keyField => metadata map */ static async deploy(metadataMap, deployDir, retrieveDir) { const upsertedMetadataMap = await this.upsert(metadataMap, deployDir); if (retrieveDir) { // deploy can be run with retrieveDir set to null for deploying auto-created foldes - these should not be saved to the retrieve-folder while everything else should const savedMetadataMap = await this.saveResults(upsertedMetadataMap, retrieveDir, null); if ( this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) && !this.definition.documentInOneFile ) { // * do not await here as this might take a while and has no impact on the deploy // * this should only be run if documentation is on a per metadata record level. Types that document an overview into a single file will need a full retrieve to work instead await this.document(savedMetadataMap, true); } } return upsertedMetadataMap; } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @param {MetadataTypeMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates * @returns {Promise.<void>} - */ static async postDeployTasks(upsertResults, originalMetadata, createdUpdated) {} /** * Gets executed before deleting a list of keys for the current type * * @param {string} keyArr metadata keys * @returns {Promise.<void>} - */ static async preDeleteTasks(keyArr) {} /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @param {MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped * @returns {Promise.<object>} apiResponse, potentially modified */ static async postCreateTasks(metadataEntry, apiResponse, metadataEntryWithAllFields) { return apiResponse; } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @param {MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry, apiResponse, metadataEntryWithAllFields) { return apiResponse; } /** * helper for {@link MetadataType.createREST} when legacy API endpoints as these do not return the created item but only their new id * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<void>} - */ static async postDeployTasks_legacyApi(metadataEntry, apiResponse) { if (!apiResponse?.[this.definition.idField] && !metadataEntry?.[this.definition.idField]) { return; } const id = apiResponse?.[this.definition.idField] || metadataEntry?.[this.definition.idField]; // re-retrieve created items because the API does not return any info for them except the new id (api key) try { const { metadata } = await this.retrieveForCache(null, null, 'id:' + id); const item = Object.values(metadata)[0]; // ensure the "created item" cli log entry has the new auto-generated value metadataEntry[this.definition.keyField] = item[this.definition.keyField]; // ensure postRetrieveTasks has the complete object in "apiResponse" Object.assign(apiResponse, item); // postRetrieveTasks will be run automatically on this via super.saveResult } catch (ex) { throw new Error( `Could not get details for new ${this.definition.type} ${id} from server (${ex.message})`, { cause: ex } ); } } /** * Gets executed after retreive of metadata type * * @param {MetadataTypeItem} metadata a single item * @param {string} targetDir folder where retrieves should be saved * @param {boolean} [isTemplating] signals that we are retrieving templates * @returns {MetadataTypeItem} cloned metadata */ static postRetrieveTasks(metadata, targetDir, isTemplating) { return structuredClone(metadata); } /** * generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single item */ static setFolderPath(metadata) { if (!this.definition.folderIdField) { return; } try { metadata.r__folder_Path = cache.searchForField( 'folder', metadata[this.definition.folderIdField], 'ID', 'Path' ); delete metadata[this.definition.folderIdField]; } catch (ex) { Util.logger.warn( Util.getMsgPrefix(this.definition, metadata) + `: Could not find folder (${ex.message})` ); } } /** * generic script that retrieves the folder ID from cache and updates the given metadata with it before deploy * * @param {MetadataTypeItem} metadata a single item */ static setFolderId(metadata) { if (!this.definition.folderIdField) { return; } if (!metadata.r__folder_Path) { throw new Error( `Dependent folder could not be found because r__folder_Path is not set` ); } metadata[this.definition.folderIdField] = cache.getFolderId(metadata.r__folder_Path); delete metadata.r__folder_Path; } /** * Gets metadata from Marketing Cloud * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] optionally limit to a single subtype * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} metadata */ static async retrieve(retrieveDir, additionalFields, subTypeArr, key) { Util.logNotSupported(this.definition, 'retrieve'); return { metadata: {}, type: this.definition.type }; } /** * Gets metadata from Marketing Cloud * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] optionally limit to a single subtype * @returns {Promise.<MetadataTypeMapObj>} metadata */ static retrieveChangelog(additionalFields, subTypeArr) { return this.retrieveForCache(additionalFields, subTypeArr); } /** * Gets metadata cache with limited fields and does not store value to disk * * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @param {string[]} [subTypeArr] optionally limit to a single subtype * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} metadata */ static async retrieveForCache(additionalFields, subTypeArr, key) { return this.retrieve(null, additionalFields, subTypeArr, key); } /** * Gets metadata cache with limited fields and does not store value to disk * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} [subType] optionally limit to a single subtype * @returns {Promise.<MetadataTypeItemObj>} metadata */ static async retrieveAsTemplate(templateDir, name, templateVariables, subType) { Util.logNotSupported(this.definition, 'retrieveAsTemplate'); Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); return { metadata: null, type: this.definition.type }; } /** * Retrieve a specific Script by Name * * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} uri rest endpoint for GET * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} name name (not key) of the metadata item * @returns {Promise.<{metadata: MetadataTypeItem, type: string}>} Promise */ static async retrieveTemplateREST(templateDir, uri, templateVariables, name) { return this.retrieveREST(templateDir, uri, templateVariables, name); } /** * Gets metadata cache with limited fields and does not store value to disk * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string} templateDir (List of) Directory where built definitions will be saved * @param {string} key name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} single metadata */ static async buildTemplate(retrieveDir, templateDir, key, templateVariables) { // retrieve metadata template let metadataStr; const typeDirArr = [this.definition.type]; const subType = await this.findSubType(retrieveDir, key); if (subType) { typeDirArr.push(subType); } const suffix = subType ? `-${subType}-meta` : '-meta'; const fileName = key + '.' + this.definition.type + suffix; try { // ! do not load via readJSONFile to ensure we get a string, not parsed JSON // templated files might contain illegal json before the conversion back to the file that shall be saved metadataStr = await File.readFilteredFilename( [retrieveDir, ...typeDirArr], fileName, 'json' ); if (!metadataStr) { throw new Error('File not found'); } } catch (ex) { try { metadataStr = await this.readSecondaryFolder( retrieveDir, typeDirArr, key, fileName, ex ); } catch { // only happening for types that use readSecondaryFolder (e.g. asset) // if we still have no metadataStr then we have to skip this metadata for all types and hence handle it outside of this catch } if (!metadataStr) { Util.logger.warn( Util.getGrayMsg(` ☇ skipped ${this.definition.type} ${key}: not found`) ); return; } } if (this.definition.stringifyFieldsBeforeTemplate) { // numeric fields are returned as numbers by the SDK/API. If we try to replace them in buildTemplate it would break the JSON format - but not if we stringify them first because then the {{{var}}} is in quotes const metadataTemp = JSON.parse(metadataStr); for (const field of this.definition.stringifyFieldsBeforeTemplate) { if (metadataTemp[field]) { if (Array.isArray(metadataTemp[field])) { for (let i = 0; i < metadataTemp[field].length; i++) { metadataTemp[field][i] = metadataTemp[field][i].toString(); } } else if ('object' === typeof metadataTemp[field]) { for (const subField in metadataTemp[field]) { metadataTemp[field][subField] = metadataTemp[field][subField].toString(); } } else { metadataTemp[field] = metadataTemp[field].toString(); } } } metadataStr = JSON.stringify(metadataTemp); } // handle extracted code // templating to extracted content is applied inside of buildTemplateForNested() await this.buildTemplateForNested( retrieveDir, templateDir, JSON.parse(metadataStr), templateVariables, key ); const metadata = JSON.parse(Util.replaceByObject(metadataStr, templateVariables)); this.keepTemplateFields(metadata); try { // write to file await File.writeJSONToFile([templateDir, ...typeDirArr], fileName, metadata); Util.logger.info( ` - templated ${this.definition.type}: ${key} (${ metadata[this.definition.nameField] })` ); return { metadata: metadata, type: this.definition.type }; } catch (ex) { throw new Error(`${this.definition.type}:: ${ex.message}`, { cause: ex }); } } /** * Gets executed before deploying metadata * * @param {MetadataTypeItem} metadata a single metadata item * @param {string} deployDir folder where files for deployment are stored * @returns {Promise.<MetadataTypeItem>} Promise of a single metadata item */ static async preDeployTasks(metadata, deployDir) { return metadata; } /** * helper to find a new unique name during item creation * * @param {string} key key of the item * @param {string} name name of the item * @param {{ type: string; key: string; name: any; }[]} namesInFolder names of the items in the same folder * @param {string} [subtype] itemType-name * @returns {string} new name */ static findUniqueName(key, name, namesInFolder, subtype) { let newName = name; let suffix; let i = 1; while ( namesInFolder.find( (item) => item.name === newName && item.key !== key && (!subtype || item.type === subtype) ) ) { suffix = ' (' + i + ')'; // for customer key max is 100 chars newName = name.slice(0, Math.max(0, 100 - suffix.length)) + suffix; i++; } return newName; } /** * Abstract create method that needs to be implemented in child metadata type * * @param {MetadataTypeItem} metadata single metadata entry * @param {string} deployDir directory where deploy metadata are saved * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async create(metadata, deployDir) { Util.logNotSupported(this.definition, 'create', metadata); return; } /** * Abstract update method that needs to be implemented in child metadata type * * @param {MetadataTypeItem} metadata single metadata entry * @param {MetadataTypeItem} [metadataBefore] metadata mapped by their keyField * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async update(metadata, metadataBefore) { Util.logNotSupported(this.definition, 'update', metadata); return; } /** * Abstract refresh method that needs to be implemented in child metadata type * * @param {string[]} [keyArr] metadata keys * @param {boolean} [checkKey] whether to check if the key is valid * @param {MetadataTypeMap} [upsertResults] metadata mapped by their keyField as returned by update/create; needs to be refreshed after publish * @returns {Promise.<string[]>} Returns list of keys that were refreshed */ static async refresh(keyArr, checkKey = true, upsertResults) { Util.logNotSupported(this.definition, 'refresh'); return []; } /** * * @param {string[]} keyArr limit retrieval to given metadata type * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<Set.<string>>} found asset keys */ static async getCbReferenceKeys(keyArr, retrieveDir, findAssetKeys) { if (!Object.prototype.hasOwnProperty.call(this, 'replaceCbReference')) { // only types that have a replaceCbReference method actually have ampscript/ssjs return; } // get all metadata of the current type; then filter by keys in selectedTypes const metadataMap = Util.filterObjByKeys( await this.getJsonFromFS(File.normalizePath([retrieveDir, this.definition.type])), keyArr ); await this.replaceCbReferenceLoop(metadataMap, retrieveDir, findAssetKeys); return findAssetKeys; } /** * this iterates over all items found in the retrieve folder and executes the type-specific method for replacing references * * @param {MetadataTypeMap} metadataMap list of metadata (keyField => metadata) * @param {string} retrieveDir retrieve dir including cred and bu * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<string[]>} Returns list of keys for which references were replaced */ static async replaceCbReferenceLoop(metadataMap, retrieveDir, findAssetKeys) { const keysForDeploy = []; if (!metadataMap) { // 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 return keysForDeploy; } const fromDescription = Util.OPTIONS.referenceFrom .map((from) => 'ContentBlockBy' + Util.capitalizeFirstLetter(from)) .join(' and '); if (Object.keys(metadataMap).length) { Util.logger.debug(` - Searching in ${this.definition.type} `); const baseDir = [retrieveDir, ...this.definition.type.split('-')]; const deployMap = {}; for (const key in metadataMap) { const item = metadataMap[key]; if (this.isFiltered(item, true) || this.isFiltered(item, false)) { // we would not have saved these items to disk but they exist in the cache and hence need to be skipped here continue; } try { // add key but make sure to turn it into string or else numeric keys will be filtered later deployMap[key] = await this.replaceCbReference( item, retrieveDir, findAssetKeys ); keysForDeploy.push(key + ''); if (!findAssetKeys) { await this.saveToDisk(deployMap, key, baseDir); Util.logger.info( ` - added ${this.definition.type} to update queue: ${key}` ); } } catch (ex) { if (ex.code !== 200) { // dont print error if we simply did not find relevant content blocks Util.logger.errorStack( ex, 'issue with ' + this.definition.type + ' ' + key ); } if (!findAssetKeys) { Util.logger.info( Util.getGrayMsg( ` ☇ skipping ${Util.getTypeKeyName(this.definition, item)}: no ${fromDescription} found` ) ); } } } if (!findAssetKeys) { Util.logger.info( `Found ${keysForDeploy.length} ${this.definition.type}${keysForDeploy.length === 1 ? '' : 's'} to update` ); } } return keysForDeploy; } /** * Abstract execute method that needs to be implemented in child metadata type * * @param {MetadataTypeItem} item single metadata item * @param {string} [retrieveDir] directory where metadata is saved * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem | CodeExtractItem>} key of the item that was updated */ static async replaceCbReference(item, retrieveDir, findAssetKeys) { Util.logNotSupported(this.definition, 'replaceCbReference'); return []; } /** * Abstract execute method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were executed */ static async execute(keyArr, cache) { Util.logNotSupported(this.definition, 'execute'); return []; } /** * Abstract schedule method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were executed */ static async schedule(keyArr, cache) { Util.logNotSupported(this.definition, 'schedule'); return []; } /** * Abstract pause method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching * @returns {Promise.<string[]>} Returns list of keys that were paused */ static async pause(keyArr, cache) { Util.logNotSupported(this.definition, 'pause'); return []; } /** * Abstract stop method that needs to be implemented in child metadata type * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were stopped */ static async stop(keyArr) { Util.logNotSupported(this.definition, 'stop'); return []; } /** * test if metadata was actually changed or not to potentially skip it during deployment * * @param {MetadataTypeItem} cachedVersion cached version from the server * @param {MetadataTypeItem} metadata item to upload * @param {string} [fieldName] optional field name to use for identifying the record in logs * @returns {boolean} true if metadata was changed */ static hasChanged(cachedVersion, metadata, fieldName) { // should be set up type by type but the *_generic version is likely a good start for many types return true; } /** * test if metadata was actually changed or not to potentially skip it during deployment * * @param {MetadataTypeItem} cachedVersion cached version from the server * @param {MetadataTypeItem} metadataItem item to upload * @param {string} [fieldName] optional field name to use for identifying the record in logs * @param {boolean} [silent] optionally suppress logging * @returns {boolean} true on first identified deviation or false if none are found */ static hasChangedGeneric(cachedVersion, metadataItem, fieldName, silent) { if (!cachedVersion) { return true; } // we do need the full set in other places and hence need to work with a clone here const clonedMetada = structuredClone(metadataItem); // keep copy of identifier in case it is among the non-updateable fields const identifier = clonedMetada[fieldName || this.definition.keyField]; this.removeNotUpdateableFields(clonedMetada); // iterate over what we want to upload rather than what we cached to avoid false positives for (const prop in clonedMetada) { if (this.definition.ignoreFieldsForUpdateCheck?.includes(prop)) { continue; } if ( clonedMetada[prop] === null || ['string', 'number', 'boolean'].includes(typeof clonedMetada[prop]) ) { // check simple variables directly // check should ignore types to bypass string/number auto-conversions caused by SFMC-SDK if (clonedMetada[prop] != cachedVersion[prop]) { Util.logger.debug( `${this.definition.type}:: ${ identifier }.${prop} changed: '${cachedVersion[prop]}' to '${clonedMetada[prop]}'` ); return true; } } else if (deepEqual(clonedMetada[prop], cachedVersion[prop])) { // test complex objects here Util.logger.debug( `${this.definition.type}:: ${ identifier }.${prop} changed: '${cachedVersion[prop]}' to '${clonedMetada[prop]}'` ); return true; } } if (!silent) { Util.logger.verbose( ` ☇ skipping ${this.definition.type} ${identifier} / ${ clonedMetada[this.definition.nameField] || '' }: no change detected` ); } return false; } /** * helper for {@link MetadataType.upsert} to enforce max key length * * @param {string} metadataKey key of metadata */ static enforceMaxKeyLength(metadataKey) { if (this.definition.maxKeyLength && metadataKey.length > this.definition.maxKeyLength) { throw new Error( `key exceeds maximum length of ${this.definition.maxKeyLength} characters for this type` ); } } /** * MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {boolean} [runUpsertSequentially] when a type has self-dependencies creates need to run one at a time and created/changed keys need to be cached to ensure following creates/updates have thoses keys available * @returns {Promise.<MetadataTypeMap>} keyField => metadata map */ static async upsert(metadataMap, deployDir, runUpsertSequentially = false) { const orignalMetadataMap = structuredClone(metadataMap); const metadataToUpdate = []; const metadataToCreate = []; let createResults = []; let updateResults = []; let filteredByPreDeploy = 0; for (const metadataKey in metadataMap) { let hasError = false; try { // preDeployTasks parsing let deployableMetadata; try { this.enforceMaxKeyLength(metadataKey); metadataMap[metadataKey] = await this.validation( 'deploy', metadataMap[metadataKey], deployDir ); if (metadataMap[metadataKey]) { // only run unless we encountered a situation in our validation that made us want to filter this record deployableMetadata = await this.preDeployTasks( metadataMap[metadataKey], deployDir ); } } catch (ex) { // do this in case something went wrong during pre-deploy steps to ensure the total counter is correct hasError = true; deployableMetadata = metadataMap[metadataKey]; if (deployableMetadata) { // * include ": ${ex.message}" in the error if this is ever turned back into Util.logger.error() Util.logger.errorStack( ex, ` ☇ skipping ${this.definition.type} ${ deployableMetadata[this.definition.keyField] } / ${deployableMetadata[this.definition.nameField]}` ); } else { Util.logger.errorStack( ex, ` ☇ skipping ${this.definition.type} ${metadataKey}` ); } } // if preDeploy returns nothing then it cannot be deployed so skip deployment if (deployableMetadata) { metadataMap[metadataKey] = deployableMetadata; // create normalizedKey off of whats in the json rather than from "metadataKey" because preDeployTasks might have altered something (type asset) const action = await this.createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ); if (runUpsertSequentially) { if (action === 'create') { // handle creates sequentially here becasue we might have interdepencies const result = await this.create(metadataMap[metadataKey], deployDir); if (result) { createResults.push(result); if (result[this.definition.idField]) { // ensure we have the ID in the cache metadataMap[metadataKey][this.definition.idField] = result[this.definition.idField]; } // make this newly created item available in cache for other itmes that might reference it /** @type {MetadataTypeMap} */ const newObject = { [metadataKey]: metadataMap[metadataKey] }; cache.mergeMetadata(this.definition.type, newObject); } } else if (action === 'update' && !Util.OPTIONS.noUpdate) { const metadataEntry = metadataToUpdate.find( (el) => el !== null && el.after[this.definition.keyField] === metadataMap[metadataKey][this.definition.keyField] ); if (!metadataEntry) { Util.logger.error( ` - ${this.definition.type} ${metadataKey} / ${metadataMap[metadataKey][this.definition.keyField]} not found in update list` ); continue; } // handle updates sequentially here becasue we might have interdepencies // this is especially important when we use features like --matchName which are updates but change the key const result = await this.update( metadataEntry.after, metadataEntry.before ); if (result) { updateResults.push(result); // make this newly created item available in cache for other itmes that might reference it const newObject = { [metadataKey]: structuredClone(metadataMap[metadataKey]), }; if (result.objectID) { // required for assets newObject[metadataKey].objectID = result.objectID; } cache.mergeMetadata(this.definition.type, newObject); } } } } else { filteredByPreDeploy++; } } catch (ex) { if ( metadataMap[metadataKey] && metadataMap[metadataKey][this.definition.nameField] ) { Util.logger.error( ` ☇ skipping ${this.definition.type} ${metadataKey} / ${metadataMap[metadataKey][this.definition.nameField]}: ${ex.message}` ); } else { Util.logger.errorStack(ex, `Upserting ${this.definition.type} failed`); } } } if (!runUpsertSequentially) { // create const createLimit = pLimit(10); createResults = ( await Promise.all( metadataToCreate .filter((r) => r !== undefined && r !== null) .map((metadataEntry) => createLimit(() => this.create(metadataEntry, deployDir)) ) ) ).filter((r) => r !== undefined && r !== null); // update if (Util.OPTIONS.noUpdate && metadataToUpdate.length) { Util.logger.info( ` ☇ skipping update of ${metadataToUpdate.length} ${this.definition.type}${metadataToUpdate.length == 1 ? '' : 's'}: --noUpdate flag is set` ); } else if (metadataToUpdate.length) { const updateLimit = pLimit(10); updateResults = ( await Promise.all( metadataToUpdate .filter((r) => r !== undefined && r !== null) .map((metadataEntry) => updateLimit(() => this.update(metadataEntry.after, metadataEntry.before) ) ) ) ).filter((r) => r !== undefined && r !== null); } } // Logging Util.logger.info( `${this.definition.type} upsert: ${createResults.length} of ${metadataToCreate.length} created / ${updateResults.length} of ${metadataToUpdate.length} updated` + (filteredByPreDeploy > 0 ? ` / ${filteredByPreDeploy} filtered` : '') ); let upsertResults; if (this.definition.bodyIteratorField === 'Results') { // if Results then parse as SOAP // put in Retrieve Format for parsing // todo add handling when response does not contain items. const metadataResults = createResults .concat(updateResults) // TODO remove Object.keys check after create/update SOAP methods stop returning empty objects instead of null .filter((r) => r !== undefined && r !== null && Object.keys(r).length !== 0) .flatMap((r) => r.Results) .map((r) => r.Object); upsertResults = this.parseResponseBody({ Results: metadataResults }); } else { // likely comming from one of the many REST APIs // put in Retrieve Format for parsing // todo add handling when response does not contain items. const metadataResults = createResults.concat(updateResults).filter(Boolean); upsertResults = this.parseResponseBody(metadataResults); } await this.postDeployTasks(upsertResults, orignalMetadataMap, { created: createResults.length, updated: updateResults.length, }); return upsertResults; } /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadataMap list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create * @returns {Promise.<'create' | 'update' | 'skip'>} action to take */ static async createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ) { let normalizedKey = File.reverseFilterIllegalFilenames( metadataMap[metadataKey][this.definition.keyField] ); // Update if it already exists; Create it if not const maxKeyLength = this.definition.maxKeyLength || 36; // make sure keySuffix always has a string value Util.OPTIONS.keySuffix = Util.OPTIONS.keySuffix ? Util.OPTIONS.keySuffix.trim() : ''; if (Util.OPTIONS.keySuffix && !cache.getByKey(this.definition.type, normalizedKey)) { // to ensure we go into update mode like we would with appending the MID to asset-keys, recreated the normalized key here const newKey = this.getNewKey( this.definition.keyField, metadataMap[metadataKey], maxKeyLength ); normalizedKey = File.reverseFilterIllegalFilenames(newKey); } const cacheMatchedByKey = cache.getByKey(this.definition.type, normalizedKey); const cacheMatchedByName = cacheMatchedByKey ? null : this.getCacheMatchedByName(metadataMap[metadataKey]); if ( Util.logger.level === 'debug' && metadataMap[metadataKey][this.definition.idField] && this.definition.idField !== this.definition.keyField ) { // TODO: re-evaluate in future releases if & when we managed to solve folder dependencies once and for all // only used if resource is excluded from cache and we still want to update it // needed e.g. to rewire lost folders Util.logger.warn( ' - Hotfix for non-cachable resource found in deploy folder. Trying update:' ); Util.logger.warn(JSON.stringify(metadataMap[metadataKey])); if (hasError) { metadataToUpdate.push(null); return 'skip'; } else { metadataToUpdate.push({ before: {}, after: metadataMap[metadataKey], }); return 'update'; } } else if (cacheMatchedByKey || cacheMatchedByName) { // normal way of processing update files const cachedVersion = cacheMatchedByKey || cacheMatchedByName; if (!cacheMatchedByKey && cacheMatchedByName) { Util.matchedByName[this.definition.type] ||= {}; Util.matchedByName[this.definition.type][metadataKey] = cacheMatchedByName[this.definition.keyField]; } if (!this.hasChanged(cachedVersion, metadataMap[metadataKey])) { hasError = true; } if (Util.OPTIONS.changeKeyField) { if (this.definition.keyField == this.definition.idField) { Util.logger.error( ` - --changeKeyField cannot be used for types that use their ID as key. Skipping change.` ); hasError = true; } else if (this.definition.keyIsFixed) { Util.logger.error( ` - type ${this.definition.type} does not support --changeKeyField and --changeKeyValue. Skipping change.` ); hasError = true; } else if (!metadataMap[metadataKey][Util.OPTIONS.changeKeyField]) { Util.logger.error( ` - --changeKeyField is set to ${Util.OPTIONS.changeKeyField} but no value was found in the metadata. Skipping change.` ); hasError = true; } else if (Util.OPTIONS.changeKeyField === this.definition.keyField) { // simple issue, used WARN to avoid signaling a problem to ci/cd and don't fail deploy Util.logger.warn( ` - --changeKeyField is set to the same value as the keyField for ${this.definition.type}. Skipping change.` ); } else if (metadataMap[metadataKey][Util.OPTIONS.changeKeyField]) { const newKey = this.getNewKey( Util.OPTIONS.changeKeyField, metadataMap[metadataKey], maxKeyLength ); if ( metadataMap[metadataKey][Util.OPTIONS.changeKeyField] + '' + Util.OPTIONS.keySuffix > maxKeyLength ) { Util.logger.warn( `${this.definition.type} ${this.definition.keyField} may not exceed ${maxKeyLength} characters. Truncated the value in field ${Util.OPTIONS.changeKeyField} to ${newKey}` ); } if (metadataKey == newKey) { Util.logger.warn( ` - --changeKeyField(${Util.OPTIONS.changeKeyField}) is providing the current value of the key (${metadataKey}). Skipping change.` ); } else { Util.logger.info( ` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --changeKeyField=${Util.OPTIONS.changeKeyField}` ); metadataMap[metadataKey][this.definition.keyField] = newKey; // ensure we can delete the old file(s) after the successful update Util.changedKeysMap[this.definition.type] ||= {}; Util.changedKeysMap[this.definition.type][newKey] = metadataKey; } } } else if (Util.OPTIONS.changeKeyValue) { if (Util.OPTIONS.keySuffix !== '') { Util.logger.warn(`Ignoring --keySuffix as --changeKeyValue is set.`); } // NOTE: trim twice while getting the newKey value to remove leading spaces before limiting the length const newKey = Util.OPTIONS.changeKeyValue.trim().slice(0, maxKeyLength).trim(); if (Util.OPTIONS.changeKeyValue.trim().length > maxKeyLength) { Util.logger.warn( `${this.definition.type} ${this.definition.keyField} may not exceed ${maxKeyLength} characters. Truncated your value to ${newKey}` ); } if (this.definition.keyField == this.definition.idField) { Util.logger.error( ` - --changeKeyValue cannot be used for types that use their ID as key. Skipping change.` ); hasError = true; } else if (this.definition.keyIsFixed) { Util.logger.error( ` - type ${this.definition.type} does not support --changeKeyField and --changeKeyValue. Skipping change.` ); hasError = true; } else if (metadataKey == newKey) { Util.logger.warn( ` - --changeKeyValue is providing the current value of the key (${metadataKey}). Skipping change.` ); } else { Util.logger.info( ` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --changeKeyValue` ); metadataMap[metadataKey][this.definition.keyField] = newKey; // ensure we can delete the old file(s) after the successful update Util.changedKeysMap[this.definition.type] ||= {}; Util.changedKeysMap[this.definition.type][newKey] = metadataKey; } } else if (Util.OPTIONS.keySuffix && Util.OPTIONS.keySuffix !== '') { // assume we simply want to append a suffix const newKey = this.getNewKey( this.definition.keyField, metadataMap[metadataKey], maxKeyLength ); Util.logger.info( ` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --keySuffix=${Util.OPTIONS.keySuffix}` ); metadataMap[metadataKey][this.definition.keyField] = newKey; // ensure we can delete the old file(s) after the successful update Util.changedKeysMap[this.definition.type] ||= {}; Util.changedKeysMap[this.definition.type][newKey] = metadataKey; } if (hasError) { // do this in case something went wrong during pre-deploy steps to ensure the total counter is correct metadataToUpdate.push(null); return 'skip'; } else { // add ObjectId to allow actual update metadataMap[metadataKey][this.definition.idField] = cachedVersion[this.definition.idField]; metadataToUpdate.push({ before: cachedVersion, after: metadataMap[metadataKey], }); return 'update'; } } else { if (hasError) { // do this in case something went wrong during pre-deploy steps to ensure the total counter is correct metadataToCreate.push(null); return 'skip'; } else { if (Util.OPTIONS.keySuffix && Util.OPTIONS.keySuffix !== '') { // assume we simply want to append a suffix const newKey = this.getNewKey( this.definition.keyField, metadataMap[metadataKey], maxKeyLength ); Util.logger.info( ` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --keySuffix=${Util.OPTIONS.keySuffix}` ); metadataMap[metadataKey][this.definition.keyField] = newKey; } metadataToCreate.push(metadataMap[metadataKey]); return 'create'; } } } /** * helper for {@link MetadataType.createOrUpdate} * * @param {MetadataTypeItem} metadataItem to be deployed item * @returns {MetadataTypeItem} cached item or undefined */ static getCacheMatchedByName(metadataItem) { // not supported generically return null; } /** * Creates a single metadata entry via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for POST * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async createREST(metadataEntry, uri, handleOutside) { const metadataClone = structuredClone(metadataEntry); this.removeNotCreateableFields(metadataEntry); try { // set to empty object in case API returned nothing to be able to update it in helper classes let response = (await this.client.rest.post(uri, metadataEntry)) || {}; response = await this.postCreateTasks(metadataEntry, response, metadataClone); if (!handleOutside) { Util.logger.info( ` - created ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } return response; } catch (ex) { const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error creating ${Util.getTypeKeyName(this.definition, metadataEntry)}:` ); if (parsedErrors.length) { for (const msg of parsedErrors) { Util.logger.error(' • ' + msg); } } else if (ex?.message) { Util.logger.debug(ex.message); } return null; } } /** * Creates a single metadata entry via fuel-soap (generic lib not wrapper) * * @param {MetadataTypeItem} metadataEntry single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async createSOAP(metadataEntry, handleOutside) { const soapType = this.definition.soapType || this.definition.type; this.removeNotCreateableFields(metadataEntry); try { const response = await this.client.soap.create( Util.capitalizeFirstLetter(soapType), metadataEntry, null ); if (!handleOutside) { Util.logger.info( ` - created ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } return response; } catch (ex) { this._handleSOAPErrors(ex, 'creating', metadataEntry, handleOutside); return null; } } /** * Updates a single metadata entry via REST * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for PATCH * @param {'patch'|'post'|'put'} [httpMethod] defaults to 'patch'; some update requests require PUT instead of PATCH * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async updateREST(metadataEntry, uri, httpMethod = 'patch', handleOutside) { const metadataClone = structuredClone(metadataEntry); this.removeNotUpdateableFields(metadataEntry); try { // set to empty object in case API returned nothing to be able to update it in helper classes let response = (await this.client.rest[httpMethod](uri, metadataEntry)) || {}; await this._postChangeKeyTasks(metadataEntry); this.getErrorsREST(response); response = await this.postUpdateTasks(metadataEntry, response, metadataClone); // some times, e.g. automation dont return a key in their update response and hence we need to fall back to name if (!handleOutside) { Util.logger.info( ` - updated ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } return response; } catch (ex) { const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error updating ${Util.getTypeKeyName(this.definition, metadataEntry)}:` ); for (const msg of parsedErrors) { Util.logger.error(' • ' + msg); } return null; } } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {boolean} [keepMap] some types require to check the old-key new-key relationship in their postDeployTasks; currently used by dataExtension only * @returns {Promise.<void>} - */ static async _postChangeKeyTasks(metadataEntry, keepMap = false) { if ( (Util.OPTIONS.changeKeyField || Util.OPTIONS.changeKeyValue) && Util.changedKeysMap?.[this.definition.type]?.[metadataEntry[this.definition.keyField]] ) { const oldKey = Util.changedKeysMap?.[this.definition.type]?.[ metadataEntry[this.definition.keyField] ]; // delete file(s) of old key await this.postDeleteTasks(oldKey); // fix key in cache const typeCache = cache.getCache()[this.definition.type]; typeCache[metadataEntry[this.definition.keyField]] = typeCache[oldKey]; delete typeCache[oldKey]; if (!keepMap) { // clean entry from to-do list delete Util.changedKeysMap?.[this.definition.type]?.[ metadataEntry[this.definition.keyField] ]; } } } /** * Updates a single metadata entry via fuel-soap (generic lib not wrapper) * * @param {MetadataTypeItem} metadataEntry single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<object> | null} Promise of API response or null in case of an error */ static async updateSOAP(metadataEntry, handleOutside) { const soapType = this.definition.soapType || this.definition.type; const metadataClone = structuredClone(metadataEntry); this.removeNotUpdateableFields(metadataEntry); try { let response = await this.client.soap.update( Util.capitalizeFirstLetter(soapType), metadataEntry, null ); if (!handleOutside) { Util.logger.info( ` - updated ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } await this._postChangeKeyTasks(metadataEntry); response = await this.postUpdateTasks(metadataEntry, response, metadataClone); return response; } catch (ex) { this._handleSOAPErrors(ex, 'updating', metadataEntry, handleOutside); return null; } } /** * * @param {SOAPError} ex error that occured * @param {'creating'|'updating'|'retrieving'|'executing'|'pausing'} msg what to print in the log * @param {MetadataTypeItem} [metadataEntry] single metadata entry * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @param {string} [nameAttribute] name attribute to use in the error message instead of keyField */ static _handleSOAPErrors(ex, msg, metadataEntry, handleOutside, nameAttribute) { if (handleOutside) { throw ex; } else { const errorMsg = this.getSOAPErrorMsg(ex); const name = metadataEntry ? ` '${metadataEntry[nameAttribute || this.definition.keyField]}'` : ''; Util.logger.error(` ☇ error ${msg} ${this.definition.type}${name}: ${errorMsg}`); } } /** * helper for {@link MetadataType._handleSOAPErrors} * * @param {SOAPError} ex error that occured * @returns {string} error message */ static getSOAPErrorMsg(ex) { if (ex?.json?.Results?.length) { if (ex?.json?.Results[0].StatusMessage) { return `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})`; } else if (ex?.json?.Results[0].Result.StatusMessage) { return `${ex.json.Results[0].Result.StatusMessage} (Code ${ex.json.Results[0].Result.ErrorCode})`; } } return ex.message; } /** * Retrieves SOAP via generic fuel-soap wrapper based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {SoapRequestParams} [requestParams] required for the specific request (filter for example) * @param {string} [singleRetrieve] key of single item to filter by * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<MetadataTypeMapObj>} Promise of item map */ static async retrieveSOAP(retrieveDir, requestParams, singleRetrieve, additionalFields) { requestParams ||= {}; const fields = this.getFieldNamesToRetrieve(additionalFields, !retrieveDir); const soapType = this.definition.soapType || this.definition.type; let response; try { response = await this.client.soap.retrieveBulk( Util.capitalizeFirstLetter(soapType), fields, requestParams ); } catch (ex) { this._handleSOAPErrors(ex, 'retrieving'); return; } const metadata = this.parseResponseBody(response); if (retrieveDir) { const savedMetadata = await this.saveResults(metadata, retrieveDir, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(singleRetrieve) ); if (Object.keys(savedMetadata).length > 0) { await this.runDocumentOnRetrieve(singleRetrieve, savedMetadata); } else if (singleRetrieve) { this.postDeleteTasks(singleRetrieve); } } return { metadata: metadata, type: this.definition.type }; } /** * Retrieves Metadata for Rest Types * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {string} uri rest endpoint for GET * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @param {string} [singleRetrieve] key of single item to filter by * @returns {Promise.<{metadata: (MetadataTypeMap | MetadataTypeItem), type: string}>} Promise of item map (single item for templated result) */ static async retrieveREST(retrieveDir, uri, templateVariables, singleRetrieve) { const response = this.definition.restPagination && !singleRetrieve ? await this.client.rest.getBulk(uri, this.definition.restPageSize || 500) : await this.client.rest.get(uri); const results = this.parseResponseBody(response, singleRetrieve); // get extended metadata if applicable if (this.definition.hasExtended) { const amount = Object.keys(results).length; if (amount > 100) { Util.logger.info( Util.getGrayMsg( ` - retrieving extended metadata for ${amount} ${this.definition.type}s...` ) ); } else { Util.logger.debug(' - retrieving extended metadata'); } const rateLimit = pLimit(this.definition.restConcurrentLimit || 5); const extended = await Promise.all( Object.keys(results) .map((key) => { const url = uri.endsWith(results[key][this.definition.idField]) ? null : uri + results[key][this.definition.idField]; return url ? { url, key } : null; }) .filter(Boolean) .map((el) => rateLimit(async () => { try { return await this.client.rest.get(el.url); } catch (ex) { return await this.handleRESTErrors(ex, el.key, el.url); } }) ) ); for (const ext of extended) { const key = ext[this.definition.keyField]; results[key] = Object.assign(results[key], ext); } } if (retrieveDir) { const savedMetadata = await this.saveResults( results, retrieveDir, null, templateVariables ); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(singleRetrieve) ); if (Object.keys(savedMetadata).length > 0) { await this.runDocumentOnRetrieve(singleRetrieve, savedMetadata); } else if (singleRetrieve) { await this.postDeleteTasks(singleRetrieve); } } return { metadata: templateVariables ? Object.values(results)[0] : results, type: this.definition.type, }; } /** * * @param {object[]} urlArray {uri: string, id: string} combo of URL and ID/key of metadata * @param {number} [concurrentRequests] optionally set a different amount of concurrent requests * @param {boolean} [logAmountOfUrls] if true, prints an info message about to-be loaded amount of metadata * @returns {Promise.<{metadata: (MetadataTypeMap | MetadataTypeItem), type: string}>} Promise of item map (single item for templated result) */ static async retrieveRESTcollection(urlArray, concurrentRequests = 10, logAmountOfUrls = true) { if (logAmountOfUrls) { Util.logger.debug( Util.getGrayMsg( ` - ${urlArray?.length} ${this.definition.type}${ urlArray?.length === 1 ? '' : 's' } found. Retrieving details...` ) ); } const rateLimit = pLimit(concurrentRequests); const metadataArr = urlArray.length ? await Promise.all( urlArray.map(async (item) => rateLimit(async () => { try { return await this.client.rest.get(item.uri); } catch (ex) { return await this.handleRESTErrors(ex, item.id, item.uri); } }) ) ) : []; const results = {}; for (const item of metadataArr) { this.createCustomKeyField(item); const key = item[this.definition.keyField]; results[key] = item; } return { metadata: results, type: this.definition.type, }; } /** * helper for {@link this.retrieveRESTcollection} * * @param {RestError} ex exception * @param {string} key id or key of item * @param {string} url url to call for retry * @returns {Promise.<any>} - */ static async handleRESTErrors(ex, key, url) { // if the ID is too short, the system will throw the 400 error Util.logger.debug(` ☇ skipping ${this.definition.type} ${key}: ${ex.message} ${ex.code}`); return null; } /** * Used to execute a query/automation etc. * * @param {string} uri REST endpoint where the POST request should be sent * @param {string} key item key * @returns {Promise.<{key:string, response:string}>} metadata key and API response (OK or error) */ static async executeREST(uri, key) { try { const response = await this.client.rest.post(uri, {}); // payload is empty for this request if (response === 'OK') { Util.logger.info(` - executed ${this.definition.type}: ${key}`); } else { throw new Error(response); } return { key, response }; } catch (ex) { Util.logger.error(`Failed to execute ${this.definition.type} ${key}: ${ex.message}`); } } /** * Used to execute a query/automation etc. * * @param {MetadataTypeItem} [metadataEntry] single metadata entry * @returns {Promise.<{key:string, response:object}>} metadata key and API response */ static async executeSOAP(metadataEntry) { const soapType = this.definition.soapType || this.definition.type; try { const response = await this.client.soap.perform( Util.capitalizeFirstLetter(soapType), 'start', { ObjectID: metadataEntry[this.definition.idField], } ); if (response?.OverallStatus === 'OK') { Util.logger.info( ` - executed ${Util.getTypeKeyName(this.definition, metadataEntry)}` ); } else { throw new Error(response?.OverallStatus); } return { key: metadataEntry[this.definition.keyField], response }; } catch (ex) { this._handleSOAPErrors(ex, 'executing', metadataEntry); return null; } } /** * helper for {@link MetadataType.retrieveREST} and {@link MetadataType.retrieveSOAP} * * @param {string|number} singleRetrieve key of single item to filter by * @param {MetadataTypeMap} metadataMap saved metadata * @returns {Promise.<void>} - */ static async runDocumentOnRetrieve(singleRetrieve, metadataMap) { if ( this.buObject && this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) ) { if (!singleRetrieve || (singleRetrieve && !this.definition.documentInOneFile)) { const count = Object.keys(metadataMap).length; Util.logger.debug( ` - Running document for ${count} record${count === 1 ? '' : 's'}` ); await this.document(metadataMap); } else { Util.logger.info( Util.getGrayMsg( ` - Skipped running document because you supplied keys and ${this.definition.type} is documented in a single file for all.` ) ); } } } /** * helper for {@link parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword * * @param {MetadataTypeItem} metadata single item */ static createCustomKeyField(metadata) {} /** * Builds map of metadata entries mapped to their keyfields * * @param {object} body json of response body * @param {string} [singleRetrieve] key of single item to filter by * @returns {MetadataTypeMap} keyField => metadata map */ static parseResponseBody(body, singleRetrieve) { const bodyIteratorField = this.definition.bodyIteratorField; const keyField = this.definition.keyField; const metadataStructure = {}; if (body !== null) { if (Array.isArray(body)) { // in some cases data is just an array for (const item of body) { this.createCustomKeyField(item); const key = item[keyField]; metadataStructure[key] = item; } } else if (body[bodyIteratorField]) { for (const item of body[bodyIteratorField]) { this.createCustomKeyField(item); const key = item[keyField]; metadataStructure[key] = item; } } else if (singleRetrieve) { // some types will return a single item intead of an array if the key is supported by their api this.createCustomKeyField(body); // ! currently, the id: prefix is only supported by journey (interaction) if (singleRetrieve.startsWith('id:')) { singleRetrieve = body[keyField]; } metadataStructure[singleRetrieve] = body; return metadataStructure; } if ( metadataStructure[singleRetrieve] && (typeof singleRetrieve === 'string' || typeof singleRetrieve === 'number') ) { // in case we really just wanted one entry but couldnt do so in the api call, filter it here const single = { [singleRetrieve]: metadataStructure[singleRetrieve] }; return single; } else if (singleRetrieve) { return {}; } } return metadataStructure; } /** * Deletes a field in a metadata entry if the selected definition property equals false. * * @example * Removes field (or nested fields childs) that are not updateable * deleteFieldByDefinition(metadataEntry, 'CustomerKey', 'isUpdateable'); * @param {MetadataTypeItem} metadataEntry One entry of a metadataType * @param {string} fieldPath field path to be checked if it conforms to the definition (dot seperated if nested): 'fuu.bar' * @param {'isCreateable'|'isUpdateable'|'retrieving'|'template'} definitionProperty delete field if definitionProperty equals false for specified field. Options: [isCreateable | isUpdateable] * @param {string} origin string of parent object, required when using arrays as these are parsed slightly differently. * @returns {void} */ static deleteFieldByDefinition(metadataEntry, fieldPath, definitionProperty, origin) { // Get content of nested property let fieldContent; try { fieldContent = fieldPath.split('.').reduce((field, key) => field[key], metadataEntry); } catch { // when we hit fields that have dots in their name (e.g. interarction, metaData['simulation.id']) then this will fail // decided to skip these cases for now entirely return; } // revert back placeholder to dots let originHelper; if (origin) { originHelper = this.definition.fields[origin + '.%'] ? origin + '.%' : origin + '.' + fieldPath; } else { originHelper = fieldPath; } if (this.definition.fields[originHelper]?.skipValidation || originHelper === '@_xsi:type') { // skip if current field should not be validated OR if field is internal helper field xsi:type return; } else if ( Array.isArray(fieldContent) && this.definition.fields[originHelper]?.[definitionProperty] === true ) { for (const subObject of fieldContent) { // for simple arrays skip, only process object or array arrays further if (Array.isArray(subObject) || typeof subObject === 'object') { for (const subField in subObject) { this.deleteFieldByDefinition( subObject, subField, definitionProperty, originHelper + '[]' ); } } } } else if ( typeof fieldContent === 'object' && !Array.isArray(fieldContent) && (this.definition.fields[originHelper] == null || this.definition.fields[originHelper][definitionProperty] === true) ) { // Recursive call of this method if there are nested fields for (const subField in fieldContent) { this.deleteFieldByDefinition( fieldContent, subField, definitionProperty, originHelper ); } } else if (!this.definition.fields[originHelper]) { // Display warining if there is no definition for the current field Util.logger.verbose( `MetadataType[${this.definition.type}].deleteFieldByDefinition[${definitionProperty}]:: Field ${originHelper} not in metadata info` ); } else if (this.definition.fields[originHelper][definitionProperty] === false) { // Check if field/nested field should be deleted depending on the definitionProperty fieldPath.split('.').reduce((field, key, index) => { if (index === fieldPath.split('.').length - 1) { delete field[key]; } else { return field[key]; } }, metadataEntry); } } /** * Remove fields from metadata entry that are not createable * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static removeNotCreateableFields(metadataEntry) { for (const field in metadataEntry) { this.deleteFieldByDefinition(metadataEntry, field, 'isCreateable', null); } } /** * Remove fields from metadata entry that are not updateable * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static removeNotUpdateableFields(metadataEntry) { for (const field in metadataEntry) { this.deleteFieldByDefinition(metadataEntry, field, 'isUpdateable', null); } } /** * Remove fields from metadata entry that are not needed in the template * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static keepTemplateFields(metadataEntry) { for (const field in metadataEntry) { this.deleteFieldByDefinition(metadataEntry, field, 'template', null); } } /** * Remove fields from metadata entry that are not needed in the stored metadata * * @param {MetadataTypeItem} metadataEntry metadata entry * @returns {void} */ static keepRetrieveFields(metadataEntry) { for (const field in metadataEntry) { this.deleteFieldByDefinition(metadataEntry, field, 'retrieving', null); } } /** * checks if the current metadata entry should be saved on retrieve or not * * @static * @param {MetadataTypeItem} metadataEntry metadata entry * @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude * @returns {boolean} true: skip saving == filtered; false: continue with saving * @memberof MetadataType */ static isFiltered(metadataEntry, include) { if (include) { // check include-only filters (== discard rest) const includeByDefinition = this._filterOther(this.definition.include, metadataEntry); const includeByConfig = this._filterOther( this.properties.options.include[this.definition.type], metadataEntry ); if (includeByDefinition === false || includeByConfig === false) { Util.logger.debug( `Filtered ${Util.getTypeKeyName(this.definition, metadataEntry)}: not matching include filter` ); return true; } } else { // check exclude-only filters (== keep rest) const excludeByDefinition = this._filterOther(this.definition.filter, metadataEntry); const excludeByConfig = this._filterOther( this.properties.options.exclude[this.definition.type], metadataEntry ); if (excludeByDefinition || excludeByConfig) { Util.logger.debug( `Filtered ${Util.getTypeKeyName(this.definition, metadataEntry)}: matching exclude filter` ); return true; } } // this metadata type has no filters defined or no match was found return false; } /** * optionally filter by what folder something is in * * @static * @param {object} metadataEntry metadata entry * @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude * @returns {boolean} true: filtered == do NOT save; false: not filtered == do save * @memberof MetadataType */ static isFilteredFolder(metadataEntry, include) { if (metadataEntry.json?.r__folder_Path) { // r__folder_Path found in sub-object metadataEntry = metadataEntry.json; } else if (!metadataEntry.r__folder_Path) { // no r__folder_Path found at all return false; } // r__folder_Path found if (include) { const errorMsg = `Filtered ${Util.getTypeKeyName( this.definition, metadataEntry )}: not matching include filter for folder`; // check include-only filters (== discard rest) const includeByDefinition = this._filterFolder( this.definition.include, metadataEntry.r__folder_Path ); if (includeByDefinition === false) { Util.logger.debug(errorMsg + ' (Accenture SFMC DevTools default)'); return true; } const includeByConfig = this._filterFolder( this.properties.options.include[this.definition.type], metadataEntry.r__folder_Path ); if (includeByConfig === false) { Util.logger.debug(errorMsg + ' (project config)'); return true; } } else { const errorMsg = `Filtered ${Util.getTypeKeyName(this.definition, metadataEntry)}: matching exclude filter for folder`; // check exclude-only filters (== keep rest) const excludeByDefinition = this._filterFolder( this.definition.filter, metadataEntry.r__folder_Path ); if (excludeByDefinition) { Util.logger.debug(errorMsg + ' (Accenture SFMC DevTools default)'); return true; } const excludeByConfig = this._filterFolder( this.properties.options.exclude[this.definition.type], metadataEntry.r__folder_Path ); if (excludeByConfig) { Util.logger.debug(errorMsg + ' (project config)'); return true; } } // this metadata type has no filters defined or no match was found return false; } /** * internal helper * * @private * @param {object} myFilter include/exclude filter object * @param {string} r__folder_Path already determined folder path * @returns {?boolean} true: filter value found; false: filter value not found; null: no filter defined */ static _filterFolder(myFilter, r__folder_Path) { if (!myFilter || !myFilter.r__folder_Path) { // no filter defined return null; } // consolidate input: could be String[] or String const filteredValues = Array.isArray(myFilter.r__folder_Path) ? myFilter.r__folder_Path : [myFilter.r__folder_Path]; for (const path of filteredValues) { if (r__folder_Path.startsWith(path)) { // filter matched // this filters the given folder and anything below it. // to only filter subfolders, end with "/", to also filter the given folder, omit the "/" return true; } } // no filters matched return false; } /** * internal helper * * @private * @param {object} myFilter include/exclude filter object * @param {object} metadataEntry metadata entry * @returns {?boolean} true: filter value found; false: filter value not found; null: no filter defined */ static _filterOther(myFilter, metadataEntry) { // not possible to check r__folder_Path before postRetrieveTasks was run; handled in `isFilteredFolder()` if ( !myFilter || !Object.keys(myFilter).filter((item) => item !== 'r__folder_Path').length ) { // no filter defined return null; } for (const key in myFilter) { // consolidate input: could be String[] or String const filteredValues = Array.isArray(myFilter[key]) ? myFilter[key] : [myFilter[key]]; if (filteredValues.includes(metadataEntry[key])) { // filter matched return true; } } // no filters matched return false; } /** * Helper for writing Metadata to disk, used for Retrieve and deploy * * @param {MetadataTypeMap} results metadata results from deploy * @param {string} retrieveDir directory where metadata should be stored after deploy/retrieve * @param {string} [overrideType] for use when there is a subtype (such as folder-queries) * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMap>} Promise of saved metadata */ static async saveResults(results, retrieveDir, overrideType, templateVariables) { const savedResults = {}; let filterCounter = 0; let subtypeExtension; for (const originalKey in results) { if (this.definition.type === 'asset') { overrideType = this.definition.type + '-' + Object.keys(this.definition.extendedSubTypes).find((type) => this.definition.extendedSubTypes[type].includes( results[originalKey].assetType.name ) ); } subtypeExtension = '.' + (overrideType || this.definition.type) + '-meta'; try { if ( this.isFiltered(results[originalKey], true) || this.isFiltered(results[originalKey], false) ) { // if current metadata entry is filtered don't save it filterCounter++; continue; } // define directory into which the current metdata shall be saved const baseDir = [retrieveDir, ...(overrideType || this.definition.type).split('-')]; results[originalKey] = await this.postRetrieveTasks( results[originalKey], retrieveDir, templateVariables ? true : false ); if (!results[originalKey] || results[originalKey] === null) { // we encountered a situation in our postRetrieveTasks that made us want to filter this record delete results[originalKey]; filterCounter++; continue; } if ( this.isFilteredFolder(results[originalKey], true) || this.isFilteredFolder(results[originalKey], false) ) { // if current metadata entry is filtered don't save it filterCounter++; continue; } results[originalKey] = await this.validation( 'retrieve', results[originalKey], retrieveDir ); if (!results[originalKey]) { // we encountered a situation in our validation that made us want to filter this record delete results[originalKey]; filterCounter++; continue; } savedResults[originalKey] = await this.saveToDisk( results, originalKey, baseDir, subtypeExtension, templateVariables ); if (!savedResults[originalKey]) { // happens in case like-filter struck delete savedResults[originalKey]; filterCounter++; continue; } } catch (ex) { Util.logger.debug(JSON.stringify(savedResults[originalKey])); Util.logger.errorStack( ex, ` - Saving ${this.definition.type} ${originalKey} / ${results[originalKey][this.definition.nameField]} failed` ); } } if (filterCounter && this.definition.type !== 'asset') { // interferes with progress bar in assets and is printed 1-by-1 otherwise Util.logger.info( ` - Filtered ${this.definition.type}: ${filterCounter} (downloaded but not saved to disk)` ); } return savedResults; } /** * * @param {MetadataTypeMap} results metadata results from deploy * @param {string} originalKey key of metadata * @param {string[]} baseDir [retrieveDir, ...overrideType.split('-')] * @param {string} [subtypeExtension] e.g. ".asset-meta" or ".query-meta" * @param {TemplateMap} [templateVariables] variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItem>} saved metadata */ static async saveToDisk(results, originalKey, baseDir, subtypeExtension, templateVariables) { subtypeExtension ||= '.' + this.definition.type + '-meta'; // for complex types like asset, script, query we need to save the scripts that were extracted from the JSON if (results[originalKey].json && results[originalKey].codeArr) { // replace market values with template variable placeholders (do not do it on .codeArr) if (templateVariables) { results[originalKey].json = Util.replaceByObject( results[originalKey].json, templateVariables ); results[originalKey].subFolder = Util.replaceByObject( results[originalKey].subFolder, templateVariables ); } const postRetrieveData = results[originalKey]; // normalize results[metadataEntry] results[originalKey] = postRetrieveData.json; if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey], this.definition)) { Util.logger.debug(`Filtered ${originalKey} because of --like option`); return; } if (postRetrieveData.subFolder) { // very complex types have their own subfolder baseDir.push(...postRetrieveData.subFolder); } // save extracted scripts await Promise.all( postRetrieveData.codeArr.map(async (script) => { const dir = [...baseDir]; if (script.subFolder) { // some files shall be saved in yet a deeper subfolder dir.push(...script.subFolder); } return File.writePrettyToFile( dir, script.fileName + subtypeExtension, script.fileExt, script.content, templateVariables ); }) ); } else { // not a complex type, run the the entire JSON through templating // replace market values with template variable placeholders if (templateVariables) { results[originalKey] = Util.replaceByObject( results[originalKey], templateVariables ); } if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey], this.definition)) { Util.logger.debug(`Filtered ${originalKey} because of --like option`); return; } } // we dont store Id on local disk, but we need it for caching logic, // so its in retrieve but not in save. Here we put into the clone so that the original // object used for caching doesnt have the Id removed. const saveClone = structuredClone(results[originalKey]); if (!this.definition.keepId && this.definition.idField !== this.definition.keyField) { delete saveClone[this.definition.idField]; } if (templateVariables) { this.keepTemplateFields(saveClone); } else { this.keepRetrieveFields(saveClone); } await File.writeJSONToFile( // manage subtypes baseDir, originalKey + subtypeExtension, saveClone ); if (templateVariables) { Util.logger.info( `- templated ${this.definition.type}: ${saveClone[this.definition.nameField]}` ); } return saveClone; } /** * helper for {@link MetadataType.buildDefinitionForNested} * searches extracted file for template variable names and applies the market values * * @param {string} code code from extracted code * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {string} code with markets applied */ static applyTemplateValues(code, templateVariables) { // replace template variables with their values return Mustache.render(code, templateVariables, {}, ['{{{', '}}}']); } /** * helper for {@link MetadataType.buildTemplateForNested} * searches extracted file for template variable values and applies the market variable names * * @param {string} code code from extracted code * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {string} code with markets applied */ static applyTemplateNames(code, templateVariables) { // replace template variables with their values return Util.replaceByObject(code, templateVariables); } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types (e.g script, asset, query) * * @param {string} templateDir Directory where metadata templates are stored * @param {string | string[]} targetDir Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} variables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async buildDefinitionForNested( templateDir, targetDir, metadata, variables, templateName ) { // generic version here does nothing. actual cases handled in type classes return null; } /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { // generic version here does nothing. actual cases handled in type classes return null; } /** * check template directory for complex types that open subfolders for their subtypes * * @param {string} templateDir Directory where metadata templates are stored * @param {string} templateName name of the metadata file * @returns {Promise.<string>} subtype name */ static async findSubType(templateDir, templateName) { return null; } /** * optional method used for some types to try a different folder structure * * @param {string} templateDir Directory where metadata templates are stored * @param {string[]} typeDirArr current subdir for this type * @param {string} templateName name of the metadata template * @param {string} fileName name of the metadata template file w/o extension * @param {Error} ex error from first attempt * @returns {Promise.<string>} metadata in string form */ static async readSecondaryFolder(templateDir, typeDirArr, templateName, fileName, ex) { // we just want to push the method into the catch here return; } /** * Builds definition based on template * NOTE: Most metadata files should use this generic method, unless custom * parsing is required (for example scripts & queries) * * @param {string} templateDir Directory where metadata templates are stored * @param {string | string[]} targetDir (List of) Directory where built definitions will be saved * @param {string} templateName name of the metadata file * @param {TemplateMap} variables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeMapObj>} Promise of item map */ static async buildDefinition(templateDir, targetDir, templateName, variables) { // retrieve metadata template let metadataStr; let typeDirArr = [this.definition.type]; const subType = await this.findSubType(templateDir, templateName); if (subType) { typeDirArr.push(subType); } const suffix = subType ? `-${subType}-meta` : '-meta'; const fileName = templateName + '.' + this.definition.type + suffix; try { // ! do not load via readJSONFile to ensure we get a string, not parsed JSON // templated files might contain illegal json before the conversion back to the file that shall be saved metadataStr = await File.readFilteredFilename( [templateDir, ...typeDirArr], fileName, 'json' ); if (!metadataStr) { throw new Error('File not found'); } } catch (ex) { try { metadataStr = await this.readSecondaryFolder( templateDir, typeDirArr, templateName, fileName, ex ); } catch { // only happening for types that use readSecondaryFolder (e.g. asset) // if we still have no metadataStr then we have to skip this metadata for all types and hence handle it outside of this catch } if (!metadataStr) { Util.logger.warn( Util.getGrayMsg( ` ☇ skipped ${this.definition.type} ${templateName}: template not found` ) ); return; } } let metadata; try { // update all initial variables & create metadata object metadata = JSON.parse(this.applyTemplateValues(metadataStr, variables)); typeDirArr = typeDirArr .map((el) => (el === templateName ? metadata[this.definition.keyField] : el)) .map((el) => this.applyTemplateValues(el, variables)); } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ templateName + '.' + this.definition.type }${suffix}.json. Please check if your replacement values will result in valid json.` ); } // run validations before buildDefinitionForNested because that method writes extracted code to disk metadata = await this.validation( 'buildDefinition', metadata, Array.isArray(targetDir) ? targetDir[0] : targetDir ); if (!metadata) { // we encountered a situation in our validation that made us want to filter this record return; } // handle extracted code // run after metadata was templated and converted into JS-object // templating to extracted content is applied inside of buildDefinitionForNested() await this.buildDefinitionForNested( templateDir, targetDir, metadata, variables, templateName ); try { // write to file const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; for (const targetDir of targetDirArr) { await File.writeJSONToFile( [targetDir, ...typeDirArr], metadata[this.definition.keyField] + '.' + this.definition.type + suffix, metadata ); } Util.logger.info( ` - prepared deployment definition of ${Util.getTypeKeyName( this.definition, metadata )}` ); if ( metadata.r__folder_Path && (metadata.r__folder_Path.startsWith('Shared Content/') || metadata.r__folder_Path.startsWith('Shared Items/')) ) { Util.logger.warn( Util.getMsgPrefix(this.definition, metadata) + ` is in a shared folder: ${metadata.r__folder_Path}` ); } return { metadata: metadata, type: this.definition.type }; } catch (ex) { Util.logger.error( ` ☇ skipped ${Util.getTypeKeyName(this.definition, metadata)}: ${ex.message}` ); } } /** * Standardizes a check for multiple messages * * @param {object} ex response payload from REST API * @returns {string[]} formatted Error Message */ static getErrorsREST(ex) { const errors = []; if (ex?.response?.status >= 400 && ex?.response?.status < 600) { if (ex.response.data.errors) { for (const errMsg of ex.response.data.errors) { errors.push( ...errMsg.message .split('<br />') .map((el) => el.trim()) .filter(Boolean) ); } } else if (ex.response.data.validationErrors) { for (const errMsg of ex.response.data.validationErrors) { errors.push( ...errMsg.message .split('<br />') .map((el) => el.trim()) .filter(Boolean) ); } } else if (ex.response.data.message) { errors.push(ex.response.data.message); } else if (ex.response.data) { errors.push(`Undefined Errors: ${JSON.stringify(ex.response.data)}`); Util.logger.debug(JSON.stringify(ex.response.data)); } else { errors.push(`${ex.response.status} ${ex.response.statusText}`); } Util.logger.debug(JSON.stringify(ex.config)); } return errors; } /** * Gets metadata cache with limited fields and does not store value to disk * * @param {MetadataTypeMap} [metadata] a list of type definitions * @param {boolean} [isDeploy] used to skip non-supported message during deploy * @returns {void} */ static document(metadata, isDeploy) { if (!isDeploy) { Util.logNotSupported(this.definition, 'document'); } } /** * get name & key for provided id * * @param {string} id Identifier of metadata * @returns {Promise.<{key:string, name:string}>} key, name and path of metadata; null if not found */ static async resolveId(id) { Util.logNotSupported(this.definition, 'resolveId'); return; } /** * Delete a metadata item from the specified business unit * * @param {string} customerKey Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(customerKey) { Util.logNotSupported(this.definition, 'delete'); return false; } /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @param {string[]} [additionalExtensions] additional file extensions to delete on top of `${this.definition.type}-meta.json` * @returns {Promise.<void>} - Promise */ static async postDeleteTasks(customerKey, additionalExtensions) { // delete local copy: retrieve/cred/bu/type/...json + whatever additional extensions were passed const extArr = [`${this.definition.type}-meta.json`, ...(additionalExtensions || [])]; for (const ext of extArr) { const jsonFile = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, `${customerKey}.${ext}`, ]); await File.remove(jsonFile); } } /** * Delete a data extension from the specified business unit * * @param {string} key Identifier of metadata * @param {string} [overrideKeyField] optionally change the name of the key field if the api uses a different name * @param {number} [codeNotFound] error code that is responded with if the item was not found * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKeySOAP(key, overrideKeyField, codeNotFound, handleOutside) { const metadata = { [overrideKeyField || this.definition.keyField]: key }; const soapType = this.definition.soapType || this.definition.type; try { await this.client.soap.delete(Util.capitalizeFirstLetter(soapType), metadata, null); if (!handleOutside) { Util.logger.info(` - deleted ${this.definition.type}: ${key}`); } await this.postDeleteTasks(key); return true; } catch (ex) { if (handleOutside) { throw ex; } else if ( codeNotFound && (ex.results?.[0]?.ErrorCode == codeNotFound || ex.json?.Results?.[0]?.ErrorCode == codeNotFound) ) { await this.deleteNotFound(key); } else { const errorMsg = ex?.results?.length ? `${ex.results[0].StatusMessage} (Code ${ex.results[0].ErrorCode})` : ex?.json?.Results?.length ? `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})` : ex.message; Util.logger.error( ` - Deleting ${this.definition.type} '${key}' failed: ${errorMsg}` ); } return false; } } /** * Delete a data extension from the specified business unit * * @param {string} url endpoint * @param {string} key Identifier of metadata * @param {number} [codeNotFound] error code that is responded with if the item was not found * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKeyREST(url, key, codeNotFound, handleOutside) { try { await this.client.rest.delete(url); if (!handleOutside) { Util.logger.info(` - deleted ${this.definition.type}: ${key}`); } await this.postDeleteTasks(key); return true; } catch (ex) { if (handleOutside) { throw ex; } else if ( codeNotFound && (ex.code === codeNotFound || ex.response?.status === codeNotFound) ) { await this.deleteNotFound(key); } else { Util.logger.errorStack(ex, ` - Deleting ${this.definition.type} '${key}' failed`); } return false; } } /** * helper for {@link deleteByKey}, {@link deleteByKeyREST}, {@link deleteByKeySOAP} * * @param {string} key Identifier of metadata */ static async deleteNotFound(key) { Util.logger.error( ` ☇ skipping deletion of ${this.definition.type} ${key}: not found on server` ); await this.postDeleteTasks(key); } /** * Returns metadata of a business unit that is saved locally * * @param {string} readDir root directory of metadata. * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @param {object} [buMetadata] Metadata of BU in local directory * @returns {Promise.<object>} Metadata of BU in local directory */ static async readBUMetadataForType(readDir, listBadKeys, buMetadata) { buMetadata ||= {}; readDir = File.normalizePath([readDir, this.definition.type]); if (await File.pathExists(readDir)) { // check if folder name is a valid metadataType, then check if the user limited to a certain type in the command params buMetadata[this.definition.type] = await this.getJsonFromFS(readDir, listBadKeys); return buMetadata; } else { throw new Error(`Directory '${readDir}' does not exist.`); } } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const typeExtension = '.' + this.definition.type + '-meta.json'; const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.map((key) => File.normalizePath([path, File.filterIllegalFilenames(key) + typeExtension]) ); return fileList; } /** * * @param {string[]} keyArr customerkey of the metadata * @param {TypeKeyCombo} multiTypeKeyList list of all keys that need to be deployed * @param {TypeKeyCombo} notFoundList list of all keys that were not found * @param {boolean} isFirstCall will not gray out the log message for type/keys that you initially selected but only for their dependencies * @returns {Promise.<TypeKeyCombo>} list of all keys that need to be deployed */ static async getDependentFiles( keyArr, multiTypeKeyList = {}, notFoundList = {}, isFirstCall = false ) { if ( !Object.prototype.hasOwnProperty.call(this, 'create') && !Object.prototype.hasOwnProperty.call(this, 'update') ) { Util.logger.info( Util.getGrayMsg( ` ☇ skipping ${this.definition.type} (${keyArr.join(', ')}) as it is currently not supported to deploy it` ) ); return; } // initialize key array for current type unless it already exists multiTypeKeyList[this.definition.type] ||= []; notFoundList[this.definition.type] ||= []; keyArr = keyArr // make sure all keys are strings .map((key) => key + '') .filter( (key) => // make sure we don't retry components that we have already searched without result !notFoundList[this.definition.type].includes(key) && // make sure we don't search for components that we have already found !multiTypeKeyList[this.definition.type].includes(key) && // filter out ampscript code that was used instead of actual keys; relevant e.g. for domainVerifications mentioned in senderProfiles !key.startsWith('%%') && !key.endsWith('%%') ); if (!keyArr.length) { return; } const msg = ` - ${this.definition.type}: ${keyArr.join(', ')}`; Util.logger.info(isFirstCall ? msg : Util.getGrayMsg(msg)); // get paths to jsons const filePaths = (await this.getFilesToCommit(keyArr)) .filter(Boolean) .filter((path) => path.endsWith('.json')); /** @type {TypeKeyCombo} */ const dependentTypeKeyCombo = {}; for (const filePath of filePaths) { let metadataItem; try { metadataItem = await File.readJson(filePath); } catch { Util.logger.debug( `- Could not read ${filePath} while trying to find dependencies. Skipping` ); continue; } // store current key if JSON file was found; because otherwise we could not include it in the package anyways multiTypeKeyList[this.definition.type].push( metadataItem[this.definition.keyField] + '' ); // get dependent keys for this type if (this.definition.dependencyGraph) { for (const depType in this.definition.dependencyGraph) { MetadataTypeInfo[depType].properties = this.properties; MetadataTypeInfo[depType].buObject = this.buObject; const dependentKeyArr = []; for (const fieldReference of this.definition.dependencyGraph[depType]) { // ! this assumes we always have keys in this; will fail for list const foundKeys = this.getNestedValue( metadataItem, fieldReference, depType ); if (foundKeys) { dependentKeyArr.push(...foundKeys); } } if (dependentKeyArr.length) { dependentTypeKeyCombo[depType] ||= []; dependentTypeKeyCombo[depType].push(...dependentKeyArr); } } } this.getDependentFilesExtra(metadataItem, dependentTypeKeyCombo); } if (Object.keys(dependentTypeKeyCombo).length) { for (const type in dependentTypeKeyCombo) { // ensure we don't have duplicates dependentTypeKeyCombo[type] = [...new Set(dependentTypeKeyCombo[type])]; // try to read the jsons for those dependant keys await MetadataTypeInfo[type].getDependentFiles( dependentTypeKeyCombo[type], multiTypeKeyList, notFoundList ); } } else { Util.logger.verbose( ` - ${this.definition.type} ${keyArr.join(', ')}: No new dependencies found` ); } const notFound = keyArr.filter( (key) => !multiTypeKeyList[this.definition.type].includes(key) ); if (notFound && notFound.length) { const remainingNotFound = await this.handleNotFoundDependencies(notFound); if (remainingNotFound.length) { Util.logger.warn( Util.getGrayMsg( ` ☇ skipping ${this.definition.type} dependenc${remainingNotFound.length === 1 ? 'y' : 'ies'} ${remainingNotFound.join(', ')}: Not found on your in your project folder.` ) ); // make sure we don't search for it twice notFoundList[this.definition.type] ||= []; notFoundList[this.definition.type].push(...remainingNotFound); } } return multiTypeKeyList; } /** * optional helper for {@link this.getDependentTypes} * * @param {object} metadataItem metadata json read from filesystem * @param {TypeKeyCombo} dependentTypeKeyCombo list started in this.getDependentTypes */ static getDependentFilesExtra(metadataItem, dependentTypeKeyCombo) {} /** * Hook called when dependency keys were not found in the primary retrieve folder. * Override in subtypes to show type-specific warnings (e.g. shared/synchronized dataExtensions). * Keys returned by this method still receive the generic "not found" warning. * Used by {@link MetadataType.getDependentFiles}. * * @param {string[]} notFound keys that could not be found in the retrieve folder * @returns {Promise.<string[]>} keys that should still trigger the default "not found" warning */ static async handleNotFoundDependencies(notFound) { return notFound; } /** * helper for {@link MetadataType.getDependentFiles} * * @param {MetadataTypeItem} obj the metadataItem to search in * @param {string} nestedKey e.g "my.field.here" * @param {string} dependentType used for types that need custom handling * @returns {(string)[]} result array or null if nothing was found */ static getNestedValue(obj, nestedKey, dependentType) { const nestedKeyParts = nestedKey.split('.'); const result = this.getNestedValueHelper(obj, nestedKeyParts, dependentType); // remove duplicates and null values const resultArr = (Array.isArray(result) ? [...new Set(result)] : [result]).filter(Boolean); // return array if entries were found or null otherwise return resultArr.length ? resultArr : null; } /** * helper for {@link MetadataType.getNestedValue} * * @param {any} obj the metadataItem to search in (or the result) * @param {string[]} nestedKeyParts key in dot-notation split into parts * @param {string} dependentType used for types that need custom handling * @returns {(string) | (string)[]} result */ static getNestedValueHelper(obj, nestedKeyParts, dependentType) { if (nestedKeyParts.length == 0) { // key was found; append '' to ensure we always return a string return obj + ''; } // get most left key const key = nestedKeyParts.shift(); if (!obj[key]) { // key was not found return; } return Array.isArray(obj[key]) ? obj[key].flatMap((x) => this.getNestedValueHelper(x, [...nestedKeyParts], dependentType) ) : this.getNestedValueHelper(obj[key], [...nestedKeyParts], dependentType); } /** * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @returns {string[]} list of keys */ static getKeysForFixing(metadataMap) { const keysForDeploy = []; if (!metadataMap) { // 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 return keysForDeploy; } if (Object.keys(metadataMap).length) { Util.logger.info( `Searching for ${this.definition.type} keys among downloaded items that need fixing:` ); Util.OPTIONS.keySuffix = Util.OPTIONS.keySuffix ? Util.OPTIONS.keySuffix.trim() : ''; const maxKeyLength = this.definition.maxKeyLength || 36; for (const item of Object.values(metadataMap)) { if (this.isFiltered(item, true) || this.isFiltered(item, false)) { // we would not have saved these items to disk but they exist in the cache and hence need to be skipped here continue; } if ( (item[this.definition.nameField].endsWith(Util.OPTIONS.keySuffix) && item[this.definition.nameField].length > maxKeyLength) || (!item[this.definition.nameField].endsWith(Util.OPTIONS.keySuffix) && item[this.definition.nameField].length + Util.OPTIONS.keySuffix.length > maxKeyLength) ) { Util.logger.warn( `Name of the item ${Util.getKeyName( this.definition, item )} is too long for a key${Util.OPTIONS.keySuffix.length ? ' (including the suffix ' + Util.OPTIONS.keySuffix + ')' : ''}. Consider renaming your item. Key will be equal first ${maxKeyLength} characters of the name` ); } const newKey = this.getNewKey(this.definition.nameField, item, maxKeyLength); if (newKey != item[this.definition.keyField] && !this.definition.keyIsFixed) { // add key but make sure to turn it into string or else numeric keys will be filtered later keysForDeploy.push(item[this.definition.keyField] + ''); Util.logger.info( ` - added ${this.definition.type} to fixKey queue: ${Util.getKeyName( this.definition, item )} >> ${newKey}` ); } else { Util.logger.info( Util.getGrayMsg( ` ☇ skipping ${Util.getTypeKeyName( this.definition, item )}: key does not need to be updated` ) ); } } Util.logger.info(`Found ${keysForDeploy.length} ${this.definition.type} keys to fix`); } return keysForDeploy; } /** * helper for getKeysForFixing and createOrUpdate * * @param {string} baseField name of the field to start the new key with * @param {MetadataTypeItem} metadataItem - * @param {number} maxKeyLength - * @returns {string} newKey */ static getNewKey(baseField, metadataItem, maxKeyLength) { const keySuffix = Util.OPTIONS.keySuffix; let newKey; newKey = (metadataItem[baseField] + '').trim().slice(0, maxKeyLength).trim(); if (keySuffix.length && !newKey.endsWith(keySuffix)) { newKey = (metadataItem[baseField] + '') .trim() .slice(0, maxKeyLength - keySuffix.length) .trim() + keySuffix; } return newKey; } /** * @typedef {'off'|'warn'|'error'} ValidationLevel */ /** * @typedef {object} ValidationRules * @property {ValidationLevel} [noGuidKeys] flags metadata that did not get a proper key * @property {ValidationLevel} [noRootFolder] flags metadata that did not get a proper key * @property {{type:string[], options: ValidationRules}[]} [overrides] flags metadata that did not get a proper key */ /** * Gets executed before deploying metadata * * @param {'retrieve'|'buildDefinition'|'deploy'} method used to select the right config * @param {MetadataTypeItem | CodeExtractItem} originalItem a single metadata item * @param {string} targetDir folder where files for deployment are stored * @returns {Promise.<MetadataTypeItem | CodeExtractItem>} Promise of a single metadata item */ static async validation(method, originalItem, targetDir) { if (!this.properties.options?.validation?.[method]) { return originalItem; } // if the fix parameter was set, allow validation rules to override the metadata /** @type {MetadataTypeItem | CodeExtractItem} */ let item = Util.OPTIONS.fix ? originalItem : structuredClone(originalItem); /** @type {MetadataTypeItem} */ const metadataItem = item.json && item.codeArr ? item.json : item; const codeArr = item.codeArr || null; /** @type {ValidationRules} */ const validationConfig = structuredClone(this.properties.options?.validation?.[method]); // check if the config contains overrides for the current type const overrides = Array.isArray(validationConfig.overrides) ? validationConfig.overrides : [validationConfig.overrides]; if (validationConfig.overrides) { delete validationConfig.overrides; for (const override of overrides) { if ( override.type?.includes(this.definition.type) && override.options && Object.keys(override.options) ) { Object.assign(validationConfig, override.options); } } } // get default and custom validation rules const definition = this.definition; const validationRules = await validationsRules( this.definition, metadataItem, targetDir, codeArr ); // run validation rules const info = []; const warnings = []; let fixed = false; for (const rule of Object.keys(validationRules)) { if ( validationConfig[rule] && validationConfig[rule] !== 'off' && !this.definition.skipValidation?.[rule] ) { const fixable = Object.prototype.hasOwnProperty.call(validationRules[rule], 'fix'); if (!fixable && validationConfig[rule] === 'fix') { // reduce from fix to error if not fixable validationConfig[rule] = 'error'; } const mode = Util.OPTIONS.fix && fixable ? 'fix' : validationConfig[rule]; let passed; try { passed = await (!Util.OPTIONS.skipValidation && mode === 'fix' ? validationRules[rule].fix() : validationRules[rule].passed()); } catch (ex) { Util.logger.errorStack( ex, `Error while running validation rule ${rule} (check log file for details!)` ); continue; } if (mode === 'fix') { // potentially fixed really fixed = true; } if (!passed) { if (!Util.OPTIONS.skipValidation && mode === 'fix') { if (passed === false) { info.push('😎 auto-fixed: ' + validationRules[rule].failedMsg); } else if (passed === null) { // ensure this item no longer exists outside of the validation rule item = null; warnings.length = 0; info.length = 0; info.push( `🚫 ☇ filtered item via validation rule fix: ` + validationRules[rule].failedMsg ); break; } } else if ( !Util.OPTIONS.skipValidation && validationConfig[rule] === 'error' && passed === false ) { throw new Error(validationRules[rule].failedMsg); } else if ( (Util.OPTIONS.skipValidation || validationConfig[rule] === 'warn') && passed === false ) { warnings.push(validationRules[rule].failedMsg); } } } } if (info.length) { Util.logger.info( Util.getMsgPrefix(this.definition, metadataItem) + `:${info.length > 1 ? '\n ·' : ''} ${info.join('\n · ')}` ); } if (warnings.length) { Util.logger.warn( Util.getMsgPrefix(this.definition, metadataItem) + `:${warnings.length > 1 ? '\n ·' : ''} ${warnings.join('\n · ')}` ); } // only return "fixed" item if --fix is set, otherwise return the original item return !Util.OPTIONS.skipValidation && (Util.OPTIONS.fix || fixed) ? item : originalItem; } } MetadataType.definition = { bodyIteratorField: '', dependencies: [], fields: null, hasExtended: null, idField: '', keyField: '', nameField: '', type: '', }; /** * @type {SDK} */ MetadataType.client = undefined; /** * @type {Mcdevrc} */ MetadataType.properties = null; /** * @type {string} */ MetadataType.subType = null; /** * @type {BuObject} */ MetadataType.buObject = null; export default MetadataType; ================================================ FILE: lib/metadataTypes/MobileCode.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MobileCode MetadataType * * @augments MetadataType */ class MobileCode extends MetadataType { /** * Retrieves Metadata of Mobile Keywords * Endpoint /legacy/v1/beta/mobile/code/ return all Mobile Codes with all details. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { return super.retrieveREST( retrieveDir, '/legacy/v1/beta/mobile/code/' + (key ? `?$where=keyword%20eq%20%27${key}%27%20` : ''), null, key ); } /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache() { return super.retrieveREST(null, '/legacy/v1/beta/mobile/code/'); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; MobileCode.definition = MetadataTypeDefinitions.mobileCode; export default MobileCode; ================================================ FILE: lib/metadataTypes/MobileKeyword.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MobileKeyword MetadataType * * @augments MetadataType */ class MobileKeyword extends MetadataType { /** * Retrieves Metadata of Mobile Keywords * Endpoint /legacy/v1/beta/mobile/keyword/ return all Mobile Keywords with all details. * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { try { let queryParams; [key, queryParams] = this.#getRetrieveKeyAndUrl(key); return super.retrieveREST( retrieveDir, '/legacy/v1/beta/mobile/keyword/' + queryParams, null, key ); } catch (ex) { // if the mobileMessage does not exist, the API returns the error "Request failed with status code 400 (ERR_BAD_REQUEST)" which would otherwise bring execution to a hold if (key && ex.code === 'ERR_BAD_REQUEST') { Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString(key)}` ); this.postDeleteTasks(key); } else { throw ex; } } return; } /** * helper for {@link parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword * * @param {MetadataTypeItem} metadata single item */ static createCustomKeyField(metadata) { metadata.c__codeKeyword = metadata.code.code + '.' + metadata.keyword; } /** * helper for {@link MobileKeyword.preDeployTasks} and {@link MobileKeyword.createOrUpdate} to ensure we have code & keyword properly set * * @param {MetadataTypeItem} metadata single item */ static #setCodeAndKeyword(metadata) { const [code, keyword] = metadata.c__codeKeyword.split('.'); if (!code || !metadata.r__mobileCode_key || code !== metadata.r__mobileCode_key) { throw new Error( `r__mobileCode_key (${metadata.r__mobileCode_key}) does not match code (${code}) in c__codeKeyword (${metadata.c__codeKeyword}).` ); } // mobileCode metadata.code = { id: cache.searchForField('mobileCode', code, 'code', 'id'), }; // keyword metadata.keyword = keyword; } /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadataMap list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {MetadataTypeItemDiff[]} metadataToUpdate list of items to update * @param {MetadataTypeItem[]} metadataToCreate list of items to create * @returns {Promise.<'create'|'update'|'skip'>} action to take */ static async createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ) { const createOrUpdateAction = await super.createOrUpdate( metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate ); if (createOrUpdateAction === 'update') { // in case --changeKeyField or --changeKeyValue was used, let's ensure we set code & keyword here again this.#setCodeAndKeyword(metadataMap[metadataKey]); } return createOrUpdateAction; } /** * Retrieves event definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(_, __, key) { return this.retrieve(null, null, null, key); } /** * retrieve an item and create a template from it * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} key name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<MetadataTypeItemObj>} Promise of metadata */ static async retrieveAsTemplate(templateDir, key, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); try { let queryParams; [key, queryParams] = this.#getRetrieveKeyAndUrl(key); return super.retrieveTemplateREST( templateDir, `/legacy/v1/beta/mobile/keyword/` + queryParams, templateVariables, key ); } catch (ex) { // if the mobileMessage does not exist, the API returns the error "Request failed with status code 400 (ERR_BAD_REQUEST)" which would otherwise bring execution to a hold if (key && ex.code === 'ERR_BAD_REQUEST') { Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString(key)}` ); } else { throw ex; } } } /** * helper for {@link MobileKeyword.retrieve} and {@link MobileKeyword.retrieveAsTemplate} * * @param {string} key customer key of single item to retrieve / name of the metadata file * @returns {Array} key, queryParams */ static #getRetrieveKeyAndUrl(key) { let queryParams; if (key) { if (key.startsWith('id:')) { // overwrite queryParams queryParams = key.slice(3); } else if (key.includes('.')) { // keywords are always uppercased key = key.toUpperCase(); // format: code.keyword const [code, keyword] = key.split('.'); queryParams = `?view=simple&$where=keyword%20eq%20%27${keyword}%27%20and%code%20eq%20%27${code}%27%20`; } else { throw new Error( `key ${key} has unexpected format. Expected 'code.keyword' or 'id:yourId'` ); } } else { queryParams = '?view=simple'; } return [key, queryParams]; } /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata) { return super.createREST(metadata, '/legacy/v1/beta/mobile/keyword/'); } /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata) { return super.updateREST( metadata, '/legacy/v1/beta/mobile/keyword/' + metadata[this.definition.idField], 'post' // upsert API, post for insert and update! ); } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {CodeExtractItem | MetadataTypeItem | void} Array with one metadata object and one ssjs string; or single metadata object; nothing if filtered */ static postRetrieveTasks(metadata) { try { metadata.r__mobileCode_key = cache.searchForField( 'mobileCode', metadata.code.code, 'code', 'code' ); } catch { // in case the the mobileCode cannot be found, do not save this keyword as its no longer accessible in the UI either Util.logger.debug( ` - skipping ${this.definition.type} ${ metadata[this.definition.keyField] }. Could not find parent mobileCode ${metadata.code.code}` ); return; } if (metadata.responseMessage) { // extract message body const codeArr = []; // keep between tags const { fileExt, code } = this.prepExtractedCode(metadata.responseMessage); delete metadata.responseMessage; codeArr.push({ subFolder: null, fileName: metadata[this.definition.keyField], fileExt: fileExt, content: code, }); return { json: metadata, codeArr: codeArr, subFolder: null }; } else { return metadata; } } /** * helper for {@link MobileKeyword.postRetrieveTasks} and {@link MobileKeyword._buildForNested} * * @param {string} metadataScript the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content */ static prepExtractedCode(metadataScript) { const code = metadataScript; const fileExt = 'amp'; return { fileExt, code }; } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'definition' ); } /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'template' ); } /** * helper for {@link MobileKeyword.buildTemplateForNested} / {@link MobileKeyword.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async _buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, mode ) { // get code from filesystem let code = await this._mergeCode(metadata, templateDir, templateName); if (!code) { return null; } const file = this.prepExtractedCode(code); const fileExt = file.fileExt; code = file.code; // apply templating try { if (mode === 'definition') { // replace template variables with their values code = this.applyTemplateValues(code, templateVariables); } else if (mode === 'template') { // replace template values with corresponding variable names code = this.applyTemplateNames(code, templateVariables); } } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ templateName + '.' + this.definition.type }-meta.${fileExt}.` ); } // write to file const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; const nestedFilePaths = []; // keep old name if creating templates, otherwise use new name const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName; for (const targetDir of targetDirArr) { File.writeToFile( [targetDir, this.definition.type], fileName + '.' + this.definition.type + '-meta', fileExt, code ); nestedFilePaths.push([ targetDir, this.definition.type, fileName + '.' + this.definition.type + '-meta.' + fileExt, ]); } return nestedFilePaths; } /** * prepares an event definition for deployment * * @param {MetadataTypeItem} metadata a single MobileKeyword * @param {string} deployDir directory of deploy files * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata, deployDir) { // code metadata.responseMessage = await this._mergeCode(metadata, deployDir); if (metadata.responseMessage && metadata.keywordType === 'NORMAL') { throw new Error( `Custom Response Text is not supported for keywords of type 'NORMAL'. Please remove the .amp file or change the keywordType to 'STOP' or 'INFO'.` ); } if (!metadata.companyName && metadata.keywordType !== 'NORMAL') { metadata.companyName = 'IGNORED'; Util.logger.debug( ` - No companyName found for keyword ${ metadata[this.definition.keyField] }. Setting to IGNORED.` ); } this.#setCodeAndKeyword(metadata); return metadata; } /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse */ static async postCreateTasks(metadataEntry, apiResponse) { await super.postDeployTasks_legacyApi(metadataEntry, apiResponse); return apiResponse; } /** * helper for {@link MetadataType.updateREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static async postUpdateTasks(metadataEntry, apiResponse) { await super.postDeployTasks_legacyApi(metadataEntry, apiResponse); return apiResponse; } /** * helper for {@link MobileKeyword.preDeployTasks} that loads extracted code content back into JSON * * @param {MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} content for metadata.script */ static async _mergeCode(metadata, deployDir, templateName) { templateName ||= metadata[this.definition.keyField]; const codePath = File.normalizePath([ deployDir, this.definition.type, templateName + '.' + this.definition.type + '-meta', ]); if (await File.pathExists(codePath + '.amp')) { return await File.readFilteredFilename( [deployDir, this.definition.type], templateName + '.' + this.definition.type + '-meta', 'amp' ); } else { // keeep this as a debug message, as it is optional and hence not an error Util.logger.debug(`Could not find ${codePath}.amp`); return null; } } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(key) { // get id from cache const { metadata } = await this.retrieveForCache(undefined, undefined, key); if (!metadata[key]) { await this.deleteNotFound(key); return false; } const id = metadata[key][this.definition.idField]; // execute delete Util.logger.info( ' - Note: As long as the provided API key once existed, you will not see an error even if the mobileKeyword is already deleted.' ); return super.deleteByKeyREST('/legacy/v1/beta/mobile/keyword/' + id, key); } /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static async postDeleteTasks(customerKey) { // delete local copy: retrieve/cred/bu/type/...-meta.json // delete local copy: retrieve/cred/bu/type/...-meta.amp super.postDeleteTasks(customerKey, [`${this.definition.type}-meta.amp`]); } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-meta.amp`]), ]); return fileList; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; MobileKeyword.definition = MetadataTypeDefinitions.mobileKeyword; export default MobileKeyword; ================================================ FILE: lib/metadataTypes/MobileMessage.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MobileMessage MetadataType * * @augments MetadataType */ class MobileMessage extends MetadataType { /** * Retrieves Metadata of Mobile Keywords * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { if (key && key.startsWith('id:')) { // if key starts with id: remove it to be compatible with other legacy API types (MetadataType.postCreateTasks_legacyApi) key = key.slice(3); } try { return super.retrieveREST( retrieveDir, '/legacy/v1/beta/mobile/message/' + (key || '?view=details&version=3&$sort=lastUpdated%20DESC&$where=isTest%20eq%200%20and%20status%20neq%20%27Archive%27'), null, key ); } catch (ex) { // if the mobileMessage does not exist, the API returns the error "Request failed with status code 400 (ERR_BAD_REQUEST)" which would otherwise bring execution to a hold if (key && ex.code === 'ERR_BAD_REQUEST') { Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString(key)}` ); this.postDeleteTasks(key); } else { throw ex; } } return; } /** * Retrieves event definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(_, __, key) { return this.retrieve(null, null, null, key); } /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata) { return super.updateREST( metadata, '/legacy/v1/beta/mobile/message/' + metadata[this.definition.idField], 'post' // upsert API, post for insert and update! ); } /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata) { return super.createREST(metadata, '/legacy/v1/beta/mobile/message/'); } /** * helper for {@link MobileMessage.preDeployTasks} that loads extracted code content back into JSON * * @param {MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} code */ static async _mergeCode(metadata, deployDir, templateName) { const fileExtension = 'amp'; templateName ||= metadata[this.definition.keyField]; const codePath = File.normalizePath([ deployDir, this.definition.type, templateName + '.' + this.definition.type + '-meta', ]); if (await File.pathExists(codePath + '.' + fileExtension)) { return await File.readFilteredFilename( [deployDir, this.definition.type], templateName + '.' + this.definition.type + '-meta', fileExtension ); } else { throw new Error(`Could not find ${codePath}.${fileExtension}`); } } /** * helper for {@link MobileMessage.postRetrieveTasks} and {@link MobileMessage._buildForNested} * * @param {string} code the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content */ static prepExtractedCode(code) { const fileExt = 'amp'; return { fileExt, code }; } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-meta.amp`]), ]); return fileList; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single query * @returns {CodeExtractItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata) { // mobileCode try { metadata.r__mobileCode_key = cache.searchForField( 'mobileCode', metadata.code.code, 'code', 'code' ); delete metadata.code; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } // mobileKeyword try { for (const attr of ['keyword', 'subscriptionKeyword', 'nextKeyword']) { if (metadata[attr]?.id) { metadata[attr] = { r__mobileKeyword_key: cache.searchForField( 'mobileKeyword', metadata[attr].id, 'id', 'c__codeKeyword' ), }; } } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } // campaign try { if (Array.isArray(metadata.campaigns)) { metadata.r__campaign_key = []; for (const campaign of metadata.campaigns) { try { // test if exists const test = cache.getByKey('campaign', campaign.name); if (!test) { throw new Error(`campaign ${campaign.name} not found in cache`); } metadata.r__campaign_key.push(campaign.name); } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]}: ${ ex.message }` ); } } delete metadata.campaigns; } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } if (metadata.smsTriggeredSendDefinitionId !== '00000000-0000-0000-0000-000000000000') { // TODO unknown type } if (metadata.triggeredSendName) { // TODO unknown type } if (metadata.messageObjectId) { // TODO unknown type } if (metadata.template?.id) { // TODO unknown type } // extract text/code const codeArr = []; // keep between tags const { fileExt, code } = this.prepExtractedCode(metadata.text); delete metadata.text; codeArr.push({ subFolder: null, fileName: metadata[this.definition.keyField], fileExt: fileExt, content: code, }); return { json: metadata, codeArr: codeArr, subFolder: null }; } /** * prepares an event definition for deployment * * @param {MetadataTypeItem} metadata a single MobileMessage * @param {string} deployDir directory of deploy files * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata, deployDir) { // mobileCode if (metadata.r__mobileCode_key) { metadata.code ||= {}; const code = cache.getByKey('mobileCode', metadata.r__mobileCode_key); if (!code) { throw new Error(`mobileCode ${metadata.r__mobileCode_key} not found in cache`); } metadata.code = code; delete metadata.r__mobileCode_key; } // mobileKeyword for (const attr of ['keyword', 'subscriptionKeyword', 'nextKeyword']) { if (metadata[attr]?.r__mobileKeyword_key) { const keywordObj = cache.getByKey( 'mobileKeyword', metadata[attr].r__mobileKeyword_key ); if (!keywordObj) { throw new Error( `mobileKeyword ${metadata[attr].r__mobileKeyword_key} not found in cache` ); } metadata[attr] = keywordObj; } } // campaign if (Array.isArray(metadata.r__campaign_key)) { metadata.campaigns = []; for (const campaignName of metadata.r__campaign_key) { const campaign = cache.getByKey('campaign', campaignName); if (!campaign) { throw new Error(`campaign ${campaignName} not found in cache`); } metadata.campaigns.push({ id: campaign.id, name: campaignName, display: { name: 'color', value: campaign.color, }, }); } delete metadata.r__campaign_key; } if (metadata.smsTriggeredSendDefinitionId !== '00000000-0000-0000-0000-000000000000') { // TODO unknown type } // code metadata.text = await this._mergeCode(metadata, deployDir); return metadata; } /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse */ static async postCreateTasks(metadataEntry, apiResponse) { await super.postDeployTasks_legacyApi(metadataEntry, apiResponse); return apiResponse; } /** * helper for {@link MetadataType.updateREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static async postUpdateTasks(metadataEntry, apiResponse) { await super.postDeployTasks_legacyApi(metadataEntry, apiResponse); return apiResponse; } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'definition' ); } /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'template' ); } /** * helper for {@link MobileMessage.buildTemplateForNested} / {@link MobileMessage.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async _buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, mode ) { // get code from filesystem let code = await this._mergeCode(metadata, templateDir, templateName); // try to remove script tags and decide on file extension (html/ssjs) const file = this.prepExtractedCode(code); const fileExt = file.fileExt; code = file.code; // apply templating try { if (mode === 'definition') { // replace template variables with their values code = this.applyTemplateValues(code, templateVariables); } else if (mode === 'template') { // replace template values with corresponding variable names code = this.applyTemplateNames(code, templateVariables); } } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ templateName + '.' + this.definition.type }-meta.amp.` ); } // write to file const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; const nestedFilePaths = []; // keep old name if creating templates, otherwise use new name const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName; for (const targetDir of targetDirArr) { File.writeToFile( [targetDir, this.definition.type], fileName + '.' + this.definition.type + '-meta', fileExt, code ); nestedFilePaths.push([ targetDir, this.definition.type, fileName + '.' + this.definition.type + '-meta.' + fileExt, ]); } return nestedFilePaths; } /** * Delete a metadata item from the specified business unit * ! the endpoint expects the ID and not a key but for mcdev in this case key==id * * @param {string} id Identifier of item * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(id) { Util.logger.info( Util.getGrayMsg( ' - Note: As long as the provided API key once existed, you will not see an error even if the mobileMessage is already deleted.' ) ); return super.deleteByKeyREST('/legacy/v1/beta/mobile/message/' + id, id, 400); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; MobileMessage.definition = MetadataTypeDefinitions.mobileMessage; export default MobileMessage; ================================================ FILE: lib/metadataTypes/Query.js ================================================ 'use strict'; import { Util } from '../util/util.js'; import MetadataType from './MetadataType.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * @typedef {import('../../types/mcdev.d.js').QueryItem} QueryItem * @typedef {import('../../types/mcdev.d.js').QueryMap} QueryMap */ /** * Query MetadataType * * @augments MetadataType */ class Query extends MetadataType { /** * Retrieves Metadata of queries * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: QueryMap, type: string}>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { await File.initPrettier('sql'); let objectId = null; if (key) { objectId = await this._getObjectIdForSingleRetrieve(key); if (!objectId) { // avoid running the rest request below by returning early Util.logger.info( `Downloaded: ${this.definition.type} (0)${Util.getKeysString(key)}` ); return { metadata: {}, type: this.definition.type }; } } return super.retrieveREST( retrieveDir, '/automation/v1/queries/' + (objectId || ''), null, key ); } /** * a function to start query execution via API * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} Returns list of keys that were executed successfully */ static async execute(keyArr) { const results = []; // works only with objectId let objectId; for (const key of keyArr) { if (key) { objectId = await this._getObjectIdForSingleRetrieve(key); if (!objectId) { Util.logger.info(`Skipping ${key} - did not find an item with such key`); continue; } } results.push( super.executeREST(`/automation/v1/queries/${objectId}/actions/start/`, key) ); } const executedKeyArr = (await Promise.all(results)) .filter((r) => r.response === 'OK') .map((r) => r.key); Util.logger.info(`Executed ${executedKeyArr.length} of ${keyArr.length} items`); return executedKeyArr; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static async _getObjectIdForSingleRetrieve(key) { const response = await this.client.soap.retrieve('QueryDefinition', ['ObjectID'], { filter: { leftOperand: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, operator: 'AND', rightOperand: { leftOperand: 'Status', operator: 'equals', rightOperand: 'Active', }, }, }); return response?.Results?.length ? response.Results[0].ObjectID : null; } /** * Retrieves query metadata for caching * * @returns {Promise.<{metadata: QueryMap, type: string}>} Promise of metadata */ static async retrieveForCache() { return super.retrieveREST(null, '/automation/v1/queries/'); } /** * Retrieve a specific Query by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<{metadata: Query, type: string}>} Promise of metadata */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); await File.initPrettier('sql'); return super.retrieveREST( templateDir, '/automation/v1/queries/?$filter=Name%20eq%20' + encodeURIComponent(name), templateVariables ); } /** * manages post retrieve steps * * @param {QueryItem} metadata a single query * @returns {CodeExtractItem} Array with one metadata object and one query string */ static postRetrieveTasks(metadata) { // folder super.setFolderPath(metadata); // extract SQL const codeArr = [ { subFolder: null, fileName: metadata[this.definition.keyField], fileExt: 'sql', content: metadata.queryText, }, ]; delete metadata.queryText; try { if (metadata.targetId) { // overwrite targetKey via targetId (it's not updated on name/key change of the DE) const targetKey = cache.searchForField( 'dataExtension', metadata.targetId, 'ObjectID', 'CustomerKey' ); if (targetKey !== metadata.targetKey) { Util.logger.debug( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Replacing targetKey value in saved JSON '${ metadata.targetKey }' --> '${targetKey}'. Acquired new value from looking up the DE's ObjectID in targetId.` ); } metadata.r__dataExtension_key = targetKey; } else { // if no targetId is set, at least check if the targetKey points to an existing DE (no override needed) metadata.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.targetKey, 'CustomerKey', 'CustomerKey' ); } delete metadata.targetKey; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } delete metadata.targetId; return { json: metadata, codeArr: codeArr, subFolder: null }; } /** * Creates a single query * * @param {QueryItem} query a single query * @returns {Promise} Promise */ static create(query) { const uri = '/automation/v1/queries/'; return super.createREST(query, uri); } /** * Updates a single query * * @param {QueryItem} query a single query * @returns {Promise} Promise */ static update(query) { const uri = '/automation/v1/queries/' + query.queryDefinitionId; return super.updateREST(query, uri); } /** * prepares a Query for deployment * * @param {QueryItem} metadata a single query activity * @param {string} deployDir directory of deploy files * @returns {Promise.<QueryItem>} Promise */ static async preDeployTasks(metadata, deployDir) { // folder super.setFolderId(metadata); // reinject queryText metadata.queryText = await File.readFilteredFilename( deployDir + '/' + this.definition.type, metadata[this.definition.keyField] + '.' + this.definition.type + '-meta', 'sql' ); // dataExtension metadata.targetKey = cache.searchForField( 'dataExtension', metadata.r__dataExtension_key, 'CustomerKey', 'CustomerKey' ); // we've seen queries without this ID set - crucial in case the DE ever gets renamed to ensure the query keeps working metadata.targetId = cache.searchForField( 'dataExtension', metadata.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); // set ID for Append / Overwrite/ Update action metadata.targetUpdateTypeId = this.definition.targetUpdateTypeMapping[metadata.targetUpdateTypeName]; if (!Util.OPTIONS.matchName) { // make sure the name is unique const thisCache = cache.getCache()[this.definition.type]; const relevantNames = Object.keys(thisCache).map((key) => ({ type: null, key: key, name: thisCache[key][this.definition.nameField], })); // if the name is already in the folder for a different key, add a number to the end metadata[this.definition.nameField] = this.findUniqueName( metadata[this.definition.keyField], metadata[this.definition.nameField], relevantNames ); } return metadata; } /** * helper for {@link Query.buildDefinitionForNested} * searches extracted SQL file for template variables and applies the market values * * @param {string} code code from extracted code * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {string} code with markets applied */ static applyTemplateValues(code, templateVariables) { // fix bad formatting applied by SQL Formatter Plus code = code .split(' { { { ') .join('{{{') .split('{ { { ') .join('{{{') .split(' } } } ') .join('}}}') .split(' } } }') .join('}}}'); // replace template variables with their values return super.applyTemplateValues(code, templateVariables); } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {QueryItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'definition' ); } /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example queries are saved as 1 json and 1 sql file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {QueryItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'template' ); } /** * helper for {@link Query.buildTemplateForNested} / {@link Query.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @private * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {QueryItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async _buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, mode ) { // get SQL from filesystem let code = await File.readFilteredFilename( [templateDir, this.definition.type], templateName + '.' + this.definition.type + '-meta', 'sql' ); try { if (mode === 'definition') { code = this.applyTemplateValues(code, templateVariables); } else if (mode === 'template') { code = this.applyTemplateNames(code, templateVariables); } } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ templateName + '.' + this.definition.type }-meta.sql.` ); } // write to file const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; const nestedFilePaths = []; // keep old name if creating templates, otherwise use new name const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName; for (const targetDir of targetDirArr) { File.writeToFile( [targetDir, this.definition.type], fileName + '.' + this.definition.type + '-meta', 'sql', code ); nestedFilePaths.push([ targetDir, this.definition.type, fileName + '.' + this.definition.type + '-meta.sql', ]); } return nestedFilePaths; } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-meta.sql`]), ]); return fileList; } /** * Standardizes a check for multiple messages but adds query specific filters to error texts * * @param {object} ex response payload from REST API * @returns {string[]} formatted Error Message */ static getErrorsREST(ex) { const errors = super.getErrorsREST(ex); if (errors?.length > 0) { return errors.map((msg) => msg.split('Error saving the Query field.').join('')); } return errors; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/automation/v1/queries/' + objectId, key); } /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static async postDeleteTasks(customerKey) { // delete local copy: retrieve/cred/bu/.../...-meta.json // delete local copy: retrieve/cred/bu/.../...-meta.sql await super.postDeleteTasks(customerKey, [`${this.definition.type}-meta.sql`]); } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create */ static async postDeployTasks(upsertResults) { if (Util.OPTIONS.execute) { Util.logger.info(`Executing: ${this.definition.type}`); await this.execute(Object.keys(upsertResults)); } } } // Assign definition & cache to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Query.definition = MetadataTypeDefinitions.query; export default Query; ================================================ FILE: lib/metadataTypes/Role.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').SoapSDKFilterSimple} SoapSDKFilterSimple * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * ImportFile MetadataType * * @augments MetadataType */ class Role extends MetadataType { /** * Gets metadata from Marketing Cloud * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] Returns specified fields even if their retrieve definition is not set to true * @param {void | string[]} [___] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Metadata store object */ static async retrieve(retrieveDir, _, ___, key) { if (retrieveDir && this.buObject.eid !== this.buObject.mid) { // don't run for BUs other than Parent BU // this check does not work during caching Util.logger.info(' - Skipping Role retrieval on non-parent BU'); return; } const fields = super.getFieldNamesToRetrieve(null, !retrieveDir); /** @type {SoapRequestParams} */ let requestParams = { // filter individual roles filter: { leftOperand: 'IsPrivate', operator: 'equals', rightOperand: false, }, }; if (key) { // move original filter down one level into rightOperand and add key filter into leftOperand /** @type {SoapSDKFilterSimple} */ const keyFilter = { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }; requestParams = { filter: { leftOperand: keyFilter, operator: 'AND', rightOperand: requestParams.filter, }, }; } const results = await this.client.soap.retrieve('Role', fields, requestParams); const parsed = this.parseResponseBody(results); if (retrieveDir) { const savedMetadata = await super.saveResults(parsed, retrieveDir, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(key) ); await this.runDocumentOnRetrieve(key, savedMetadata); } await this.cacheDefaultRolesAndTimezones(parsed); return { metadata: parsed, type: this.definition.type }; } /** * adds default roles to the list of retrieved roles for proper caching (but not storing) * also caches available timezones for retrieve-user * * @param {MetadataTypeMap} parsed list or previously retrieved items as reference */ static async cacheDefaultRolesAndTimezones(parsed) { // retrieve "Marketing Cloud%" roles not returned by SOAP API for cache (required by retrieve-user) // also cache available timezones for retrieve-user Util.logger.info(Util.getGrayMsg(' - Caching default roles and timezones')); const { roles, timeZones } = await this.client.rest.get( '/platform/v1/setup/quickflow/data' ); // this endpoint does not provide keys const roleNameKeyMap = { 'Marketing Cloud Administrator': 'SYS_DEF_IMHADMIN', 'Marketing Cloud Channel Manager': 'SYS_DEF_CHANNELMANAGER', 'Marketing Cloud Content Editor/Publisher': 'SYS_DEF_CONTENTEDIT', 'Marketing Cloud Security Administrator': 'SYS_DEF_SECURITYADMIN', 'Marketing Cloud Viewer': 'SYS_DEF_VIEWER', }; for (const role of roles) { if (roleNameKeyMap[role.roleName]) { parsed[roleNameKeyMap[role.roleName]] = { CustomerKey: roleNameKeyMap[role.roleName], Name: role.roleName, ObjectID: role.roleID, Desscription: role.description, CreatedDate: '2012-02-21T02:09:19.983', IsSystemDefined: true, c__notAssignable: true, }; } } // the languages object is incomplete. the actual list is much longer --> ignoring it here // convert timeZones to object const timeZonesObj = {}; for (const timeZone of timeZones) { timeZonesObj[timeZone.id] = timeZone; } // cache timeZones to share it with other type-classes cache.setMetadata('_timezone', timeZonesObj); } /** * Gets executed before deploying metadata * * @param {MetadataTypeItem} metadata a single metadata item * @returns {MetadataTypeItem} Promise of a single metadata item */ static preDeployTasks(metadata) { if (this.definition.deployBlacklist.includes(metadata.CustomerKey)) { throw new Error( `Skipped ${metadata.Name} (${metadata.CustomerKey}) because its CustomerKey is reserved for a default system role.` ); } return metadata; } /** * Create a single Role. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata) { return super.createSOAP(metadata); } /** * Updates a single Role. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static update(metadata) { return super.updateSOAP(metadata); } /** * Creates markdown documentation of all roles * * @param {MetadataTypeMap} [metadata] role definitions * @returns {Promise.<void>} - */ static async document(metadata) { if (this.buObject.eid !== this.buObject.mid) { Util.logger.error( `Roles can only be retrieved & documented for the ${Util.parentBuName}` ); return; } if (!metadata) { try { metadata = ( await this.readBUMetadataForType( File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, Util.parentBuName, ]), true ) ).role; } catch (ex) { Util.logger.error(ex.message); return; } } const directory = File.normalizePath([this.properties.directories.docs, 'role']); // initialize permission object this.allPermissions = {}; // traverse all permissions recursively and write them into allPermissions object once it has reached the end for (const role in metadata) { // filter standard rules if ( this.properties.options?.documentStandardRoles === false && 'string' === typeof metadata[role]?.CustomerKey && // key could be numeric metadata[role].CustomerKey.startsWith('SYS_DEF') ) { delete metadata[role]; } else { for (const element of metadata[role].PermissionSets.PermissionSet) { this._traverseRoles(role, element); } } } // Create output markdown let output = `# Permission Overview - ${this.buObject.credential}\n\n`; output += `> **Legend** > > <hr> > > **[Role Name]** = System Default Role > > **Role Name** = Custom Role > > **+** = _Allow_: User has access to the application or functionality > > ** •** = _Not Set_: User permission for this app or functionality is not explicitely granted nor denied, but defaults to Deny > > **-** = _Deny_: User does not have access to the app or functionality > > <hr>\n\n`; // Loop through all permissions for (const permGroup in this.allPermissions) { output += '## ' + permGroup + '\n\n'; // create table header output += '| Permission |'; let separator = '| --- |'; for (const role in metadata) { output += metadata[role].IsSystemDefined === true ? ` [${metadata[role].Name}] |` : ` ${metadata[role].Name} |`; separator += ' --- |'; } output += '\n' + separator + '\n'; // Write all permissions of a major permission group // output += '| '; for (const permission in this.allPermissions[permGroup]) { output += '| ' + permission + ' |'; for (const role in this.allPermissions[permGroup][permission]) { if (this.allPermissions[permGroup][permission][role] === true) { output += ' + |'; } else if (this.allPermissions[permGroup][permission][role] === false) { output += ' - |'; } else if ( 'undefined' === typeof this.allPermissions[permGroup][permission][role] ) { output += ' • |'; } else { output += ' ' + this.allPermissions[permGroup][permission][role] + ' |'; } } output += '\n'; } output += '\n'; } try { const filename = this.buObject.credential; // write to disk await File.writeToFile(directory, filename + '.roles', 'md', output); Util.logger.info(`Created ${File.normalizePath([directory, filename])}.roles.md`); if (['html', 'both'].includes(this.properties.options.documentType)) { Util.logger.warn(' - HTML-based documentation of roles currently not supported.'); } } catch (ex) { Util.logger.error(`Roles.document():: error | `, ex.message); } } /** * iterates through permissions to output proper row-names for nested permissionss * * @static * @param {string} role name of the user role * @param {object} element data of the permission * @param {string} [permission] name of the permission * @param {string} [isAllowed] "true" / "false" from the parent * @memberof Role * @returns {void} */ static _traverseRoles(role, element, permission, isAllowed) { const _permission = permission ? permission + ' > ' + element.Name : element.Name; // Reached end: write permission into this.allPermissions if (element.Operation) { const permSplit = _permission.split(' > '); const permOperation = permSplit.pop(); let basePermission = permSplit.shift(); if (basePermission === 'Interactive Marketing Hub') { basePermission = 'Salesforce Marketing Cloud'; } const permissionName = `<nobr><b>${permSplit.join( ' > ' )}</b> > ${permOperation}</nobr>`; if (!this.allPermissions[basePermission]) { this.allPermissions[basePermission] = {}; } if (!this.allPermissions[basePermission][permissionName]) { this.allPermissions[basePermission][permissionName] = {}; } this.allPermissions[basePermission][permissionName][role] = element.IsAllowed || isAllowed; // Not at end: Traverse more } else if (element.PermissionSets) { if (Array.isArray(element.PermissionSets.PermissionSet)) { for (const nextElement of element.PermissionSets.PermissionSet) { this._traverseRoles(role, nextElement, _permission); } } else { this._traverseRoles( role, element.PermissionSets.PermissionSet, _permission, element.IsAllowed || isAllowed ); } // Not at end: Traverse more } else if (element.Permissions) { if (Array.isArray(element.Permissions.Permission)) { for (const nextElement of element.Permissions.Permission) { this._traverseRoles( role, nextElement, _permission, element.IsAllowed || isAllowed ); } } else { this._traverseRoles( role, element.Permissions.Permission, _permission, element.IsAllowed || isAllowed ); } } } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Role.definition = MetadataTypeDefinitions.role; export default Role; ================================================ FILE: lib/metadataTypes/Script.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import ReplaceCbReference from '../util/replaceContentBlockReference.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * @typedef {import('../../types/mcdev.d.js').ScriptItem} ScriptItem * @typedef {import('../../types/mcdev.d.js').ScriptMap} ScriptMap */ /** * Script MetadataType * * @augments MetadataType */ class Script extends MetadataType { /** * Retrieves Metadata of Script * Endpoint /automation/v1/scripts/ return all Scripts with all details. * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<{metadata: ScriptMap, type: string}>} Promise */ static async retrieve(retrieveDir, _, __, key) { await File.initPrettier('ssjs'); return super.retrieveREST(retrieveDir, '/automation/v1/scripts/', null, key); } /** * Retrieves script metadata for caching * * @returns {Promise.<{metadata: ScriptMap, type: string}>} Promise */ static async retrieveForCache() { return super.retrieveREST(null, '/automation/v1/scripts/'); } /** * Retrieve a specific Script by Name * * @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version. * @param {string} templateDir Directory where retrieved metadata directory will be saved * @param {string} name name of the metadata file * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @returns {Promise.<{metadata: ScriptItem, type: string}>} Promise */ static async retrieveAsTemplate(templateDir, name, templateVariables) { Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`); await File.initPrettier('ssjs'); return super.retrieveREST( templateDir, '/automation/v1/scripts/?$filter=name%20eq%20' + encodeURIComponent(name), templateVariables ); } /** * Updates a single Script * * @param {MetadataTypeItem} script a single Script * @returns {Promise} Promise */ static update(script) { return super.updateREST(script, '/automation/v1/scripts/' + script.ssjsActivityId); } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse, potentially modified */ static async postUpdateTasks(metadataEntry, apiResponse) { // script update endpoint returns wrong values for createdDate and modifiedDate - need to re-retrieve to get correct values const ssjsActivityId = apiResponse?.ssjsActivityId; if (ssjsActivityId) { apiResponse = await this.client.rest.get('/automation/v1/scripts/' + ssjsActivityId); } return apiResponse; } /** * Creates a single Script * * @param {MetadataTypeItem} script a single Script * @returns {Promise} Promise */ static create(script) { return super.createREST(script, '/automation/v1/scripts/'); } /** * helper for {@link Script.preDeployTasks} that loads extracted code content back into JSON * * @param {ScriptItem} metadata a single asset definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} content for metadata.script */ static async _mergeCode(metadata, deployDir, templateName) { templateName ||= metadata[this.definition.keyField]; let code; const codePath = File.normalizePath([ deployDir, this.definition.type, templateName + '.' + this.definition.type + '-meta', ]); if (await File.pathExists(codePath + '.ssjs')) { code = await File.readFilteredFilename( [deployDir, this.definition.type], templateName + '.' + this.definition.type + '-meta', 'ssjs' ); code = `<script runat="server">\n${code.trim()}\n</script>`; } else if (await File.pathExists(codePath + '.html')) { code = await File.readFilteredFilename( [deployDir, this.definition.type], templateName + '.' + this.definition.type + '-meta', 'html' ); } else { throw new Error(`Could not find ${codePath}.ssjs (or html)`); } return code; } /** * prepares a Script for deployment * * @param {ScriptItem} metadata a single script activity definition * @param {string} dir directory of deploy files * @returns {Promise.<ScriptItem>} Promise */ static async preDeployTasks(metadata, dir) { // folder super.setFolderId(metadata); // code metadata.script = await this._mergeCode(metadata, dir); return metadata; } /** * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {ScriptItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'definition' ); } /** * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {ScriptItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'template' ); } /** * helper for {@link Script.buildTemplateForNested} / {@link Script.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {ScriptItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async _buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, mode ) { // get SSJS from filesystem let code = await this._mergeCode(metadata, templateDir, templateName); // try to remove script tags and decide on file extension (html/ssjs) const file = this.prepExtractedCode(code, metadata.name); const fileExt = file.fileExt; code = fileExt === 'ssjs' ? file.code.replace(/^\n/, '') : file.code; // apply templating try { if (mode === 'definition') { // replace template variables with their values code = this.applyTemplateValues(code, templateVariables); } else if (mode === 'template') { // replace template values with corresponding variable names code = this.applyTemplateNames(code, templateVariables); } } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ templateName + '.' + this.definition.type }-meta.ssjs.` ); } // write to file const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; const nestedFilePaths = []; // keep old name if creating templates, otherwise use new name const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName; for (const targetDir of targetDirArr) { File.writeToFile( [targetDir, this.definition.type], fileName + '.' + this.definition.type + '-meta', fileExt, code ); nestedFilePaths.push([ targetDir, this.definition.type, fileName + '.' + this.definition.type + '-meta.' + fileExt, ]); } return nestedFilePaths; } /** * manages post retrieve steps * * @param {ScriptItem} metadata a single item * @returns {CodeExtractItem} a single item with code parts extracted */ static postRetrieveTasks(metadata) { // folder super.setFolderPath(metadata); return this.getCodeExtractItem(metadata); } /** * manages post retrieve steps * * @param {ScriptItem} metadata a single item * @returns {CodeExtractItem} a single item with code parts extracted */ static getCodeExtractItem(metadata) { // extract SSJS const codeArr = []; // keep between tags const { fileExt, code } = this.prepExtractedCode(metadata.script, metadata.name); delete metadata.script; codeArr.push({ subFolder: null, fileName: metadata[this.definition.keyField], fileExt: fileExt, content: code, }); return { json: metadata, codeArr: codeArr, subFolder: null }; } /** * helper for {@link Script.postRetrieveTasks} and {@link Script._buildForNested} * * @param {string} metadataScript the code of the file * @param {string} metadataName the name of the metadata * @returns {{fileExt:string,code:string}} returns found extension and file content */ static prepExtractedCode(metadataScript, metadataName) { let code; let fileExt; const ssjs = Util.getSsjs(metadataScript); if (ssjs) { code = ssjs; fileExt = 'ssjs'; } else { code = metadataScript; fileExt = 'html'; Util.logger.verbose( ` - Could not find script tags, saving code in ${metadataName}.script-meta.html instead of as SSJS file.` ); } return { fileExt, code }; } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-meta.ssjs`]), File.normalizePath([path, `${key}.${this.definition.type}-meta.html`]), ]); return fileList; } /** * helper to allow us to select single metadata entries via REST * * @private * @param {string} key customer key * @returns {Promise.<string>} objectId or enpty string */ static async _getObjectIdForSingleRetrieve(key) { const name = key.startsWith('name:') ? key.slice(5) : null; const filter = name ? '?$filter=name%20eq%20' + encodeURIComponent(name) : '?$filter=key%20eq%20' + encodeURIComponent(key); const results = await this.client.rest.get('/automation/v1/scripts/' + filter); const items = results?.items || []; const found = items.find((item) => name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key ); return found?.ssjsActivityId || null; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success flag */ static async deleteByKey(key) { // delete only works with the query's object id const objectId = key ? await this._getObjectIdForSingleRetrieve(key) : null; if (!objectId) { await this.deleteNotFound(key); return false; } return super.deleteByKeyREST('/automation/v1/scripts/' + objectId, key); } /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static async postDeleteTasks(customerKey) { // delete local copy: retrieve/cred/bu/.../...-meta.json // delete local copy: retrieve/cred/bu/.../...-meta.ssjs // delete local copy: retrieve/cred/bu/.../...-meta.html await super.postDeleteTasks(customerKey, [ `${this.definition.type}-meta.ssjs`, `${this.definition.type}-meta.html`, ]); } /** * * @param {MetadataTypeItem} item single metadata item * @param {string} retrieveDir directory where metadata is saved * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<CodeExtractItem>} key of the item that was updated */ static async replaceCbReference(item, retrieveDir, findAssetKeys) { const parentName = `${this.definition.type} ${item[this.definition.keyField]}`; const code = await this._mergeCode(item, retrieveDir); item.script = ReplaceCbReference.replaceReference(code, parentName, findAssetKeys); // *** finish *** // replaceReference will throw an error if nothing was updated which will end execution here // no error means we have a new item to deploy and need to update the item in our retrieve folder return this.getCodeExtractItem(item); } } // Assign definition & cache to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Script.definition = MetadataTypeDefinitions.script; export default Script; ================================================ FILE: lib/metadataTypes/SendClassification.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import SenderProfile from './SenderProfile.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * SendClassification MetadataType * * @augments MetadataType */ class SendClassification extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = null; if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * Retrieves event definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieveForCache() { const typeMap = await this.retrieve(null); if (cache.getCache().deliveryProfile) { for (const item of Object.values(typeMap.metadata)) { // run postRetrieveTasks to cross-update deliveryProfile cache this.updateDeliveryProfileIdInCache(item); } } return typeMap; } /** * Updates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static update(metadataItem) { return super.updateSOAP(metadataItem); } /** * Creates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem) { return super.createSOAP(metadataItem); } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(key) { return super.deleteByKeySOAP(key, undefined, 24100); } /** * prepares a import definition for deployment * * @param {MetadataTypeItem} metadata a single importDef * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata) { metadata.SendClassificationType = this.definition.sendClassificationTypeMapping[metadata.c__classification]; delete metadata.c__classification; const spId = cache.searchForField( 'senderProfile', metadata.r__senderProfile_key, 'CustomerKey', 'ObjectID' ); const sp = cache.getByKey('senderProfile', metadata.r__senderProfile_key); SenderProfile.verifySenderEmailAddresses(sp, metadata, this.definition); metadata.SenderProfile = { ObjectID: spId, CustomerKey: metadata.r__senderProfile_key, }; delete metadata.r__senderProfile_key; const dpId = cache.searchForField( 'deliveryProfile', metadata.r__deliveryProfile_key, 'key', 'ObjectID' ); metadata.DeliveryProfile = { ObjectID: dpId, CustomerKey: metadata.r__deliveryProfile_key, }; delete metadata.r__deliveryProfile_key; return metadata; } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static async postDeployTasks(upsertResults) { // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present) Util.logger.debug( `Caching all ${this.definition.type} post-deploy to ensure we have all fields` ); const typeCache = await this.retrieveForCache(); // update values in upsertResults with retrieved values before saving to disk for (const key of Object.keys(upsertResults)) { if (typeCache.metadata[key]) { upsertResults[key] = typeCache.metadata[key]; } } } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} parsed metadata */ static postRetrieveTasks(metadata) { metadata.c__classification = Util.inverseGet( this.definition.sendClassificationTypeMapping, metadata.SendClassificationType ); delete metadata.SendClassificationType; // when sendClassification was only cached it can happen that we don't have the senderProfile cache yet try { metadata.r__senderProfile_key = cache.searchForField( 'senderProfile', metadata.SenderProfile.ObjectID, 'ObjectID', 'CustomerKey' ); delete metadata.SenderProfile; const sp = cache.getByKey('senderProfile', metadata.r__senderProfile_key); SenderProfile.verifySenderEmailAddresses(sp, metadata, this.definition); } catch (ex) { Util.logger.warn(` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}`); } try { metadata.r__deliveryProfile_key = cache.searchForField( 'deliveryProfile', metadata.DeliveryProfile.CustomerKey, 'key', 'key' ); // add ObjectID to deliveryProfile cache because it cannot be retrieved any other way and this way we can resolve it in journeys this.updateDeliveryProfileIdInCache(metadata); delete metadata.DeliveryProfile; } catch (ex) { Util.logger.warn(` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}`); } return metadata; } /** * this is the only known way to get the object ID for a deliveryProfile * * @param {MetadataTypeItem} metadata a single sendClassification item */ static updateDeliveryProfileIdInCache(metadata) { const dp = cache.getByKey('deliveryProfile', metadata.DeliveryProfile.CustomerKey); if (dp) { dp.ObjectID = metadata.DeliveryProfile.ObjectID; } else { Util.logger.debug( ` - ${this.definition.type} ${metadata.CustomerKey}: Could not find deliveryProfile ${metadata.DeliveryProfile.CustomerKey} in cache` ); } } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; SendClassification.definition = MetadataTypeDefinitions.sendClassification; export default SendClassification; ================================================ FILE: lib/metadataTypes/SenderProfile.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import File from '../util/file.js'; import DomainVerification from './DomainVerification.js'; import cache from '../util/cache.js'; import { Util } from '../util/util.js'; import ReplaceCbReference from '../util/replaceContentBlockReference.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * SenderProfile MetadataType * * @augments MetadataType */ class SenderProfile extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams; if (key) { requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * Updates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static update(metadataItem) { return super.updateSOAP(metadataItem); } /** * Creates a single item * * @param {MetadataTypeItem} metadataItem a single item * @returns {Promise} Promise */ static create(metadataItem) { return super.createSOAP(metadataItem); } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(key) { return super.deleteByKeySOAP(key, undefined, 40100); } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} a single item */ static postRetrieveTasks(metadata) { // makes or easier reading if (metadata.Client) { try { metadata.createdBy = cache.searchForField( 'user', metadata.Client.CreatedBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } try { metadata.modifiedBy = cache.searchForField( 'user', metadata.Client.ModifiedBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } delete metadata.Client; } // check if email address is verified. Otherwise this SenderProfile (and Send Classifications using it) will not be usable in Journey Builder this.verifySenderEmailAddresses(metadata); return metadata; } /** * * @param {MetadataTypeItem} metadata a single item * @param {MetadataTypeItem} [metadataCaller] if called from SendClassification this can be used to adjust logs * @param {any} [definition] type defintiion from SendClassification */ static verifySenderEmailAddresses(metadata, metadataCaller, definition) { if (!metadataCaller) { metadataCaller = metadata; } if (!definition) { definition = this.definition; } const emailsToCheck = { FromAddress: metadata.FromAddress.trim() + '', FallbackFromAddress: metadata.FallbackFromAddress.trim() + '', }; for (const [field, email] of Object.entries(emailsToCheck)) { if (email && !email.startsWith('%%') && email.includes('@')) { const domainVerification = cache.getByKey('domainVerification', email); if (domainVerification) { if (domainVerification.status !== 'Verified') { Util.logger.warn( Util.getMsgPrefix(definition, metadataCaller) + `: ${field} ${email} is currently in status ${domainVerification.status}. This ${definition.typeName} will not be usable in Journey Builder. To fix, please go to Setup > Feature Settings > Email Studio > From Address Management to verify the email.` ); } if (domainVerification.isSendable === false) { Util.logger.warn( Util.getMsgPrefix(definition, metadataCaller) + `: ${field} ${email} is currently not sendable. This ${definition.typeName} will not be usable in Journey Builder. To auto-fix run any update on senderProfile:"${metadata[this.definition.keyField]}" via mcdev.` ); } } else { Util.logger.warn( Util.getMsgPrefix(definition, metadataCaller) + `: ${field} ${email} is not verified. This ${definition.typeName} will not be usable in Journey Builder. To auto-fix run any update on senderProfile:"${metadata[this.definition.keyField]}" via mcdev. Alternatively, please go to Setup > Feature Settings > Email Studio > From Address Management.` ); } } } } /** * prepares a single item for deployment * * @param {MetadataTypeItem} metadata a single query activity * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata) { // cleanup delete metadata.createdBy; delete metadata.modifiedBy; if ( metadata.UseDefaultRMMRules && (metadata.AutoForwardToEmailAddress !== '' || metadata.AutoForwardToName !== '') ) { Util.logger.warn( Util.getMsgPrefix(this.definition, metadata) + `AutoForwardToEmailAddress and AutoForwardToName will be ignored because UseDefaultRMMRules is set to true; setting UseDefaultRMMRules to false` ); metadata.UseDefaultRMMRules = false; } if (!Util.OPTIONS.matchName) { // #4 make sure the name is unique const thisCache = cache.getCache()[this.definition.type]; const relevantNames = Object.keys(thisCache).map((key) => ({ type: null, key: key, name: thisCache[key][this.definition.nameField], })); // if the name is already in the folder for a different key, add a number to the end metadata[this.definition.nameField] = this.findUniqueName( metadata[this.definition.keyField], metadata[this.definition.nameField], relevantNames ); } return metadata; } /** * Gets executed after deployment of metadata type * * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @returns {Promise.<void>} - */ static async postDeployTasks(upsertResults) { // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present) Util.logger.debug( `Caching all ${this.definition.type} post-deploy to ensure we have all fields` ); const domainVerificationEmails = new Set(); const typeCache = await this.retrieveForCache(); // update values in upsertResults with retrieved values before saving to disk for (const key of Object.keys(upsertResults)) { if (typeCache.metadata[key]) { upsertResults[key] = typeCache.metadata[key]; } // ensure the FromAddress is verified or else attempt to create it const emailsToCheck = [ upsertResults[key].FromAddress.trim() + '', upsertResults[key].FallbackFromAddress.trim() + '', ]; for (const email of emailsToCheck) { if (email && !email.startsWith('%%') && email.includes('@')) { const domainVerification = cache.getByKey('domainVerification', email); if (!domainVerification) { domainVerificationEmails.add(email); } } } } if (domainVerificationEmails.size) { Util.logger.info( Util.getGrayMsg(`Setting up required E-Mail Addresses for Sender Profiles:`) ); const domainVerificationCreateMap = {}; for (const email of domainVerificationEmails) { domainVerificationCreateMap[email] = { domain: email, isSendable: true, }; } const deployDir = File.normalizePath([ this.properties.directories.deploy, this.buObject.credential, this.buObject.businessUnit, ]); const retrieveDir = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, ]); DomainVerification.buObject = this.buObject; DomainVerification.client = this.client; DomainVerification.properties = this.properties; const domainVerificationCreateResult = await DomainVerification.deploy( domainVerificationCreateMap, deployDir, retrieveDir ); cache.mergeMetadata('domainVerification', domainVerificationCreateResult); } } /** * * @param {MetadataTypeItem} item single metadata item * @param {string} [_] parameter not used * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem>} key of the item that was updated */ static async replaceCbReference(item, _, findAssetKeys) { const parentName = `${this.definition.type} ${item[this.definition.keyField]}`; let changes = false; let error; // *** type specific logic *** try { item.FromName = ReplaceCbReference.replaceReference( item.FromName, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { item.FromAddress = ReplaceCbReference.replaceReference( item.FromAddress, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { item.AutoForwardToEmailAddress = ReplaceCbReference.replaceReference( item.AutoForwardToEmailAddress, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { item.AutoForwardToName = ReplaceCbReference.replaceReference( item.AutoForwardToName, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } if (error) { throw error; } if (!changes) { const ex = new Error('No changes made to the code.'); // @ts-expect-error custom error object ex.code = 200; throw ex; } // *** finish *** // replaceReference will throw an error if nothing was updated which will end execution here // no error means we have a new item to deploy and need to update the item in our retrieve folder return item; } } // Assign definition & cache to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; SenderProfile.definition = MetadataTypeDefinitions.senderProfile; export default SenderProfile; ================================================ FILE: lib/metadataTypes/TransactionalEmail.js ================================================ 'use strict'; import TransactionalMessage from './TransactionalMessage.js'; import Journey from './Journey.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalEmail MetadataType * * @augments TransactionalMessage */ class TransactionalEmail extends TransactionalMessage { static subType = 'email'; /** @type {Array} */ static _createdJourneyKeys; /** * Updates a single item * * @param {MetadataTypeItem} metadata how the item shall look after the update * @returns {Promise} Promise */ static update(metadata) { if (metadata.options?.createJourney) { // only send this during create or else we might end up with an unexpected outcome Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Cannot update journey link during update. If you need to relink this item to a new journey please delete and recreate it.` ); delete metadata.options.createJourney; } return super.update(metadata); } /** * Updates a single item * * @param {MetadataTypeItem} metadata how the item shall look after the update * @returns {Promise} Promise */ static create(metadata) { if (metadata.definitionType === 'Transactional' && metadata.channel === 'email') { // only send this during create or else we might end up with an unexpected outcome Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): While possible, it is not recommended to create transactional journeys via transactionalEmail. Instead, create the journey and then publish it (mcdev deploy cred/bu journey --publish)` ); } return super.create(metadata); } /** * prepares for deployment * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} - */ static async preDeployTasks(metadata) { // asset if (metadata.r__asset_key) { // we merely want to be able to show an error if it does not exist metadata.content = { customerKey: cache.searchForField( 'asset', metadata.r__asset_key, 'customerKey', 'customerKey' ), }; delete metadata.r__asset_key; } // subscriptions: dataExtension if (metadata.subscriptions?.r__dataExtension_key) { // we merely want to be able to show an error if it does not exist metadata.subscriptions.dataExtension = cache.searchForField( 'dataExtension', metadata.subscriptions.r__dataExtension_key, 'CustomerKey', 'CustomerKey' ); } // subscriptions: list if (metadata.subscriptions?.r__list_PathName) { metadata.subscriptions.list = cache.getListObjectId( metadata.subscriptions.r__list_PathName, 'CustomerKey' ); delete metadata.subscriptions.r__list_PathName; } // journey // ! update & create enpoints dont accept journey.interactionKey. They only allow to create a new journey metadata.options ||= {}; metadata.options.createJourney = true; // only send this during create or else we might end up with an unexpected outcome // subscriptions: sendClassification if (metadata.r__sendClassification_key) { // we merely want to be able to show an error if it does not exist metadata.classification = cache.searchForField( 'sendClassification', metadata.r__sendClassification_key, 'CustomerKey', 'CustomerKey' ); delete metadata.r__sendClassification_key; } return metadata; } /** * helper for {@link TransactionalEmail.createREST} * * @param {MetadataTypeItem} _ not used * @param {object} apiResponse varies depending on the API call * @returns {Promise.<object>} apiResponse */ static async postCreateTasks(_, apiResponse) { if (apiResponse.journey?.interactionKey) { Util.logger.warn( ` - created journey: ${apiResponse.journey.interactionKey} (auto-created when ${this.definition.type} ${apiResponse.definitionKey} was created)` ); // when we create new transactionalEmails, we should also download the new journey that was created with it this._createdJourneyKeys ||= []; this._createdJourneyKeys.push(apiResponse.journey?.interactionKey); // do what postRetrieveTasks won't be able to do without spending lots of time on caching apiResponse.r__journey_key = apiResponse.journey.interactionKey; delete apiResponse.journey; } return apiResponse; } /** * Gets executed after deployment of metadata type * * @returns {Promise.<void>} - */ static async postDeployTasks() { if (this._createdJourneyKeys?.length) { Util.logger.warn( `Please download related journeys via: mcdev retrieve ${this.buObject.credential}/${this.buObject.businessUnit} -m ${this._createdJourneyKeys.map((el) => `"journey:${el}"`).join(' ')}` ); } delete this._createdJourneyKeys; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} a single item */ static postRetrieveTasks(metadata) { // asset if (metadata.content?.customerKey) { metadata.r__asset_key = metadata.content.customerKey; try { // we merely want to be able to show an error if it does not exist cache.searchForField( 'asset', metadata.content.customerKey, 'customerKey', 'customerKey' ); } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } delete metadata.content; } // subscriptions: dataExtension if (metadata.subscriptions?.dataExtension) { metadata.subscriptions.r__dataExtension_key = metadata.subscriptions.dataExtension; try { // we merely want to be able to show a warning if it does not exist cache.searchForField( 'dataExtension', metadata.subscriptions.dataExtension, 'CustomerKey', 'CustomerKey' ); } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } delete metadata.subscriptions.dataExtension; } // subscriptions: list if (metadata.subscriptions?.list) { try { // List metadata.subscriptions.r__list_PathName = cache.getListPathName( metadata.subscriptions.list, 'CustomerKey' ); delete metadata.subscriptions.list; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } } // journey if (metadata.journey?.interactionKey) { metadata.r__journey_key = metadata.journey.interactionKey; try { // we merely want to be able to show a warning if it does not exist metadata.r__journey_key = cache.searchForField( 'journey', metadata.journey.interactionKey, 'key', 'key' ); } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } delete metadata.journey; } // sendClassification if (metadata.classification) { metadata.r__sendClassification_key = metadata.classification; try { // we merely want to be able to show a warning if it does not exist metadata.r__sendClassification_key = cache.searchForField( 'sendClassification', metadata.classification, 'CustomerKey', 'CustomerKey' ); } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } delete metadata.classification; } return metadata; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success status */ static async deleteByKey(key) { const metadataMapObj = await this.retrieveForCache(null, null, key); const journeyKey = metadataMapObj?.metadata?.[key]?.journey?.interactionKey; const isDeleted = await super.deleteByKeyREST( '/messaging/v1/' + this.subType + '/definitions/' + key, key, 30003 ); if (isDeleted && journeyKey) { Util.logger.info( ` - deleted ${Journey.definition.type}: ${journeyKey} (SFMC auto-deletes the related journey of ${this.definition.type} ${key})` ); Journey.buObject = this.buObject; Journey.properties = this.properties; Journey.client = this.client; Journey.postDeleteTasks(journeyKey); } return isDeleted; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; TransactionalEmail.definition = MetadataTypeDefinitions.transactionalEmail; export default TransactionalEmail; ================================================ FILE: lib/metadataTypes/TransactionalMessage.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalMessage MetadataType * * @augments MetadataType */ class TransactionalMessage extends MetadataType { // define this.subType as string here for intellisense; requires to be redefined in child class static subType; /** * Retrieves Metadata * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { let keyList; const baseUri = '/messaging/v1/' + this.subType + '/definitions/'; if (key) { // Retrieve single keyList = [key]; } else { // Retrieve all // * keep deleted items for caching (and to decide on update vs create) const parsed = ( await this.retrieveREST( null, baseUri + (retrieveDir ? '?$filter=status%20neq%20deleted' : '') ) ).metadata; keyList = Object.keys(parsed); } // get all transactionalX items with additional details not given by the list endpoint const details = ( await Promise.all( keyList.map(async (key) => { try { return await this.client.rest.get(baseUri + (key || '')); } catch { return null; } }) ) ).filter(Boolean); const parsed = this.parseResponseBody({ definitions: details }); let savedMetadata; if (retrieveDir) { // * retrieveDir is mandatory in this method as it is not used for caching (there is a seperate method for that) savedMetadata = await this.saveResults(parsed, retrieveDir, null, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(key) ); if (!Object.keys(savedMetadata).length && key) { this.postDeleteTasks(key); } } return { metadata: savedMetadata || parsed, type: this.definition.type }; } /** * Retrieves event definition metadata for caching * * @param {void | string[]} [_] parameter not used * @param {void | string[]} [__] parameter not used * @param {string} [key] customer key of single item to cache * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieveForCache(_, __, key) { // the call to /messaging/v1/email/definitions/ does not return definitionId // definitionId is required for resolving dependencies on interactions. // we should therefore use the already defined retrieve method return this.retrieve(undefined, undefined, undefined, key); } /** * Updates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static update(metadata) { return super.updateREST( metadata, '/messaging/v1/' + this.subType + '/definitions/' + metadata[this.definition.keyField] ); } /** * Creates a single item * * @param {MetadataTypeItem} metadata a single item * @returns {Promise} Promise */ static create(metadata) { return super.createREST(metadata, '/messaging/v1/' + this.subType + '/definitions'); } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(key) { return super.deleteByKeyREST( '/messaging/v1/' + this.subType + '/definitions/' + key, key, 30003 ); } } // Assign definition to static attributes // ! using SMS definitions here as placeholder to have auto completion import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; TransactionalMessage.definition = MetadataTypeDefinitions.transactionalMessage; TransactionalMessage.definition; export default TransactionalMessage; ================================================ FILE: lib/metadataTypes/TransactionalPush.js ================================================ 'use strict'; import TransactionalMessage from './TransactionalMessage.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalPush TransactionalMessage * * @augments TransactionalMessage */ class TransactionalPush extends TransactionalMessage { static subType = 'push'; /** * prepares for deployment * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<MetadataTypeItem>} - */ static async preDeployTasks(metadata) { // asset if (metadata.r__asset_key) { // we merely want to be able to show an error if it does not exist metadata.content ||= {}; metadata.content.customerKey = cache.searchForField( 'asset', metadata.r__asset_key, 'customerKey', 'customerKey' ); delete metadata.r__asset_key; } if (metadata.options?.badge && typeof metadata.options?.badge !== 'string') { // ensure it's a string, or else the API will return an error. Our SDK turns numbers in strings into actual numbers metadata.options.badge += ''; } return metadata; } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem} a single item */ static postRetrieveTasks(metadata) { // asset if (metadata.content?.customerKey) { try { // we merely want to be able to show an error if it does not exist metadata.r__asset_key = cache.searchForField( 'asset', metadata.content.customerKey, 'customerKey', 'customerKey' ); delete metadata.content; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } } if (metadata.options?.badge && typeof metadata.options?.badge !== 'string') { // ensure it's a string, or else the API will return an error. Our SDK turns numbers in strings into actual numbers metadata.options.badge += ''; } return metadata; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; TransactionalPush.definition = MetadataTypeDefinitions.transactionalPush; export default TransactionalPush; ================================================ FILE: lib/metadataTypes/TransactionalSMS.js ================================================ 'use strict'; import TransactionalMessage from './TransactionalMessage.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TransactionalSMS MetadataType * * @augments TransactionalMessage */ class TransactionalSMS extends TransactionalMessage { static subType = 'sms'; /** * clean up after deleting a metadata item * * @param {string} customerKey Identifier of metadata item * @returns {Promise.<void>} - */ static async postDeleteTasks(customerKey) { // delete local copy: retrieve/cred/bu/type/...-meta.json // delete local copy: retrieve/cred/bu/type/...-meta.amp return super.postDeleteTasks(customerKey, [`${this.definition.type}-meta.amp`]); } /** * prepares for deployment * * @param {MetadataTypeItem} metadata a single item * @param {string} deployDir directory of deploy files * @returns {Promise.<MetadataTypeItem>} Promise */ static async preDeployTasks(metadata, deployDir) { // code metadata.content = { message: await this._mergeCode(metadata, deployDir), }; if (this._isHTML(metadata.content?.message)) { // keep this as a non-blocking warning because the test not 100% accurate Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): HTML detected` ); } // subscriptions: mobileKeyword if (metadata.subscriptions?.r__mobileKeyword_key) { // we merely want to be able to show an error if it does not exist cache.searchForField( 'mobileKeyword', metadata.subscriptions.r__mobileKeyword_key, 'c__codeKeyword', 'c__codeKeyword' ); const codeKeywordArr = metadata.subscriptions.r__mobileKeyword_key.split('.'); metadata.subscriptions.shortCode = codeKeywordArr[0]; metadata.subscriptions.keyword = codeKeywordArr[1]; // make sure the code actually exists cache.searchForField('mobileCode', metadata.subscriptions.shortCode, 'code', 'code'); } else if (metadata.subscriptions?.r__mobileCode_key) { // subscriptions: mobileCode // in case we dont have r__mobileKeyword_key set metadata.subscriptions.shortCode = cache.searchForField( 'mobileCode', metadata.subscriptions.r__mobileCode_key, 'code', 'code' ); } delete metadata.subscriptions.r__mobileKeyword_key; delete metadata.subscriptions.r__mobileCode_key; return metadata; } /** * helper for {@link TransactionalSMS.preDeployTasks} that loads extracted code content back into JSON * * @param {MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files * @param {string} [templateName] name of the template used to built defintion (prior applying templating) * @returns {Promise.<string>} content for metadata.script */ static async _mergeCode(metadata, deployDir, templateName) { templateName ||= metadata[this.definition.keyField]; const codePath = File.normalizePath([ deployDir, this.definition.type, templateName + '.' + this.definition.type + '-meta', ]); if (await File.pathExists(codePath + '.amp')) { return await File.readFilteredFilename( [deployDir, this.definition.type], templateName + '.' + this.definition.type + '-meta', 'amp' ); } else { throw new Error(`Could not find ${codePath}.amp`); } } /** * manages post retrieve steps * * @param {MetadataTypeItem} metadata a single item * @returns {Promise.<CodeExtractItem>} Array with one metadata object and one ssjs string */ static async postRetrieveTasks(metadata) { // extract message body const codeArr = []; // keep between tags const { fileExt, code } = await this.prepExtractedCode(metadata.content?.message); delete metadata.content; codeArr.push({ subFolder: null, fileName: metadata[this.definition.keyField], fileExt: fileExt, content: code, }); if (this._isHTML(code)) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): HTML detected` ); } // subscriptions: mobileCode if (metadata.subscriptions?.shortCode) { try { // we merely want to be able to show a warning if it does not exist cache.searchForField( 'mobileCode', metadata.subscriptions.shortCode, 'code', 'code' ); metadata.subscriptions.r__mobileCode_key = metadata.subscriptions.shortCode; delete metadata.subscriptions.shortCode; } catch { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Could not find mobileCode ${metadata.subscriptions.shortCode}.` ); } // subscriptions: mobileKeyword if (metadata.subscriptions?.keyword) { try { // we merely want to be able to show a warning if it does not exist metadata.subscriptions.r__mobileKeyword_key = cache.searchForField( 'mobileKeyword', (metadata.subscriptions.shortCode || metadata.subscriptions.r__mobileCode_key) + '.' + metadata.subscriptions.keyword, 'c__codeKeyword', 'c__codeKeyword' ); delete metadata.subscriptions.r__mobileCode_key; delete metadata.subscriptions.shortCode; delete metadata.subscriptions.keyword; } catch { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): Could not find mobileKeyword ${metadata.subscriptions.keyword}.` ); } } } return { json: metadata, codeArr: codeArr, subFolder: null }; } /** * helper for {@link TransactionalSMS.postRetrieveTasks} and {@link TransactionalSMS._buildForNested} * * @param {string} metadataScript the code of the file * @returns {Promise.<{fileExt:string,code:string}>} returns found extension and file content */ static async prepExtractedCode(metadataScript) { const code = await File.beautify_beautyAmp(metadataScript, false); const fileExt = 'amp'; return { fileExt, code }; } /** * helper for {@link TransactionalMessage.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildDefinitionForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'definition' ); } /** * helper for {@link TransactionalMessage.buildTemplate} * handles extracted code if any are found for complex types * * @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static buildTemplateForNested( templateDir, targetDir, metadata, templateVariables, templateName ) { return this._buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, 'template' ); } /** * helper for {@link TransactionalSMS.buildTemplateForNested} / {@link TransactionalSMS.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored * @param {string|string[]} targetDir (List of) Directory where built definitions will be saved * @param {MetadataTypeItem} metadata main JSON file that was read from file system * @param {TemplateMap} templateVariables variables to be replaced in the metadata * @param {string} templateName name of the template to be built * @param {'definition'|'template'} mode defines what we use this helper for * @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array */ static async _buildForNested( templateDir, targetDir, metadata, templateVariables, templateName, mode ) { // get code from filesystem let code = await this._mergeCode(metadata, templateDir, templateName); const file = await this.prepExtractedCode(code); const fileExt = file.fileExt; code = file.code; // apply templating try { if (mode === 'definition') { // replace template variables with their values code = this.applyTemplateValues(code, templateVariables); } else if (mode === 'template') { // replace template values with corresponding variable names code = this.applyTemplateNames(code, templateVariables); } } catch { throw new Error( `${this.definition.type}:: Error applying template variables on ${ templateName + '.' + this.definition.type }-meta.${fileExt}.` ); } // write to file const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir]; const nestedFilePaths = []; // keep old name if creating templates, otherwise use new name const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName; for (const targetDir of targetDirArr) { File.writeToFile( [targetDir, this.definition.type], fileName + '.' + this.definition.type + '-meta', fileExt, code ); nestedFilePaths.push([ targetDir, this.definition.type, fileName + '.' + this.definition.type + '-meta.' + fileExt, ]); } return nestedFilePaths; } /** * very simplified test for HTML code in our SMS * * @param {string} code sms source code * @returns {boolean} true if HTML is found */ static _isHTML(code) { return /(<([^>]+)>)/gi.test(code); } /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ static async getFilesToCommit(keyArr) { const path = File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, this.buObject.businessUnit, this.definition.type, ]); const fileList = keyArr.flatMap((key) => [ File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]), File.normalizePath([path, `${key}.${this.definition.type}-meta.amp`]), ]); return fileList; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; TransactionalSMS.definition = MetadataTypeDefinitions.transactionalSMS; export default TransactionalSMS; ================================================ FILE: lib/metadataTypes/TriggeredSend.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; import asset from './Asset.js'; import folder from './Folder.js'; import list from './List.js'; import sendClassification from './SendClassification.js'; import senderProfile from './SenderProfile.js'; import ReplaceCbReference from '../util/replaceContentBlockReference.js'; import pLimit from 'p-limit'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * MessageSendActivity MetadataType * * @augments MetadataType */ class TriggeredSend extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = { filter: { leftOperand: 'TriggeredSendStatus', operator: 'IN', rightOperand: ['New', 'Active', 'Inactive', 'Moved', 'Canceled'], // New, Active=Running, Inactive=Paused, (Deleted) }, }; if (key) { // move original filter down one level into rightOperand and add key filter into leftOperand requestParams = { filter: { leftOperand: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, operator: 'AND', rightOperand: requestParams.filter, }, }; } return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * Create a single TSD. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static create(metadata) { return super.createSOAP(metadata); } /** * Updates a single TSD. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static update(metadata) { // * in case of update and active definition, we need to pause first. // * this should be done manually to not accidentally pause production queues without restarting them return super.updateSOAP(metadata); } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of data extension * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(key) { return super.deleteByKeySOAP(key, undefined, 17015); } /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem | void} Array with one metadata object and one sql string */ static postRetrieveTasks(metadata) { // remove IsPlatformObject, always has to be 'false' delete metadata.IsPlatformObject; // folder this.setFolderPath(metadata); if (!metadata.r__folder_Path) { Util.logger.verbose( ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` ); // do not save this TSD because it would not be visible in the user interface return; } // email try { // content builder const contentBuilderEmailName = cache.searchForField( 'asset', metadata.Email.ID, 'legacyData.legacyId', 'name' ); metadata.r__asset_name_readOnly = contentBuilderEmailName; const contentBuilderEmailKey = cache.searchForField( 'asset', metadata.Email.ID, 'legacyData.legacyId', 'customerKey' ); metadata.r__asset_key = contentBuilderEmailKey; delete metadata.Email; } catch { try { // classic const classicEmail = cache.searchForField('email', metadata.Email.ID, 'ID', 'Name'); metadata.r__email_name = classicEmail; delete metadata.Email; } catch { Util.logger.verbose( ` - ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find email with ID ${metadata.Email.ID} in Classic nor in Content Builder. This TSD cannot be republished but potentially restarted with its cached version of the email.` ); // save this TSD because it could be fixed by the user or potentially restarted without a fix; also, it might be used by a journey } } // message priority if (metadata.Priority) { metadata.c__priority = Util.inverseGet( this.definition.priorityMapping, metadata.Priority ); delete metadata.Priority; } // List (optional) if (metadata.List) { try { metadata.r__list_PathName = cache.getListPathName(metadata.List.ID, 'ID'); delete metadata.List; } catch (ex) { Util.logger.verbose( ` - ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': ${ex.message}` ); // save this TSD because it could be fixed by the user } } // sender profile if (metadata.SenderProfile?.ObjectID) { try { const spKey = cache.searchForField( 'senderProfile', metadata.SenderProfile.ObjectID, 'ObjectID', 'CustomerKey' ); metadata.r__senderProfile_key = spKey; delete metadata.SenderProfile; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message} (senderProfile key ${metadata.SenderProfile.CustomerKey})` ); } } // send classification if (metadata.SendClassification?.ObjectID) { try { const scKey = cache.searchForField( 'sendClassification', metadata.SendClassification.ObjectID, 'ObjectID', 'CustomerKey' ); metadata.r__sendClassification_key = scKey; delete metadata.SendClassification; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message} (sendClassification key ${metadata.SendClassification.CustomerKey})` ); } } return metadata; } /** * prepares a TSD for deployment * * @param {MetadataTypeItem} metadata of a single TSD * @returns {Promise.<MetadataTypeItem>} metadata object */ static async preDeployTasks(metadata) { const cachedVersion = cache.getByKey(this.definition.type, metadata.CustomerKey); if ( cachedVersion?.TriggeredSendStatus === 'Active' && cachedVersion?.TriggeredSendStatus === metadata.TriggeredSendStatus ) { throw new Error( `Please pause the Triggered Send '${metadata.Name}' before updating it. You may do so via GUI; or via Accenture SFMC DevTools by setting TriggeredSendStatus to 'Inactive'.` ); } // re-add IsPlatformObject, required for visibility metadata.IsPlatformObject = false; // folder super.setFolderId(metadata); // email if (metadata.r__email_name) { // classic metadata.Email = { ID: cache.searchForField('email', metadata.r__email_name, 'Name', 'ID'), }; delete metadata.r__email_name; } else if (metadata.r__asset_key) { // content builder // * this ignores r__asset_name_readOnly on purpose as that is only unique per parent folder but useful during PR reviews metadata.Email = { ID: cache.searchForField( 'asset', metadata.r__asset_key, 'customerKey', 'legacyData.legacyId' ), }; delete metadata.r__asset_key; delete metadata.r__asset_name_readOnly; } else if (metadata?.Email?.ID) { throw new Error( `r__asset_key / r__email_name not defined but instead found Email.ID. Please try re-retrieving this TSD from your BU.` ); } // message priority if (metadata.c__priority) { metadata.Priority = this.definition.priorityMapping[metadata.c__priority]; delete metadata.c__priority; } // get List (optional) if (metadata.r__list_PathName) { metadata.List = { ID: cache.getListObjectId(metadata.r__list_PathName, 'ID'), }; delete metadata.r__list_PathName; } else if (metadata?.List?.ID) { throw new Error( `r__list_PathName not defined but instead found List.ID. Please try re-retrieving this TSD from your BU.` ); } // sender profile if (metadata.r__senderProfile_key) { const spId = cache.searchForField( 'senderProfile', metadata.r__senderProfile_key, 'CustomerKey', 'ObjectID' ); metadata.SenderProfile = { ObjectID: spId, CustomerKey: metadata.r__senderProfile_key, }; delete metadata.r__senderProfile_key; } // send classification if (metadata.r__sendClassification_key) { const scId = cache.searchForField( 'sendClassification', metadata.r__sendClassification_key, 'CustomerKey', 'ObjectID' ); metadata.SendClassification = { ObjectID: scId, CustomerKey: metadata.r__sendClassification_key, }; delete metadata.r__sendClassification_key; } return metadata; } /** * TSD-specific refresh method that finds active TSDs and refreshes them * * @param {string[]} [keyArr] metadata keys * @param {boolean} [checkKey] whether to check if the key is valid * @returns {Promise.<string[]>} Returns list of keys that were refreshed */ static async refresh(keyArr, checkKey = true) { if (!keyArr) { keyArr = await this.getKeysForValidTSDs((await this.findRefreshableItems()).metadata); checkKey = false; } // then executes pause, publish, start on them. Util.logger.info(`Refreshing ${keyArr.length} ${this.definition.typeName}...`); Util.logger.debug(`Refreshing keys: ${keyArr.join(', ')}`); const refreshedKeyArr = []; const rateLimit = pLimit(10); await Promise.all( keyArr.map((key) => rateLimit(async () => { const result = await this._refreshItem(key, checkKey); if (result) { refreshedKeyArr.push(key); } }) ) ); Util.logger.info( `Refreshed ${refreshedKeyArr.length} of ${keyArr.length} ${this.definition.type}` ); return refreshedKeyArr; } /** * helper for {@link TriggeredSend.refresh} that extracts the keys from the TSD item map and eli * * @param {MetadataTypeMap} metadata TSD item map * @returns {Promise.<string[]>} keyArr */ static async getKeysForValidTSDs(metadata) { const keyArr = Object.keys(metadata).filter((key) => { const test = this.postRetrieveTasks(metadata[key]); return test?.CustomerKey || false; }); Util.logger.info(`Found ${keyArr.length} refreshable items.`); return keyArr; } /** * helper for {@link TriggeredSend.refresh} that finds active TSDs on the server and filters it by the same rules that {@link TriggeredSend.retrieve} is using to avoid refreshing TSDs with broken dependencies * * @param {boolean} [assetLoaded] if run after Asset.deploy via --refresh option this will skip caching assets * @returns {Promise.<MetadataTypeMapObj>} Promise of TSD item map */ static async findRefreshableItems(assetLoaded = false) { Util.logger.info('Finding refreshable items...'); // cache dependencies to test for broken links const requiredCache = { folder: [ 'hidden', 'list', 'mysubs', 'suppression_list', 'publication', 'contextual_suppression_list', 'triggered_send', 'triggered_send_journeybuilder', ], }; for (const dep of this.definition.dependencies) { if (dep === 'email') { // skip deprecated classic emails here, assuming they cannot be updated and hence are not relevant for {@link refresh} continue; } const [type, subtype] = dep.split('-'); if (requiredCache[type]) { requiredCache[type].push(subtype); } else { requiredCache[type] = subtype ? [subtype] : null; } } for (const [type, subTypeArr] of Object.entries(requiredCache)) { if (Array.isArray(subTypeArr)) { // make sure entries are unique requiredCache[type] = [...new Set(subTypeArr)]; } } const cacheTypes = { asset, folder, list, sendClassification, senderProfile, }; for (const [type, subTypeArr] of Object.entries(requiredCache)) { if (type === 'asset' && assetLoaded) { continue; } Util.logger.info(` - Caching dependent Metadata: ${type}`); Util.logSubtypes(subTypeArr); if (!cacheTypes[type]) { throw new Error(`Cache type ${type} not implemented.`); } cacheTypes[type].client = this.client; cacheTypes[type].buObject = this.buObject; cacheTypes[type].properties = this.properties; const result = await cacheTypes[type].retrieveForCache(null, subTypeArr); if (cache.getCache()?.[type]) { // re-run caching to merge with existing cache, assuming we might have missed subtypes cache.mergeMetadata(type, result.metadata); } else { cache.setMetadata(type, result.metadata); } } // cache ACTIVE triggeredSends from the server /** @type {SoapRequestParams} */ const requestParams = { filter: { leftOperand: 'TriggeredSendStatus', operator: 'IN', rightOperand: ['dummy', 'Active'], // using equals does not work for this field for an unknown reason and IN requires at least 2 values, hence the 'dummy' entry }, }; return super.retrieveSOAP(null, requestParams); } /** * helper for {@link TriggeredSend.refresh} that pauses, publishes and starts a triggered send * * @param {string} key external key of triggered send item * @param {boolean} checkKey whether to check if key exists on the server * @returns {Promise.<boolean>} true if refresh was successful */ static async _refreshItem(key, checkKey) { const item = {}; let test; item[this.definition.keyField] = key; // check triggeredSend-key exists on the server AND its status==ACTIVE if (checkKey) { /** @type {SoapRequestParams} */ const requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; try { test = ( await super.retrieveSOAP(null, requestParams, key, [ 'CustomerKey', 'TriggeredSendStatus', ]) )?.metadata; } catch (ex) { const errorMsg = super.getSOAPErrorMsg(ex); Util.logger.error(` ☇ skipping ${this.definition.typeName}: ${key} - ${errorMsg}}`); return false; } if (!test[key]) { Util.logger.error( ` ☇ skipping ${this.definition.typeName}: ${key} - not found on server` ); return false; } if (test[key].TriggeredSendStatus !== 'Active') { Util.logger.error( ` ☇ skipping ${this.definition.typeName}: ${key} - refresh only needed for running entries (TriggeredSendStatus=Active)` ); return false; } } // pause try { item.TriggeredSendStatus = 'Inactive'; test = await super.updateSOAP(item, true); if (test.OverallStatus !== 'OK') { throw new Error(test.Results[0].StatusMessage); } delete item.TriggeredSendStatus; Util.logger.info(` - 🛑 paused ${this.definition.typeName}: ${key}`); } catch (ex) { const errorMsg = super.getSOAPErrorMsg(ex); Util.logger.error( ` - failed to pause ${this.definition.typeName}: ${key} - ${errorMsg}` ); return false; } // publish try { item.RefreshContent = 'true'; test = await super.updateSOAP(item, true); if (test.OverallStatus !== 'OK') { throw new Error(test.Results[0].StatusMessage); } delete item.RefreshContent; Util.logger.info(` - 🔃 published ${this.definition.typeName}: ${key}`); } catch (ex) { const errorMsg = super.getSOAPErrorMsg(ex); Util.logger.error( ` - failed to publish ${this.definition.typeName}: ${key} - ${errorMsg}` ); return false; } // start try { item.TriggeredSendStatus = 'Active'; test = await super.updateSOAP(item, true); if (test.OverallStatus !== 'OK') { throw new Error(test.Results[0].StatusMessage); } delete item.RefreshContent; Util.logger.info(` - ✅ started ${this.definition.typeName}: ${key}`); } catch (ex) { const errorMsg = super.getSOAPErrorMsg(ex); Util.logger.error( ` - failed to publish ${this.definition.typeName}: ${key} - ${errorMsg}` ); return false; } return true; } /** * * @param {MetadataTypeItem} item single metadata item * @param {string} [_] parameter not used * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {Promise.<MetadataTypeItem>} key of the item that was updated */ static async replaceCbReference(item, _, findAssetKeys) { const parentName = `${this.definition.type} ${item[this.definition.keyField]}`; let changes = false; let error; // *** type specific logic *** try { item.FromName = ReplaceCbReference.replaceReference( item.FromName, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { item.FromAddress = ReplaceCbReference.replaceReference( item.FromAddress, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { item.EmailSubject = ReplaceCbReference.replaceReference( item.EmailSubject, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } try { item.DynamicEmailSubject = ReplaceCbReference.replaceReference( item.DynamicEmailSubject, parentName, findAssetKeys ); changes = true; } catch (ex) { if (ex.code !== 200) { error = ex; } } if (error) { throw error; } if (!changes) { const ex = new Error('No changes made to the code.'); // @ts-expect-error custom error object ex.code = 200; throw ex; } // *** finish *** // replaceReference will throw an error if nothing was updated which will end execution here // no error means we have a new item to deploy and need to update the item in our retrieve folder return item; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; TriggeredSend.definition = MetadataTypeDefinitions.triggeredSend; export default TriggeredSend; ================================================ FILE: lib/metadataTypes/TriggeredSendSummary.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import cache from '../util/cache.js'; import { Util } from '../util/util.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * TriggeredSendSummary MetadataType * * @augments MetadataType */ class TriggeredSendSummary extends MetadataType { /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static retrieve(retrieveDir, _, __, key) { /** @type {SoapRequestParams} */ let requestParams = {}; if (key) { // filter by CustomerKey when a specific key is requested requestParams = { filter: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, }; } return super.retrieveSOAP(retrieveDir, requestParams, key); } /** * parses retrieved Metadata before saving * * @param {MetadataTypeItem} metadata a single item * @returns {MetadataTypeItem | void} Array with one metadata object and one sql string */ static postRetrieveTasks(metadata) { // CustomerKey for this type is the same as the CustomerKey of the TriggeredSend it relates to const triggeredSend = cache.getByKey('triggeredSend', metadata.CustomerKey); if (!triggeredSend) { Util.logger.verbose( `Could not find related TriggeredSend with CustomerKey '${metadata.CustomerKey}' for the TriggeredSendSummary.` ); return null; } metadata['TriggeredSend.CategoryID'] = triggeredSend.CategoryID; // folder path for a TriggeredSendSummary is the same as for the related TriggeredSend. CategoryID is not retrievable for this type, so use the TriggeredSend's field this.setFolderPath(metadata); delete metadata['TriggeredSend.CategoryID']; metadata.r__triggeredSend_name = triggeredSend.Name; metadata.r__triggeredSend_key = triggeredSend.CustomerKey; return metadata; } /** * retrieves the folder path from cache and updates the TriggeredSendSummary metadata with it after retrieve * * @param {MetadataTypeItem} metadata a single item */ static setFolderPath(metadata) { try { metadata.r__folder_Path = cache.searchForField( 'folder', metadata[this.definition.folderIdField], 'ID', 'Path' ); delete metadata[this.definition.folderIdField]; } catch { Util.logger.verbose( ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` ); // do not save this Triggered Send Summary because it would not be visible in the user interface return; } } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; TriggeredSendSummary.definition = MetadataTypeDefinitions.triggeredSendSummary; export default TriggeredSendSummary; ================================================ FILE: lib/metadataTypes/User.js ================================================ 'use strict'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import File from '../util/file.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap */ /** * @typedef {import('../../types/mcdev.d.js').UserDocument} UserDocument * @typedef {import('../../types/mcdev.d.js').UserDocumentDocument} UserDocumentDocument * @typedef {import('../../types/mcdev.d.js').UserDocumentDiff} UserDocumentDiff * @typedef {import('../../types/mcdev.d.js').UserDocumentMap} UserDocumentMap * @typedef {import('../../types/mcdev.d.js').AccountUserConfiguration} AccountUserConfiguration */ /** * MetadataType * * @augments MetadataType */ class User extends MetadataType { static userBUassignments; static userIdBuMap; /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {void | string[]} _ unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { if (retrieveDir && this.buObject.eid !== this.buObject.mid) { // only skip if this was not for caching Util.logger.info(' - Skipping User retrieval on non-parent BU'); return; } return this._retrieve(retrieveDir, key); } /** * Retrieves import definition metadata for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise */ static async retrieveForCache() { return this.retrieve(null); } /** * Create a single item. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static async create(metadata) { if (this.buObject.eid !== this.buObject.mid) { Util.logger.info(' - Skipping User creation on non-parent BU'); return; } return super.createSOAP(metadata); } /** * Updates a single item. * * @param {MetadataTypeItem} metadata single metadata entry * @returns {Promise} Promise */ static async update(metadata) { if (this.buObject.eid !== this.buObject.mid) { Util.logger.info(' - Skipping User update on non-parent BU'); return; } return super.updateSOAP(metadata); } /** * prepares a item for deployment * * @param {UserDocument} metadata of a single item * @returns {Promise.<UserDocument>} metadata object */ static async preDeployTasks(metadata) { metadata.Client = { ID: this.buObject.mid, }; // convert roles into API compliant format if (metadata.c__RoleNamesGlobal?.length) { metadata.Roles = { Role: metadata.c__RoleNamesGlobal .filter( // individual role (which are not manageable nor visible in the GUI) (roleName) => !roleName.startsWith('Individual role for ') ) .map((roleName) => { let roleCache; try { const roleKey = cache.searchForField( 'role', roleName, 'Name', 'CustomerKey' ); roleCache = cache.getByKey('role', roleKey + ''); } catch { // skip this role in case of errors return; } if (roleCache?.c__notAssignable) { throw new Error( `Default roles starting on 'Marketing Cloud' are not assignable via API and get removed upon update. Please create/update the user manually in the GUI or remove that role.` ); } return { ObjectID: roleCache.ObjectID, Name: roleName, }; }) .filter(Boolean), }; } delete metadata.c__RoleNamesGlobal; // check if DefaultBusinessUnit is listed in AssociatedBUs if (!metadata.c__AssociatedBusinessUnits.includes(metadata.DefaultBusinessUnit)) { metadata.c__AssociatedBusinessUnits.push(metadata.DefaultBusinessUnit); Util.logger.info( Util.getGrayMsg( ` - adding DefaultBusinessUnit to list of associated Business Units (${metadata.CustomerKey} / ${metadata.Name}): ${metadata.DefaultBusinessUnit}` ) ); } if (metadata.c__AssociatedBusinessUnits.length) { // ensure we do not have duplicates in the list - could happen due to user error or due to templating metadata.c__AssociatedBusinessUnits = [...new Set(metadata.c__AssociatedBusinessUnits)]; } // Timezone if (metadata.c__TimeZoneName) { // find the ID of the timezone metadata.TimeZone = { Name: metadata.c__TimeZoneName }; metadata.TimeZone.ID = '' + cache.searchForField('_timezone', metadata.c__TimeZoneName, 'description', 'id'); delete metadata.c__TimeZoneName; } // Locale if (metadata.c__LocaleCode) { // we cannot easily confirm if hte code is valid but SFMC's API will likely throw an error if not metadata.Locale = { LocaleCode: metadata.c__LocaleCode }; delete metadata.c__LocaleCode; } // convert SSO / Federation Token into API compliant format if (metadata.SsoIdentity || metadata.SsoIdentities) { const ssoIdentity = {}; let error = false; if (metadata.SsoIdentity) { // assume metadata.SsoIdentity is an object ssoIdentity.IsActive = metadata.SsoIdentity.IsActive; ssoIdentity.FederatedID = metadata.SsoIdentity.FederatedID; delete metadata.SsoIdentity; } else if (Array.isArray(metadata.SsoIdentities)) { // be nice and allow SsoIdentities as an alternative if its an array of objects ssoIdentity.IsActive = metadata.SsoIdentities[0].IsActive; ssoIdentity.FederatedID = metadata.SsoIdentities[0].FederatedID; } else if ( Array.isArray(metadata.SsoIdentities?.SsoIdentity) && metadata.SsoIdentities?.SsoIdentity.length ) { // API-compliant format already provided; just use it ssoIdentity.IsActive = metadata.SsoIdentities.SsoIdentity[0]?.IsActive; ssoIdentity.FederatedID = metadata.SsoIdentities.SsoIdentity[0]?.FederatedID; } else { error = true; } if ( (ssoIdentity.IsActive !== true && ssoIdentity.IsActive !== false) || !ssoIdentity.FederatedID || error ) { throw new TypeError( 'SsoIdentity should be an object with IsActive and FederatedID properties.' ); } // if SsoIdentity is set, assume this was on purpose and bring it metadata.SsoIdentities = { SsoIdentity: [ { IsActive: ssoIdentity.IsActive, FederatedID: ssoIdentity.FederatedID, }, ], }; } delete metadata.c__type; delete metadata.c__AccountUserID; delete metadata.c__IsLocked_readOnly; return metadata; } /** * MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. * * @param {MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {boolean} [runUpsertSequentially] when a type has self-dependencies creates need to run one at a time and created/changed keys need to be cached to ensure following creates/updates have thoses keys available * @returns {Promise.<MetadataTypeMap>} keyField => metadata map */ static async upsert(metadataMap, deployDir, runUpsertSequentially = false) { if (typeof this.userIdBuMap !== 'object' || Object.keys(this.userIdBuMap).length === 0) { this.cacheBusinessUnitAssignments(); } return super.upsert(metadataMap, deployDir, runUpsertSequentially); } /** * helper for {@link MetadataType.upsert} * * @param {MetadataTypeMap} metadata list of metadata * @param {string} metadataKey key of item we are looking at * @param {boolean} hasError error flag from previous code * @param {UserDocumentDiff[]} metadataToUpdate list of items to update * @param {UserDocument[]} metadataToCreate list of items to create * @returns {Promise.<'create'|'update'|'skip'>} action to take */ static async createOrUpdate( metadata, metadataKey, hasError, metadataToUpdate, metadataToCreate ) { const action = await super.createOrUpdate( metadata, metadataKey, hasError, metadataToUpdate, metadataToCreate ); if (action === 'create') { const createItem = metadataToCreate.at(-1); User._setPasswordForNewUser(createItem); User._prepareRoleAssignments({ before: null, after: createItem }); User._prepareBuAssignments(metadata[metadataKey], null, createItem); } else if (action === 'update') { const updateItem = metadataToUpdate.at(-1); User._prepareRoleAssignments(updateItem); User._prepareBuAssignments(metadata[metadataKey], updateItem, null); } return action; } /** * helper for {@link createOrUpdate} * * @private * @param {MetadataTypeItem} metadata single metadata itme * @param {UserDocumentDiff} [updateItem] item to update * @param {UserDocument} [createItem] item to create */ static _prepareBuAssignments(metadata, updateItem, createItem) { this.userBUassignments ||= { add: {}, delete: {} }; if (updateItem) { // remove business units that were unassigned const deletedBUs = []; updateItem.before.c__AssociatedBusinessUnits = this.userIdBuMap[updateItem.before.ID] || []; for (const oldBuAssignment of updateItem.before.c__AssociatedBusinessUnits) { // check if oldRole is missing in list of new roles if (!updateItem.after.c__AssociatedBusinessUnits.includes(oldBuAssignment)) { deletedBUs.push(oldBuAssignment); } } if (deletedBUs.length > 0) { this.userBUassignments['delete'][updateItem.before.AccountUserID] = deletedBUs; } // add business units that were newly assigned const addedBUs = []; for (const newBuAssignment of updateItem.after.c__AssociatedBusinessUnits) { // check if oldRole is missing in list of new roles if (!updateItem.before.c__AssociatedBusinessUnits.includes(newBuAssignment)) { addedBUs.push(newBuAssignment); } } if (addedBUs.length > 0) { this.userBUassignments['add'][updateItem.before.AccountUserID] = addedBUs; } } // add BUs for new users if (createItem) { const addedBUs = createItem.c__AssociatedBusinessUnits || []; if (addedBUs.length > 0) { this.userBUassignments['add']['key:' + createItem.CustomerKey] = addedBUs; } } delete metadata.c__AssociatedBusinessUnits; } /** * Gets executed after deployment of metadata type * * @param {UserDocumentMap} upsertResults metadata mapped by their keyField * @returns {Promise.<void>} promise */ static async postDeployTasks(upsertResults) { if (Object.keys(upsertResults).length) { await this._handleBuAssignments(upsertResults); } } /** * create/update business unit assignments. helper for {@link postDeployTasks} * * @private * @param {UserDocumentMap} upsertResults metadata mapped by their keyField * @returns {Promise.<void>} - */ static async _handleBuAssignments(upsertResults) { /** @type {AccountUserConfiguration[]} */ const configs = []; for (const action in this.userBUassignments) { for (const data of Object.entries(this.userBUassignments[action])) { const buIds = data[1]; let userId = data[0]; if (!userId) { continue; } userId = userId.startsWith('key:') ? upsertResults[userId.slice(4)].ID : userId; configs.push( /** @type {AccountUserConfiguration} */ { Client: { ID: this.buObject.eid }, ID: userId, BusinessUnitAssignmentConfiguration: { BusinessUnitIds: { BusinessUnitId: buIds }, IsDelete: action === 'delete', }, } ); } } if (configs.length > 0) { Util.logger.info('Deploying: BU assignment changes'); // run update const buResponse = await this.client.soap.configure('AccountUser', configs); // process response if (buResponse.OverallStatus === 'OK') { // get userIdNameMap const userIdNameMap = {}; for (const user of Object.values(upsertResults)) { userIdNameMap[user.ID] = `${user.CustomerKey} / ${user.Name}`; } // log what was added / removed let configureResults = buResponse.Results?.[0]?.Result; if (!configureResults) { Util.logger.debug( 'buResponse.Results?.[0]?.Result not defined: ' + JSON.stringify(buResponse) ); return; } if (!Array.isArray(configureResults)) { configureResults = [configureResults]; } const userBUresults = {}; for (const result of configureResults) { if (result.StatusCode === 'OK') { /** @type {AccountUserConfiguration} */ const config = result.Object; const buArr = config.BusinessUnitAssignmentConfiguration.BusinessUnitIds .BusinessUnitId; userBUresults[config.ID] ||= { add: [], delete: [], }; userBUresults[config.ID][ config.BusinessUnitAssignmentConfiguration.IsDelete ? 'delete' : 'add' ] = Array.isArray(buArr) ? buArr : [buArr]; } else { Util.logger.debug( `Unknown error occured during processing of BU assignment reponse: ${JSON.stringify( result )}` ); } } for (const [userId, buResult] of Object.entries(userBUresults)) { // show CLI log const msgs = []; if (buResult['add']?.length) { msgs.push(`MID ${buResult['add'].join(', ')} access granted`); } else { msgs.push('no new access granted'); } if (buResult['delete']?.length) { msgs.push(`MID ${buResult['delete'].join(', ')} access removed`); } else { msgs.push('no access removed'); } Util.logger.info(` - user ${userIdNameMap[userId]}: ${msgs.join(' / ')}`); // update BU map in local variable if (buResult['add']?.length) { this.userIdBuMap[userId] ||= []; this.userIdBuMap[userId].push( ...buResult['add'].filter( (item) => !this.userIdBuMap[userId].includes(item) ) ); } if (buResult['delete']?.length) { this.userIdBuMap[userId] ||= []; this.userIdBuMap[userId] = this.userIdBuMap[userId].filter( (item) => !buResult['delete'].includes(item) ); } } } } } /** * helper for {@link User.createOrUpdate} * * @private * @param {UserDocument} metadata single created user * @returns {void} */ static _setPasswordForNewUser(metadata) { // if Password is not set during CREATE, generate one // avoids error "Name, Email, UserID, and Password are required fields when creating a new user. (Code 11003)" if (!metadata.Password) { metadata.Password = this._generatePassword(); Util.logger.info( ` - Password for ${metadata.UserID} was not given. Generated password:` ); // use console.log here to print the generated password to bypass the logfile // eslint-disable-next-line no-console console.log(metadata.Password); } } /** * helper for {@link User.createOrUpdate} * It searches for roles that were removed from the user and unassigns them; it also prints a summary of added/removed roles * Adding roles works automatically for roles listed on the user * * @private * @param {UserDocumentDiff} item updated user with before and after state * @returns {void} */ static _prepareRoleAssignments(item) { // delete global roles from user that were not in the c__RoleNamesGlobal array / Roles.Role const deletedRoles = []; const deletedRoleNames = []; if (item.after?.Roles?.Role && !Array.isArray(item.after.Roles.Role)) { item.after.Roles.Role = [item.after.Roles.Role]; } if (item.before?.Roles?.Role) { if (!Array.isArray(item.before.Roles.Role)) { item.before.Roles.Role = [item.before.Roles.Role]; } for (const oldRole of item.before.Roles.Role) { // check if oldRole is missing in list of new roles --> removing role let oldRoleFound = false; if (item.after.Roles?.Role) { for (const newRole of item.after.Roles.Role) { if (newRole.ObjectID == oldRole.ObjectID) { oldRoleFound = true; break; } } } if (!oldRoleFound && !oldRole.Name.startsWith('Individual role for ')) { // delete role unless it is an individual role (which are not manageable nor visible in the GUI) deletedRoles.push({ ObjectID: oldRole.ObjectID, Name: oldRole.Name }); deletedRoleNames.push(oldRole.Name); } } } const addedRoleNames = []; if (item.after?.Roles?.Role) { for (const newRole of item.after.Roles.Role) { // check if newRole is missing in list of old roles --> adding role let roleAlreadyExisting = false; if (item.before?.Roles?.Role) { for (const oldRole of item.before.Roles.Role) { if (newRole.ObjectID == oldRole.ObjectID) { roleAlreadyExisting = true; break; } } } if (!roleAlreadyExisting) { addedRoleNames.push(newRole.Name); // Note: no AssignmentConfigurations property is needed to ADD global roles } } if (addedRoleNames.length) { Util.logger.info( Util.getGrayMsg( ` - adding role-assignment (${item.after.CustomerKey} / ${ item.after.Name }): ${addedRoleNames.join(', ')}` ) ); } } if (deletedRoles.length) { Util.logger.info( Util.getGrayMsg( ` - removing role-assignment (${item.after.CustomerKey} / ${ item.after.Name }): ${deletedRoleNames.join(', ')}` ) ); // add deleted roles to payload with IsDelete=true if (!item.after.Roles) { item.after.Roles = { Role: [] }; } else if (!item.after.Roles.Role) { item.after.Roles.Role = []; } item.after.Roles.Role.push( ...deletedRoles.map((role) => this._getRoleObjectForDeploy( role.ObjectID, role.Name, item.after.AccountUserID, false, true ) ) ); } } /** * helper for {@link User._prepareRoleAssignments} * * @param {string} roleId role.ObjectID * @param {string} roleName role.Name * @param {number} userId user.AccountUserID * @param {boolean} assignmentOnly if true, only assignment configuration will be returned * @param {boolean} [isRoleRemovale] if true, role will be removed from user; otherwise added * @returns {object} format needed by API */ static _getRoleObjectForDeploy( roleId, roleName, userId, assignmentOnly, isRoleRemovale = false ) { const assignmentConfigurations = { AssignmentConfiguration: [ { AccountUserId: userId, AssignmentConfigureType: 'RoleUser', IsDelete: isRoleRemovale, }, ], }; return assignmentOnly ? assignmentConfigurations : { ObjectID: roleId, Name: roleName, AssignmentConfigurations: assignmentConfigurations, }; } /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieveChangelog() { return this._retrieve(); } /** * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @private * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async _retrieve(retrieveDir, key) { /** @type {SoapRequestParams} */ const requestParams = { QueryAllAccounts: true, filter: { // normal users leftOperand: 'Email', operator: 'like', rightOperand: '@', }, }; if (key) { // move original filter down one level into rightOperand and add key filter into leftOperand requestParams.filter = { leftOperand: { leftOperand: 'CustomerKey', operator: 'equals', rightOperand: key, }, operator: 'AND', rightOperand: requestParams.filter, }; } else { // if we are not filtering by key the following requests will take long. Warn the user Util.logger.info(` - Loading ${this.definition.type}s. This might take a while...`); } // get actual user details return this.retrieveSOAP(retrieveDir, requestParams, key); } /** * Retrieves SOAP via generic fuel-soap wrapper based metadata of metadata type into local filesystem. executes callback with retrieved metadata * * @param {string} retrieveDir Directory where retrieved metadata directory will be saved * @param {SoapRequestParams} [requestParams] required for the specific request (filter for example) * @param {string} [singleRetrieve] key of single item to filter by * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true * @returns {Promise.<MetadataTypeMapObj>} Promise of item map */ static async retrieveSOAP(retrieveDir, requestParams, singleRetrieve, additionalFields) { // to avoid not retrieving roles and userPermissions for users above the 2500 records limit we need to retrieve users twice, once with ActiveFlag=true and once with ActiveFlag=false const requestParamsUser = { QueryAllAccounts: true, filter: { leftOperand: { leftOperand: 'ActiveFlag', operator: 'equals', rightOperand: null, }, operator: 'AND', rightOperand: requestParams.filter, }, }; const fields = this.getFieldNamesToRetrieve(additionalFields, !retrieveDir); const soapType = this.definition.soapType || this.definition.type; let resultsBulk; let foundSingle = false; for (const active of [true, false]) { requestParamsUser.filter.leftOperand.rightOperand = active; try { const resultsBatch = await this.client.soap.retrieveBulk( soapType, fields, requestParamsUser ); if (Array.isArray(resultsBatch?.Results)) { Util.logger.debug( Util.getGrayMsg( ` - found ${resultsBatch?.Results.length} ${ active ? 'active' : 'inactive' } ${this.definition.type}s` ) ); if (resultsBulk) { // once first batch is done, the follow just add to result payload resultsBulk.Results.push(...resultsBatch.Results); } else { resultsBulk = resultsBatch; } if (singleRetrieve && resultsBatch?.Results.length) { foundSingle = true; break; } } } catch (ex) { this._handleSOAPErrors(ex, 'retrieving'); return; } } if ( !foundSingle && !(await this._retrieveSOAP_installedPackage( requestParams, soapType, fields, resultsBulk )) ) { return; } const metadata = this.parseResponseBody(resultsBulk); if (retrieveDir) { if (!singleRetrieve) { Util.logger.info( Util.getGrayMsg(` - found ${resultsBulk?.Results.length} users`) ); } if (resultsBulk?.Results?.length > 0) { // get BUs that each users have access to // split array resultsBulk?.Results into chunks to avoid not getting all roles await this.cacheBusinessUnitAssignments(resultsBulk.Results); } const savedMetadata = await this.saveResults(metadata, retrieveDir, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(singleRetrieve) ); if (!singleRetrieve) { // print summary to cli const counter = { userActive: 0, userInactive: 0, installedPackage: 0, }; for (const id in savedMetadata) { /** @typedef {UserDocument} */ const item = savedMetadata[id]; if (item.c__type === 'Installed Package') { counter.installedPackage++; } else if (item.ActiveFlag) { counter.userActive++; } else { counter.userInactive++; } } Util.logger.info( Util.getGrayMsg( `Found ${counter.userActive} active users / ${counter.userInactive} inactive users / ${counter.installedPackage} installed packages` ) ); } await this.runDocumentOnRetrieve(singleRetrieve, savedMetadata); } return { metadata: metadata, type: this.definition.type }; } /** * helper for {@link retrieveSOAP} and {@link upsert}; populates userIdBuMap * * @param {MetadataTypeItem[]} [metadataList] - * @returns {Promise.<void>} - */ static async cacheBusinessUnitAssignments(metadataList) { if (!metadataList) { // if run via upsert() then we won't have the metadataList with AccountUserID anywhere but in cache const cacheUsers = cache.getCache().user; metadataList = cacheUsers ? Object.values(cacheUsers) : []; } const chunkSize = 100; this.userIdBuMap = {}; Util.logger.info(` - Caching dependent Metadata: Business Unit assignments`); for (let i = 0; i < metadataList?.length; i += chunkSize) { if (i > 0) { Util.logger.info( Util.getGrayMsg(` - Requesting next batch (retrieved BUs for ${i} users)`) ); } const accountUserIDList = metadataList .map((item) => item.AccountUserID) .filter(Boolean); const chunk = accountUserIDList?.slice(i, i + chunkSize); const resultsBatch = ( await this.client.soap.retrieveBulk( 'AccountUserAccount', ['AccountUser.AccountUserID', 'Account.ID'], { filter: { leftOperand: 'AccountUser.AccountUserID', operator: chunk.length > 1 ? 'IN' : 'equals', // API does not allow IN for single item rightOperand: chunk, }, } ) ).Results; for (const item of resultsBatch) { this.userIdBuMap[item.AccountUser.AccountUserID] ||= []; // push to array if not already in array if (!this.userIdBuMap[item.AccountUser.AccountUserID].includes(item.Account.ID)) { this.userIdBuMap[item.AccountUser.AccountUserID].push(item.Account.ID); } } } } /** * helper for {@link User.retrieveSOAP} * * @private * @param {SoapRequestParams} requestParams required for the specific request (filter for example) * @param {string} soapType e.g. AccountUser * @param {string[]} fields list of fields to retrieve * @param {object} resultsBulk actual return value of this method * @returns {Promise.<boolean>} success flag */ static async _retrieveSOAP_installedPackage(requestParams, soapType, fields, resultsBulk) { /** @type {SoapRequestParams} */ const requestParamsInstalledPackage = { QueryAllAccounts: true, filter: { leftOperand: { leftOperand: 'ActiveFlag', operator: 'equals', rightOperand: true, // inactive installed packages are not visible in UI and hence cannot be reactivated there. Let's not retrieve them }, operator: 'AND', rightOperand: { leftOperand: { // filter out normal users leftOperand: 'Email', operator: 'isNull', }, operator: 'OR', rightOperand: { // installed packages leftOperand: { leftOperand: 'Name', operator: 'like', rightOperand: ' app user', // ! will not work if the name was too long as "app user" might be cut off }, operator: 'AND', rightOperand: { // this is used to filter out system generated installed packages. in our testing, at least those installed packages created in the last few years have hat set this to false while additional (hidden) installed packages have it set to true. leftOperand: 'MustChangePassword', operator: 'equals', rightOperand: 'false', }, }, }, }, }; if ( 'object' === typeof requestParams?.filter?.leftOperand && requestParams?.filter?.leftOperand?.leftOperand === 'CustomerKey' ) { requestParamsInstalledPackage.filter = { leftOperand: requestParams?.filter?.leftOperand, operator: 'AND', rightOperand: requestParamsInstalledPackage.filter, }; } try { const resultsBatch = await this.client.soap.retrieveBulk( soapType, fields, requestParamsInstalledPackage ); if (Array.isArray(resultsBatch?.Results)) { Util.logger.debug( Util.getGrayMsg(` - found ${resultsBatch?.Results.length} installed packages`) ); if (resultsBulk) { // once first batch is done, the follow just add to result payload resultsBulk.Results.push(...resultsBatch.Results); } else { resultsBulk = resultsBatch; } } } catch (ex) { this._handleSOAPErrors(ex, 'retrieving'); return false; } return true; } /** * * @param {string} dateStr first date * @param {string} interval defaults to 'days' * @returns {string} time difference */ static #timeSinceDate(dateStr, interval = 'days') { const second = 1000, minute = second * 60, hour = minute * 60, day = hour * 24, week = day * 7; const date = new Date(dateStr); const now = new Date(); // get difference in miliseconds const timediff = now.valueOf() - date.valueOf(); if (Number.isNaN(timediff)) { return ''; } let result; switch (interval) { case 'years': { result = now.getFullYear() - date.getFullYear(); break; } case 'months': { result = now.getFullYear() * 12 + now.getMonth() - (date.getFullYear() * 12 + date.getMonth()); break; } case 'weeks': { result = Math.floor(timediff / week); break; } case 'days': { result = Math.floor(timediff / day); break; } case 'hours': { result = Math.floor(timediff / hour); break; } case 'minutes': { result = Math.floor(timediff / minute); break; } case 'seconds': { result = Math.floor(timediff / second); break; } default: { return; } } return result + ' ' + interval; } /** * helper to print bu names * * @private * @param {number} id bu id * @returns {string} "bu name (bu id)"" */ static _getBuName(id) { const name = this.buObject.eid == id ? '_ParentBU_' : this.buIdName[id]; return `<nobr>${name} (${id})</nobr>`; } /** * helper that gets BU names from config * * @private */ static _getBuNames() { this.buIdName = {}; for (const cred in this.properties.credentials) { for (const buName in this.properties.credentials[cred].businessUnits) { this.buIdName[this.properties.credentials[cred].businessUnits[buName]] = buName; } } } /** * helper for {@link User.createOrUpdate} to generate a random initial password for new users * note: possible minimum length values in SFMC are 6, 8, 10, 15 chars. Therefore we should default here to 15 chars. * * @private * @param {number} [length] length of password; defaults to 15 * @returns {string} random password */ static _generatePassword(length = 15) { const alpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const special = '!@#$%&'; const numeric = '0123456789'; const charset = alpha + special + numeric; let retVal; do { retVal = ''; for (let i = 0, n = charset.length; i < length; ++i) { retVal += charset.charAt(Math.floor(Math.random() * n)); } // check if password contains at least one of each character type or else generate a new one } while ( !/[a-z]/.test(retVal) || !/[A-Z]/.test(retVal) || !/[0-9]/.test(retVal) || !/[!@#$%&]/.test(retVal) ); return retVal; } /** * Creates markdown documentation of all roles * * @param {UserDocumentMap} [metadata] user list * @returns {Promise.<void>} - */ static async document(metadata) { if (this.buObject.eid !== this.buObject.mid) { Util.logger.error( `Users can only be retrieved & documented for the ${Util.parentBuName}` ); return; } if (!metadata) { // load users from disk if document was called directly and not part of a retrieve try { metadata = ( await this.readBUMetadataForType( File.normalizePath([ this.properties.directories.retrieve, this.buObject.credential, Util.parentBuName, ]), true ) ).user; } catch (ex) { Util.logger.error(ex.message); return; } } // init map of BU Ids > BU Name this._getBuNames(); /** @type {UserDocumentDocument[]} */ const users = []; for (const id in metadata) { const user = metadata[id]; // TODO resolve user permissions to something readable // user roles let roles = ''; if (user.c__RoleNamesGlobal) { roles = '<nobr>' + user.c__RoleNamesGlobal.join(',</nobr><br> <nobr>') + '</nobr>'; } let associatedBus = ''; if (user.c__AssociatedBusinessUnits) { // ensure Parent BU is first in list user.c__AssociatedBusinessUnits.push(user.DefaultBusinessUnit); // ensure associatedBus have no duplicates associatedBus = [ ...new Set(user.c__AssociatedBusinessUnits.map((mid) => this._getBuName(mid))), ] .toSorted((a, b) => (a < b ? -1 : a > b ? 1 : 0)) .join(',<br> '); } const defaultBUName = this._getBuName(user.DefaultBusinessUnit); const LastSuccessfulLogin = user.LastSuccessfulLogin.split('.')[0]; users.push({ ...user, // keep that here to satisfy the type TYPE: user.c__type, UserID: user.UserID, AccountUserID: user.c__AccountUserID, CustomerKey: user.CustomerKey, Name: user.Name, Email: user.Email, NotificationEmailAddress: user.NotificationEmailAddress, ActiveFlagDocs: user.ActiveFlag === true ? '✓' : '-', IsLockedDocs: user.IsLocked === true ? '✓' : '-', IsAPIUserDocs: user.IsAPIUser === true ? '✓' : '-', MustChangePasswordDocs: user.MustChangePassword === true ? '✓' : '-', DefaultBusinessUnitDocs: defaultBUName, AssociatedBusDocs: associatedBus, RolesDocs: roles, LastSuccessfulLogin: user.LastSuccessfulLogin ? // on create & update, LastSuccessfulLogin often gets overwritten with the current date LastSuccessfulLogin === user.CreatedDate.split('.')[0] || LastSuccessfulLogin === user.ModifiedDate.split('.')[0] ? 'unknown' : this.#timeSinceDate(user.LastSuccessfulLogin) : 'never', CreatedDate: user.CreatedDate ? user.CreatedDate.split('T').join(' ') : 'n/a', ModifiedDate: user.ModifiedDate ? user.ModifiedDate.split('T').join(' ') : 'n/a', ModifiedBy: user.Client.ModifiedBy || 'n/a', TimeZoneName: user.c__TimeZoneName.slice(1, 10), c__LocaleCode: user.c__LocaleCode, }); } users.sort((a, b) => (a.Name < b.Name ? -1 : a.Name > b.Name ? 1 : 0)); const columnsToPrint = [ ['Name', 'Name'], ['Last successful Login', 'LastSuccessfulLogin'], ['Active', 'ActiveFlagDocs'], ['Access Locked out', 'IsLockedDocs'], ['API User', 'IsAPIUserDocs'], ['Must change PW', 'MustChangePasswordDocs'], ['Default BU', 'DefaultBusinessUnitDocs'], ['BU Access', 'AssociatedBusDocs'], ['Roles', 'RolesDocs'], ['Login', 'UserID'], ['ID', 'AccountUserID'], ['Key', 'CustomerKey'], ['E-Mail', 'Email'], ['Notification E-Mail', 'NotificationEmailAddress'], ['Timezone', 'TimeZoneName'], ['SFMC Locale', 'c__LocaleCode'], ['Modified Date', 'ModifiedDate'], ['Modified By', 'ModifiedBy'], ['Created Date', 'CreatedDate'], ]; let output = `# User Overview - ${this.buObject.credential}`; output += this._generateDocMd( users.filter((user) => user.TYPE === 'User' && user.ActiveFlagDocs === '✓'), 'User', columnsToPrint ); output += this._generateDocMd( users.filter((user) => user.TYPE === 'User' && user.ActiveFlagDocs === '-'), 'Inactivated User', columnsToPrint ); output += this._generateDocMd( users.filter((user) => user.TYPE === 'Installed Package'), 'Installed Package', columnsToPrint ); const docPath = File.normalizePath([this.properties.directories.docs, 'user']); try { const filename = this.buObject.credential; // write to disk await File.writeToFile(docPath, filename + '.users', 'md', output); Util.logger.info(`Created ${File.normalizePath([docPath, filename])}.users.md`); if (['html', 'both'].includes(this.properties.options.documentType)) { Util.logger.warn(' - HTML-based documentation of user currently not supported.'); } } catch (ex) { Util.logger.error(`user.document():: error | `, ex.message); } } /** * * @private * @param {object[]} users list of users and installed package * @param {'Installed Package'|'User'|'Inactivated User'} type choose what sub type to print * @param {Array[]} columnsToPrint helper array * @returns {string} markdown */ static _generateDocMd(users, type, columnsToPrint) { let output = `\n\n## ${type}s (${users.length})\n\n`; let tableSeparator = ''; for (const column of columnsToPrint) { output += `| ${column[0]} `; tableSeparator += '| --- '; } output += `|\n${tableSeparator}|\n`; for (const user of users) { for (const column of columnsToPrint) { output += `| ${user[column[1]]} `; } output += `|\n`; } return output; } /** * manages post retrieve steps * * @param {UserDocument} metadata a single item * @returns {MetadataTypeItem | void} a single item */ static postRetrieveTasks(metadata) { metadata.c__type = 'Installed Package'; if (metadata.Email.includes('@') && !metadata.Name.endsWith('app user')) { metadata.c__type = 'User'; } if (metadata.c__type === 'Installed Package' && !metadata.ActiveFlag) { // deleted installed package - we do try to filter them in the API call but sometimes they slip through in the other calls return; } // rewrite AccountUserID to avoid accidental overwrites by create attempts but still allow users to search for this ID metadata.c__AccountUserID = metadata.AccountUserID; delete metadata.AccountUserID; // the actual field cannot be updated. to avoid confusion, we rename it metadata.c__IsLocked_readOnly = metadata.IsLocked; delete metadata.IsLocked; if (metadata.c__IsLocked_readOnly) { // add this field in case the user is locked to offer the opportunity to unlock it via api metadata.Unlock = false; } metadata.c__AssociatedBusinessUnits = this.userIdBuMap[metadata.ID] || []; metadata.c__AssociatedBusinessUnits.sort(); // make roles easily accessible let roles; if (metadata.Roles?.Role) { // normalize to always use array if (!metadata.Roles.Role.length) { metadata.Roles.Role = [metadata.Roles.Role]; } // convert complex object into basic set of info // turns out, Role Names are unique and hence we can turn this into a simple array of names roles = metadata.Roles.Role.map((item) => item.Name) .filter(Boolean) .filter( // individual role (which are not manageable nor visible in the GUI) (roleName) => !roleName.startsWith('Individual role for ') ) .toSorted((a, b) => (a < b ? -1 : a > b ? 1 : 0)); } else { // set to empty array roles = []; } metadata.c__RoleNamesGlobal = roles; delete metadata.Roles; // Timezone if (metadata.TimeZone?.ID) { metadata.c__TimeZoneName = cache.searchForField( '_timezone', metadata.TimeZone.ID, 'id', 'description' ); delete metadata.TimeZone; } // Locale if (metadata.Locale?.LocaleCode) { metadata.c__LocaleCode = metadata.Locale.LocaleCode; delete metadata.Locale; } return metadata; } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; User.definition = MetadataTypeDefinitions.user; export default User; ================================================ FILE: lib/metadataTypes/Verification.js ================================================ 'use strict'; import Automation from './Automation.js'; import MetadataType from './MetadataType.js'; import { Util } from '../util/util.js'; import cache from '../util/cache.js'; /** * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').RestError} RestError */ /** * @typedef {import('../../types/mcdev.d.js').VerificationItem} VerificationItem */ /** * Verification MetadataType * * @augments MetadataType */ class Verification extends MetadataType { static verificationIdKeyMap; /** * Retrieves Metadata of Data Verification Activity. * * @param {string} [retrieveDir] Directory where retrieved metadata directory will be saved * @param {void | string[]} [_] unused parameter * @param {void | string[]} [__] unused parameter * @param {string} [key] customer key of single item to retrieve * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieve(retrieveDir, _, __, key) { const paramArr = []; let automationKey; if (key) { const regex = /^(.*?)__s\d{1,3}\.\d{1,3}$/; const match = key.match(regex); if (match) { // automation key found automationKey = match[1]; } else { // invalid key, unset it Util.logger.error(`Invalid key: ${key}`); return; } } const results = {}; // there is no API endpoint to retrieve all dataVerification items, so we need to retrieve all automations and iterate over their activities Util.logger.info(` - Caching dependent Metadata: automation`); Automation.client = this.client; Automation.buObject = this.buObject; Automation.properties = this.properties; Automation._skipNotificationRetrieve = true; delete Automation._cachedMetadataMap; const automationsMapObj = automationKey ? await Automation.retrieve(undefined, undefined, undefined, automationKey) : await Automation.retrieve(); delete Automation._skipNotificationRetrieve; if (automationsMapObj?.metadata && Object.keys(automationsMapObj?.metadata).length) { if (!key) { // if we are not retrieving a single item, cache the automations for later use during retrieval of automations Automation._cachedMetadataMap = automationsMapObj?.metadata; } // automations found, lets iterate over their activities to find the dataVerification items this.verificationIdKeyMap = {}; for (const automation of Object.values(automationsMapObj.metadata)) { if (automation.steps) { for (const step of automation.steps) { // ideally one would use activity.displayOrder here but that doesnt always start at 1 nor is it always sequential. To avoid cross-BU issues, we use a custom order let order = 1; for (const activity of step.activities) { if ( activity.objectTypeId === 1000 && activity.activityObjectId && activity.activityObjectId !== '00000000-0000-0000-0000-000000000000' ) { // log the verification id this.verificationIdKeyMap[activity.activityObjectId] = `${automation.key}__s${step.step}.${order}`; } order++; } } } } if (Object.keys(this.verificationIdKeyMap).length) { paramArr.push(...Object.keys(this.verificationIdKeyMap)); } } if (paramArr.length) { const response = await this.retrieveRESTcollection( paramArr.map((id) => ({ id, uri: '/automation/v1/dataverifications/' + id })), undefined, !key ); if (response?.metadata) { Object.assign(results, response.metadata); } } if (retrieveDir) { const savedMetadata = await this.saveResults(results, retrieveDir, null, null); Util.logger.info( `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` + Util.getKeysString(key) ); } return { metadata: results, type: this.definition.type, }; } /** * helper for {@link this.retrieveRESTcollection} * * @param {RestError} ex exception * @param {string} id id or key of item * @returns {null} - */ static handleRESTErrors(ex, id) { if (ex.message === 'Not Found' || ex.message === 'Request failed with status code 400') { // if the ID is too short, the system will throw the 400 error Util.logger.debug( ` ☇ skipping ${this.definition.type} ${id}: ${ex.message} ${ex.code}` ); } else { // if we do get here, we should log the error and continue instead of failing to download all automations Util.logger.error( ` ☇ skipping ${this.definition.type} ${id}: ${ex.message} ${ex.code}` ); } return null; } /** * Retrieves Metadata of item for caching * * @returns {Promise.<MetadataTypeMapObj>} Promise of metadata */ static async retrieveForCache() { return this.retrieve(); } /** * Creates a single item * * @param {VerificationItem} metadata a single item * @returns {Promise} Promise */ static create(metadata) { return super.createREST(metadata, '/automation/v1/dataverifications/'); } /** * helper for {@link MetadataType.createREST} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @param {MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped * @returns {Promise.<object>} apiResponse */ static async postCreateTasks(metadataEntry, apiResponse, metadataEntryWithAllFields) { if (!apiResponse?.[this.definition.idField]) { return; } // update apiResponse to ensure the new metadata is saved correctly on disk apiResponse[this.definition.keyField] = metadataEntryWithAllFields?.[this.definition.keyField]; // update info on metadataEntry to allow for proper logs metadataEntry[this.definition.keyField] = metadataEntryWithAllFields?.[this.definition.keyField]; metadataEntry[this.definition.idField] = apiResponse?.[this.definition.idField]; return apiResponse; } /** * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} * * @param {MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call * @param {MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped * @returns {Promise.<object>} apiResponse, potentially modified */ static postUpdateTasks(metadataEntry, apiResponse, metadataEntryWithAllFields) { // update apiResponse to ensure the new metadata is saved correctly on disk apiResponse[this.definition.keyField] = metadataEntryWithAllFields?.[this.definition.keyField]; // update info on metadataEntry to allow for proper logs metadataEntry[this.definition.keyField] = metadataEntryWithAllFields?.[this.definition.keyField]; metadataEntry[this.definition.idField] = apiResponse?.[this.definition.idField]; return apiResponse; } /** * Updates a single item * * @param {VerificationItem} metadata a single item * @returns {Promise} Promise */ static update(metadata) { return super.updateREST( metadata, '/automation/v1/dataverifications/' + metadata.dataVerificationDefinitionId ); } /** * prepares a verification for deployment * * @param {VerificationItem} metadata a single verification activity definition * @returns {Promise.<VerificationItem>} metadata object */ static async preDeployTasks(metadata) { metadata.targetObjectId = cache.searchForField( 'dataExtension', metadata.r__dataExtension_key, 'CustomerKey', 'ObjectID' ); delete metadata.r__dataExtension_key; return metadata; } /** * helper for {@link parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword * * @param {MetadataTypeItem} metadata single item */ static createCustomKeyField(metadata) { if (this.verificationIdKeyMap[metadata[this.definition.idField]]) { metadata[this.definition.keyField] = this.verificationIdKeyMap[metadata[this.definition.idField]]; } } /** * parses retrieved Metadata before saving * * @param {VerificationItem} metadata a single verification activity definition * @returns {VerificationItem} Array with one metadata object and one sql string */ static postRetrieveTasks(metadata) { try { // @ts-expect-error metadata.createdBy = cache.searchForField( 'user', metadata.createdBy, 'AccountUserID', 'Name' ); } catch (ex) { Util.logger.verbose( ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${ metadata[this.definition.keyField] }): ${ex.message}.` ); } try { metadata.r__dataExtension_key = cache.searchForField( 'dataExtension', metadata.targetObjectId, 'ObjectID', 'CustomerKey' ); delete metadata.targetObjectId; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ex.message}` ); } return metadata; } /** * Delete a metadata item from the specified business unit * * @param {string} key Identifier of item * @returns {Promise.<boolean>} deletion success status */ static deleteByKey(key) { return super.deleteByKeyREST('/automation/v1/dataverifications/' + key, key, 400); } } // Assign definition to static attributes import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js'; Verification.definition = MetadataTypeDefinitions.verification; export default Verification; ================================================ FILE: lib/metadataTypes/definitions/Asset.definition.js ================================================ // asset types https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/base-asset-types.htm export default { bodyIteratorField: 'items', dependencies: ['folder-asset', 'folder-asset-shared', 'folder-cloudpages'], dependencyGraph: { asset: ['views.html.template.r__asset_key'] }, folderType: 'asset', hasExtended: false, idField: 'id', keyIsFixed: false, keyField: 'customerKey', nameField: 'name', folderIdField: 'category.id', createdDateField: 'createdDate', createdNameField: 'createdBy.name', lastmodDateField: 'modifiedDate', lastmodNameField: 'modifiedBy.name', restPagination: true, maxKeyLength: 36, // confirmed max length type: 'asset', typeDescription: 'Assets from Content Builder grouped into subtypes.', typeRetrieveByDefault: [ 'asset', 'code', 'coderesource', 'textfile', 'block', 'message', 'template', 'other', ], typeCdpByDefault: true, typeName: 'Asset-[Subtype]', stringifyFieldsBeforeTemplate: ['memberId', 'enterpriseId'], allowMatchingByName: true, fields: { activeDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, allowedBlocks: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, assetType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'assetType.displayName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'assetType.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'assetType.name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, availableViews: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, modelVersion: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, blocks: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, businessUnitAvailability: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'businessUnitAvailability.%': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'businessUnitAvailability.%.view': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'businessUnitAvailability.%.update': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'businessUnitAvailability.%.delete': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'businessUnitAvailability.%.memberId': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'businessUnitAvailability.%.transferOwnership': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, category: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'category.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: true, }, 'category.name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'category.parentId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, channels: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, content: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'content.url': { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, contentType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'createdBy.email': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'createdBy.id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'createdBy.name': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'createdBy.userId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, customerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, customFields: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'data.campaigns': { skipValidation: true, }, 'data.approvals': { skipValidation: true, }, 'data.email': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'data.email.attributes': { skipValidation: true, }, 'data.email.legacy': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'data.email.options': { skipValidation: true, }, 'data.portfolio': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'data.site': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'data.site.content': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'data.site.content.url': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, design: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, enterpriseId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, file: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'fileProperties.fileName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileProperties.extension': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileProperties.externalUrl': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileProperties.fileSize': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'fileProperties.fileCreatedDate': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'fileProperties.width': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileProperties.height': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileProperties.publishedURL': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, id: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, legacyData: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, locked: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxBlocks: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, memberId: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, meta: { skipValidation: true, }, minBlocks: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'modifiedBy.email': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'modifiedBy.id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'modifiedBy.name': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'modifiedBy.userId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, objectID: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, owner: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'owner.email': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'owner.id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'owner.name': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'owner.userId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, sharingProperties: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sharingProperties.localAssets': { skipValidation: true, }, 'sharingProperties.sharedWith': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sharingProperties.sharedFrom': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sharingProperties.sharedFromMID': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sharingProperties.sharingType': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, slots: { skipValidation: true, }, 'status.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: true, }, 'status.name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, superContent: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, tags: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, template: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, thumbnail: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, version: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, views: { skipValidation: true, }, r__folder_Path: { skipValidation: true }, }, subTypes: [ 'archive', 'asset', 'audio', 'block', 'cloudpage', 'code', 'coderesource', 'document', 'image', 'message', 'other', 'rawimage', 'template', 'textfile', 'video', ], crosslinkedSubTypes: ['asset', 'code', 'textfile', 'block', 'other'], selflinkedSubTypes: ['asset', 'code', 'textfile', 'block', 'other', 'template'], binarySubtypes: ['archive', 'audio', 'document', 'image', 'rawimage', 'video'], extendedSubTypes: { archive: [ '7z', 'arj', 'bz2', 'cab', 'gz', 'gzip', 'iso', 'lha', 'sit', 'tgz', 'jar', 'rar', 'tar', 'zip', 'gpg', 'archive', ], asset: ['webpage', 'webtemplate', 'jsonmessage', 'icemailformblock', 'asset'], audio: [ 'aac', 'm4a', 'au', 'aif', 'aiff', 'aifc', 'mp3', 'wav', 'wma', 'midi', 'oga', 'ogg', 'ra', 'vox', 'voc', 'audio', ], block: [ 'freeformblock', 'textblock', 'htmlblock', 'textplusimageblock', 'imageblock', 'abtestblock', 'dynamicblock', 'stylingblock', 'einsteincontentblock', 'socialshareblock', 'socialfollowblock', 'buttonblock', 'layoutblock', 'block', ], cloudpage: ['cloudpages', 'landingpage', 'microsite', 'interactivecontent'], code: [ 'htm', 'html', 'xhtml', 'xht', 'css', 'less', 'sass', 'js', 'json', 'atom', 'rss', 'xml', 'xsl', 'xslt', 'md', 'markdown', 'as', 'fla', 'eml', 'code', ], coderesource: [ 'jscoderesource', 'csscoderesource', 'jsoncoderesource', 'rsscoderesource', 'textcoderesource', 'xmlcoderesource', ], document: [ 'indd', 'indt', 'incx', 'wwcx', 'doc', 'docx', 'dot', 'dotx', 'mdb', 'mpp', 'ics', 'xls', 'xlsx', 'xlk', 'xlsm', 'xlt', 'xltm', 'csv', 'tsv', 'tab', 'pps', 'ppsx', 'ppt', 'pptx', 'pot', 'thmx', 'pdf', 'ps', 'qxd', 'rtf', 'sxc', 'sxi', 'sxw', 'odt', 'ods', 'ots', 'odp', 'otp', 'epub', 'dvi', 'key', 'keynote', 'pez', 'document', ], image: [ 'ai', 'psd', 'pdd', 'eps', 'gif', 'jpe', 'jpeg', 'jpg', 'jp2', 'jpx', 'pict', 'pct', 'png', 'tif', 'tiff', 'tga', 'bmp', 'wmf', 'vsd', 'pnm', 'pgm', 'pbm', 'ppm', 'svg', 'image', ], message: ['templatebasedemail', 'htmlemail', 'textonlyemail', 'message'], other: [ 'smartcaptureblock', 'smartcaptureformfieldblock', 'smartcapturesubmitoptionsblock', 'slotpropertiesblock', 'externalcontentblock', 'codesnippetblock', 'rssfeedblock', 'formstylingblock', 'referenceblock', 'imagecarouselblock', 'customblock', 'liveimageblock', 'livesettingblock', 'contentmap', ], rawimage: [ '3fr', 'ari', 'arw', 'bay', 'cap', 'crw', 'cr2', 'dcr', 'dcs', 'dng', 'drf', 'eip', 'erf', 'fff', 'iiq', 'k25', 'kdc', 'mef', 'mos', 'mrw', 'nef', 'nrw', 'orf', 'pef', 'ptx', 'pxn', 'raf', 'raw', 'rw2', 'rwl', 'rwz', 'srf', 'sr2', 'srw', 'x3f', 'rawimage', ], template: ['defaulttemplate', 'template'], textfile: ['text', 'txt', 'textfile'], video: [ '3gp', '3gpp', '3g2', '3gp2', 'asf', 'avi', 'm2ts', 'mts', 'dif', 'dv', 'mkv', 'mpg', 'f4v', 'flv', 'mjpg', 'mjpeg', 'mxf', 'mpeg', 'mp4', 'm4v', 'mp4v', 'mov', 'swf', 'wmv', 'rm', 'ogv', 'video', ], }, typeMapping: { asset: 1, file: 2, // not inherited on Asset Types block: 3, template: 4, message: 5, custom: 6, // not inherited on Asset Types default: 7, // not inherited on Asset Types image: 8, rawimage: 9, video: 10, document: 11, audio: 12, archive: 13, code: 14, textfile: 15, ai: 16, psd: 17, pdd: 18, eps: 19, gif: 20, jpe: 21, jpeg: 22, jpg: 23, jp2: 24, jpx: 25, pict: 26, pct: 27, png: 28, tif: 29, tiff: 30, tga: 31, bmp: 32, wmf: 33, vsd: 34, pnm: 35, pgm: 36, pbm: 37, ppm: 38, svg: 39, '3fr': 40, ari: 41, arw: 42, bay: 43, cap: 44, crw: 45, cr2: 46, dcr: 47, dcs: 48, dng: 49, drf: 50, eip: 51, erf: 52, fff: 53, iiq: 54, k25: 55, kdc: 56, mef: 57, mos: 58, mrw: 59, nef: 60, nrw: 61, orf: 62, pef: 63, ptx: 64, pxn: 65, raf: 66, raw: 67, rw2: 68, rwl: 69, rwz: 70, srf: 71, sr2: 72, srw: 73, x3f: 74, '3gp': 75, '3gpp': 76, '3g2': 77, '3gp2': 78, asf: 79, avi: 80, m2ts: 81, mts: 82, dif: 83, dv: 84, mkv: 85, mpg: 86, f4v: 87, flv: 88, mjpg: 89, mjpeg: 90, mxf: 91, mpeg: 92, mp4: 93, m4v: 94, mp4v: 95, mov: 96, swf: 97, wmv: 98, rm: 99, ogv: 100, indd: 101, indt: 102, incx: 103, wwcx: 104, doc: 105, docx: 106, dot: 107, dotx: 108, mdb: 109, mpp: 110, ics: 111, xls: 112, xlsx: 113, xlk: 114, xlsm: 115, xlt: 116, xltm: 117, csv: 118, tsv: 119, tab: 120, pps: 121, ppsx: 122, ppt: 123, pptx: 124, pot: 125, thmx: 126, pdf: 127, ps: 128, qxd: 129, rtf: 130, sxc: 131, sxi: 132, sxw: 133, odt: 134, ods: 135, ots: 136, odp: 137, otp: 138, epub: 139, dvi: 140, key: 141, keynote: 142, pez: 143, aac: 144, m4a: 145, au: 146, aif: 147, aiff: 148, aifc: 149, mp3: 150, wav: 151, wma: 152, midi: 153, oga: 154, ogg: 155, ra: 156, vox: 157, voc: 158, '7z': 159, arj: 160, bz2: 161, cab: 162, gz: 163, gzip: 164, iso: 165, lha: 166, sit: 167, tgz: 168, jar: 169, rar: 170, tar: 171, zip: 172, gpg: 173, htm: 174, html: 175, xhtml: 176, xht: 177, css: 178, less: 179, sass: 180, js: 181, json: 182, atom: 183, rss: 184, xml: 185, xsl: 186, xslt: 187, md: 188, markdown: 189, as: 190, fla: 191, eml: 192, text: 193, txt: 194, freeformblock: 195, textblock: 196, htmlblock: 197, textplusimageblock: 198, imageblock: 199, abtestblock: 200, dynamicblock: 201, stylingblock: 202, einsteincontentblock: 203, webpage: 205, webtemplate: 206, templatebasedemail: 207, htmlemail: 208, textonlyemail: 209, socialshareblock: 210, socialfollowblock: 211, buttonblock: 212, layoutblock: 213, defaulttemplate: 214, smartcaptureblock: 215, smartcaptureformfieldblock: 216, smartcapturesubmitoptionsblock: 217, slotpropertiesblock: 218, externalcontentblock: 219, codesnippetblock: 220, rssfeedblock: 221, formstylingblock: 222, referenceblock: 223, imagecarouselblock: 224, customblock: 225, liveimageblock: 226, livesettingblock: 227, contentmap: 228, jsonmessage: 230, icemailformblock: 232, coderesource: 239, jscoderesource: 240, csscoderesource: 241, jsoncoderesource: 242, rsscoderesource: 243, textcoderesource: 244, xmlcoderesource: 245, cloudpages: 246, landingpage: 247, microsite: 248, interactivecontent: 249, }, }; ================================================ FILE: lib/metadataTypes/definitions/AttributeGroup.definition.js ================================================ export default { bodyIteratorField: 'attributeGroupDefinitions', dependencies: ['attributeSet'], // future may have dependency on Data Extensions dependencyGraph: { attributeSet: ['r__attributeSet_key'] }, hasExtended: false, idField: 'definitionID', keyIsFixed: true, keyField: 'definitionKey', nameField: 'definitionName.value', restPagination: false, // Hub API does not support pagination and returns everything instead type: 'attributeGroup', typeDescription: 'Groupings of Attribute Sets (Data Extensions) in Data Designer.', typeRetrieveByDefault: true, typeCdpByDefault: false, typeName: 'Data Designer Attribute Groups', fields: { applicationID: { // used by system generated attribute groups only; contains UUID isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, applicationKey: { // used by system generated attribute groups only isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, attributeCount: { // auto-populated isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, attributeGroupIconKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, attributeGroupType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, attributeSetIdentifiers: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'attributeSetIdentifiers[].connectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: false, }, 'attributeSetIdentifiers[].definitionID': { isCreateable: null, isUpdateable: null, retrieving: true, template: false, }, 'attributeSetIdentifiers[].definitionKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: true, }, 'attributeSetIdentifiers[].definitionName.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: false, }, 'attributeSetIdentifiers[].namespace': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, canAddProperties: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, canAddRelationships: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, canChangeProperties: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, canModify: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, canRemove: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, connectingID: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'connectingID.identifierType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, containsSchemaAttributes: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, definitionID: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, definitionKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'definitionName.value': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { // optional field. not returned by API if empty isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, displayOrder: { // auto-set to i+1 isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, fullyQualifiedName: { // equal to defitionName.value; auto-populated by preDeployTasks isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, isHidden: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isOwner: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isPrimary: { // always false, purpose unknown isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, isSystemDefined: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, localizedDescription: { // always an empty object isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'localizedDescription.resourceSetKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: true, }, 'localizedDescription.resourceValueKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: true, }, 'localizedDescription.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: true, }, mID: { // auto-populated in preDeployTask isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, namespace: { // always an empty string isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, objectState: { // seems to always contain "Created" isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, requiredRelationships: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__attributeSet_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/AttributeSet.definition.js ================================================ export default { bodyIteratorField: 'setDefinition', dependencies: [ 'folder-hidden', 'folder-dataextension', 'folder-salesforcedataextension', 'folder-shared_data', 'folder-shared_dataextension', 'folder-shared_salesforcedataextension', 'folder-synchronizeddataextension', 'dataExtension', ], dependencyGraph: { dataExtension: ['r__dataExtension_key'], attributeSet: [ 'relationships.leftItem.identifier.r__attributeSet_key', 'relationships.rightItem.identifier.r__attributeSet_key', ], attributeGroup: [ 'relationships.leftItem.identifier.r__attributeGroup_key', 'relationships.rightItem.identifier.r__attributeGroup_key', ], }, hasExtended: false, idField: 'definitionID', keyIsFixed: true, keyField: 'definitionKey', nameField: 'name', folderIdField: 'categoryID', createdDateField: 'createDate', createdNameField: 'createdBy', lastmodDateField: null, lastmodNameField: null, restPagination: false, // Hub API does not support pagination and returns everything instead type: 'attributeSet', typeDescription: 'Data Extensions linked together in Attribute Groups in Data Designer.', typeRetrieveByDefault: true, typeCdpByDefault: false, typeName: 'Data Designer Attribute Sets', fields: { applicationID: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, applicationKey: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, attributeCount: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, canAddValues: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, canChangeValues: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, canModify: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, canRemove: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, categoryID: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'connectingID.identifierType': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, createDate: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, createdBy: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, customObjectOwnerMID: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'dataRetentionProperties.isDeleteAtEndOfRetentionPeriod': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'dataRetentionProperties.isResetRetentionPeriodOnImport': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'dataRetentionProperties.isRowBasedRetention': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'dataRetentionProperties.periodUnitOfMeasure': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'dataRetentionProperties.setDefinitionID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'dataRetentionProperties.periodLength': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, definitionID: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, definitionKey: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, definitionName: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'definitionName.value': { // equal to 'name' isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, fullyQualifiedName: { // equal to 'name' isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, isCustomObjectBacked: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isEvent: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isHidden: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isReadOnly: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isRoot: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isSendable: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isShared: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isSystemDefined: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, isTestaable: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'leftConnectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'leftItem.cardinality': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'leftItem.cardinality ': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'leftItem.connectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'leftItem.identifier': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'leftItem.relationshipType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, localizedDescription: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'localizedDescription.resourceSetKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'localizedDescription.resourceValueKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'localizedDescription.value': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, name: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, nonStandardAttributeGroupReferences: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'nonStandardAttributeGroupReferences[].attributeGroupType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'nonStandardAttributeGroupReferences[].attributeGroupID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'nonStandardAttributeGroupReferences[].definitionKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'obfuscationProperties.maskType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'obfuscationProperties.maskTypeID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'obfuscationProperties.storageType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'obfuscationProperties.storageTypeID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'obfuscationProperties.valueDefinitionID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'parentDefinition.connectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'parentDefinition.definitionID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'parentDefinition.definitionKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'parentDefinition.definitionName.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, parentID: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, relationshipCount: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, relationships: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].canModify': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].canRemove': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].isGroupToSetRelationship': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].isHidden': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].isSystemDefined': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftRelationshipID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftRelationshipIDs': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftItem.cardinality': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftItem.relationshipType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftItem.r__attributeSet_key': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftItem.r__attributeGroup_key': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].rightItem.cardinality': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].rightItem.relationshipType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].rightItem.r__attributeSet_key': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].rightItem.r__attributeGroup_key': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftRelationshipIDs[].type': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftRelationshipIDs[].value': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].leftRelationshipReferenceType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].relationshipAttributes': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].relationshipAttributes[].leftAttributeID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].relationshipAttributes[].rightAttributeID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].relationshipAttributes[].c__leftFullyQualifiedName': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].relationshipAttributes[].c__rightFullyQualifiedName': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'relationships[].relationshipID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'rightConnectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'rightItem.cardinality': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'rightItem.connectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'rightItem.identifier': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'rightItem.relationshipType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, sendAttributeStorageName: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, sendContactKeyStorageName: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, setDefinitionID: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, setDefinitionKey: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'setDefinitionName.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageFieldReferenceID.type': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageFieldReferenceID.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, storageLogicalType: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, storageName: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageObjectFieldInformation.externalIsRowIdentifier': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageObjectFieldInformation.externalObjectFieldAPIName': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageObjectFieldInformation.externalObjectFieldDataTypeName': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageObjectFieldInformation.externalObjectFieldLength': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, storageObjectIDs: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageObjectInformation.externalObjectAPIName': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageReferenceID.type': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'storageReferenceID.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, valueDefinitions: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].baseType': { // "Numeric", "Text", ... valueDefinitions[].dataType is more relevant isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].customerDataID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].connectingID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].dataSourceID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].dataSourceName': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].dataType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].defaultValue': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].definitionID': { // likely the main ID of the value definition. No use for simple checks on git though as long as we cannot update it isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].definitionKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].definitionName': { // equal to valueDefinitions[].name isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].description': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].displayOrder': { // merely a numeric counter; equal to valueDefinitions[].ordinal; not given for isHidden:true entries isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].fullyQualifiedName': { // dataExtension name + field name isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].identifierType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isHidden': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isIdentityValue': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isNullable': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isPrimaryKey': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isReadOnly': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isSystemDefined': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].isUpdateable': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].length': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].localizedDescription': { // always equal to { value: "" } isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].name': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].obfuscationProperties': { // might become relevant when fields are encrypted but for most cases we should simply skip it isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].obfuscationProperties.maskType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].obfuscationProperties.maskTypeID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].obfuscationProperties.storageType': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].obfuscationProperties.storageTypeID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].obfuscationProperties.valueDefinitionID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].ordinal': { // merely a numeric counter; equal to valueDefinitions[].displayOrder; not given for isHidden:true entries isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].parentDefinition': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].parentIdentifier': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].parentType': { // always "Set" isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].restrictionLookupListID': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].scale': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].setDefinitionID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].setDefinitionKey': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].setDefinitionName': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].storageFieldReferenceID': { isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].storageFieldReferenceID.type': { // always "guid" isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].storageFieldReferenceID.value': { // unknown GUID isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].storageFieldValueID.type': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].storageFieldValueID.value': { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, 'valueDefinitions[].storageName': { // always equal valueDefinitions[].definitionKey, except for when that is CustomObjectKey - then this will be _CustomObjectKey (with an underscore) isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].storageObjectFieldInformation': { skipValidation: true, }, 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldAPIName': { skipValidation: true, }, 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldDataTypeName': { skipValidation: true, }, 'valueDefinitions[].storageObjectFieldInformation.externalObjectFieldLength': { skipValidation: true, }, 'valueDefinitions[].storageObjectFieldInformation.externalIsRowIdentifier': { skipValidation: true, }, 'valueDefinitions[].valueDefinitionID': { // equal to valueDefinitions[].definitionID isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, 'valueDefinitions[].valueDefinitionKey': { // equal to valueDefinitions[].definitionKey isCreateable: null, isUpdateable: null, retrieving: false, template: null, }, r__folder_Path: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, r__dataExtension_key: { isCreateable: null, isUpdateable: null, retrieving: true, template: null, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Automation.definition.js ================================================ export default { activityTypeMapping: { dataExtract: 73, dataFactoryUtility: 425, emailSend: 42, fileTransfer: 53, filter: 303, fireEvent: 749, importFile: 43, journeyEntry: 952, journeyEntryOld: 733, query: 300, script: 423, verification: 1000, wait: 467, push: 736, sms: 725, reportDefinition: 84, refreshMobileFilteredList: 724, refreshGroup: 45, interactions: 1101, interactionStudioData: 1010, importMobileContact: 726, }, bodyIteratorField: 'items', dependencies: [ 'dataExtract', 'emailSend', 'fileTransfer', 'fileLocation', 'filter', 'folder-automations', 'importFile', 'query', 'script', 'verification', ], dependencyGraph: { dataExtract: ['steps.activities.r__type'], emailSend: ['steps.activities.r__type'], fileTransfer: ['steps.activities.r__type'], importFile: ['steps.activities.r__type'], query: ['steps.activities.r__type'], script: ['steps.activities.r__type'], verification: ['steps.activities.r__type'], }, folderType: 'automations', hasExtended: false, filter: { description: ['Event Definition Automation'], }, idField: 'id', keyIsFixed: false, keyField: 'key', nameField: 'name', folderIdField: 'categoryId', createdDateField: 'createdDate', // only returned by upsert & legacy createdNameField: 'createdName', // only returned by upsert & legacy lastmodDateField: 'modifiedDate', // only returned by upsert & legacy lastmodNameField: 'modifiedName', // only returned by upsert & legacy restPagination: true, maxKeyLength: 200, // confirmed max length scheduleTypeMapping: { MINUTELY: 1, HOURLY: 2, DAILY: 3, WEEKLY: 4, MONTHLY: 5, }, statusMapping: { AwaitingTrigger: 7, Building: 1, BuildingError: 0, Error: -1, InactiveTrigger: 8, PausedSchedule: 4, Ready: 2, Running: 3, Scheduled: 6, Stopped: 5, }, fileNameOperatorMapping: { Equals: 4, Contains: 1, 'Begins with': 2, 'Ends with': 3, }, timeZoneMapping: { // bugs in SFMC timezones: // * Yerevan GMT+4 always is changing to 'Caucasus Standard Time' GMT+4, so no id 29 // * La Paz GMT+4 is changing always to 'SA Western Standard Time' GMT-3, so no id 71 // * no ids 81 and 85, because two Mexican timezones in UI are showing with the suffix 'Old' 'Afghanistan Standard Time': 30, 'Alaskan Standard Time': 89, 'Arab Standard Time': 20, 'Arabian Standard Time': 25, 'Arabic Standard Time': 19, 'Argentina Standard Time': 65, 'Atlantic Standard Time': 70, 'AUS Central Standard Time': 51, 'AUS Eastern Standard Time': 53, 'Azerbaijan Standard Time': 26, 'Azores Standard Time': 61, 'Canada Central Standard Time': 82, 'Cape Verde Standard Time': 62, 'Caucasus Standard Time': 27, 'Cen. Australia Standard Time': 50, 'Central America Standard Time': 78, 'Central Asia Standard Time': 38, 'Central Brazilian Standard Time': 72, 'Central Europe Standard Time': 6, 'Central European Standard Time': 8, 'Central Pacific Standard Time': 57, 'Central Standard Time': 79, 'Central Standard Time (Mexico)': 80, 'Central Standard Time (no DST)': 1, 'China Standard Time': 42, 'Dateline Standard Time': 92, 'E. Africa Standard Time': 22, 'E. Australia Standard Time': 52, 'E. Europe Standard Time': 17, 'E. South America Standard Time': 64, 'Eastern Standard Time': 76, 'Egypt Standard Time': 13, 'Ekaterinburg Standard Time': 31, 'Fiji Standard Time': 59, 'FLE Standard Time': 15, 'Georgian Standard Time': 23, 'GMT Standard Time': 3, 'Greenland Standard Time': 67, 'Greenwich Standard Time': 4, 'GTB Standard Time': 11, 'Hawaiian Standard Time': 90, 'India Standard Time': 34, 'Iran Standard Time': 24, 'Israel Standard Time': 16, 'Jordan Standard Time': 10, 'Korea Standard Time': 48, 'Mauritius Standard Time': 28, 'Mid-Atlantic Standard Time': 63, 'Middle East Standard Time': 12, 'Montevideo Standard Time': 68, 'Morocco Standard Time': 2, 'Mountain Standard Time': 86, 'Mountain Standard Time (Mexico)': 84, 'Myanmar Standard Time': 39, 'N. Central Asia Standard Time': 37, 'Namibia Standard Time': 18, 'Nepal Standard Time': 36, 'New Zealand Standard Time': 58, 'Newfoundland Standard Time': 69, 'North Asia East Standard Time': 43, 'North Asia Standard Time': 41, 'Pacific SA Standard Time': 73, 'Pacific Standard Time': 87, 'Pacific Standard Time (Mexico)': 88, 'Pakistan Standard Time': 32, 'Romance Standard Time': 7, 'Russian Standard Time': 21, 'SA Pacific Standard Time': 75, 'SA Western Standard Time': 66, 'Samoa Standard Time': 91, 'SE Asia Standard Time': 40, 'Singapore Standard Time': 44, 'South Africa Standard Time': 14, 'Sri Lanka Standard Time': 35, 'Taipei Standard Time': 46, 'Tasmania Standard Time': 55, 'Tokyo Standard Time': 47, 'Tonga Standard Time': 60, 'US Eastern Standard Time': 77, 'US Mountain Standard Time': 83, 'Venezuela Standard Time': 74, 'Vladivostok Standard Time': 56, 'W. Australia Standard Time': 45, 'W. Central Africa Standard Time': 9, 'W. Europe Standard Time': 5, 'West Asia Standard Time': 33, 'West Pacific Standard Time': 54, 'Yakutsk Standard Time': 49, }, timeZoneDifference: { 1: '-06:00', 2: '+00:00', 3: '+00:00', 4: '+00:00', 5: '+01:00', 6: '+01:00', 7: '+01:00', 8: '+01:00', 9: '+01:00', 10: '+02:00', 11: '+02:00', 12: '+02:00', 13: '+02:00', 14: '+02:00', 15: '+02:00', 16: '+02:00', 17: '+02:00', 18: '+02:00', 19: '+03:00', 20: '+03:00', 21: '+03:00', 22: '+03:00', 23: '+03:00', 24: '+03:30', 25: '+04:00', 26: '+04:00', 27: '+04:00', 28: '+04:00', 29: '+04:00', 30: '+04:30', 31: '+05:00', 32: '+05:00', 33: '+05:00', 34: '+05:30', 35: '+05:30', 36: '+05:45', 37: '+06:00', 38: '+06:00', 39: '+06:30', 40: '+07:00', 41: '+07:00', 42: '+08:00', 43: '+08:00', 44: '+08:00', 45: '+08:00', 46: '+08:00', 47: '+09:00', 48: '+09:00', 49: '+09:00', 50: '+09:30', 51: '+09:30', 52: '+10:00', 53: '+10:00', 54: '+10:00', 55: '+10:00', 56: '+10:00', 57: '+11:00', 58: '+12:00', 59: '+12:00', 60: '+13:00', 61: '-01:00', 62: '-01:00', 63: '-02:00', 64: '-03:00', 65: '-03:00', 66: '-03:00', 67: '-03:00', 68: '-03:00', 69: '-03:30', 70: '-04:00', 71: '-04:00', 72: '-04:00', 73: '-04:00', 74: '-04:30', 75: '-05:00', 76: '-05:00', 77: '-05:00', 78: '-06:00', 79: '-06:00', 80: '-06:00', 81: '-06:00', 82: '-06:00', 83: '-07:00', 84: '-07:00', 85: '-07:00', 86: '-07:00', 87: '-08:00', 88: '-08:00', 89: '-09:00', 90: '-10:00', 91: '-11:00', 92: '-12:00', }, type: 'automation', typeDescription: 'Used via Automation Studio directly - or indirectly via Journey Builder & MC Connect.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation', customDeployTypes: ['wait'], manualDeployTypes: [], fields: { categoryId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileTrigger.fileNamePatternTypeId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileTrigger.fileNamingPattern': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileTrigger.folderLocationText': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileTrigger.isPublished': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileTrigger.queueFiles': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'fileTrigger.triggerActive': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, id: { isCreateable: false, isUpdateable: null, retrieving: true, template: false, }, key: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, lastRunInstanceId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, lastRunTime: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, legacyId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, lastSavedDate: { isCreateable: false, isUpdateable: false, retrieving: false, // only returned by upsert template: false, }, lastSavedByName: { isCreateable: false, isUpdateable: false, retrieving: false, // only returned by upsert template: false, }, createdByName: { isCreateable: false, isUpdateable: false, retrieving: false, // only returned by upsert template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, // only returned by upsert + legacy template: false, }, createdName: { isCreateable: false, isUpdateable: false, retrieving: true, // only returned by legacy template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, // only returned by legacy template: false, }, modifiedName: { isCreateable: false, isUpdateable: false, retrieving: true, // only returned by legacy template: false, }, pausedDate: { isCreateable: false, isUpdateable: false, retrieving: true, // only returned by legacy template: false, }, pausedName: { isCreateable: false, isUpdateable: false, retrieving: true, // only returned by legacy template: false, }, updateInProgress: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, notifications: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'notifications[].email': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'notifications[].message': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'notifications[].channelType': { // always 'Account' isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'notifications[].type': { // custom shorthand for channelType isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'notifications[].notificationType': { // Error, Complete isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, startSource: { skipValidation: true, }, 'schedule.endDate': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.icalRecur': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'schedule.occurrences': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'schedule.pattern': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'schedule.rangeTypeId': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'schedule.scheduledTime': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'schedule.scheduleStatus': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'schedule.startDate': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.statusId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'schedule.timezoneId': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'schedule.timezoneName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.typeId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'schedule.scheduleTypeId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'schedule.description': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, statusId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, steps: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'steps[].activities': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'steps[].activities[].activityObjectId': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'steps[].activities[].displayOrder': { // we remove it during post-processing but need to ensure the array order equals the displayOrder isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'steps[].activities[].id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'steps[].activities[].name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'steps[].activities[].objectTypeId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'steps[].activities[].targetDataExtensions': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'steps[].activities[].description': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'steps[].activities[].serializedObject': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'steps[].activities[].r__type': { skipValidation: true, }, 'steps[].activities[].r__key': { skipValidation: true, }, 'steps[].activities[].timeZone': { // used for wait actitivity isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'steps[].description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'steps[].annotation': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'steps[].id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'steps[].name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'steps[].step': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'steps[].stepNumber': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, type: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, typeId: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, r__folder_Path: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Campaign.definition.js ================================================ export default { bodyIteratorField: 'entry', dependencies: [], dependencyGraph: null, hasExtended: false, idField: 'id', keepId: true, keyIsFixed: true, keyField: 'name', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'lastUpdated', lastmodNameField: null, restPagination: true, restPageSize: 50, type: 'campaign', typeDescription: 'Way of tagging/categorizing emails, journeys and alike.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Campaign Tag', fields: { id: { // alphanumeric string isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, campaignId: { // numeric isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, type: { // always set to "Campaign" isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, createdBy: { // returns https://mc....rest.marketingcloudapis.com/legacy/v1/beta/organization/user/Nzc1MTU2ODo0OjA isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ownerId: { // returns https://mc....rest.marketingcloudapis.com/legacy/v1/beta/organization/user/Nzc1MTU2ODo0OjA isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, lastUpdated: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, name: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, description: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, externalKey: { // can be empty - should use "name" instead as key isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, campaignCode: { // always empty string; real value is in field "externalKey" isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'display.name': { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, 'display.value': { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, isFavorite: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, campaignOwnerName: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, campaignOwner: { // value like "MDo0OjE" isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, campaignStatus: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/ContentArea.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: ['folder'], dependencyGraph: null, hasExtended: false, idField: 'ID', keepId: true, keyIsFixed: true, keyField: 'CustomerKey', nameField: 'Name', folderIdField: 'CategoryID', restPagination: null, type: 'contentArea', typeDescription: 'DEPRECATED: Old way of saving Content Blocks; please migrate these to new Content Blocks (`Asset: ...`).', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Content Area (Classic)', fields: { // https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/contentarea.htm BackgroundColor: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, BorderColor: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, BorderWidth: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CategoryID: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Cellpadding: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Cellspacing: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Content: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, CorrelationID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, CustomerKey: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, FontFamily: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, HasFontSize: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ID: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, IsBlank: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, IsDynamicContent: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, IsLocked: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IsSurvey: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Key: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Layout: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Name: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ObjectID: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Owner: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Width: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataExtension.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [ 'folder-hidden', 'folder-dataextension', 'folder-salesforcedataextension', 'folder-shared_data', 'folder-shared_dataextension', 'folder-shared_salesforcedataextension', 'folder-synchronizeddataextension', 'dataExtensionTemplate', ], dependencyGraph: null, // dataExtensionTemplate cannot be deployed folderType: 'dataextension', filter: { CustomerKey: [ 'Einstein_MC_Email_Frequency_Oversaturation', 'Einstein_MC_Email_Frequency_Undersaturation', 'Einstein_MC_Predictive_Scores', 'IGO_PRODUCTATTRIBS', 'IGO_PRODUCTS', 'IGO_PROFILES', 'IGO_PURCHASES', 'IGO_VIEWS', 'PI_ABANDONED_CART_EVENT', 'PI_ABANDONED_CART_ITEMS', 'PI_CONTENT', 'PI_CONTENTATTRIBS', 'PI_CONTENTVIEWS', 'PI_SESSION_ENDS', 'PI_SESSIONS', 'PI_TRIGGEREVENT', 'PI_TRIGGEREVENTDETAIL', 'PREDICTIVE_SCORES', ], Name: [ '_ChatMessagingSubscription', '_EnterpriseAttribute', '_MobileAddress', '_MobileAddressApplication', '_MobileLineAddress', '_MobileLineAddressContact', '_MobileLineProfile', '_MobileLineProfileAttribute', '_MobileLineSubscription', '_MobileSubscription', '_PushAddress', '_PushTag', 'CloudPages_DataExtension', 'ExpressionBuilderAttributes', 'MobileLineOrphanContact', 'SocialPages_DataExtension', ], }, templateFields: { AudienceBuilderResult: [ 'SubscriberKey', 'CustomerKey', 'AudienceId', 'TrackingCode', 'AudienceCode', 'SegmentCode', 'SegmentName', 'Priority', 'SegmentID', 'SplitID', 'SplitName', 'SplitCode', 'SendGroupID', ], CONTEXTUAL_SUPPRESSION_LISTS: ['Email Address', 'Date Added'], DomainExclusion: ['Domain'], 'Event DE Template': ['EventInstanceID', 'ParentEventInstanceID', 'ContactKey'], PushSendLog: [ 'PushJobID', 'PushTriggeredSendRequestID', 'PushBatchID', 'SubID', 'DeviceId', 'AppId', 'LogDate', ], SendLog: ['JobID', 'ListID', 'BatchID', 'SubID', 'TriggeredSendID', 'ErrorCode'], 'SmartCapture - Contacts Template Extension': ['Source', 'EmailAddress', 'CreateDate'], SmsSendLog: ['SmsJobID', 'SmsTriggeredSendID', 'SmsBatchID', 'SubID'], SMSMessageTracking: null, // CustomerKey cannot be retrieved SMSSubscriptionLog: null, // CustomerKey cannot be retrieved TriggeredSendDataExtension: ['SubscriberKey', 'EmailAddress'], }, dataRetentionPeriodUnitOfMeasureMapping: { Days: 3, Weeks: 4, Months: 5, Years: 6, }, hasExtended: false, idField: 'ObjectID', keyIsFixed: false, keyField: 'CustomerKey', nameField: 'Name', folderIdField: 'CategoryID', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: null, restPagination: false, maxKeyLength: 200, // confirmed max length type: 'dataExtension', typeDescription: 'Database table schemas.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Data Extension', fields: { CategoryID: { isCreateable: null, isUpdateable: null, retrieving: true, template: true, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CreatedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DataRetentionPeriod: { // not used isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, DataRetentionPeriodLength: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DataRetentionPeriodUnitOfMeasure: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DeleteAtEndOfRetentionPeriod: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, Description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, Fields: { skipValidation: true, }, folderContentType: { skipValidation: true, }, IsPlatformObject: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, IsSendable: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, IsTestable: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ModifiedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ResetRetentionPeriodOnImport: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, RetainUntil: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, RowBasedRetention: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'SendableDataExtensionField.Name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'SendableDataExtensionField.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'SendableDataExtensionField.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, SendableSubscriberField: { skipValidation: true, }, 'SendableSubscriberField.Name': { // '_SubscriberKey' needs to be replaced with 'Subscriber Key' isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, Status: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'Template.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'Template.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'Template.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, r__folder_ContentType: { skipValidation: true, }, r__folder_Path: { skipValidation: true, }, r__dataExtensionTemplate_name: { skipValidation: true, }, c__retentionPolicy: { skipValidation: true, }, c__retainUntil: { skipValidation: true, }, c__dataRetentionPeriodUnitOfMeasure: { skipValidation: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataExtensionField.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: ['dataExtension'], dependencyGraph: null, filter: {}, hasExtended: false, idField: 'ObjectID', keyIsFixed: true, // renamed via name_new on dataExtension update keyField: 'CustomerKey', nameField: 'Name', restPagination: false, type: 'dataExtensionField', typeDescription: 'Internal Type: Fields for type dataExtension.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Data Extension Field', deleteSynchronously: true, // should be run one at a time to allow asking for permission to mass-delete if *.fieldname is used fields: { 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'DataExtension.CustomerKey': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'DataExtension.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'DataExtension.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, DefaultValue: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, FieldType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, IsPrimaryKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, IsRequired: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, MaxLength: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, Ordinal: { isCreateable: true, isUpdateable: true, // Ignored on update for existing fields but respected for the order of amended new fields. to re-order existing fields, delete DE on target & recreate retrieving: true, template: true, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Scale: { isCreateable: true, isUpdateable: true, // Doesnt work for decimal field updates retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataExtensionTemplate.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [], dependencyGraph: null, filter: {}, hasExtended: false, idField: 'ObjectID', keyIsFixed: true, keyField: 'CustomerKey', nameField: 'Name', restPagination: false, type: 'dataExtensionTemplate', typeDescription: 'Templates used for special DE use cases like Triggered Send.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Data Extension Template', fields: { 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CustomerKey: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, ObjectID: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, Name: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, Description: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, IsSendable: { isCreateable: false, isUpdateable: false, retrieving: true, template: false }, IsTestable: { isCreateable: false, isUpdateable: false, retrieving: true, template: false }, SendableCustomObjectField: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, SendableSubscriberField: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, DataRetentionPeriodLength: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, DataRetentionPeriodUnitOfMeasure: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, RowBasedRetention: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, ResetRetentionPeriodOnImport: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, DeleteAtEndOfRetentionPeriod: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, RetainUntil: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataExtract.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['dataExtension', 'dataExtractType', 'user'], dependencyGraph: { dataExtension: ['r__dataExtension_key'], }, hasExtended: true, idField: 'dataExtractDefinitionId', keyIsFixed: false, keyField: 'key', createdDateField: 'createdDate', createdNameField: 'createdBy', lastmodDateField: 'modifiedDate', lastmodNameField: 'modifiedBy', nameField: 'name', restPagination: true, maxKeyLength: 36, // confirmed max length type: 'dataExtract', typeDescription: 'Creates zipped files in your FTP directory or convert XML into CSV.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: Data Extract Activity', fields: { createdBy: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, dataExtractDefinitionId: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, dataExtractTypeId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, dataFields: { skipValidation: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, endDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fileSpec: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, intervalType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, key: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, modifiedBy: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, startDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__dataExtractType_name: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataExtractType.definition.js ================================================ export default { bodyIteratorField: '', dependencies: [], dependencyGraph: null, hasExtended: false, idField: 'extractId', keyIsFixed: true, keyField: 'name', nameField: 'name', restPagination: false, type: 'dataExtractType', typeDescription: 'Types of Data Extracts enabled for a specific business unit. This normally should not be stored.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Data Extract Type', fields: { name: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, extractId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataFilter.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['folder-filterdefinition', 'folder-hidden', 'dataExtension'], dependencyGraph: { dataExtension: ['r__source_dataExtension_key'], }, filter: {}, hasExtended: false, idField: 'id', keyIsFixed: false, keyField: 'key', nameField: 'name', folderType: 'filterdefinition', folderIdField: 'categoryId', createdDateField: 'createdDate', createdNameField: 'createdBy', lastmodDateField: 'lastUpdated', lastmodNameField: 'lastUpdatedBy', restPagination: true, restPageSize: 100, maxKeyLength: 36, // confirmed max length type: 'dataFilter', soapType: 'FilterDefinition', typeDescription: 'Defines an audience based on specified rules. Used by Filter Activities.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Data Filter', fields: { // the GUI seems to ONLY send fields during update that are actually changed. It has yet to be tested if that also works with sending other fiedls as well id: { isCreateable: false, isUpdateable: false, // included in URL retrieving: false, template: false, }, key: { isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, createdBy: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, owner: { // equal to createdBy isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, createdByName: { // actual name of user indicated by id in createdBy isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, lastUpdated: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, lastUpdatedBy: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, lastUpdatedByName: { // actual name of user indicated by id in lastUpdatedBy isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, categoryId: { // returned by GET / CREATE / UPDATE; used in CREATE payload isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, filterDefinitionXml: { isCreateable: true, isUpdateable: true, // this is the only field that can be updated retrieving: true, template: true, }, // DerivedFromType: { // // this upper-cased spelling is used by GUI when creating a dataExtension based filterDefintion // isCreateable: true, // isUpdateable: false, // cannot be updated // retrieving: false, // template: false, // }, derivedFromType: { // 1: SubscriberAttributes, 2: DataExtension, 6: EntryCriteria; isCreateable: true, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, derivedFromObjectId: { // dataExtension ID or '00000000-0000-0000-0000-000000000000' for lists isCreateable: true, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, derivedFromObjectTypeName: { // "SubscriberAttributes" | "DataExtension" | "EntryCriteria" ...; only returned by GET API isCreateable: false, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, derivedFromObjectName: { // dataExtension name; field only returned by GET-API isCreateable: false, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, isSendable: { isCreateable: false, // automatically set during create isUpdateable: false, // cannot be updated retrieving: true, template: true, }, r__source_dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, c__filterDefinition: { skipValidation: true, }, r__folder_Path: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DataFilterHidden.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['folder-filterdefinition', 'folder-hidden', 'dataExtension'], dependencyGraph: { dataExtension: ['r__source_dataExtension_key'], }, filter: {}, hasExtended: false, idField: 'id', keyIsFixed: false, keyField: 'key', nameField: 'name', folderType: 'filterdefinition', folderIdField: 'categoryId', createdDateField: 'createdDate', createdNameField: 'createdBy', lastmodDateField: 'lastUpdated', lastmodNameField: 'lastUpdatedBy', restPagination: true, restPageSize: 100, maxKeyLength: 36, // confirmed max length type: 'dataFilterHidden', soapType: 'FilterDefinition', typeDescription: 'Defines an audience based on specified rules. Auto-generated by filtered DEs and filtered Lists.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Data Filter (auto-generated)', fields: { // the GUI seems to ONLY send fields during update that are actually changed. It has yet to be tested if that also works with sending other fiedls as well id: { isCreateable: false, isUpdateable: false, // included in URL retrieving: false, template: false, }, key: { isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, createdBy: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, owner: { // equal to createdBy isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, createdByName: { // actual name of user indicated by id in createdBy isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, lastUpdated: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, lastUpdatedBy: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, lastUpdatedByName: { // actual name of user indicated by id in lastUpdatedBy isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, categoryId: { // returned by GET / CREATE / UPDATE; used in CREATE payload isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, // can be updated retrieving: true, template: true, }, filterDefinitionXml: { isCreateable: true, isUpdateable: true, // this is the only field that can be updated retrieving: true, template: true, }, // DerivedFromType: { // // this upper-cased spelling is used by GUI when creating a dataExtension based filterDefintion // isCreateable: true, // isUpdateable: false, // cannot be updated // retrieving: false, // template: false, // }, derivedFromType: { // 1: SubscriberAttributes, 2: DataExtension, 6: EntryCriteria; isCreateable: true, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, derivedFromObjectId: { // dataExtension ID or '00000000-0000-0000-0000-000000000000' for lists isCreateable: true, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, derivedFromObjectTypeName: { // "SubscriberAttributes" | "DataExtension" | "EntryCriteria" ...; only returned by GET API isCreateable: false, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, derivedFromObjectName: { // dataExtension name; field only returned by GET-API isCreateable: false, isUpdateable: false, // cannot be updated retrieving: true, template: true, }, isSendable: { isCreateable: false, // automatically set during create isUpdateable: false, // cannot be updated retrieving: true, template: true, }, r__source_dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, c__filterDefinition: { skipValidation: true, }, r__folder_Path: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DeliveryProfile.definition.js ================================================ export default { bodyIteratorField: 'entry', dependencies: [], dependencyGraph: null, filter: {}, hasExtended: false, idField: 'id', keyField: 'key', keyIsFixed: false, maxKeyLength: 36, // confirmed max length nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'lastUpdated', lastmodNameField: null, restPagination: false, type: 'deliveryProfile', typeDescription: 'Delivery profiles specify details such as IP address, domain, header inclusion, and footer; Via API we can only check for their existence but not see any details.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Delivery Profile', fields: { id: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, key: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, lastUpdated: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Discovery.definition.js ================================================ export default { bodyIteratorField: null, dependencies: [], dependencyGraph: null, endPointMapping: { Address: '/address/v1/rest', Asset: '/asset/v1/rest', Automation: '/automation/v1/rest', Contacts: '/contacts/v1/rest', Data: '/data/v1/rest', Device: '/device/v1/rest', Email: '/email/v1/rest', Guide: '/guide/v1/rest', Hub: '/hub/v1/rest', Interaction: '/interaction/v1/rest', 'Interaction-Experimental': '/interaction-experimental/v1/rest', Legacy: '/legacy/v1/rest', Messaging: '/messaging/v1/rest', 'Messaging-Experimental': '/messaging-experimental/v1/rest', OTT: '/ott/v1/rest', 'OTT-Experimental': '/ott/v1/rest/experimental', Platform: '/platform/v1/rest', 'Platform-Experimental': '/platform/v1/rest/experimental', Provisioning: '/provisioning/v1/rest', Push: '/push/v1/rest', SMS: '/sms/v1/rest', }, hasExtended: false, idField: '', keyIsFixed: true, keyField: 'key', nameField: 'name', restPagination: false, type: 'discovery', typeDescription: 'Description of all API endpoints accessible via REST API; only relevant for developers of Accenture SFMC DevTools.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'API Discovery', fields: { basePath: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, baseUrl: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, description: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, discoveryVersion: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, documentationLink: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, id: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, key: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, kind: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, methods: { skipValidation: true, }, metadata: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metadata.supportsResponseEncoding': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, protocol: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, resources: { skipValidation: true, }, rootUrl: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, schemas: { skipValidation: true, }, servicePath: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, title: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, version: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/DomainVerification.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: [], dependencyGraph: null, hasExtended: false, idField: 'domain', keyIsFixed: true, // you can only change the "isSendable" property keyField: 'domain', createdDateField: null, createdNameField: null, lastmodDateField: null, lastmodNameField: null, nameField: 'domain', restPagination: true, maxKeyLength: 254, // assumed max length type: 'domainVerification', typeDescription: 'Domains emails that are verified for sending', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Domain Verification', fields: { domain: { isCreateable: true, isUpdateable: false, retrieving: true, template: true, }, emailAddress: { // this is the same as domain, but the update API uses this field name instead isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, enterpriseId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, memberId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, domainType: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, isSendable: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, status: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, emailSendTime: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Email.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: ['folder-hidden', 'folder-email', 'folder-shared_email_default'], dependencyGraph: null, hasExtended: false, idField: 'ID', keepId: true, keyIsFixed: true, keyField: 'CustomerKey', nameField: 'Name', folderIdField: 'CategoryID', restPagination: null, type: 'email', typeDescription: 'DEPRECATED: Old way of saving E-Mails; please migrate these to new E-Mail (`Asset: message`).', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'E-Mail (Classic)', fields: { CategoryID: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, CharacterSet: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'Client.PartnerClientKey': { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ClonedFromID: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ContentAreas: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, 'ContentAreas.CategoryID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.Content': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.CustomerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.IsBlank': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.IsDynamicContent': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.IsLocked': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.IsSurvey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.Key': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.Name': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].CategoryID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].Content': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].CustomerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].IsBlank': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].IsDynamicContent': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].IsLocked': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].IsSurvey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].Key': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].Name': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'ContentAreas[].PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ContentCheckStatus: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, CustomerKey: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, EmailType: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Folder: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, HasDynamicSubjectLine: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, HTMLBody: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ID: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, IsActive: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, IsHTMLPaste: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Name: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, ObjectID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, PreHeader: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Status: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, Subject: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, SyncTextWithHTML: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, TextBody: { isCreateable: false, isUpdateable: false, retrieving: true, templating: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/EmailSend.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [ 'folder-userinitiatedsends', 'email', 'asset-message', 'dataExtension', 'list', 'sendClassification', 'senderProfile', 'deliveryProfile', ], // filter(+) dependencyGraph: { asset: ['r__asset_key'], dataExtension: ['SendDefinitionList.r__dataExtension_key'], deliveryProfile: ['r__deliveryProfile_key'], list: ['SendDefinitionList.r__list_PathName'], sendClassification: ['r__sendClassification_key'], senderProfile: ['r__senderProfile_key'], }, folderType: 'userinitiatedsends', hasExtended: false, idField: 'ObjectID', keepId: true, keyIsFixed: false, keyField: 'CustomerKey', nameField: 'Name', folderIdField: 'CategoryID', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: null, restPagination: null, maxKeyLength: 36, // confirmed max length type: 'emailSend', soapType: 'emailSendDefinition', typeDescription: 'Mainly used in Automations as "Send Email Activity".', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'E-Mail Send Definition', fields: { Additional: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, AutoBccEmail: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, BccEmail: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, CategoryID: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, CCEmail: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CorrelationID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CreatedDate: { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, DeduplicateByEmail: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'DeliveryProfile.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'DeliveryProfile.DomainType': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.FooterContentArea.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.FooterSalutationSource': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.HeaderContentArea.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.HeaderSalutationSource': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.PrivateDomain': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'DeliveryProfile.PrivateIP': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'DeliveryProfile.SourceAddressType': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, DeliveryScheduledTime: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Description: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, DomainType: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, DynamicEmailSubject: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'Email.ID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'Email.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'Email.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'Email.Name': { isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, 'Email.Subject': { isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, 'Email.Status': { isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, EmailSubject: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, ExclusionFilter: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, FooterContentArea: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, FooterSalutationSource: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, FromAddress: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, FromName: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, HeaderContentArea: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, HeaderSalutationSource: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IntegratedTracking: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, InteractionObjectID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IsMultipart: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, IsPlatformObject: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, IsSeedListSend: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IsSendLogging: { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, IsWrapped: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, Keyword: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, MessageDeliveryType: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ModifiedDate: { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: false, templating: false, }, ObjectState: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Owner: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PreHeader: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PrivateDomain: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PrivateIP: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ReplyToAddress: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ReplyToDisplayName: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SeedListOccurance: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendClassification.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'SendClassification.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendClassification.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendDefinitionList.CustomObjectID': { isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, SendDefinitionList: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'SendDefinitionList[].ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendDefinitionList[].PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendDefinitionList[].CustomObjectID': { skipValidation: true, // cannot be asked for but will be retrieved }, 'SendDefinitionList[].SendDefinitionListType': { skipValidation: true, // cannot be asked for but will be retrieved }, 'SendDefinitionList[].DataSourceTypeID': { skipValidation: true, // cannot be asked for but will be retrieved }, 'SendDefinitionList[].IsTestObject': { skipValidation: true, // cannot be asked for but will be retrieved }, 'SendDefinitionList[].SalesForceObjectID': { skipValidation: true, // cannot be asked for but will be retrieved }, 'SendDefinitionList[].Name': { skipValidation: true, // cannot be asked for but will be retrieved }, 'SendDefinitionList[].r__dataExtension_key': { skipValidation: true, }, 'SendDefinitionList[].List.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendDefinitionList[].List.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendDefinitionList[].r__list_PathName': { skipValidation: true, }, 'SenderProfile.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'SenderProfile.FromAddress': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SenderProfile.FromName': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SenderProfile.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SenderProfile.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SendLimit: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, SendWindowClose: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, SendWindowDelete: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SendWindowOpen: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, SourceAddressType: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SuppressTracking: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, TestEmailAddr: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, TimeZone: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, TrackingUsers: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, r__asset_name_readOnly: { skipValidation: true }, r__asset_key: { skipValidation: true }, r__email_name: { skipValidation: true }, r__folder_Path: { skipValidation: true }, r__senderProfile_key: { skipValidation: true }, r__sendClassification_key: { skipValidation: true }, r__deliveryProfile_key: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Event.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['automation', 'dataExtension', 'dataExtensionField', 'user'], dependencyGraph: { automation: ['r__automation_key'], dataExtension: ['r__dataExtension_key'] }, hasExtended: false, idField: 'id', keyIsFixed: false, keyField: 'eventDefinitionKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: 'createdBy', lastmodDateField: 'modifiedDate', lastmodNameField: 'modifiedBy', restPagination: true, maxKeyLength: 200, // confirmed max length type: 'event', typeDescription: 'Used in Journeys (Interactions) to define Entry Events.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Journey: Entry Event Definition', validTypes: [ 'EmailAudience', // category: Audience; DEAudience-... 'AutomationAudience', // category: Audience; DEAudience-... 'APIEvent', // category: Event; APIEvent-... 'SalesforceObjectTriggerV2', // category: Event; SalesforceObj... ], fields: { 'arguments.audienceCount': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.audienceDefinitionID': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.audienceDescription': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.audienceSource': { skipValidation: true, }, 'arguments.audienceName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.automationId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.buildAudienceDefinitionID': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.contactAttributeGroup': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.contactAttributeId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.contactAttributeName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.criteria': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.dataExtensionId': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'arguments.dataTargetName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.formName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.dateOffset': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.dateOffsetUnit': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.dateType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.eid': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.eventDefinitionId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'arguments.eventDefinitionKey': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'arguments.mid': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.resetHighWatermark': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.serializedObjectType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.transactionKeyDataExtension': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.transactionKeyEvent': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'arguments.useHighWatermark': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, automationId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, category: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, configurationArguments: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.applicationExtensionKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.contactKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.contactKey.relationshipIdName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.contactKey.relationshipName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.contactKey.isPolymorphic': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.contactKey.referenceObjectName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.contactPersonType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.dataExtensionId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'configurationArguments.evaluationCriteriaSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.eventDataConfig': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.eventDataConfig.objects': { skipValidation: true, }, 'configurationArguments.eventDataSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.objectAPIName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.passThroughArgument': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.passThroughArgument.fields': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.passThroughArgument.fields.ContactKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.passThroughArgument.fields.Email': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.primaryObjectFilterCriteria': { skipValidation: true, }, 'configurationArguments.primaryObjectFilterSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.relatedObjectFilterCriteria': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.relatedObjectFilterSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.salesforceTriggerCriteria': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.unconfigured': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'configurationArguments.version': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'configurationArguments.whoToInject': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdBy: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, dataExtensionId: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, dataExtensionName: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, disableDEDataLogging: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, eventDefinitionKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, filterDefinitionId: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, filterDefinitionTemplate: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, iconUrl: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, id: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, interactionCount: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, isPlatformObject: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, isVisibleInPicker: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.attributeName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.automationType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.categoryId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.createdBy.email': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.createdBy.id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.createdBy.name': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.createdDate': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.folderPath': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.guidId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.id': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.isPlatformObject': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.key': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.lastRunInstance': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.lastRunTime': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.lastSaveDate': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.lastSavedBy.email': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.lastSavedBy.id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.lastSavedBy.name': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.memberId': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'metaData.automationData.modifiedDate': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.notifications': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.processes': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.schedule': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.createdBy': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.scheduleObject.createdDate': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.scheduleObject.description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.iCalRecur': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.id': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.scheduleObject.key': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.scheduleObject.lastUpdated': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.scheduleObject.lastUpdatedBy': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.automationData.scheduleObject.name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.scheduleState': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.scheduleStatus': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.startDate': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.timeZone': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduleObject.timeZoneId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.scheduledTime': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.selectedCategoryId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.selectedCategoryId[]': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.automationData.status': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.automationData.updateInProgress': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'metaData.criteriaDescription': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.customAttributeName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.formattedDate': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.formattedTime': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.icon': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.original_icon': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.isConfigured': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.runOnceScheduleMode': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.scheduleFlowMode': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.scheduleState': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.timeZone': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.transactionKeys': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.transactionKeys.0': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.transactionKeys.0.from': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'metaData.transactionKeys.0.to': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, mode: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, modifiedBy: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, publishedInteractionCount: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'schedule.scheduledDayOfWeek': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.scheduledWeek': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.endDateTime': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.endType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.frequency': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.interval': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.occurrences': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.recurrencePattern': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.scheduledDay': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.startDateTime': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.timeZone': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.monday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.tuesday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.wednesday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.thursday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.friday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.saturday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schedule.sunday': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].dataType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].defaultValue': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].isDevicePreference': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].isNullable': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].isPrimaryKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].maxLength': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.fields[].name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.id': { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, 'schema.name': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'schema.sendableCustomObjectField': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.sendableSubscriberField': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'schema.isPlatformObject': { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, sourceApplicationExtensionId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, entrySourceGroupConfigUrl: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, type: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__automation_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/FileLocation.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: [], dependencyGraph: null, hasExtended: false, idField: 'id', keyIsFixed: true, keyField: 'customerKey', nameField: 'name', createdDateField: null, createdNameField: null, lastmodDateField: null, lastmodNameField: null, restPagination: false, maxKeyLength: 36, // confirmed max length type: 'fileLocation', typeDescription: 'Used for export or import of files to/from Marketing Cloud. Previously this was labeled ftpLocation.', typeRetrieveByDefault: true, typeCdpByDefault: false, typeName: 'File Location', locationTypeMapping: { 'Enhanced FTP Site Import Directory': 0, 'External FTP Site': 1, 'External SFTP Site': 2, 'External FTPS Site': 3, 'Salesforce Objects and Reports': 4, Safehouse: 5, 'Enhanced FTP Site Export Directory': 6, 'Legacy Import Directory': 8, 'Relative location under FTP Site': 9, 'Amazon Simple Storage Service': 13, 'Azure Blob Storage': 15, 'Google Cloud Storage': 16, }, locationTypeMappingDeployable: { 'External SFTP Site': 'ExternalSftp', 'Amazon Simple Storage Service': 'AmazonSimpleStorage', 'Azure Blob Storage': 'AzureBlobStorage', 'Google Cloud Storage': 'GcpBlobStorage', }, locationTypeIdMappingDeployable: { 2: 'ExternalSftp', 13: 'AmazonSimpleStorage', 15: 'AzureBlobStorage', 16: 'GcpBlobStorage', }, fields: { id: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, locationTypeId: { // automation endpoint isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, locationType: { // data endpoint isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, locationUrl: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, customerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, relPath: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, awsFileTransferLocation: { skipValidation: true, }, azureFileTransferLocation: { skipValidation: true, }, gcpFileTransferLocation: { skipValidation: true, }, sFtpFileTransferLocation: { skipValidation: true, }, c__locationType: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/FileTransfer.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['fileLocation'], dependencyGraph: { // fileLocation cannot be deployed // fileLocation: ['metadata.source.r__fileLocation_name'], }, hasExtended: true, idField: 'id', keyIsFixed: false, keyField: 'customerKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, type: 'fileTransfer', typeDescription: 'Unzip, decrypt a file or move a file from secure location into FTP directory.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: File Transfer Activity', fields: { createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, customerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fileSpec: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fileTransferLocationId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, id: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, isCompressed: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isEncrypted: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isFileSpecLocalized: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isPgp: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isUpload: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxFileAge: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxFileAgeScheduleOffset: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxImportFrequency: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, publicKeyManagementId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__fileLocation_name: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Filter.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: [ 'dataFilter', 'dataFilterHidden', 'list', 'dataExtension', 'folder-filteractivity', 'folder-hidden', ], dependencyGraph: { dataFilter: ['r__dataFilter_key'], dataExtension: ['r__source_dataExtension_key', 'r__destination_dataExtension_key'], }, hasExtended: false, idField: 'filterActivityId', keyIsFixed: true, keyField: 'customerKey', nameField: 'name', folderType: 'filteractivity', folderIdField: 'categoryId', filter: { statusId: 0, // exclude deleted filters }, createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, maxKeyLength: 36, // confirmed max length type: 'filter', soapType: 'FilterActivity', typeDescription: 'Used in automations to filter lists and DEs. Depends on type "DataFilter".', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: Filter Activity', fields: { // https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/filteractivity.htm categoryId: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, customerKey: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, CustomerKey: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, description: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, Description: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, destinationObjectId: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, DestinationObjectID: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, destinationTypeId: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, DestinationTypeID: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, filterActivityId: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, filterDefinitionId: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, FilterDefinitionID: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, Name: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, sourceObjectId: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, SourceObjectID: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, sourceTypeId: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, SourceTypeID: { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, filterDefinitionSourceTypeId: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, statusId: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, resultDEName: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, resultDEKey: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, resultDEDescription: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, r__folder_Path: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__dataFilter_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__source_dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__destination_dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Folder.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [], dependencyGraph: null, subTypes: [ 'asset-shared', 'asset', 'automations', 'contextual_suppression_list', 'cloudpages', 'dataextension', 'filteractivity', 'filterdefinition', 'hidden', 'journey', 'list', 'mysubs', 'publication', 'queryactivity', 'salesforcedataextension', 'shared_content', 'shared_data', 'shared_dataextension', 'shared_email', 'shared_item', 'shared_portfolio', 'shared_publication', 'shared_salesforcedataextension', 'shared_suppression_list', 'shared_template', 'ssjsactivity', 'suppression_list', 'synchronizeddataextension', 'triggered_send_journeybuilder', 'triggered_send', ], deployFolderTypes: [ // lower-case values! 'asset', 'automations', 'cloudpages', 'dataextension', 'filteractivity', 'filterdefinition', 'journey', 'list', 'mysubs', 'publication', 'queryactivity', 'salesforcedataextension', 'shared_dataextension', 'shared_salesforcedataextension', 'ssjsactivity', 'suppression_list', 'synchronizeddataextension', 'triggered_send_journeybuilder', 'triggered_send', ], deployFolderTypesEmailRest: ['automations', 'journey', 'triggered_send_journeybuilder'], deployFolderTypesAssetRest: ['cloudpages', 'asset', 'asset-shared'], deployFolderBlacklist: [ // lower-case values! 'shared data extensions', 'shared salesforce data extensions', ], folderTypesFromParent: [ 'asset-shared', 'asset', 'shared_content', 'shared_data', 'shared_dataextension', 'shared_email', 'shared_item', 'shared_portfolio', 'shared_publication', 'shared_salesforcedataextension', 'shared_suppression_list', 'shared_template', 'synchronizeddataextension', ], hasExtended: false, idField: 'ID', keepId: true, keyIsFixed: true, keyField: 'CustomerKey', nameField: 'Name', restPagination: false, type: 'folder', soapType: 'DataFolder', typeDescription: 'Used to structure all kinds of other metadata.', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Folder', fields: { $: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, '@_xsi:type': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ID: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, Description: { isCreateable: true, isUpdateable: false, // dont update this to prevent accidental overrides by auto-created folders retrieving: true, template: false, }, description: { // used for cloudpages folders only isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, ContentType: { isCreateable: true, isUpdateable: false, retrieving: true, template: true, }, categoryType: { // REST only, used for cloudpages folders only isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, catType: { // REST only, equal to SOAP's ContentType isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, IsActive: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, IsEditable: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, editable: { // used for cloudpages folders only isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, AllowChildren: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, extendable: { // used for cloudpages folders only isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, ObjectID: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, objectId: { // REST only, equal to SOAP's ObjectID // automation/journey folders only isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, name: { // REST only, equal to SOAP's Name // cloudpages and automation/journey folders only isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'ParentFolder.CustomerKey': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'ParentFolder.ID': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, parentCatId: { // REST only, used for journey/automation folders, equal to SOAP's ParentFolder.ID isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, parentId: { // REST only, used for cloudpages folders, equal to SOAP's ParentFolder.ID isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'ParentFolder.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'ParentFolder.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'ParentFolder.Path': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Path: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, _generated: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/ImportFile.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['fileLocation', 'dataExtension', 'list', 'mobileKeyword'], dependencyGraph: { // fileLocation cannot be deployed // fileLocation: ['source.r__fileLocation_name'], dataExtension: ['destination.r__dataExtension_key', 'source.r__dataExtension_key'], list: ['destination.r__list_PathName'], mobileKeyword: ['destination.r__mobileKeyword_key'], }, destinationObjectTypeMapping: { unknown: 783, DataExtension: 310, List: 13, SMS: 584, Push: 613, WhatsApp: 2600, }, hasExtended: true, idField: 'importDefinitionId', keyIsFixed: false, keyField: 'customerKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, restPageSize: 100, restConcurrentLimit: 2, subscriberImportTypeMapping: { DataExtension: 255, Email: 0, }, maxKeyLength: 36, // confirmed max length type: 'importFile', typeDescription: 'Reads files in FTP directory for further processing.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: Import File Activity', updateTypeMapping: { Add: 1, AddUpdate: 0, Overwrite: 4, Update: 2, }, blankFileProcessingTypeMapping: { Fail: 0, Process: 1, Skip: 2, }, fields: { allowErrors: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, blankFileProcessingType: { // only visible if retrieved with ID isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, customerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, dateFormatLocale: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, deleteFile: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, destinationId: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, destinationName: { // only visible if retrieved with ID isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, destinationObjectId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, destinationObjectTypeId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, encodingName: { // only visible if retrieved with ID isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fieldMappingType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fieldMappings: { skipValidation: true, }, fileNamingPattern: { // for FTP-import: pattern to look for; for DE-import: "_CustomObject" isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fileSpec: { // same as fileNamingPattern isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fileTransferLocationId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, fileTransferLocationName: { // only visible if retrieved with ID isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, fileTransferLocationTypeId: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, fileType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, filter: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, hasColumnHeader: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, importDefinitionId: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, isOrderedImport: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isSequential: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxFileAgeHours: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxFileAgeScheduleOffsetHours: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, maxImportFrequencyHours: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, }, notificationEmailAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, otherDelimiter: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, sendEmailNotification: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, standardQuotedStrings: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, subscriberImportTypeId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, updateTypeId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, sourceCustomObjectId: { // for FTP-import: empty string; for DE-import: dataExtension id isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, sourceDataExtensionName: { // for FTP-import: empty string; for DE-import: dataExtension name isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, c__dataAction: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'destination.r__mobileKeyword_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'source.r__dataExtension_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'destination.r__dataExtension_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'source.c__type': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'destination.c__type': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'destination.r__list_PathName': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'source.r__fileLocation_name': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, c__subscriberImportType: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, c__blankFileProcessing: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Journey.definition.js ================================================ // overview: https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/jb-api-specification.html // obj definition: https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/getting-started-spec.html // insert: https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/postCreateInteraction.html // update: https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/putUpdateInteraction.html export default { folderType: 'journey', bodyIteratorField: 'items', dependencies: [ 'folder-journey', 'triggeredSend', // for EMAILV2-activity 'dataExtension', // for transactionalEmails: EMAILV2-activity and for UPDATECONTACTDATA activity 'deliveryProfile', 'event', // for Multistep and Quicksend journeys 'mobileMessage', // for SMSSYNC-activity 'mobileCode', // for SMSSYNC-activity 'mobileKeyword', // for SMSSYNC-activity 'asset-asset', // for SMSSYNC-activity (sub-subtype jsonmessage) 'list', // for EMAILV2-activity 'email', // for EMAILV2-activity 'asset-message', // for EMAILV2-activity 'sendClassification', // for EMAILV2-activity 'senderProfile', // for EMAILV2-activity ], // ! interaction and transactionalEmail both link to each other. caching transactionalEmail here "manually" instead of via dependencies array, assuming that it is quicker than the other way round dependencyGraph: { // classic email cannot be deployed anymore event: ['triggers.metaData.r__event_key'], dataExtension: [ 'activities.metaData.highThroughput.r__dataExtension_key', 'activities.configurationArguments.triggeredSend.r__dataExtension_key.domainExclusions', 'activities.arguments.activityData.updateContactFields.r__dataExtension_key', ], deliveryProfile: ['activities.configurationArguments.triggeredSend.r__deliveryProfile_key'], list: [ 'activities.configurationArguments.triggeredSend.r__list_PathName.publicationList', 'activities.configurationArguments.triggeredSend.r__list_PathName.suppressionLists', ], senderProfile: ['activities.configurationArguments.triggeredSend.r__senderProfile_key'], sendClassification: [ 'activities.configurationArguments.triggeredSend.r__sendClassification_key', ], asset: [ 'activities.configurationArguments.triggeredSend.r__asset_key', 'activities.configurationArguments.r__asset_key', ], mobileMessage: ['activities.configurationArguments.r__mobileMessage_key'], mobileKeyword: [ 'activities.configurationArguments.r__mobileKeyword_key.current', 'activities.configurationArguments.r__mobileKeyword_key.next', ], mobileCode: ['activities.configurationArguments.r__mobileCode_key'], }, folderIdField: 'categoryId', hasExtended: false, idField: 'id', keyIsFixed: true, keyField: 'key', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, restPageSize: 500, maxKeyLength: 200, // confirmed max length type: 'journey', typeDescription: 'Journey (internally called "Interaction").', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Journey', priorityMapping: { High: 3, Medium: 4, // not inherited on Asset Types Low: 5, }, fields: { activities: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'activities[].key': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].type': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].outcomes': { skipValidation: true, }, 'activities[].arguments': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.waitEndDateAttributeDataBound': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.waitDefinitionId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'activities[].arguments.waitForEventId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.executionMode': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.startActivityKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.waitQueueId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.activityId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.definitionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.emailSubjectDataBound': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.contactId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.contactKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.emailAddress': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.sourceCustomObjectId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.sourceCustomObjectKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.fieldType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.eventData': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.obfuscationProperties': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.customObjectKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.definitionInstanceId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.filterResult': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.version': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.requestObjectId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].arguments.activityData': { skipValidation: true, }, 'activities[].arguments.objectMap': { skipValidation: true, }, 'activities[].configurationArguments': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.isReconcilable': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.isActivityBatchValidated': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSendKey': { // if used during create then we are stuck with old data isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, 'activities[].configurationArguments.triggeredSendId': { // if used during create then we are stuck with old data isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, 'activities[].configurationArguments.triggeredSend': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.id': { // if used during create then we are stuck with old data isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, 'activities[].configurationArguments.triggeredSend.key': { // if used during create then we are stuck with old data isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, 'activities[].configurationArguments.triggeredSend.campaigns': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.suppressionLists': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.autoAddSubscribers': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.autoUpdateSubscribers': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.bccEmail': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.categoryId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.ccEmail': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.created': { skipValidation: true, }, 'activities[].configurationArguments.triggeredSend.description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.domainExclusions': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.dynamicEmailSubject': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.emailSubject': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.exclusionFilter': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.isSalesforceTracking': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.isMultipart': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.isSendLogging': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.isStoppedOnJobError': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.keyword': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.modified': { skipValidation: true, }, 'activities[].configurationArguments.triggeredSend.name': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'activities[].configurationArguments.triggeredSend.preHeader': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.replyToAddress': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.replyToDisplayName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.suppressTracking': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.triggeredSendStatus': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.version': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.throttleOpens': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.throttleCloses': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.throttleLimit': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.isTrackingClicks': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.emailId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__triggeredSend_key': { isCreateable: false, isUpdateable: false, retrieving: true, /* dont include in templates, we rather want this to be re-created from the journey */ template: false, }, 'activities[].configurationArguments.triggeredSend.senderProfileId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.deliveryProfileId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__senderProfile_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.sendClassificationId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__deliveryProfile_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__sendClassification_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__list_PathName': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.publicationListId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__list_PathName.publicationList': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__list_PathName.suppressionLists': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__dataExtension_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__dataExtension_key.domainExclusions': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.priority': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.c__priority': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.r__asset_name_readOnly': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'activities[].configurationArguments.triggeredSend.r__asset_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.triggeredSend.updateSubscriber': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.applicationExtensionKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.r__transactionalEmail_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].configurationArguments.applicationExtensionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.isModified': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.isSimulation': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.googleAnalyticsCampaignName': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.useLLTS': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.fuelAgentRequested': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.r__triggeredSend_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'activities[].configurationArguments.waitDuration': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.waitUnit': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.specifiedTime': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.timeZone': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.waitEndDateAttributeExpression': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.specificDate': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.waitForEventKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.schemaVersionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'activities[].configurationArguments.criteria': { skipValidation: true, }, 'activities[].configurationArguments.eventDataConfig': { skipValidation: true, }, 'activities[].metaData': { skipValidation: true, }, 'activities[].schema': { skipValidation: true, }, 'activities[].arguments.activityData.updateContactFields[].r__dataExtension_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].arguments.activityData.updateContactFields[].r__dataExtensionField_name': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'activities[].arguments.activityData.updateContactFields[].field': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, categoryId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, channel: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'defaults.email': { skipValidation: true, }, 'defaults.mobileNumber': { skipValidation: true, }, 'defaults.properties.analyticsTracking.enabled': { isCreateable: null, isUpdateable: null, retrieving: null, template: null, }, 'defaults.properties': { skipValidation: true, }, 'defaults.properties.analyticsTracking.analyticsType': { isCreateable: null, isUpdateable: null, retrieving: null, template: null, }, 'defaults.properties.analyticsTracking.urlDomainsToTrack': { isCreateable: null, isUpdateable: null, retrieving: null, template: null, }, definitionId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, definitionType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, entryMode: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, executionMode: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, exits: { skipValidation: true, }, goals: { skipValidation: true, }, healthStats: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, id: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, key: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, lastPublishedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'metaData.templateId': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, modifiedDate: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, scheduledStatus: { isCreateable: null, isUpdateable: null, retrieving: null, template: null, }, stats: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, triggers: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'triggers[].key': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].name': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].description': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].type': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].outcomes': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.startActivityKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.dequeueReason': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.lastExecutedActivityKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.filterResult': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.serializedObjectType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.eventDefinitionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.eventDefinitionKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.dataExtensionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.automationId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].arguments.r__event_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'triggers[].arguments.r__dataExtension_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'triggers[].configurationArguments': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.eventDataConfig': { skipValidation: true, }, 'triggers[].configurationArguments.primaryObjectFilterCriteria': { skipValidation: true, }, 'triggers[].configurationArguments.relatedObjectFilterCriteria': { skipValidation: true, }, 'triggers[].configurationArguments.salesforceTriggerCriteria': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.objectApiName': { // journey capitalization; rewritten to event way of writing it by mcdev isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.objectAPIName': { // capitalization like on event, customly created by mcdev in journey isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.version': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.contactKey': { skipValidation: true, }, 'triggers[].configurationArguments.contactPersonType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.primaryObjectFilterSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.relatedObjectFilterSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.eventDataSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.evaluationCriteriaSummary': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.applicationExtensionKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.passThroughArgument': { skipValidation: true, }, 'triggers[].configurationArguments.filterDefinitionId': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'triggers[].configurationArguments.criteria': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.schemaVersionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.whoToInject': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].configurationArguments.additionalObjectFilterCriteria': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.sourceInteractionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.entrySourceGroupConfigUrl': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.r__event_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'triggers[].metaData.category': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.eventDefinitionId': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.eventDefinitionKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.chainType': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.configurationRequired': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.iconUrl': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.title': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'triggers[].metaData.scheduleState': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, version: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, workflowApiVersion: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, campaigns: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, metaData: { skipValidation: true, }, notifiers: { skipValidation: true, }, tags: { skipValidation: true, }, r__folder_Path: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/List.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: ['folder-mysubs', 'folder-list', 'folder-publication'], dependencyGraph: null, folderType: 'list', hasExtended: false, idField: 'ObjectID', keyIsFixed: true, keyField: 'CustomerKey', nameField: 'ListName', restPagination: null, type: 'list', typeDescription: 'Old way of storing data. Still used for central Email Subscriber DB.', typeRetrieveByDefault: true, typeCdpByDefault: false, typeName: 'List', fields: { 'AutomatedEmail.ID': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'AutomatedEmail.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'AutomatedEmail.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Category: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'Client.PartnerClientKey': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, CustomerKey: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, Description: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, ID: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, ListClassification: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, ListName: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, ObjectID: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Type: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__folder_Path: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/MobileCode.definition.js ================================================ export default { bodyIteratorField: 'entry', dependencies: [], dependencyGraph: null, hasExtended: false, idField: 'id', keyIsFixed: true, keyField: 'code', nameField: 'code', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'lastUpdated', lastmodNameField: null, restPagination: true, restPageSize: 50, type: 'mobileCode', typeDescription: 'Used to send SMS Messages', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Mobile Code', fields: { id: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, lastUpdated: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, startDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, endDate: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, keywordLimit: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, keywordsUsed: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, code: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, codeType: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, isShortCode: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, keywordsUsedOther: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, isGsmCharacterSetOnly: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, isMms: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, isStackIndependant: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, supportsConcatenation: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, isClientOwned: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, isOwner: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, dipSwitches: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, sendableCountries: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sendableCountries[].countryCode': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sendableCountries[].vendor': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'sendableCountries[].fromNameSupported': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, countryCode: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, moEngineVersion: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/MobileKeyword.definition.js ================================================ export default { bodyIteratorField: 'entry', dependencies: ['mobileCode'], dependencyGraph: { mobileCode: ['r__mobileCode_key'] }, hasExtended: false, idField: 'id', keyIsFixed: false, // custom field but mapped to normal fields keyField: 'c__codeKeyword', nameField: 'c__codeKeyword', createdDateField: 'createdDate', createdNameField: 'createdBy.name', lastmodDateField: 'lastUpdated', lastmodNameField: null, restPagination: true, restPageSize: 50, maxKeyLength: 50, // assumed max length type: 'mobileKeyword', typeDescription: 'Used for managing subscriptions for Mobile numbers in Mobile Connect', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Mobile Keyword', fields: { id: { // irregular format: NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, c__codeKeyword: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__mobileCode_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, keyword: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, lastUpdated: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, startDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, endDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, createdBy: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'createdBy.id': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'createdBy.name': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'createdBy.lastUpdated': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, dipSwitches: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, isInherited: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, decodedId: { // GUID format (4b5dece6-c042-45a4-b7c2-d67e032ff3cb). unsure what this is used for isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, restriction: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, keywordType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, companyName: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, responseMessage: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, status: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, messages: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, code: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.code': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.createdDate': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.lastUpdated': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.startDate': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.endDate': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.keywordLimit': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.keywordsUsed': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.codeType': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.isShortCode': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.keywordsUsedOther': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.isGsmCharacterSetOnly': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.isMms': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.isStackIndependant': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.supportsConcatenation': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.isClientOwned': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.isOwner': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.dipSwitches': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.sendableCountries': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.countryCode': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'code.moEngineVersion': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/MobileMessage.definition.js ================================================ export default { bodyIteratorField: 'entry', dependencies: ['mobileCode', 'mobileKeyword', 'campaign'], dependencyGraph: { mobileCode: ['r__mobileCode_key'], mobileKeyword: [ 'keyword.r__mobileKeyword_key', 'subscriptionKeyword.r__mobileKeyword_key', 'nextKeyword.r__mobileKeyword_key', ], // campaign: ['r__campaign_key'], // campaign cannot be deployed }, hasExtended: false, idField: 'id', keepId: true, keyIsFixed: true, // key == id keyField: 'id', nameField: 'name', createdDateField: null, createdNameField: null, lastmodDateField: 'lastUpdated', lastmodNameField: null, restPagination: true, restPageSize: 50, type: 'mobileMessage', typeDescription: 'Used by Journey Builder and to send SMS from MobileConnect triggered by API or manually on-the-fly', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'MobileConnect SMS', fields: { allowSingleOptin: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, audience: { skipValidation: true, }, 'audience[]': { skipValidation: true, }, campaigns: { skipValidation: true, }, 'campaigns[]': { skipValidation: true, }, r__mobileCode_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'code.code': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'code.codeType': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.countryCode': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.createdDate': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.dipSwitches': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.endDate': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.isClientOwned': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.isGsmCharacterSetOnly': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.isMms': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.isOwner': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.isShortCode': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.isStackIndependant': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.keywordLimit': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.keywordsUsed': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.keywordsUsedOther': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.lastUpdated': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.moEngineVersion': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.sendableCountries': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.sendableCountries[]': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.sendableCountries[].countryCode': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.sendableCountries[].vendor': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.sendableCountries[].fromNameSupported': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.startDate': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'code.supportsConcatenation': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, concatenateMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, currentEditStep: { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, doubleOptinConfirmMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, doubleOptinInitialMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, doubleOptinValidResponses: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, duplicateOptInResponseMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, expireHours: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, fromName: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, id: { isCreateable: false, isUpdateable: true, retrieving: true, template: true, }, invalidMessage: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isCertified: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isDuplicationAllowed: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isExpireSet: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isFromNameCertificationAccepted: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isSentImmediately: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isSubscriberResponseToAnySubscriptionForShortCode: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isSuppressMt: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isTest: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, isTimeZoneBased: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'keyword.id': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'keyword.isInherited': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'keyword.keyword': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'keyword.r__mobileKeyword_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'keyword.keywordType': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'keyword.restriction': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, lastUpdated: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, messageObjectId: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, messagesPerPeriod: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, minutesPerPeriod: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, moStartDate: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, moEndDate: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'moTimezone.name': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'moTimezone.offset': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.id': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.key': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.createdDate': { isCreatable: false, isUpdatable: false, retrieving: true, template: false, }, 'mtRecurrence.createdBy': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'mtRecurrence.lastUpdated': { isCreatable: false, isUpdatable: false, retrieving: true, template: false, }, 'mtRecurrence.lastUpdatedBy': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'mtRecurrence.name': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.description': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.startDate': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.iCalRecur': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.timeZone': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'mtRecurrence.timeZoneId': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, mtSendDate: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, nextJob: { // contains lots of info but deemed not needed for retrieving or deploying isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, nextKeyword: { // contains lots of info but deemed not needed for retrieving or deploying isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, numberMessagesPerPeriod: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, optinErrorMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, optinInvalidAgeMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, optinMinimumAge: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, optinType: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, origin: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, outboundSendBehaviorFlag: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, outboundSendTypeFlag: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, periodType: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, programId: { // always "00000000-0000-0000-0000-000000000000" isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, publishedMessage: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, responseMessage: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, sendMethod: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, smsTriggeredSendDefinitionId: { // if no value then it's set to "00000000-0000-0000-0000-000000000000" isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, statistics: { // not relevant for deployment or configuration isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'statistics.outbound': { // not relevant for deployment or configuration isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'statistics.outbound.sent': { // not relevant for deployment or configuration isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'statistics.outbound.delivered': { // not relevant for deployment or configuration isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'statistics.outbound.undelivered': { // not relevant for deployment or configuration isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'statistics.outbound.unknown': { // not relevant for deployment or configuration isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, statusId: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'subscriptionKeyword.id': { isCreatable: true, isUpdatable: true, retrieving: false, template: false, }, 'subscriptionKeyword.keyword': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'subscriptionKeyword.r__mobileKeyword_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'subscriptionKeyword.restriction': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'subscriptionKeyword.isInherited': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'nextKeyword.id': { isCreatable: true, isUpdatable: true, retrieving: false, template: false, }, 'nextKeyword.keyword': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'nextKeyword.r__mobileKeyword_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'nextKeyword.restriction': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, 'nextKeyword.isInherited': { isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, subscriberResponseMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, surveyCorrectResponseMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, surveyIncorrectResponseMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, surveyResponsesAllowed: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, surveyTooManyEntriesMessage: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, surveyType: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'template.description': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'template.icon': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'template.id': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'template.lastUpdated': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, 'template.name': { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, text: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, triggeredSendId: { // always "00000000-0000-0000-0000-000000000000" isCreatable: false, isUpdatable: false, retrieving: false, template: false, }, triggeredSendName: { isCreatable: true, isUpdatable: true, retrieving: true, template: true, }, type: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__campaign_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'r__campaign_key[]': { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Query.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['folder-queryactivity', 'dataExtension'], dependencyGraph: { dataExtension: ['r__dataExtension_key'], }, folderType: 'queryactivity', filter: { description: ['Query created by Query Studio'], }, hasExtended: false, idField: 'queryDefinitionId', keyIsFixed: false, keyField: 'key', nameField: 'name', folderIdField: 'categoryId', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, targetUpdateTypeMapping: { Append: 2, Overwrite: 0, Update: 1, }, maxKeyLength: 36, // confirmed max length type: 'query', typeDescription: 'Select & transform data using SQL.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: SQL Query Activity', fields: { categoryId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, isFrozen: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, key: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, queryDefinitionId: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, queryText: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, targetDescription: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, targetId: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, targetKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, targetName: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, targetUpdateTypeId: { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, targetUpdateTypeName: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, validatedQueryText: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, r__dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__folder_Path: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Role.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [], dependencyGraph: null, deployBlacklist: [ 'SYS_DEF_ADMIN', 'SYS_DEF_ANALYST', 'SYS_DEF_CONTENT', 'SYS_DEF_DATA', 'SYS_DEF_DS_USER', 'SYS_DEF_IMHADMIN', 'SYS_DEF_CHANNELMANAGER', 'SYS_DEF_CONTENTEDIT', 'SYS_DEF_SECURITYADMIN', 'SYS_DEF_VIEWER', ], documentInOneFile: true, hasExtended: true, idField: 'ObjectID', keyIsFixed: false, keyField: 'CustomerKey', nameField: 'Name', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: null, maxKeyLength: 36, // confirmed max length type: 'role', typeDescription: 'User Roles define groups that are used to grant users access to SFMC systems.', typeRetrieveByDefault: true, typeCdpByDefault: false, typeName: 'Role', fields: { CreatedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, Description: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, ModifiedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, Name: { isCreateable: null, isUpdateable: null, retrieving: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: false, template: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, IsSystemDefined: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, PermissionSets: { retrieving: true, skipCache: true, skipValidation: true, }, c__notAssignable: { skipValidation: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Script.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['folder-ssjsactivity'], dependencyGraph: null, folderType: 'ssjsactivity', hasExtended: false, idField: 'ssjsActivityId', keyIsFixed: false, keyField: 'key', nameField: 'name', folderIdField: 'categoryId', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, type: 'script', typeDescription: 'Execute more complex tasks via SSJS or AMPScript.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: Script Activity', fields: { categoryId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdBy: { // not existing in rest api isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, folderLocationText: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, key: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, modifiedBy: { // not existing in rest api isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, script: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ssjsActivityId: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, status: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, statusId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, parentCategoryId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, r__folder_Path: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/SendClassification.definition.js ================================================ // https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/sendclassification.html export default { bodyIteratorField: 'Results', dependencies: ['senderProfile', 'deliveryProfile', 'domainVerification'], dependencyGraph: { senderProfile: ['r__senderProfile_key'], // deliveryProfile: ['r__deliveryProfile_key'], // deliveryProfile cannot be deployed }, filter: {}, hasExtended: false, idField: 'ObjectID', keyField: 'CustomerKey', keyIsFixed: false, maxKeyLength: 36, // confirmed max length nameField: 'Name', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: null, restPagination: false, type: 'sendClassification', typeDescription: 'Lets admins define Delivery Profile, Sender Profile and CAN-SPAM for an email job in a central location.', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Send Classification', sendClassificationTypeMapping: { Commercial: 'Marketing', Transactional: 'Operational', }, fields: { 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CreatedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, ModifiedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, Description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ArchiveEmail: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'DeliveryProfile.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'DeliveryProfile.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'DeliveryProfile.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, HonorPublicationListOptOutsForTransactionalSends: { /* not supported */ isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, SendClassificationType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'SenderProfile.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'SenderProfile.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'SenderProfile.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, SendPriority: { /* not supported */ isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, c__classification: { skipValidation: true, }, r__deliveryProfile_key: { skipValidation: true, }, r__senderProfile_key: { skipValidation: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/SenderProfile.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: ['user', 'domainVerification'], dependencyGraph: { domainVerification: ['FallbackFromAddress', 'FromAddress'], }, filter: {}, hasExtended: false, idField: 'ObjectID', keyField: 'CustomerKey', keyIsFixed: false, maxKeyLength: 36, // confirmed max length nameField: 'Name', createdDateField: 'CreatedDate', createdNameField: 'Client.CreatedBy', lastmodDateField: 'ModifiedDate', lastmodNameField: 'Client.ModifiedBy', restPagination: false, type: 'senderProfile', typeDescription: 'Specifies the From information for a send in a central location', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Sender Profile', fields: { 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'Client.CreatedBy': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'Client.ModifiedBy': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, createdBy: { isCreateable: false, isUpdateable: false, retrieving: null, template: false, }, modifiedBy: { isCreateable: false, isUpdateable: false, retrieving: null, template: false, }, CreatedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, ModifiedDate: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, Description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, AutoForwardToEmailAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, AutoForwardToName: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'AutoForwardTriggeredSend.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, AutoReply: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'AutoReplyTriggeredSend.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DataRetentionPeriodLength: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DataRetentionPeriodUnitOfMeasure: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DirectForward: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, FallbackFromAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, FromAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, FromName: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ID: { // not supported isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'ReplyManagementRuleSet.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'RMMRuleCollection.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ReplyToAddress: { // not supported isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ReplyToDisplayName: { // not supported isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, SenderHeaderEmailAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, SenderHeaderName: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, UseDefaultRMMRules: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/TransactionalEmail.definition.js ================================================ export default { bodyIteratorField: 'definitions', dependencies: ['asset-message', 'dataExtension', 'list', 'journey', 'sendClassification'], dependencyGraph: { // classic email cannot be deployed anymore asset: ['r__asset_key'], dataExtension: ['subscriptions.r__dataExtension_key'], list: ['subscriptions.r__list_PathName'], journey: ['r__journey_key'], sendClassification: ['r__sendClassification_key'], }, hasExtended: false, idField: 'definitionId', keyIsFixed: true, // sending definitionKey in update call not allowed by API keyField: 'definitionKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, restPageSize: 100, maxKeyLength: 36, // confirmed max length type: 'transactionalEmail', typeDescription: 'Lets you send immediate Email messages via API events', typeRetrieveByDefault: true, typeCdpByDefault: false, typeName: 'Transactional Email', fields: { name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, definitionKey: { isCreateable: true, isUpdateable: false, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, requestId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, definitionId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, classification: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'content.customerKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.dataExtension': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.r__dataExtension_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'subscriptions.list': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.r__list_PathName': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'subscriptions.autoAddSubscriber': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.updateSubscriber': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.trackLinks': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.cc': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.bcc': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.createJourney': { isCreateable: true, isUpdateable: false, retrieving: false, template: false, }, journey: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'journey.interactionKey': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__asset_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__journey_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, r__sendClassification_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/TransactionalMessage.definition.js ================================================ export default { bodyIteratorField: 'definitions', dependencies: [], dependencyGraph: null, hasExtended: false, idField: 'definitionId', keyIsFixed: true, // sending definitionKey in update call not allowed by API keyField: 'definitionKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, restPageSize: 100, type: '', typeDescription: 'here as a placeholder to have auto completion', typeRetrieveByDefault: false, typeCdpByDefault: true, typeName: '', fields: { name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, definitionKey: { isCreateable: true, isUpdateable: false, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, requestId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, definitionId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/TransactionalPush.definition.js ================================================ export default { bodyIteratorField: 'definitions', dependencies: ['asset-asset'], dependencyGraph: { asset: ['r__asset_key'], }, hasExtended: false, idField: 'definitionId', keyIsFixed: true, // sending definitionKey in update call not allowed by API keyField: 'definitionKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, restPageSize: 100, type: 'transactionalPush', typeDescription: 'Lets you send immediate Push messages via API events', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Transactional Push', fields: { name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, definitionKey: { isCreateable: true, isUpdateable: false, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, requestId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, definitionId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'content.customerKey': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__asset_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'options.badge': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.sound': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.customKeys': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.customKeys[].value': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'options.customKeys[].key': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, applicationId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/TransactionalSMS.definition.js ================================================ export default { bodyIteratorField: 'definitions', dependencies: ['mobileCode', 'mobileKeyword'], dependencyGraph: { mobileKeyword: ['subscriptions.r__mobileKeyword_key'], mobileCode: ['subscriptions.r__mobileCode_key'], }, hasExtended: false, idField: 'definitionId', keyIsFixed: true, // sending definitionKey in update call not allowed by API keyField: 'definitionKey', nameField: 'name', createdDateField: 'createdDate', createdNameField: null, lastmodDateField: 'modifiedDate', lastmodNameField: null, restPagination: true, restPageSize: 100, type: 'transactionalSMS', typeDescription: 'Lets you send immediate SMS messages via API events', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Transactional SMS', fields: { name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, definitionKey: { isCreateable: true, isUpdateable: false, retrieving: true, template: true, }, description: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, requestId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, definitionId: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, status: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, createdDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, modifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'content.message': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.shortCode': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.countryCode': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.autoAddSubscriber': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.updateSubscriber': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.keyword': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'subscriptions.r__mobileKeyword_key': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/TriggeredSend.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [ 'folder-hidden', 'folder-triggered_send', 'folder-triggered_send_journeybuilder', 'email', 'asset-message', 'list', 'sendClassification', 'senderProfile', ], dependencyGraph: { // classic email cannot be deployed anymore asset: ['r__asset_key'], list: ['r__list_PathName'], sendClassification: ['r__sendClassification_key'], senderProfile: ['r__senderProfile_key'], }, filter: { r__folder_Path: [ 'Journey Builder Sends/', 'HiddenCategory/HiddenJourneyBuilderTriggeredSends/', ], }, folderType: 'triggered_send', hasExtended: false, idField: 'ObjectID', keepId: true, keyIsFixed: false, keyField: 'CustomerKey', nameField: 'Name', folderIdField: 'CategoryID', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: null, restPagination: null, maxKeyLength: 36, // confirmed max length type: 'triggeredSend', soapType: 'triggeredSendDefinition', typeDescription: 'Used by Journey Builder to send triggered emails', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Triggered Send', priorityMapping: { High: 3, Medium: 4, Low: 5, }, fields: { AllowedSlots: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, AutoAddSubscribers: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, AutoUpdateSubscribers: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, BatchInterval: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, BccEmail: { // while this can be retrieved, it seems to be always returned empty isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, CategoryID: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, CCEmail: { // this field is updatable but not retrievable for some reason isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'Client.PartnerClientKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CorrelationID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CreatedDate: { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, DataSchemas: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'DeliveryProfile.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'DeliveryProfile.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, Description: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, DisableOnEmailBuildError: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, DomainType: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, DynamicEmailSubject: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'Email.ID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'Email.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'Email.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, EmailSubject: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, ExclusionFilter: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ExclusionListCollection: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'FooterContentArea.ID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, FooterSalutationSource: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, FromAddress: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, FromName: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'HeaderContentArea.ID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, HeaderSalutationSource: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, InteractionObjectID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IsAlwaysOn: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IsMultipart: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, IsPlatformObject: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, IsSendLogging: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, IsWrapped: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, KeepExistingEmailSubject: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Keyword: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'List.ID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'List.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'List.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ModifiedDate: { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, NewSlotTrigger: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, ObjectID: { isCreateable: false, isUpdateable: true, retrieving: false, templating: false, }, ObjectState: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, OptionFlags: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, OptionFlagsUpdateMask: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, OptionVersion: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Owner: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PreHeader: { // retrieve not supported by API isCreateable: true, isUpdateable: true, retrieving: false, templating: false, }, Priority: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'PrivateDomain.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'PrivateDomain.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'PrivateIP.ID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'PrivateIP.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, RefreshContent: { isCreateable: false, isUpdateable: true, retrieving: false, templating: false, }, ReplyToAddress: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, ReplyToDisplayName: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, RequestExpirationSeconds: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SendClassification.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'SendClassification.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, 'SendClassification.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, 'SenderProfile.CustomerKey': { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, 'SenderProfile.ObjectID': { isCreateable: true, isUpdateable: true, retrieving: true, templating: false, }, 'SenderProfile.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SendLimit: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, SendSourceCustomerKey: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SendSourceDataExtension: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SendWindowClose: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, SendWindowDelete: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SendWindowOpen: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, SourceAddressType: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, SuppressTracking: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, TestEmailAddr: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, TriggeredSendClass: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, TriggeredSendStatus: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, TriggeredSendSubClass: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, TriggeredSendType: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, TriggeredSendVersionID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, r__asset_name_readOnly: { skipValidation: true }, r__asset_key: { skipValidation: true }, r__email_name: { skipValidation: true }, r__folder_Path: { skipValidation: true }, r__list_PathName: { skipValidation: true }, c__priority: { skipValidation: true }, r__sendClassification_key: { skipValidation: true }, r__senderProfile_key: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/TriggeredSendSummary.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: [ 'triggeredSend', 'folder-hidden', 'folder-triggered_send', 'folder-triggered_send_journeybuilder', ], dependencyGraph: { triggeredSend: ['r__triggeredSend_key'], }, filter: {}, hasExtended: false, idField: 'ObjectID', keepId: false, keyIsFixed: true, keyField: 'CustomerKey', nameField: 'r__triggeredSend_name', folderIdField: 'TriggeredSend.CategoryID', createdDateField: null, createdNameField: null, lastmodDateField: null, lastmodNameField: null, restPagination: null, maxKeyLength: 36, type: 'triggeredSendSummary', soapType: 'triggeredSendSummary', typeDescription: 'Summary data for a Triggered Send', typeRetrieveByDefault: false, typeCdpByDefault: false, typeName: 'Triggered Send Summary', fields: { Bounces: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, Clicks: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, 'Client.ID': { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Conversions: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, templating: true, }, FTAFEmailsSent: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, FTAFOptIns: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, FTAFRequests: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, ID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, InProcess: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, NotSentDueToError: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, NotSentDueToOptOut: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, NotSentDueToUndeliverable: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, ObjectID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, /* ObjectState: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, */ // according to the documentation"Reserved for future use" Opens: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, OptOuts: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, Owner: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, Queued: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, Sent: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, SurveyResponses: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, UniqueClicks: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, UniqueConversions: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, UniqueOpens: { isCreateable: true, isUpdateable: false, retrieving: true, templating: true, }, CorrelationID: { isCreateable: false, isUpdateable: false, retrieving: false, templating: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: false /** Listed in the type documentation but not retrievable */, templating: false, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: false /** Listed in the type documentation but not retrievable */, templating: false, }, r__triggeredSend_name: { skipValidation: true }, r__triggeredSend_key: { skipValidation: true }, r__folder_Path: { skipValidation: true }, }, }; ================================================ FILE: lib/metadataTypes/definitions/User.definition.js ================================================ export default { bodyIteratorField: 'Results', dependencies: ['role'], dependencyGraph: { // role: ['c__RoleNamesGlobal'] // roles should rarely ever be deployed and hence this is not needed here }, folderType: null, hasExtended: false, idField: 'AccountUserID', // ID contains the same value as AccountUserID but is not required by API keepId: true, keyIsFixed: false, keyField: 'CustomerKey', nameField: 'Name', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: 'Client.ModifiedBy', maxKeyLength: 50, // confirmed max length type: 'user', soapType: 'AccountUser', typeDescription: 'Marketing Cloud users', typeName: 'User', typeRetrieveByDefault: false, typeCdpByDefault: false, documentInOneFile: true, stringifyFieldsBeforeTemplate: ['DefaultBusinessUnit', 'c__AssociatedBusinessUnits'], fields: { AccountUserID: { // numeric id, cannot be changed but identifies the useruniquely isCreateable: false, isUpdateable: true, retrieving: true, template: false, }, ActiveFlag: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, AssociatedBusinessUnits: { // not supported by API isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, BusinessUnit: { // not supported by API isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ChallengeAnswer: { // alwasy empty isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ChallengePhrase: { // alwasy empty isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'Client.ID': { isCreateable: true, isUpdateable: true, retrieving: false, template: false }, 'Client.ModifiedBy': { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'Client.PartnerClientKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CorrelationID: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, CreatedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, CustomerKey: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, DefaultApplication: { // not supported by API isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, DefaultBusinessUnit: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, DefaultBusinessUnitObject: { // more complex version of DefaultBusinessUnit thats not needed for deployment isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Delete: { isCreateable: false, isUpdateable: false, retrieving: false, template: false }, Email: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, ID: { isCreateable: false, isUpdateable: false, retrieving: false, template: false }, IsAPIUser: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, IsLocked: { // Indicates if account user can or cannot log into their account isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'LanguageLocale.LocaleCode': { // seems to always return en-US isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, LastSuccessfulLogin: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, 'Locale.LocaleCode': { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, 'Locale.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'Locale.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, ModifiedDate: { isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, MustChangePassword: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, Name: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, NotificationEmailAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, ObjectID: { isCreateable: null, isUpdateable: null, retrieving: false, template: null }, ObjectState: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Owner: { isCreateable: false, isUpdateable: false, retrieving: false, template: false }, PartnerKey: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, PartnerProperties: { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Password: { isCreateable: true, isUpdateable: true, retrieving: false, template: false }, Roles: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, 'Roles.Role': { skipValidation: true, }, 'Roles.Role[].Client': { skipValidation: false, }, SsoIdentities: { isCreateable: true, isUpdateable: true, retrieving: false, // retrieve not supported by API template: false, }, 'SsoIdentities.SsoIdentity': { isCreateable: true, isUpdateable: true, retrieving: false, // retrieve not supported by API template: false, }, 'SsoIdentities.SsoIdentity[].IsActive': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'SsoIdentities.SsoIdentity[].FederatedID': { isCreateable: true, isUpdateable: true, retrieving: false, template: false, }, 'TimeZone.ID': { isCreateable: true, isUpdateable: true, retrieving: true, template: false, }, 'TimeZone.Name': { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, 'TimeZone.ObjectID': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'TimeZone.PartnerKey': { isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, Unlock: { // do not retrieve it but also do not remove it from retrieve as we are adding it manually skipValidation: true, isCreateable: false, isUpdateable: true, template: true, }, UserID: { isCreateable: true, isUpdateable: true, retrieving: true, template: true }, UserPermissions: { // not sure what to do with the reponse yet. might become interesting for the future isCreateable: false, isUpdateable: false, retrieving: false, template: false, }, 'UserPermissions.PartnerKey': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions.ID': { skipValidation: true, }, 'UserPermissions.ObjectID': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions.Name': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions.Value': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions.Description': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions.Delete': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions[].PartnerKey': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions[].ID': { skipValidation: true, }, 'UserPermissions[].ObjectID': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions[].Name': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions[].Value': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions[].Description': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, 'UserPermissions[].Delete': { isCreateable: null, isUpdateable: null, retrieving: false, template: false, }, c__type: { isCreateable: false, isUpdateable: false, retrieve: null, // handled via script template: false, }, c__AssociatedBusinessUnits: { skipValidation: true, }, c__RoleNamesGlobal: { skipValidation: true, }, c__LocaleCode: { skipValidation: true, }, c__TimeZoneName: { skipValidation: true, }, c__AccountUserID: { isCreateable: false, isUpdateable: false, retrieve: null, // handled via script template: false, }, c__IsLocked_readOnly: { isCreateable: false, isUpdateable: false, retrieve: null, // handled via script template: false, }, }, }; ================================================ FILE: lib/metadataTypes/definitions/Verification.definition.js ================================================ export default { bodyIteratorField: 'items', dependencies: ['dataExtension', 'user'], dependencyGraph: { dataExtension: ['r__dataExtension_key'] }, hasExtended: false, idField: 'dataVerificationDefinitionId', keyIsFixed: true, keyField: 'c__automation_step', createdDateField: null, createdNameField: 'createdBy', lastmodDateField: null, lastmodNameField: null, nameField: 'c__automation_step', restPagination: false, maxKeyLength: 36, // confirmed max length type: 'verification', typeDescription: 'Check DataExtension for a row count', typeRetrieveByDefault: true, typeCdpByDefault: true, typeName: 'Automation: Verification Activity', fields: { createdBy: { // User ID isCreateable: false, isUpdateable: false, retrieving: true, template: false, }, dataVerificationDefinitionId: { isCreateable: false, // auto-assigned during creation by SFMC isUpdateable: true, retrieving: true, template: true, }, notificationEmailAddress: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, notificationEmailMessage: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, shouldEmailOnFailure: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, shouldStopOnFailure: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, targetObjectId: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, value1: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, value2: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, verificationType: { isCreateable: true, isUpdateable: true, retrieving: true, template: true, }, r__dataExtension_key: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, c__automation_step: { isCreateable: false, isUpdateable: false, retrieving: true, template: true, }, }, }; ================================================ FILE: lib/retrieveChangelog.js ================================================ #!/usr/bin/env node 'use strict'; /* eslint-disable unicorn/prefer-top-level-await */ /** * sample file on how to retrieve a simple changelog to use in GUIs or automated processing of any kind * * @example [{ name: 'deName', key: 'deKey', t: 'dataExtension', cd: '2020-05-06T00:16:00.737', cb: 'name of creator', ld: '2020-05-06T00:16:00.737', lb: 'name of lastmodified' }] */ import mcdev from './index.js'; import Definition from './MetadataTypeDefinitions.js'; import MetadataType from './MetadataTypeInfo.js'; // disable cli logs // mcdev._setLoggingLevel({ silent: true }); const customDefinition = { automation: { keyField: 'CustomerKey', nameField: 'Name', createdDateField: 'CreatedDate', createdNameField: 'CreatedBy', lastmodDateField: 'LastSaveDate', lastmodNameField: 'LastSavedBy', }, dataExtension: { keyField: 'CustomerKey', nameField: 'Name', createdDateField: 'CreatedDate', createdNameField: null, lastmodDateField: 'ModifiedDate', lastmodNameField: null, }, }; (async function () { // get userid>name mapping const userList = (await mcdev.retrieve('ACN-Learning/_ParentBU_', ['user'], null, true)).user; // reduce userList to simple id-name map for (const key of Object.keys(userList)) { userList[userList[key].ID] = userList[key].Name; delete userList[key]; } // get changed metadata const changelogList = await mcdev.retrieve( 'ACN-Learning/MCDEV_Training_Source', null, null, true ); const allMetadata = []; Object.keys(changelogList).map((type) => { if (changelogList[type]) { const def = customDefinition[type] || Definition[type]; allMetadata.push( ...Object.keys(changelogList[type]).map((key) => { const item = changelogList[type][key]; if ( MetadataType[type].isFiltered(item, true) || MetadataType[type].isFiltered(item, false) ) { return; } const listEntry = { name: item[def.nameField], key: item[def.keyField], t: type, cd: item[def.createdDateField], cb: getUserName(userList, item, def.createdNameField), ld: item[def.lastmodDateField], lb: getUserName(userList, item, def.lastmodNameField), }; return listEntry; }) ); } }); const finalResult = allMetadata.filter((item) => undefined !== item); console.log('finalResult', finalResult); // eslint-disable-line no-console })(); /** * * @param {Object.<string, string>} userList user-id > user-name map * @param {Object.<string, string>} item single metadata item * @param {string} fieldname name of field containing the info * @returns {string} username or user id or 'n/a' */ function getUserName(userList, item, fieldname) { return userList[item[fieldname]] || item[fieldname] || 'n/a'; } ================================================ FILE: lib/util/auth.js ================================================ import { Util } from './util.js'; import File from './file.js'; import SDK from 'sfmc-sdk'; import Conf from 'conf'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ const credentialStore = new Conf({ projectName: 'mcdev', configName: 'sessions', clearInvalidConfig: true, }); const initializedSDKs = {}; let authfile; const Auth = { /** * For each business unit, set up base credentials to be used. * * @param {AuthObject} authObject details for * @param {string} credential of the instance * @returns {Promise.<void>} - */ async saveCredential(authObject, credential) { const sdk = setupSDK(credential, authObject); // check credentials to allow clear log output and stop execution const test = await sdk.auth.getAccessToken(); if (test.error) { throw new Error(test.error_description); } else if (test.scope) { // find missing rights const missingAccess = sdk.auth .getSupportedScopes() .filter((element) => !test.scope.includes(element)); if (missingAccess.length) { Util.logger.warn( 'Installed package has insufficient access. You might encounter malfunctions!' ); Util.logger.warn('Missing scope: ' + missingAccess.join(', ')); } const existingAuth = (await File.pathExists(Util.authFileName)) ? await File.readJSON(Util.authFileName) : {}; existingAuth[credential] = authObject; await File.writeJSONToFile('./', Util.authFileName.split('.json')[0], existingAuth); authfile = existingAuth; } }, /** * Returns an SDK instance to be used for API calls * * @param {BuObject} buObject information about current context * @returns {SDK} auth object */ getSDK(buObject) { const credentialKey = `${buObject.credential}/${buObject.businessUnit}`; if (initializedSDKs[credentialKey]) { // return initialied SDK if available return initializedSDKs[credentialKey]; } else { // check existing credentials cached authfile ||= File.readJsonSync(Util.authFileName); const newAuthObj = authfile[buObject.credential]; // use client_id + MID to ensure a unique combination across instances const sessionKey = newAuthObj.client_id + '|' + buObject.mid; const existingAuthObj = credentialStore.get(sessionKey); if (!existingAuthObj) { newAuthObj.account_id = buObject.mid; } initializedSDKs[credentialKey] = setupSDK(credentialKey, existingAuthObj || newAuthObj); return initializedSDKs[credentialKey]; } }, /** * helper to clear all auth sessions * * @returns {void} */ clearSessions() { credentialStore.clear(); Util.logger.info(`Auth sessions cleared`); }, }; /** * Returns an SDK instance to be used for API calls * * @param {string} sessionKey key for specific BU * @param {AuthObject} authObject credentials for specific BU * @returns {SDK} auth object */ function setupSDK(sessionKey, authObject) { return new SDK(authObject, { eventHandlers: { onLoop: (type, accumulator) => { Util.logger.info( Util.getGrayMsg( ` - Requesting next batch (currently ${accumulator?.length} records)` ) ); }, onRefresh: (authObject) => { authObject.scope = authObject.scope.split(' '); // Scope is usually not an array, but we enforce conversion here for simplicity credentialStore.set(sessionKey, authObject); }, onConnectionError: (ex, remainingAttempts) => { Util.logger.info( ` - Connection problem (Code: ${ex.code}). Retrying ${remainingAttempts} time${ remainingAttempts > 1 ? 's' : '' }${ ex.endpoint ? Util.getGrayMsg( ' - ' + ex.endpoint.split('rest.marketingcloudapis.com')[1] ) : '' }` ); Util.logger.errorStack(ex); }, logRequest: (req) => { const msg = structuredClone(req); if (msg.url === '/Service.asmx') { msg.data = msg.data.replaceAll( /<fueloauth(.*)<\/fueloauth>/gim, '<fueloauth>*** TOKEN REMOVED ***</fueloauth>' ); } else if (msg.headers?.Authorization) { msg.headers.Authorization = 'Bearer *** TOKEN REMOVED ***'; } switch (Util.OPTIONS.api) { case 'cli': { /* eslint-disable no-console */ console.log( `${Util.color.fgMagenta}API REQUEST >>${Util.color.reset}`, msg ); /* eslint-enable no-console */ break; } case 'log': { let data; if (msg.data) { data = msg.data; delete msg.data; } Util.logger.debug('API REQUEST >> ' + JSON.stringify(msg, null, 2)); if (data) { // printing it separately leads to better formatting Util.logger.debug( 'API REQUEST body >> \n ' + (typeof data === 'string' ? data : JSON.stringify(data, null, 2)) ); } break; } // No default } }, logResponse: (res) => { const msg = typeof res.data == 'string' ? res.data : JSON.stringify(res.data, null, 2); if (Util.OPTIONS.api === 'cli') { console.log(`${Util.color.fgMagenta}API RESPONSE <<${Util.color.reset}`, msg); // eslint-disable-line no-console } else if (Util.OPTIONS.api === 'log') { Util.logger.debug('API RESPONSE body << \n ' + msg); } }, }, requestAttempts: 4, retryOnConnectionError: true, }); } export default Auth; ================================================ FILE: lib/util/businessUnit.js ================================================ 'use strict'; import { Util } from './util.js'; import File from './file.js'; import auth from './auth.js'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * Helper that handles retrieval of BU info */ const BusinessUnit = { /** * Refreshes BU names and ID's from MC instance * * @param {Mcdevrc} properties current properties that have to be refreshed * @param {string} credentialsName identifying name of the installed package / project * @returns {Promise.<boolean>} success of refresh */ refreshBUProperties: async function (properties, credentialsName) { const currentCredentials = properties.credentials[credentialsName]; Util.logger.info(`Loading BUs`); try { const client = auth.getSDK({ mid: currentCredentials.eid, eid: currentCredentials.eid, credential: credentialsName, businessUnit: '_ParentBU_', }); const buResult = await client.soap.retrieve( 'BusinessUnit', ['Name', 'ID', 'ParentName', 'ParentID', 'IsActive'], { QueryAllAccounts: true } ); if (buResult !== null && !buResult.Results) { Util.logger.error(`Credentials worked but no BUs found. Check access rights!`); } else if (buResult !== null) { Util.logger.info(`Found ${buResult.Results.length} BUs:`); // create shortcut and reset BU list at the same time. we don't want old entries clutter the new list const myBuList = (currentCredentials.businessUnits = {}); // sort array by name for better display (wont affect object in settings) for (const element of buResult.Results.map((element) => { element.ID = Number.parseInt(element.ID); element.ParentID = Number.parseInt(element.ParentID); return element; }).toSorted((a, b) => { if (a.ParentID === 0) { return -1; } if (b.ParentID === 0) { return 1; } if (a.Name.toLowerCase() < b.Name.toLowerCase()) { return -1; } if (a.Name.toLowerCase() > b.Name.toLowerCase()) { return 1; } return 0; })) { if (element.ParentID === 0) { myBuList[Util.parentBuName] = element.ID; currentCredentials.eid = element.ID; Util.logger.info(` - ${Util.parentBuName} (${element.Name})`); } else { const equalizedName = element.Name.replaceAll(/[^\w\s]/gi, '') // remove special chars .replaceAll(/ +/g, '_') // convert spaces to underscore .replaceAll(/__+/g, '_'); // make sure we never have more than one underscore in a row myBuList[equalizedName] = element.ID; Util.logger.info( ` - ${element.Name} ${ element.Name === equalizedName ? '' : `(${equalizedName})` }` ); } } Util.logger.debug(`EID: ${currentCredentials.eid}`); if (currentCredentials.eid === null) { Util.logger.warn( `It seems your 'installed package' was not created on the Parent BU of your instance.` ); Util.logger.warn( `While basic functionality will work, it is strongly recommended that you create a new 'installed package' there to enable support for shared Data Extensions and automatic retrieval of the BU list.` ); Util.logger.warn( `If you cannot create a package on the Parent BU, please open your ./.mcdevrc.json and update the list of BUs and their MIDs manually.` ); // allow user to work by setting this to an obviously false value which nonetheless doesn't block execution currentCredentials.eid = -1; } // store BU list for repo await File.writeJSONToFile( properties.directories.businessUnits, File.filterIllegalFilenames(credentialsName + '.businessUnits'), buResult.Results ); // update config await File.saveConfigFile(properties); } } catch (ex) { Util.logger.error(`Credentials failure. ${ex}`); return null; } return true; }, }; export default BusinessUnit; ================================================ FILE: lib/util/cache.js ================================================ import { Util } from './util.js'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * * @typedef {import('../../types/mcdev.d.js').ListItem} ListItem * @typedef {import('../../types/mcdev.d.js').ListMap} ListMap */ /** @type {Cache} */ const dataStore = {}; let currentMID = null; export default { /** * Method to setup buObject * NOTE: in future this may need to restore, rather than wipe the cache * * @param {BuObject} buObject for current Business unit * @returns {void} */ initCache: (buObject) => { if (buObject?.mid) { currentMID = buObject.mid; dataStore[currentMID] = {}; // If the EID is not setup, also do this for required types (ie. Folders) if (!dataStore[buObject.eid]) { dataStore[buObject.eid] = {}; } } else { throw new Error('Business Unit (buObject) used when initialzing cache was missing MID'); } }, /** * return entire cache for current MID * * @returns {MultiMetadataTypeMap} cache for one Business Unit */ getCache: () => dataStore[currentMID], /* eslint-disable unicorn/no-array-for-each */ /** * clean cache for one BU if mid provided, otherwise whole cache * * @param {number} [mid] limit clearing to provided business unit MID * @param {string} [type] optionally limit clearing to specific metadata type; only used if mid is provided * @returns {void} */ clearCache: (mid, type) => mid ? Object.keys(dataStore[mid]).forEach((key) => { if (!type || type === key) { delete dataStore[mid][key]; } }) : Object.keys(dataStore).forEach((key) => delete dataStore[key]), /* eslint-enable unicorn/no-array-for-each */ /** * return a specific item from cache * * @param {string} type of Metadata to retrieve from cache * @param {string} key of the specific metadata * @returns {MetadataTypeItem} cached metadata item */ getByKey: (type, key) => dataStore[currentMID]?.[type]?.[key], /** * override cache for given metadata type with new data * * @param {string} type of Metadata to retrieve from cache * @param {MetadataTypeMap} metadataMap map to be set * @returns {void} */ setMetadata: (type, metadataMap) => { dataStore[currentMID][type] = metadataMap; }, /** * merges entire metadata type with existing cache * * @param {string} type of Metadata to retrieve from cache * @param {MetadataTypeMap} metadataMap map to be merged * @param {number} [overrideMID] which should be used for merging * @returns {void} */ mergeMetadata: (type, metadataMap, overrideMID) => { // ensure cache exists for type dataStore[currentMID][type] ||= {}; // if overrideMID is provided, create a copy of current MID cache if (overrideMID) { // ! needs to be verified if this is actually needed. When discovering an issue with this method actually overriting metadataMap, this copy-logic was present and i did not want to break things dataStore[overrideMID][type] = Object.assign({}, dataStore[currentMID][type]); } // merge metadataMap into existing cache Object.assign(dataStore[overrideMID || currentMID][type] || {}, metadataMap); }, /** * standardized method for getting data from cache. * * @param {string} metadataType metadata type ie. query * @param {string|number|boolean} searchValue unique identifier of metadata being looked for * @param {string} searchField field name (key in object) which contains the unique identifer * @param {string} returnField field which should be returned * @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID) * @param {boolean} caseInsensitive optional; if true, search is case insensitive * @returns {string} value of specified field. Error is thrown if not found */ searchForField( metadataType, searchValue, searchField, returnField, overrideMID, caseInsensitive = false ) { if (caseInsensitive) { searchValue = (searchValue + '').toLowerCase(); } for (const key in dataStore[overrideMID || currentMID]?.[metadataType]) { if ( (caseInsensitive && ( Util.resolveObjPath( searchField, dataStore[overrideMID || currentMID][metadataType][key] ) + '' ).toLowerCase() == searchValue) || (!caseInsensitive && Util.resolveObjPath( searchField, dataStore[overrideMID || currentMID][metadataType][key] ) == searchValue) ) { try { if ( Util.resolveObjPath( returnField, dataStore[overrideMID || currentMID][metadataType][key] ) ) { return Util.resolveObjPath( returnField, dataStore[overrideMID || currentMID][metadataType][key] ); } else { throw new Error(); // eslint-disable-line unicorn/error-message } } catch { throw new Error( `${metadataType} with ${searchField} '${searchValue}' does not have field '${returnField}'` ); } } } throw new Error( `Dependent ${metadataType} with ${searchField}='${searchValue}' was not found on your BU` ); }, /** * helper for setFolderId * * @param {string} r__folder_Path folder path value * @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID) * @param {boolean} allowOtherBu getting folder from other BU; FALSE for folder parent search * @returns {number} folder ID */ getFolderId(r__folder_Path, overrideMID, allowOtherBu = true) { const folder = this.getFolderByPath(r__folder_Path, overrideMID, allowOtherBu); return folder?.ID; }, /** * helper for setFolderId * * @param {string} r__folder_Path folder path value * @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID) * @param {boolean} allowOtherBu getting folder from other BU; FALSE for folder parent search * @returns {object} folder item */ getFolderByPath(r__folder_Path, overrideMID, allowOtherBu = true) { if (!r__folder_Path) { throw new Error('r__folder_Path not set'); } /** @type {ListMap} */ const folderMap = dataStore[overrideMID || currentMID]?.['folder']; if (!folderMap) { throw new Error('No folders found in cache'); } const folderPath_lower = r__folder_Path.toLowerCase(); const potentialFolders = []; for (const folder of Object.values(folderMap)) { if (!folder?.Path) { continue; // skip folders without Path } if (folder.Path.toLowerCase() === folderPath_lower) { if (folder?.Client?.ID === (overrideMID || currentMID)) { return folder; } else if (allowOtherBu) { potentialFolders.push(folder); } } } if (potentialFolders.length >= 1) { return potentialFolders[0]; } else { throw new Error(`No folders found with path ${r__folder_Path}`); } }, /** * standardized method for getting data from cache - adapted for special case of lists * ! keeping this in util/cache.js rather than in metadataTypes/List.js to avoid potential circular dependencies * * @param {string} searchValue unique identifier of metadata being looked for * @param {'ObjectID'|'ID'|'CustomerKey'} searchField ObjectID:string(uuid), ID:numeric, CustomerKey:string(name + folder ID) * @returns {string} unique folderPath/ListName combo of list */ getListPathName(searchValue, searchField) { const returnField1 = 'r__folder_Path'; const returnField2 = 'ListName'; for (const key in dataStore[currentMID]['list']) { if (dataStore[currentMID]['list'][key][searchField] === searchValue) { try { if ( dataStore[currentMID]['list'][key][returnField1] && dataStore[currentMID]['list'][key][returnField2] ) { return ( dataStore[currentMID]['list'][key][returnField1] + '/' + dataStore[currentMID]['list'][key][returnField2] ); } else { throw new Error(); // eslint-disable-line unicorn/error-message } } catch { throw new Error( `${'list'} with ${searchField}='${searchValue}' does not have the fields ${returnField1} and ${returnField2}` ); } } } throw new Error( `Dependent list with ${searchField}='${searchValue}' was not found on your BU` ); }, /** * standardized method for getting data from cache - adapted for special case of lists * ! keeping this in util/cache.js rather than in metadataTypes/List.js to avoid potential circular dependencies * * @param {string} listPathName folderPath/ListName combo of list * @param {'ObjectID'|'ID'|'CustomerKey'|'ListName'} returnField ObjectID:string(uuid), ID:numeric, CustomerKey:string(name + folder ID) * @returns {string} unique ObjectId of list */ getListObjectId(listPathName, returnField) { const folderPathArr = listPathName.split('/'); const listName = folderPathArr.pop(); const folderPath = folderPathArr.join('/'); for (const key in dataStore[currentMID]['list']) { if ( dataStore[currentMID]['list'][key].ListName === listName && dataStore[currentMID]['list'][key].r__folder_Path === folderPath ) { try { if (dataStore[currentMID]['list'][key][returnField]) { return dataStore[currentMID]['list'][key][returnField]; } else { throw new Error(); // eslint-disable-line unicorn/error-message } } catch { throw new Error( `${'list'} with ListName='${listName}' and r__folder_Path='${folderPath}' does not have field '${returnField}'` ); } } } throw new Error( `Dependent list with ListName='${listName}' and r__folder_Path='${folderPath}' was not found on your BU` ); }, }; ================================================ FILE: lib/util/cli.js ================================================ 'use strict'; import BuHelper from './businessUnit.js'; import File from './file.js'; import config from './config.js'; import { select, checkbox, input, number, confirm, Separator } from '@inquirer/prompts'; import MetadataDefinitions from './../MetadataTypeDefinitions.js'; import { Util } from './util.js'; import auth from './auth.js'; import 'console.table'; import MetadataTypeInfo from './../MetadataTypeInfo.js'; import TransactionalMessage from './../metadataTypes/TransactionalMessage.js'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../../types/mcdev.d.js').ExplainType} ExplainType */ /** * CLI helper class */ const Cli = { /** * used when initially setting up a project. * loads default config and adds first credential * * @returns {Promise.<string | boolean>} success of init */ async initMcdevConfig() { Util.logger.info('-- Initialising server connection --'); Util.logger.info('Please enter a name for your "Installed Package" credentials:'); const propertiesTemplate = await config.getDefaultProperties(); delete propertiesTemplate.credentials.default; // wait for the interaction to finish or else an outer await will run before this is done return this._setCredential(propertiesTemplate, null); }, /** * Extends template file for properties.json * * @param {Mcdevrc} properties config file's json * @returns {Promise.<boolean | string>} status */ async addExtraCredential(properties) { const skipInteraction = Util.skipInteraction; if (await config.checkProperties(properties)) { this.logExistingCredentials(properties); Util.logger.info('\nPlease enter your new credentials'); if (skipInteraction && properties.credentials[skipInteraction.credentialName]) { Util.logger.error( `Credential '${skipInteraction.credentialName}' already existing. If you tried updating please provide run 'mcdev init ${skipInteraction.credentialName}'` ); return null; } return this._setCredential(properties, null); } else { // return null here to avoid seeing 2 error messages for the same issue return null; } }, /** * * @param {string[]} dependentTypes types that depent on type * @returns {Promise.<boolean>} true if user wants to continue with retrieve */ async postFixKeysReretrieve(dependentTypes) { if (Util.isTrue(Util.skipInteraction?.fixKeysReretrieve)) { return true; } else if (Util.isFalse(Util.skipInteraction?.fixKeysReretrieve)) { return false; } else if (Util.skipInteraction) { // generic --yes / --skipInteraction: use the confirm default (true = do re-retrieve) return true; } else { const fixKeysReretrieve = await confirm({ message: `Do you want to re-retrieve dependent types (${dependentTypes.join( ', ' )}) now?`, default: true, }); if (Util.OPTIONS._multiBuExecution) { const rememberFixKeysReretrieve = await confirm({ message: `Remember answer for other BUs?`, default: true, }); if (rememberFixKeysReretrieve) { Util.skipInteraction ||= {}; Util.skipInteraction.fixKeysReretrieve = fixKeysReretrieve; } } return fixKeysReretrieve; } }, /** * helper that logs to cli which credentials are already existing in our config file * * @param {Mcdevrc} properties config file's json * @returns {void} */ logExistingCredentials(properties) { Util.logger.info('Found the following credentials in your config file:'); for (const cred in properties.credentials) { if (Object.prototype.hasOwnProperty.call(properties.credentials, cred)) { Util.logger.info(` - ${cred}`); } } }, /** * Extends template file for properties.json * update credentials * * @param {Mcdevrc} properties config file's json * @param {string} credName name of credential that needs updating * @param {boolean} [refreshBUs] if this was triggered by mcdev join, do not refresh BUs * @returns {Promise.<string | boolean>} success of update */ async updateCredential(properties, credName, refreshBUs = true) { const skipInteraction = Util.skipInteraction; if (credName) { if (!skipInteraction) { Util.logger.info(`Please enter the details for '${credName}'`); } return await this._setCredential(properties, credName, refreshBUs); } }, /** * Returns Object with parameters required for accessing API * * @param {Mcdevrc} properties object of all configuration including credentials * @param {string} target code of BU to use * @param {boolean | string} [isCredentialOnly] true:don't ask for BU | string: name of BU * @param {boolean} [allowAll] Offer ALL as option in BU selection * @returns {Promise.<BuObject>} credential to be used for Business Unit */ async getCredentialObject(properties, target, isCredentialOnly, allowAll) { try { if (!(await config.checkProperties(properties))) { // return null here to avoid seeing 2 error messages for the same issue return null; } let [credential, businessUnit] = target ? target.split('/') : [null, null]; if ( credential && properties.credentials[credential] && !businessUnit && 'string' === typeof isCredentialOnly ) { // correct credential provided and BU pre-selected businessUnit = isCredentialOnly; } else if (!credential || !properties.credentials[credential]) { // no or unknown credential provided; BU either to be selected or pre-selected if (credential !== null) { const msg = `Credential '${credential}' not found`; if (Util.skipInteraction) { throw new Error(msg); } Util.logger.warn(msg); } const response = await this._selectBU( properties, null, !!isCredentialOnly, allowAll ); credential = response.credential; businessUnit = response.businessUnit; if (!isCredentialOnly) { Util.logger.info( `You could directly pass in this info with '${credential}/${businessUnit}'` ); } else if (credential && !businessUnit && 'string' === typeof isCredentialOnly) { // BU pre-selected businessUnit = isCredentialOnly; } } else if ( !isCredentialOnly && (!businessUnit || !properties.credentials[credential].businessUnits[businessUnit]) ) { // correct credential provided but BU still needed if (businessUnit && businessUnit !== 'undefined') { const msg = `Business Unit '${businessUnit}' not found for credential '${credential}'`; if (Util.skipInteraction) { throw new Error(msg); } Util.logger.warn(msg); } const response = await this._selectBU(properties, credential, null, allowAll); businessUnit = response.businessUnit; Util.logger.info( `You could directly pass in this info with '${credential}/${businessUnit}'` ); } return { eid: properties.credentials[credential].eid, mid: properties.credentials[credential].businessUnits[businessUnit], businessUnit: businessUnit, credential: credential, }; } catch (ex) { Util.logger.error(ex.message); return null; } }, /** * helps select the right credential in case of bad initial input * * @param {Mcdevrc} properties config file's json * @param {string} [credential] name of valid credential * @param {boolean} [isCredentialOnly] don't ask for BU if true * @param {boolean} [allowAll] Offer ALL as option in BU selection * @returns {Promise.<{businessUnit:string, credential:string}>} selected credential/BU combo */ async _selectBU(properties, credential, isCredentialOnly, allowAll) { const credList = []; const buList = []; const allBUsAnswer = { value: '*', name: '* (All BUs)' }; const answer = {}; // no proper credential nor BU was given. ask for credential first if (!credential) { for (const cred in properties.credentials) { if (Object.keys(properties.credentials[cred].businessUnits).length) { // only add credentials that have BUs const credential = { value: cred, name: cred }; if ( !isCredentialOnly && (!properties.credentials[cred]?.businessUnits || !Object.keys(properties.credentials[cred].businessUnits).length) ) { credential.disabled = 'No Business Units defined'; } credList.push(credential); } } answer.credential = await select({ message: 'Please select the credential you were looking for:', choices: credList, }); if (!isCredentialOnly) { for (const bu in properties.credentials[answer.credential].businessUnits) { buList.push({ value: bu, name: bu }); } if (!buList.length) { // unlikely error as we are filtering for this already while creating credList throw new Error('No Business Unit defined for this credential'); } else if (allowAll) { // add ALL option to beginning of list buList.unshift(allBUsAnswer); } } } else if (credential) { for (const bu in properties.credentials[credential].businessUnits) { buList.push({ value: bu, name: bu }); } if (!buList.length) { // that could only happen if config is faulty throw new Error('No Business Unit defined for this credential'); } else if (allowAll) { // add ALL option to beginning of list buList.unshift(allBUsAnswer); } } if ((credential && buList.length) || (!credential && !isCredentialOnly)) { answer.businessUnit = await select({ message: 'Please select the right BU:', choices: buList, }); } if (!answer || !Object.keys(answer).length) { throw new Error('credentials / BUs not configured'); } return answer; }, /** * helper around _askCredentials * * @param {Mcdevrc} properties from config file * @param {string} [credName] name of credential that needs updating * @param {boolean} [refreshBUs] if this was triggered by mcdev join, do not refresh BUs * @returns {Promise.<boolean | string>} success of refresh or credential name */ async _setCredential(properties, credName, refreshBUs = true) { const skipInteraction = Util.skipInteraction; // Get user input /** @type {boolean} */ let credentialsGood; let inputData; do { if (skipInteraction) { if ( skipInteraction.client_id && skipInteraction.client_secret && skipInteraction.auth_url && skipInteraction.account_id && skipInteraction.credentialName ) { // assume skipInteraction=={client_id,client_secret,auth_url,credentialName} inputData = skipInteraction; } else { throw new Error( '--skipInteraction flag found but not defined for all required inputs: client_id,client_secret,auth_url,account_id,credentialName' ); } } else { inputData = await this._askCredentials(properties, credName); } // test if credentials are valid try { await auth.saveCredential( { client_id: inputData.client_id, client_secret: inputData.client_secret, auth_url: inputData.auth_url, account_id: Number.parseInt(inputData.account_id), }, inputData.credentialName ); credentialsGood = true; // update central config now that the credentials are verified properties.credentials[inputData.credentialName] = { eid: Number.parseInt(inputData.account_id), businessUnits: {}, }; } catch (ex) { Util.logger.error( `We could not verify your credential due to a problem (${ex.message}). Please try again.` ); credentialsGood = false; if (skipInteraction) { // break the otherwise infinite loop return; } } } while (!credentialsGood); if (refreshBUs) { // Get all business units and add them to the properties const status = await BuHelper.refreshBUProperties(properties, inputData.credentialName); return status ? inputData.credentialName : status; } else { return credentialsGood; } }, /** * helper for {@link Cli.addExtraCredential} * * @param {Mcdevrc} properties from config file * @param {string} [credName] name of credential that needs updating * @returns {Promise.<object>} credential info */ async _askCredentials(properties, credName) { const responses = {}; if (!credName) { responses.credentialName = await input({ message: 'Credential name (your choice)', // eslint-disable-next-line jsdoc/require-jsdoc validate: function (value) { if (!value || value.trim().length < 2) { return 'Please enter at least 2 characters'; } if (properties && properties.credentials[value]) { return `There already is an account with the name '${value}' in your config.`; } const converted = encodeURIComponent(value).replaceAll(/[*]/g, '_STAR_'); if (value != converted) { return 'Please do not use any special chars'; } return true; }, }); } const tenantRegex = /^https:\/\/([\w-]{28})\.(auth|soap|rest)\.marketingcloudapis\.com[/]?$/iu; responses.client_id = await input({ message: 'Client Id', // eslint-disable-next-line jsdoc/require-jsdoc validate: function (value) { if (!value || value.trim().length < 10) { return 'Please enter valid client id'; } return true; }, }); responses.client_secret = await input({ message: 'Client Secret', // eslint-disable-next-line jsdoc/require-jsdoc validate: function (value) { if (!value || value.trim().length < 10) { return 'Please enter valid client secret'; } return true; }, }); responses.auth_url = await input({ message: 'Authentication Base URI', validate: (value) => { if (!value || value.trim().length < 10) { return 'Please enter a valid tenant identifier'; } else if (tenantRegex.test(value.trim())) { // all good return true; } else { return `Please copy the URI directly from the installed package's "API Integration" section. It looks like this: https://a1b2b3xy56z.auth.marketingcloudapis.com/`; } }, }); responses.account_id = await number({ message: 'MID of Parent Business Unit', }); // remove extra white space responses.client_id = responses.client_id.trim(); responses.client_secret = responses.client_secret.trim(); responses.auth_url = responses.auth_url.trim(); if (credName) { // if credential name was provided as parameter, we didn't ask the user for it responses.credentialName = credName; } return responses; }, /** * allows updating the metadata types that shall be retrieved * * @param {Mcdevrc} properties config file's json * @param {string[]} [setTypesArr] skip user prompt and overwrite with this list if given * @returns {Promise.<void>} - */ async selectTypes(properties, setTypesArr) { let selectedTypes; if (setTypesArr) { selectedTypes = setTypesArr; } else { if (Util.logger.level === 'debug') { Util.logger.warn( 'Debug mode enabled. Allowing selection of "disabled" types. Please be aware that these might be unstable.' ); } else { Util.logger.info( 'Run mcdev selectTypes --debug if you need to use "disabled" types.' ); } const flattenedDefinitions = []; for (const el in MetadataDefinitions) { if (MetadataDefinitions[el].type === '') { // dont offer wrapper types like TransactionalMessage which don't have a value in "type" continue; } // if subtypes on metadata (eg. Assets) then add each nested subtype if ( MetadataDefinitions[el].subTypes && Array.isArray(MetadataDefinitions[el].typeRetrieveByDefault) ) { for (const subtype of MetadataDefinitions[el].subTypes) { flattenedDefinitions.push({ typeName: MetadataDefinitions[el].typeName.replace('-[Subtype]', ': ') + subtype, type: MetadataDefinitions[el].type + '-' + subtype, mainType: MetadataDefinitions[el].type, typeRetrieveByDefault: MetadataDefinitions[el].typeRetrieveByDefault.includes(subtype), }); } } // else just return normal type else { flattenedDefinitions.push({ typeName: MetadataDefinitions[el].typeName, type: MetadataDefinitions[el].type, typeRetrieveByDefault: MetadataDefinitions[el].typeRetrieveByDefault, }); } } // walk through all definitions (sub and main) and select them if already selected const typeChoices = flattenedDefinitions.map((def) => ({ name: def.typeName + (Util.logger.level === 'debug' && !def.typeRetrieveByDefault ? ' \x1B[1;30;40m(non-default)\u001B[0m' : ''), value: def.type, disabled: Util.logger.level === 'debug' || def.typeRetrieveByDefault ? false : 'disabled', // subtypes can be activated through their main type checked: properties.metaDataTypes.retrieve.includes(def.type) || (properties.metaDataTypes.retrieve.includes(def.mainType) && def.typeRetrieveByDefault) ? true : false, })); // sort types by 1) initially selected and 2) alphabetically typeChoices.sort((a, b) => { if (a.name && b.name && a.name.toLowerCase() < b.name.toLowerCase()) { return -1; } if (a.name && b.name && a.name.toLowerCase() > b.name.toLowerCase()) { return 1; } if (a.value.toLowerCase() < b.value.toLowerCase()) { return -1; } if (a.value.toLowerCase() > b.value.toLowerCase()) { return 1; } return 0; }); selectedTypes = await checkbox({ message: 'Select Metadata types for retrieval', pageSize: 10, choices: [...typeChoices, new Separator(' ==== ')], }); } if (selectedTypes) { selectedTypes = Util.summarizeSubtypes('typeRetrieveByDefault', selectedTypes); // update config properties.metaDataTypes.retrieve = selectedTypes; await File.saveConfigFile(properties); } }, /** * shows metadata type descriptions * * @returns {ExplainType[]} list of supported types with their apiNames */ explainTypes() { /** @type {ExplainType[]} */ const json = []; const apiNameArr = Object.keys(MetadataDefinitions); for (const apiName of apiNameArr) { const details = MetadataDefinitions[apiName]; if (details.type === '') { // skip wrapper types like TransactionalMessage which don't have a value in "type" continue; } const supportCheckClass = apiName.startsWith('transactional') ? TransactionalMessage : MetadataTypeInfo[apiName]; json.push({ name: details.typeName, apiName: details.type, retrieveByDefault: details.typeRetrieveByDefault, supports: { retrieve: Object.prototype.hasOwnProperty.call(supportCheckClass, 'retrieve'), create: Object.prototype.hasOwnProperty.call(supportCheckClass, 'create'), update: Object.prototype.hasOwnProperty.call(supportCheckClass, 'update'), delete: Object.prototype.hasOwnProperty.call(supportCheckClass, 'deleteByKey'), changeKey: supportCheckClass.definition.keyIsFixed === false && supportCheckClass.definition.keyField !== supportCheckClass.definition.idField && supportCheckClass.definition.fields[supportCheckClass.definition.keyField] .isUpdateable && Object.prototype.hasOwnProperty.call(supportCheckClass, 'update'), buildTemplate: Object.prototype.hasOwnProperty.call( supportCheckClass, 'create' ), // supported for all types that can be created retrieveAsTemplate: Object.prototype.hasOwnProperty.call( supportCheckClass, 'retrieveAsTemplate' ), }, description: details.typeDescription, }); } if (Util.OPTIONS.json) { if (Util.OPTIONS.loggerLevel !== 'error') { console.log(JSON.stringify(json, null, 2)); // eslint-disable-line no-console } return json; } const typeChoices = []; for (const el in MetadataDefinitions) { if (MetadataDefinitions[el].type === '') { // skip wrapper types like TransactionalMessage which don't have a value in "type" continue; } if (MetadataDefinitions[el].subTypes && MetadataDefinitions[el].extendedSubTypes) { // used for assets to show whats available by default typeChoices.push({ Name: MetadataDefinitions[el].typeName, Default: '┐', Description: MetadataDefinitions[el].typeDescription, }); let lastCountdown = MetadataDefinitions[el].subTypes.length; for (const subtype of MetadataDefinitions[el].subTypes) { lastCountdown--; const subTypeRetrieveByDefault = Array.isArray(MetadataDefinitions[el].typeRetrieveByDefault) && MetadataDefinitions[el].typeRetrieveByDefault.includes(subtype); const definition = ' ' + MetadataDefinitions[el].extendedSubTypes?.[subtype]?.join(', '); typeChoices.push({ Name: MetadataDefinitions[el].typeName.replace('-[Subtype]', ': ') + subtype, Default: (lastCountdown > 0 ? '├ ' : '└ ') + (subTypeRetrieveByDefault ? 'yes' : '-'), Description: definition.length > 90 ? definition.slice(0, 90) + '...' : definition, }); } // change leading symbol of last subtype to close the tree visually } else { // types without subtypes typeChoices.push({ Name: MetadataDefinitions[el].typeName, Default: MetadataDefinitions[el].typeRetrieveByDefault ? 'yes' : '-', Description: MetadataDefinitions[el].typeDescription, }); } } typeChoices.sort((a, b) => { if (a.Name.toLowerCase() < b.Name.toLowerCase()) { return -1; } if (a.Name.toLowerCase() > b.Name.toLowerCase()) { return 1; } return 0; }); if (Util.OPTIONS.loggerLevel !== 'error') { console.table(typeChoices); // eslint-disable-line no-console } return json; }, }; export default Cli; ================================================ FILE: lib/util/config.js ================================================ import { Util } from './util.js'; import File from './file.js'; import { confirm } from '@inquirer/prompts'; import semver from 'semver'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * Central class for loading and validating properties from config and auth */ const config = { properties: null, /** * loads central properties from config file * * @param {boolean} [silent] omit throwing errors and print messages; assuming not silent if not set * @param {boolean} [isInit] don't tell the user to run init * @returns {Promise.<Mcdevrc>} central properties object */ async getProperties(silent, isInit) { if (config.properties) { return config.properties; } if (await File.pathExists(Util.configFileName)) { try { config.properties = await File.readJSON(Util.configFileName); if (!isInit && !(await this.checkProperties(config.properties, silent))) { return; } } catch (ex) { Util.logger.error(`${ex.code}: ${ex.message}`); return; } if (await File.pathExists(Util.authFileName)) { let auth; try { auth = await File.readJSON(Util.authFileName); } catch (ex) { Util.logger.error(`${ex.code}: ${ex.message}`); return; } if (!auth) { const err = `${Util.authFileName} is not set up correctly.`; Util.logger.error(err); throw new Error(err); } for (const cred in config.properties.credentials) { if (auth[cred]) { if ( config.properties.credentials[cred].eid != auth[cred].account_id && !silent ) { Util.logger.error( `'${cred}' found in ${Util.configFileName} (${typeof config .properties.credentials[cred].eid} ${ config.properties.credentials[cred].eid }) and ${Util.authFileName} (${typeof auth[cred].account_id} ${ auth[cred].account_id }) have a Enterprise ID mismatch. Please check.` ); return; } // TODO add auth checks #294 } else if (!silent) { Util.logger.error( `'${cred}' found in ${Util.configFileName} but not in ${Util.authFileName}. Please run 'mcdev init' to provide the missing credential details.` ); return; } } } else if (!silent && !isInit) { Util.logger.error( `${Util.authFileName} not found. Please run 'mcdev init' to provide the missing credential details.` ); return; } } else if (!silent && !isInit) { Util.logger.error(`Could not find ${Util.configFileName} in ${process.cwd()}.`); Util.logger.error(`Run 'mcdev init' to initialize your project.\n`); } return config.properties; }, /** * check if the config file is correctly formatted and has values * * @param {Mcdevrc} properties javascript object in .mcdevrc.json * @param {boolean} [silent] set to true for internal use w/o cli output * @returns {Promise.<boolean | string[]>} file structure ok OR list of fields to be fixed */ async checkProperties(properties, silent) { if (!(await File.pathExists(Util.configFileName))) { Util.logger.error(`Could not find ${Util.configFileName} in ${process.cwd()}.`); Util.logger.error(`Run 'mcdev init' to initialize your project.\n`); return false; } if (!(await File.pathExists(Util.authFileName))) { Util.logger.error(`Could not find ${Util.authFileName} in ${process.cwd()}.`); Util.logger.error(`Run 'mcdev init' to initialize your project.\n`); return false; } if (!properties) { // assume there was an error loading the config failed return false; } // check if user is running older (ignores patches) mcdev version than whats saved to the config if (properties.version && semver.gt(properties.version, Util.packageJsonMcdev.version)) { Util.logger.error( `Your Accenture SFMC DevTools version ${Util.packageJsonMcdev.version} is lower than your project's config version ${properties.version}` ); if (Util.skipInteraction) { // print guidance for extension users Util.logger.error( `Run 'npm install -g mcdev@${properties.version}' now to fix this.` ); return false; } const runUpgradeNow = await confirm({ message: `Do you want to run 'npm install -g mcdev@${properties.version}' now? This may take a few minutes.`, default: true, }); if (runUpgradeNow) { // use _execSync here to avoid a circular dependency Util.execSync('npm', ['install', '-g', `mcdev@${properties.version}`]); } return false; } // check config properties const defaultProps = await this.getDefaultProperties(); const errorMsgs = []; const solutionSet = new Set(); const missingFields = []; for (const key in defaultProps) { if (Object.prototype.hasOwnProperty.call(defaultProps, key)) { if (Object.prototype.hasOwnProperty.call(properties, key)) { if (!silent && key === 'credentials') { if (Object.keys(properties.credentials)) { for (const cred in properties.credentials) { if (cred.includes('/') || cred.includes('\\')) { errorMsgs.push( `Credential names may not includes slashes: ${cred}` ); solutionSet.add('Apply manual fix in your config.'); } if ( !properties.credentials[cred].eid || properties.credentials[cred].eid === 0 ) { errorMsgs.push(`invalid account_id (EID) on ${cred}`); solutionSet.add(`Run 'mcdev init ${cred}'`); } let i = 0; for (const buName in properties.credentials[cred].businessUnits) { if (buName.includes('/') || buName.includes('\\')) { errorMsgs.push( `Business Unit names may not includes slashes: ${cred}: ${buName}` ); solutionSet.add(`Run 'mcdev reloadBUs ${cred}'`); } if ( Object.prototype.hasOwnProperty.call( properties.credentials[cred].businessUnits, buName ) && properties.credentials[cred].businessUnits[buName] !== 0 ) { i++; } } if (!i) { errorMsgs.push(`no Business Units defined`); solutionSet.add(`Run 'mcdev reloadBUs ${cred}'`); } } } else { errorMsgs.push(`no Credential defined`); } } else if (['directories', 'metaDataTypes', 'options'].includes(key)) { for (const subkey in defaultProps[key]) { if ( Object.prototype.hasOwnProperty.call(defaultProps[key], subkey) && !Object.prototype.hasOwnProperty.call(properties[key], subkey) ) { errorMsgs.push( `${key}.${subkey} missing. Default value (${ Array.isArray(defaultProps[key][subkey]) ? 'Array' : typeof defaultProps[key][subkey] }): ${typeof defaultProps[key][subkey] === 'object' ? JSON.stringify(defaultProps[key][subkey]) : defaultProps[key][subkey]}` ); solutionSet.add( `Run 'mcdev upgrade' to fix missing or changed configuration options` ); missingFields.push(`${key}.${subkey}`); } else if (subkey === 'deployment') { for (const dkey in defaultProps[key][subkey]) { if ( Object.prototype.hasOwnProperty.call( defaultProps[key][subkey], dkey ) && !Object.prototype.hasOwnProperty.call( properties[key][subkey], dkey ) ) { errorMsgs.push( `${key}.${subkey} missing. Default value (${ Array.isArray(defaultProps[key][subkey][dkey]) ? 'Array' : typeof defaultProps[key][subkey][dkey] }): ${defaultProps[key][subkey][dkey]}` ); solutionSet.add( `Run 'mcdev upgrade' to fix missing or changed configuration options` ); missingFields.push(`${key}.${subkey}.${dkey}`); } } } } } } else { errorMsgs.push(`${key}{} missing`); solutionSet.add( `Run 'mcdev upgrade' to fix missing or changed configuration options` ); missingFields.push(key); } } } // check if project config version is outdated compared to user's mcdev version if ( !properties.version || (![null, 'patch'].includes( semver.diff(Util.packageJsonMcdev.version, properties.version) ) && semver.gt(Util.packageJsonMcdev.version, properties.version)) ) { errorMsgs.push( `Your project's config version ${properties.version} is lower than your Accenture SFMC DevTools version ${Util.packageJsonMcdev.version}` ); solutionSet.add(`Run 'mcdev upgrade' to ensure optimal performance`); missingFields.push('version'); } if (silent) { return missingFields; } else { if (errorMsgs.length) { const errorMsgOutput = [ `Found problems in your ./${Util.configFileName} that you need to fix first:`, ]; for (const msg of errorMsgs) { errorMsgOutput.push(' - ' + msg); } Util.logger.error(errorMsgOutput.join('\n')); Util.logger.info( [ 'Here is what you can do to fix these issues:', ...Array.from(solutionSet), ].join('\n- ') ); if (Util.skipInteraction) { // print guidance for extension users Util.logger.error(`Run 'mcdev upgrade' now to fix this.`); return false; } const runUpgradeNow = await confirm({ message: `Do you want to run 'mcdev upgrade' now?`, default: true, }); if (runUpgradeNow) { // use _execSync here to avoid a circular dependency Util.execSync('mcdev', ['upgrade']); } return false; } else { return true; } } }, /** * defines how the properties.json should look like * used for creating a template and for checking if variables are set * * @returns {Promise.<Mcdevrc>} default properties */ async getDefaultProperties() { const configFileName = path.resolve(__dirname, Util.boilerplateDirectory, 'config.json'); if (!(await File.pathExists(configFileName))) { Util.logger.debug(`Default config file not found in ${configFileName}`); return; } const defaultProperties = await File.readJSON(configFileName); // set default name for parent BU defaultProperties.credentials.default.businessUnits[Util.parentBuName] = 0; // set default retrieve values defaultProperties.metaDataTypes.retrieve = Util.getTypeChoices('typeRetrieveByDefault'); // set default retrieve values defaultProperties.metaDataTypes.createDeltaPkg = Util.getTypeChoices('typeCdpByDefault'); return defaultProperties; }, }; export default config; ================================================ FILE: lib/util/devops.js ================================================ import File from './file.js'; import path from 'node:path'; import { select, confirm, Separator } from '@inquirer/prompts'; import { Util } from './util.js'; import Cli from './cli.js'; import { simpleGit } from 'simple-git'; const git = simpleGit(); import mcdev from '../index.js'; import Builder from '../Builder.js'; import MetadataType from '../MetadataTypeInfo.js'; import jsonToTable from 'json-to-table'; import pLimit from 'p-limit'; import cliProgress from 'cli-progress'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../../types/mcdev.d.js').BuildFilter} BuildFilter */ /** * DevOps helper class */ const DevOps = { /** * Extracts the delta between a commit and the current state for deployment. * Interactive commit selection if no commits are passed. * * @param {Mcdevrc} properties central properties object * @param {string} [range] git commit range * @param {boolean} [saveToDeployDir] if true, copy metadata changes into deploy directory * @param {string} [filterPathsCSV] filter file paths that start with any specified path (comma separated) * @param {number} [commitHistory] cli option to override default commit history value in config * @returns {Promise.<DeltaPkgItem[]>} - */ async getDeltaList(properties, range, saveToDeployDir, filterPathsCSV, commitHistory) { const rangeUserInput = range; const filterPaths = filterPathsCSV ? filterPathsCSV.split(',').map( (filePath) => path .normalize(properties.directories.retrieve + filePath) .split('\\') .join('/') + '/' ) : [properties.directories.retrieve]; if (range) { if (!range.includes('..')) { // we limit the user here somewhat by always comparing to current branch if no range was given // this should make it easier in most scenrios though range = range + '..HEAD'; } Util.logger.info( `Analyzing changes in directories: ${filterPaths} based on commit range: ${range}` ); } else { // get the last 10 commits by default to choose from. Default can be changed in mcdev config. // Current commit is skipped due to no changes const commits = await git.log([ '--skip=1', `-${commitHistory || properties.options.deployment.commitHistory || 10}`, ]); /** @type {({value: string, name?: string, description?: string, disabled?: boolean | string} | Separator)[]} */ const choices = commits.all.map((commit) => ({ name: commit.date.split('T').join(' ').split('+')[0] + ' / ' + commit.message + ' / ' + commit.author_name, value: commit.hash, })); choices.push(new Separator(' ==== ')); const baseCommit = await select({ message: 'Select base commit for comparison with current commit', pageSize: 10, choices: choices, }); range = `${baseCommit}..HEAD`; } const metadata = {}; // TODO: add filter based on if metadata type is deployable or not const gitActionsCounter = { delete: 0, 'add/update': 0, move: 0, }; let diffSummary; try { diffSummary = await git.diffSummary([range]); } catch (ex) { const error = ex.message.startsWith('fatal: ambiguous argument') ? new Error( `Make sure you checked out the branches mentioned in your git range (${rangeUserInput})` ) : ex; throw error; } Util.logger.info(`Found ${diffSummary.files.length} changed files in the commit range`); /** * @type {DeltaPkgItem[]} */ // first, process everything that can be done synchronously here const deltaSync = diffSummary.files // populate additional info for all changed files .map((/** @type {DeltaPkgItem} */ file) => { // If file was moved it's path needs to be parsed file.moved = file.file.includes('=>'); if (file.moved) { const p = file.file; // TODO: rewrite remaining substring() to slice() const paths = { base: p.slice(0, Math.max(0, p.indexOf('{'))), before: p.substring(p.indexOf('{') + 1, p.indexOf('=>') - 1), // eslint-disable-line unicorn/prefer-string-slice after: p.substring(p.indexOf('=>') + 3, p.indexOf('}')), // eslint-disable-line unicorn/prefer-string-slice end: p.slice(Math.max(0, p.indexOf('}') + 1)), }; file.fromPath = path .normalize(`${paths.base}${paths.before}${paths.end}`) .split('\\') .join('/'); file.file = path .normalize(`${paths.base}${paths.after}${paths.end}`) .split('\\') .join('/'); } else { file.fromPath = '-'; file.file = path.normalize(file.file).split('\\').join('/'); } // get metadata type from file name file.type = file.file.split('/')[3]; return file; }) // Filter to only handle files that start with at least one of the passed filterPaths. // ! Filter happens after initial parse, because if file was moved its new path has to be calculated .filter((file) => filterPaths.some((path) => file.file.startsWith(path))) .filter((file) => !file.file.endsWith('.error.log')) .filter((file) => !file.file.endsWith('.md')) // ensure badly named files on unsupported metadata types are not in our subset .filter((/** @type {DeltaPkgItem} */ file) => { if (MetadataType[file.type]) { return true; } else { Util.logger.debug( `Unknown metadata-type found for (${file.file}): ` + file.type ); return false; } }); Util.logger.info( `Identified ${deltaSync.length} relevant file changes after filtering file types and folders. Processing related metadata now.` ); // second, we need to do asynchronous file operations const extendedBar = new cliProgress.SingleBar( { format: ' Processing changes [{bar}] {percentage}% | {value}/{total}', }, cliProgress.Presets.shades_classic ); extendedBar.start(deltaSync.length, 0); const rateLimit = pLimit(10); /** * @type {DeltaPkgItem[]} */ const delta = await Promise.all( deltaSync.map((/** @type {DeltaPkgItem} */ file) => rateLimit(async () => { // Gets external key based on file name und the assumption that filename = externalKey if (file.type === 'folder') { file.externalKey = null; file.name = path.basename(file.file).split('.').shift(); } else { // find the key in paths like: // - retrieve/cred/bu/asset/block/016aecc7-7063-4b78-93f4-aa119ea933c7.asset-block-meta.html // - retrieve/cred/bu/query/03efd5f1-ba1f-487a-9c9a-36aeb2ae5192.query-meta.sql // assets have an additional folder level for their subtype // keys could contain dots themselves file.externalKey = file.file .split('/') [file.type === 'asset' ? 5 : 4].split('.') .slice(0, -2) .join('.'); if (file.type === 'asset' && !file.externalKey) { // retrieve/cred/bu/asset/message/emailkey/blocks/views.html.slots.[8maw2k7jnlb-5llcajmxaqa].asset-message-meta.html file.externalKey = file.file.split('/')[5]; } file.name = null; } // Check if file doesn't exist in reported path, that means it was a git deletion // TODO: improve git action detection by switching from diffSummary to diff with --summary result parsing if (!(await File.pathExists(file.file))) { file.gitAction = 'delete'; } else if (file.moved) { file.gitAction = 'move'; } else { file.gitAction = 'add/update'; } gitActionsCounter[file.gitAction]++; file._credential = file.file.split('/')[1]; file._businessUnit = file.file.split('/')[2]; // Parse retrieve directory to also populate the name field (not possible for deleted files) if (file.gitAction !== 'delete' && file.type !== 'folder') { // folders are saved with their name as file-name, not with their key, hence this section can be skipped for folders const buPath = `${properties.directories.retrieve}/${file._credential}/${file._businessUnit}/`; if (!metadata[file._credential]) { metadata[file._credential] = {}; } if (!metadata[file._credential][file._businessUnit]) { metadata[file._credential][file._businessUnit] = {}; } if (!metadata[file._credential][file._businessUnit][file.type]) { try { await MetadataType[file.type].readBUMetadataForType( buPath, false, metadata[file._credential][file._businessUnit] ); } catch (ex) { // silently catch directory-not-found errors here Util.logger.debug(ex.message); } } const fileContent = metadata[file._credential][file._businessUnit][file.type][ file.externalKey ]; if (fileContent) { file.name = fileContent[MetadataType[file.type].definition.nameField]; } } extendedBar.increment(); return file; }) ) ); // stop the progress bar extendedBar.stop(); if ( !gitActionsCounter['add/update'] && !gitActionsCounter.move && !gitActionsCounter.delete ) { Util.logger.warn( `- ❌ No changes found. Check what branch you are currently on and if the target branch name (${rangeUserInput}${ range === rangeUserInput ? '' : ' converted to ' + range }) was correct` ); return []; } // Write into delta.json to serve as documentation const directoryDeltaPkg = 'logs/'; await File.writeJSONToFile( directoryDeltaPkg, Util.logFileName + '-delta_package-' + filterPathsCSV.replaceAll(',', '-').replaceAll('/', '-'), delta ); this.document(directoryDeltaPkg, filterPathsCSV, delta); Util.logger.info( `- ✔️ Identified changes: Add/Update=${gitActionsCounter['add/update']}, Move=${gitActionsCounter['move']}, Delete=${gitActionsCounter['delete']}` ); if (gitActionsCounter.move > 0 || gitActionsCounter.delete > 0) { Util.logger.warn( 'Deleted/Changed keys detected! Please note that re-keyed components should have their key changed as a pre-deployment step.' ); } Util.logger.info( `Saved report in ./${directoryDeltaPkg}${Util.logFileName}-delta_package.md` ); // const deletedTypeKeys = {}; // for (const file of delta.filter((file) => file.gitAction === 'delete')) { // if (deletedTypeKeys[file.type]) { // deletedTypeKeys[file.type].add(file.externalKey); // } else { // deletedTypeKeys[file.type] = new Set([file.externalKey]); // } // } // for (const deletedType in deletedTypeKeys) { // const keyArr = [...deletedTypeKeys[deletedType]]; // Util.logger.warn(`Found deleted ${deletedType} keys: ${keyArr.join(', ')}`); // } // Copy filtered list of files into deploy directory // only do that if we do not use templating if (saveToDeployDir) { // if templating is not used, we need to add related files to the delta package const typeKeysMap = {}; /** @type {Object.<string, BuObject>} */ const buObjects = {}; for (const file of delta) { if (file.gitAction === 'delete' || file.type === 'folder') { continue; } if (typeKeysMap[file.type]) { typeKeysMap[file.type].push(file.externalKey); } else { typeKeysMap[file.type] = [file.externalKey]; } if (!buObjects[`${file._credential}/${file._businessUnit}`]) { buObjects[`${file._credential}/${file._businessUnit}`] = await Cli.getCredentialObject( properties, `${file._credential}/${file._businessUnit}` ); } } // a bit crude but works for now for (const buObject of Object.values(buObjects)) { for (const type in typeKeysMap) { MetadataType[type].buObject = buObject; MetadataType[type].properties = properties; const additionalFiles = await MetadataType[type].getFilesToCommit( typeKeysMap[type] ); if (additionalFiles?.length) { delta.push( ...additionalFiles .map((filePath) => ({ file: path.normalize(filePath).split('\\').join('/'), type, gitAction: 'add/update', })) .filter( // avoid adding files that we already have in the list (addFile) => !delta.find((existFile) => existFile.file === addFile.file) ) ); } } } let isPurgeDeployFolder; if (!Util.skipInteraction) { // deploy folder is in targets for definition creation // recommend to purge their content first isPurgeDeployFolder = await confirm({ message: 'Do you want to empty the deploy folder (ensures no files from previous deployments remain)?', default: true, }); } if (Util.skipInteraction || isPurgeDeployFolder) { // Clear output folder structure for selected sub-type for (const buObject of Object.values(buObjects)) { await File.remove( File.normalizePath([ properties.directories.deploy, buObject.credential, buObject.businessUnit, ]) ); } } /** @type {Promise.<{status:'ok'|'skipped'|'failed', statusMessage:string, file:string}>[]} */ const copied = delta .filter((file) => !file.file.endsWith('.md')) // filter documentation files .map((file) => File.copyFileSimple( file.file, path .normalize(file.file) .replace( path.normalize(properties.directories.retrieve), path.normalize(properties.directories.deploy) ) ) ); const results = await Promise.all(copied); const failed = results.filter((result) => result.status === 'failed'); const skipped = results.filter((result) => result.status === 'skipped'); Util.logger.info( `Copied changes to deploy directory (${ results.length - skipped.length - failed.length } copied)` ); Util.logger.debug( `Copied changes to deploy directory (${ results.length - skipped.length - failed.length } copied, ${skipped.length} skipped, ${failed.length} failed)` ); if (skipped.length > 0) { for (const file of skipped) { Util.logger.debug(`Skipped - ${file.statusMessage} - ${file.file}`); } } if (failed.length > 0) { for (const file of failed) { Util.logger.error(`Failed - ${file.statusMessage} - ${file.file}`); } } } return delta; }, /** * wrapper around DevOps.getDeltaList, Builder.buildTemplate and M * * @param {Mcdevrc} properties project config file * @param {string} range git commit range * @param {DeltaPkgItem[]} [diffArr] instead of running git diff the method can also get a list of files to process * @param {number} [commitHistory] cli option to override default commit history value in config * @returns {Promise.<DeltaPkgItem[]>} - */ async buildDeltaDefinitions(properties, range, diffArr, commitHistory) { // check if sourceTargetMapping is valid let sourceTargetMapping; if (properties.options.deployment.branchSourceTargetMapping?.[range]) { Util.logger.info(Util.getGrayMsg('Using branch specific sourceTargetMapping')); sourceTargetMapping = properties.options.deployment.branchSourceTargetMapping[range]; } else if ( properties.options.deployment.sourceTargetMapping && Object.keys(properties.options.deployment.sourceTargetMapping).length ) { Util.logger.info(Util.getGrayMsg('Using generic sourceTargetMapping')); sourceTargetMapping = properties.options.deployment.sourceTargetMapping; } else { Util.logger.error('Bad configuration of options.deployment.sourceTargetMapping'); return; } const sourceMarketListArr = Object.keys(sourceTargetMapping); /** @type {DeltaPkgItem[]} */ const deltaDeployAll = []; for (const sourceML of sourceMarketListArr) { // check if sourceTargetMapping has valid values // #1 check source marketlist try { Util.verifyMarketList(sourceML, properties); // remove potentially existing "description"-entry delete properties.marketList[sourceML].description; const sourceMarketBuArr = Object.keys(properties.marketList[sourceML]).filter( (key) => key !== 'filter' ); if (sourceMarketBuArr.length !== 1) { throw new Error('Only 1 BU is allowed per source marketList'); } if ('string' !== typeof properties.marketList[sourceML][sourceMarketBuArr[0]]) { throw new TypeError('Only 1 market per BU is allowed per source marketList'); } } catch (ex) { Util.logger.error('Deployment Source: ' + ex.message); return; } // #2 check corresponding target marketList let targetML; try { targetML = sourceTargetMapping[sourceML]; if ('string' !== typeof targetML) { throw new TypeError( 'Please define one target marketList per source in deployment.sourceTargetMapping (No arrays allowed)' ); } Util.verifyMarketList(targetML, properties); // remove potentially existing "description"-entry delete properties.marketList[targetML].description; } catch (ex) { Util.logger.error('Deployment Target: ' + ex.message); } } if (Util.OPTIONS.purge === true && sourceMarketListArr.length > 1) { // if --purge was defined and there is more than one source-target mapping, execute the purge up front to avoid deleting the package that was created by a prior mapping in this same run for (const sourceMlName of sourceMarketListArr) { /** @type {string} */ await Builder.purgeDeployFolderList(sourceTargetMapping[sourceMlName]); } Util.OPTIONS.purge = false; } // all good let's loop a second time for actual execution for (const sourceMlName of sourceMarketListArr) { /** @type {string} */ const targetMlName = sourceTargetMapping[sourceMlName]; const sourceMarketLists = properties.marketList[sourceMlName]; /** @type {string} */ const sourceBU = Object.keys(sourceMarketLists).find((key) => key !== 'filter'); // accept ["oneMarket"] or "oneMarket" for sourceMarket, but not ["oneMarket","secondMarket"] or [] /** @type {string} */ const sourceMarket = Array.isArray(sourceMarketLists[sourceBU]) && sourceMarketLists[sourceBU].length === 1 ? sourceMarketLists[sourceBU][0] : sourceMarketLists[sourceBU]; if ('string' !== typeof sourceMarket) { Util.logger.error( 'Deployment Source market list needs to have a 1:1 BU-Market combo. Your value: ' + sourceMarket ); // skip this source-target mapping continue; } let delta; try { delta = Array.isArray(diffArr) ? diffArr : await DevOps.getDeltaList(properties, range, false, sourceBU, commitHistory); } catch (ex) { Util.logger.error(ex.message); return; } // If only chaing templating and buildDefinition if required if (!delta || delta.length === 0) { // skip this source-target mapping continue; } Util.logger.info('============='); // Put files into maps. One map with BU -> type -> file (for retrieveAsTemplate) // Other map only with type -> file (for buildDefinitionBulk) const buTypeDelta = {}; // for bt, with BU info const deltaDeploy = delta // Only template/build files that were added/updated/moved. no deletions // ! doesn't work for folder, because their name parsing doesnt work at the moment .filter((file) => file.gitAction !== 'delete' && file.name); deltaDeployAll.push(...deltaDeploy); for (const file of deltaDeploy) { const buFrom = `${file._credential}/${file._businessUnit}`; if (!buTypeDelta[buFrom]) { // init object /** @type {TypeKeyCombo} */ buTypeDelta[buFrom] = {}; } if (!buTypeDelta[buFrom][file.type]) { // init array buTypeDelta[buFrom][file.type] = []; } if (!buTypeDelta[buFrom][file.type].includes(file.externalKey)) { buTypeDelta[buFrom][file.type].push(file.externalKey); } } for (const buFrom in buTypeDelta) { for (const type of Object.keys(buTypeDelta[buFrom])) { if ( Array.isArray(properties.metaDataTypes.createDeltaPkg) && !properties.metaDataTypes.createDeltaPkg.includes(type) ) { Util.logger.warn( `Skipping ${type} for build based on config.metaDataTypes.createDeltaPkg: ${buTypeDelta[buFrom][type].join(', ')}` ); delete buTypeDelta[buFrom][type]; } } // Run buildTemplate for each business unit for each type await mcdev.build( buFrom, undefined, buTypeDelta[buFrom], [sourceMarket], [targetMlName], true, sourceMarketLists.filter ); } this._generateDeleteInstructions(delta, sourceMarket, properties, targetMlName); } if (!deltaDeployAll.length) { Util.logger.error( '- ❌ No Templates or Deploy Definitions created. Check if you expected no changes.' ); } return deltaDeployAll; }, /** * create markdown file for deployment listing * * @param {string} directory - * @param {string} filterPathsCSV - * @param {object} jsonReport - * @returns {void} */ document(directory, filterPathsCSV, jsonReport) { const tabled = jsonToTable(jsonReport); let output = `# Deployment Report\n\n`; let tableSeparator = ''; for (const column of tabled[0]) { if (column !== '') { output += `| ${column} `; tableSeparator += '| --- '; } } output += `|\n${tableSeparator}|\n`; for (let i = 1; i < tabled.length; i++) { for (let field of tabled[i]) { if (field !== '') { field = field === true ? '✓' : field === false ? '✗' : field; output += `| ${field} `; } } output += '|\n'; } try { // write to disk (asynchronously) File.writeToFile( directory, Util.logFileName + '-delta_package-' + filterPathsCSV.replaceAll(',', '-').replaceAll('/', '-'), 'md', output ); } catch (ex) { Util.logger.error(`DevOps.document():: error | ` + ex.message); } }, /** * should return only the json for all but asset, query and script that are saved as multiple files * additionally, the documentation for dataExtension and automation should be returned * * @param {Mcdevrc} properties central properties object * @param {BuObject} buObject references credentials * @param {string} metadataType metadata type to build * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext'] */ getFilesToCommit(properties, buObject, metadataType, keyArr) { MetadataType[metadataType].properties = properties; MetadataType[metadataType].buObject = buObject; return MetadataType[metadataType].getFilesToCommit(keyArr); }, /** * helper for {@link DevOps.buildDeltaDefinitions} * * @param {DeltaPkgItem[]} delta git delta * @param {string} sourceMarket market for the source BU * @param {Mcdevrc} properties mcdev config * @param {string} targetMlName marketList used to build for the target BU */ _generateDeleteInstructions(delta, sourceMarket, properties, targetMlName) { const deltaDelete = delta .filter((file) => file.gitAction === 'delete') .filter( // in case of assets we need to be careful because extracted code files might get deleted but that doesnt mean the asset was (file) => file.type !== 'asset' || (file.type === 'asset' && file.file.endsWith('.json')) ); const buTypeDeltaDelete = {}; // for bt, with BU info for (const file of deltaDelete) { const buFrom = `${file._credential}/${file._businessUnit}`; if (!buTypeDeltaDelete[buFrom]) { // init object /** @type {TypeKeyCombo} */ buTypeDeltaDelete[buFrom] = {}; } if (!buTypeDeltaDelete[buFrom][file.type]) { // init array buTypeDeltaDelete[buFrom][file.type] = []; } if (!buTypeDeltaDelete[buFrom][file.type].includes(file.externalKey)) { buTypeDeltaDelete[buFrom][file.type].push(file.externalKey); } } const deleteByBU = {}; for (const buFrom in buTypeDeltaDelete) { /** @type {TemplateMap} */ const sourceVariables = {}; if (Util.checkMarket(sourceMarket, properties)) { Object.assign(sourceVariables, properties.markets[sourceMarket]); } const typeKeyFrom = {}; const typeKeyDelete = {}; for (const type of Object.keys(buTypeDeltaDelete[buFrom])) { if ( Array.isArray(properties.metaDataTypes.createDeltaPkg) && !properties.metaDataTypes.createDeltaPkg.includes(type) ) { Util.logger.warn( `Skipping ${type} for delete based on config.metaDataTypes.createDeltaPkg: ${buTypeDeltaDelete[buFrom][type].join(', ')}` ); delete buTypeDeltaDelete[buFrom][type]; continue; } typeKeyFrom[type] = new Set(); if (Object.keys(sourceVariables).length > 0) { for (let i = 0; i < buTypeDeltaDelete[buFrom][type].length; i++) { // add templating variables to keys typeKeyFrom[type].add( Util.replaceByObject( buTypeDeltaDelete[buFrom][type][i], sourceVariables ) ); } } typeKeyFrom[type] = Array.from(typeKeyFrom[type]); for (const targetBu in properties.marketList[targetMlName]) { typeKeyDelete[targetBu] ||= {}; typeKeyDelete[targetBu][type] ||= []; deleteByBU[targetBu] || {}; const market = properties.marketList[targetMlName][targetBu]; const markets = 'string' === typeof market ? [market] : market; for (const marketArr of markets) { const templateVariables = {}; for (const market of Array.isArray(marketArr) ? marketArr : [marketArr]) { if (Util.checkMarket(market, properties)) { Object.assign(templateVariables, properties.markets[market]); } } typeKeyDelete[targetBu][type].push( ...typeKeyFrom[type].map((key) => MetadataType[type].applyTemplateValues(key, templateVariables) ) ); } } } for (const targetBu in typeKeyDelete) { const metadataList = []; for (const type in typeKeyDelete[targetBu]) { for (const key of typeKeyDelete[targetBu][type]) { metadataList.push(type + ':"' + key + '"'); } } if (metadataList.length) { Util.logger.warn( `Run the following to delete ${metadataList.length} potentially existing old files in ${targetBu}` ); Util.logger.warn(`mcdev delete ${targetBu} -m ${metadataList.join(' ')}`); } } } }, }; export default DevOps; ================================================ FILE: lib/util/file.js ================================================ 'use strict'; import fs from 'fs-extra'; import path from 'node:path'; import prettier from 'prettier'; import beautyAmp from 'beauty-amp-core2'; import { Util } from './util.js'; import updateNotifier from 'update-notifier'; import config from './config.js'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ // inform user when there is an update const notifier = updateNotifier({ pkg: Util.packageJsonMcdev, updateCheckInterval: 1000 * 3600 * 24, // once per day }); // Notify using the built-in convenience method notifier.notify(); /** * File extends fs-extra. It adds logger and util methods for file handling */ const File = { prettierConfig: null, prettierConfigFileType: null, /** * copies a file from one path to another * * @param {string} from - full filepath including name of existing file * @param {string} to - full filepath including name where file should go * @returns {Promise.<{status:'ok'|'skipped'|'failed', statusMessage:string, file:string}>} - results object */ async copyFileSimple(from, to) { try { await fs.copy(from, to); return { status: 'ok', statusMessage: null, file: from }; } catch (ex) { // This can happen in some cases where referencing files deleted in Commit return ex.message.startsWith('ENOENT: no such file or directory') ? { status: 'skipped', statusMessage: 'deleted from repository', file: from, } : { status: 'failed', statusMessage: ex.message, file: from }; } }, /** * makes sure Windows accepts path names * * @param {string} path - filename or path * @returns {string} - corrected string */ filterIllegalPathChars(path) { return ( encodeURIComponent(path) .replaceAll(/[*]/g, '_STAR_') // convert space back .split('%20') .join(' ') // convert forward slash back as it's needed in dirs .split('%2F') .join('/') // convert backward slash back as it's needed in dirs .split('%5C') .join('\\') // convert opening-curly brackets back for templating .split('%7B') .join('{') // convert closing-curly brackets back for templating .split('%7D') .join('}') // convert brackets back for asset blocks .split('%5B') .join('[') // convert brackets back for asset blocks .split('%5D') .join(']') // convert @ back for users .split('%40') .join('@') ); }, /** * makes sure Windows accepts file names * * @param {string} filename - filename or path * @returns {string} - corrected string */ filterIllegalFilenames(filename) { return ( encodeURIComponent(filename) .replaceAll(/[*]/g, '_STAR_') // convert space back .split('%20') .join(' ') // convert opening-curly brackets back for templating .split('%7B') .join('{') // convert closing-curly brackets back for templating .split('%7D') .join('}') // convert brackets back for asset blocks .split('%5B') .join('[') // convert brackets back for asset blocks .split('%5D') .join(']') // convert @ back for users .split('%40') .join('@') ); }, /** * makes sure Windows accepts file names * * @param {string} filename - filename or path * @returns {string} - corrected string */ reverseFilterIllegalFilenames(filename) { return decodeURIComponent(filename).split('_STAR_').join('*'); }, /** * Takes various types of path strings and formats into a platform specific path * * @param {string|string[]} denormalizedPath directory the file will be written to * @returns {string} Path strings */ normalizePath: function (denormalizedPath) { /* eslint-disable unicorn/prefer-ternary */ if (Array.isArray(denormalizedPath)) { // if the value is undefined set to empty string to allow parsing return path.join(...denormalizedPath.map((val) => val || '')); } else { // if directory is empty put . as otherwill will write to c:// return path.join(denormalizedPath || '.'); } /* eslint-enable unicorn/prefer-ternary */ }, /** * Saves json content to a file in the local file system. Will create the parent directory if it does not exist * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {object} content filecontent * @returns {Promise} Promise */ writeJSONToFile: async function (directory, filename, content) { directory = this.filterIllegalPathChars(this.normalizePath(directory)); filename = this.filterIllegalFilenames(filename); await fs.ensureDir(directory); try { return fs.writeJSON(path.join(directory, filename + '.json'), content, { spaces: 4 }); } catch (ex) { Util.logger.error('File.writeJSONToFile:: error | ' + ex.message); } }, /** * Saves beautified files in the local file system. Will create the parent directory if it does not exist * ! Important: run 'await File.initPrettier()' in your MetadataType.retrieve() once before hitting this * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without suffix * @param {string} filetype filetype ie. JSON or SSJS * @param {string} content filecontent * @param {TemplateMap} [templateVariables] templating variables to be replaced in the metadata * @returns {Promise.<boolean>} Promise */ writePrettyToFile: async function (directory, filename, filetype, content, templateVariables) { let formatted; const properties = await config.getProperties(); if ( (properties?.options?.formatOnSave && Util.OPTIONS.format === undefined) || Util.OPTIONS.format ) { formatted = filetype === 'amp' ? await this.beautify_beautyAmp(content, false) : await this._beautify_prettier(directory, filename, filetype, content); } else { // skip formatting formatted = content; } if (templateVariables) { formatted = Util.replaceByObject(formatted, templateVariables); } return this.writeToFile(directory, filename, filetype, formatted); }, /** * helper that applies beautyAmp onto given stringified content; strongly typed for strings only * * @param {string} content code * @param {boolean} [formatHTML] applies formatting to html and ampscript if true * @returns {Promise.<string>} formatted code */ _beautify_beautyAmp_beautify: async function (content, formatHTML = true) { const response = await beautyAmp.beautify(content, formatHTML); if (typeof response == 'string') { return response.trim() + '\n'; } else { throw new TypeError('beautyAmp failed to beautify the content'); } }, /** * helper for {@link File.writePrettyToFile}, applying beautyAmp onto given stringified content * * @param {string} content filecontent * @param {boolean} formatHTML should we format HTML or not via prettier included in beautyAmp * @returns {Promise.<string>} original string on error; formatted string on success */ beautify_beautyAmp: async function (content, formatHTML = true) { const properties = await config.getProperties(); if ( (properties?.options?.formatOnSave && Util.OPTIONS.format === undefined) || Util.OPTIONS.format ) { // logs trough console only for the moment. const logs = { loggerOn: false, // <= disable logging }; try { beautyAmp.setup(null, null, logs); // Note: we need to trim the result as beautyAmp adds a leading new line; but we also want to ensure there is a single new line at the end to comply with standard linting rules return await this._beautify_beautyAmp_beautify(content, formatHTML); } catch { return content; } } else { // skip formatting return content; } }, /** * helper for {@link File.writePrettyToFile}, applying prettier onto given stringified content * ! Important: run 'await File.initPrettier()' in your MetadataType.retrieve() once before hitting this * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without suffix * @param {string} filetype filetype ie. JSON or SSJS * @param {string} content filecontent * @returns {Promise.<string>} original string on error; formatted string on success */ _beautify_prettier: async function (directory, filename, filetype, content) { const properties = await config.getProperties(); /** @type {string} */ let formatted; try { if (!FileFs.prettierConfig) { // either no prettier config in project directory or initPrettier was not run before this return content; } else if (content.includes('%%[') || content.includes('%%=')) { // in case we find AMPScript we need to abort beautifying as prettier // will throw an error falsely assuming bad syntax return await this.beautify_beautyAmp(content, true); } if (!FileFs.prettierConfig.parser) { // load the right prettier config relative to our file switch (filetype) { case 'htm': case 'html': { FileFs.prettierConfig.parser = 'html'; break; } case 'ssjs': case 'js': { FileFs.prettierConfig.parser = 'babel'; break; } case 'json': { FileFs.prettierConfig.parser = 'json'; break; } case 'yaml': case 'yml': { FileFs.prettierConfig.parser = 'yaml'; break; } case 'ts': { FileFs.prettierConfig.parser = 'babel-ts'; break; } case 'css': { FileFs.prettierConfig.parser = 'css'; break; } case 'less': { FileFs.prettierConfig.parser = 'less'; break; } case 'sass': case 'scss': { FileFs.prettierConfig.parser = 'scss'; break; } case 'md': { FileFs.prettierConfig.parser = 'markdown'; break; } case 'sql': { FileFs.prettierConfig.parser = 'sql'; FileFs.prettierConfig.plugins = ['prettier-plugin-sql']; break; } default: { FileFs.prettierConfig.parser = 'babel'; } } } formatted = await prettier.format(content, FileFs.prettierConfig); } catch (ex) { if (properties?.options?.formatErrorLog) { // save prettier errror into log file // Note: we have to filter color codes from prettier's error message before saving it to file /* eslint-disable no-control-regex */ this.writeToFile( directory, filename + '.error', 'log', `Error Log\nParser: ${FileFs.prettierConfig.parser}\n${ex.message.replaceAll( /[\u001B\u009B][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '' )}` ); /* eslint-enable no-control-regex */ } formatted = content; } return formatted; }, /** * Saves text content to a file in the local file system. Will create the parent directory if it does not exist * * @param {string|string[]} directory directory the file will be written to * @param {string} filename name of the file without '.json' ending * @param {string} filetype filetype suffix * @param {string} content filecontent * @param {object} [encoding] added for certain file types (like images) * @returns {Promise.<boolean>} Promise */ writeToFile: async function (directory, filename, filetype, content, encoding) { directory = this.filterIllegalPathChars(this.normalizePath(directory)); await fs.ensureDir(directory); // filter characters that are illegal for file names in Windows filename = this.filterIllegalFilenames(filename); const filePath = path.join(directory, filename + '.' + filetype); try { if (await fs.pathExists(filePath)) { Util.logger.debug(`Overwriting: ${filePath}`); } await fs.writeFile(filePath, content, encoding); return true; } catch (ex) { Util.logger.error('File.writeToFile:: error | ' + ex.message); return false; } }, /** * Saves json content to a file in the local file system. Will create the parent directory if it does not exist * * @param {string | string[]} directory directory where the file is stored * @param {string} filename name of the file without '.json' ending * @param {boolean} cleanPath filters illegal chars if true * @returns {Promise.<object | object | void>} Promise or JSON object depending on if async or not; void on error */ readJSONFile: async function (directory, filename, cleanPath) { try { if (cleanPath == null || cleanPath == true) { directory = this.filterIllegalPathChars(this.normalizePath(directory)); filename = this.filterIllegalFilenames(filename); } else { directory = this.normalizePath(directory); } if (filename.endsWith('.json')) { filename = filename.slice(0, -5); } let json; try { json = await fs.readJSON(path.join(directory, filename + '.json')); } catch (ex) { Util.logger.debug(ex.stack); } return json; } catch (ex) { Util.logger.error('File.readJSONFile:: error | ' + ex.message); } }, /** * reads file from local file system. * * @param {string | string[]} directory directory where the file is stored * @param {string} filename name of the file without '.json' ending * @param {string} filetype filetype suffix * @param {string} [encoding] read file with encoding (defaults to utf-8) * @returns {Promise.<string>} file contents; void on error */ readFilteredFilename: async function (directory, filename, filetype, encoding) { try { directory = this.filterIllegalPathChars(this.normalizePath(directory)); filename = this.filterIllegalFilenames(filename); // @ts-expect-error somehow, the typing for fs-extra is not correct return fs.readFile(path.join(directory, filename + '.' + filetype), encoding || 'utf8'); } catch (ex) { Util.logger.debug('File.readFilteredFilename:: error | ' + ex.message); } return; }, /** * reads directories to a specific depth returning an array * of file paths to be iterated over * * @example ['deploy/mcdev/bu1'] * @param {string} directory directory to checkin * @param {number} depth how many levels to check (1 base) * @param {boolean} [includeStem] include the parent directory in the response * @param {number} [_stemLength] set recursively for subfolders. do not set manually! * @returns {Promise.<string[]>} array of fully defined file paths */ readDirectories: async function (directory, depth, includeStem, _stemLength) { try { if (!_stemLength) { // only set this on first iteration _stemLength = directory.length; } const raw = await fs.readdir(directory, { withFileTypes: true }); let children = []; for (const dirent of raw) { const direntPath = path.join(directory, dirent.name); if ( (await fs.pathExists(direntPath)) && (await fs.lstat(direntPath)).isDirectory() && depth > 0 ) { const nestedChildren = await this.readDirectories( direntPath, depth - 1, includeStem, _stemLength ); children = children.concat(nestedChildren); } } if (children.length === 0) { // if not includeStem then remove base directory and leading slahes and backslashes return includeStem ? [directory] : [ directory .slice(Math.max(0, _stemLength)) .replace(/^\\+/, '') .replace(/^\/+/, ''), ]; } else { return children; } } catch (ex) { Util.logger.error('File.readDirectories:: error | ' + ex.message); Util.logger.debug(ex.stack); } }, /** * reads directories to a specific depth returning an array * of file paths to be iterated over using sync api (required in constructors) * TODO - merge with readDirectories. so far the logic is really different * * @example ['deploy/mcdev/bu1'] * @param {string} directory directory to checkin * @param {number} [depth] how many levels to check (1 base) * @param {boolean} [includeStem] include the parent directory in the response * @param {number} [_stemLength] set recursively for subfolders. do not set manually! * @returns {string[] | void} array of fully defined file paths; void on error */ readDirectoriesSync: function (directory, depth, includeStem, _stemLength) { try { const children = []; if (!_stemLength) { // only set this on first iteration _stemLength = directory.length; } // add current directory if (includeStem) { children.push(directory); } else { // remove base directory and leading slahes and backslashes const currentPath = directory.slice(Math.max(0, _stemLength)).replace(path.sep, ''); children.push(currentPath || '.'); } // read all directories const raw = fs.readdirSync(directory, { withFileTypes: true }); // loop through children of current directory (if not then this is skipped) for (const dirent of raw) { // if directory found and should get children then recursively call if (dirent.isDirectory() && depth > 0) { const nestedChildren = this.readDirectoriesSync( path.join(directory, dirent.name), depth - 1, includeStem, _stemLength ); if (Array.isArray(nestedChildren) && nestedChildren.length > 0) { children.push(...nestedChildren); } } } return children; } catch (ex) { Util.logger.error('File.readDirectoriesSync:: error | ' + ex.message); Util.logger.debug(ex.stack); } }, /** * helper that splits the config back into auth & config parts to save them separately * * @param {Mcdevrc} properties central properties object * @returns {Promise.<void>} - */ async saveConfigFile(properties) { // we want to save to save the full version here to allow us to upgrade configs properly in the future properties.version = Util.packageJsonMcdev.version; await this.writeJSONToFile('', Util.configFileName.split('.json')[0], properties); Util.logger.info(`✔️ ${Util.configFileName} and ${Util.authFileName} saved successfully`); }, /** * Initalises Prettier formatting lib async. * * @param {string} [filetype] filetype ie. JSON or SSJS * @returns {Promise.<boolean>} success of config load */ async initPrettier(filetype = 'html') { if (Util.OPTIONS.format === false) { // auto-formatting was disabled via CLI option return; } const properties = await config.getProperties(); if (Util.OPTIONS.format !== true && properties.options.formatOnSave === false) { // auto-formatting was disabled via config file return; } if (FileFs.prettierConfig === null || FileFs.prettierConfigFileType !== filetype) { // run this if no config was yet found or if the filetype previously used to initialize it differs (because it results in a potentially different config!) FileFs.prettierConfigFileType = filetype; try { // pass in project dir with fake index.html to avoid "no parser" error // by using process.cwd we are limiting ourselves to a config in the project root // note: overrides will be ignored unless they are for *.html if hand in an html file here. This method includes the overrides corresponding to the file we pass in FileFs.prettierConfig = await prettier.resolveConfig( path.join(process.cwd(), 'index.' + filetype) ); if (FileFs.prettierConfig === null) { // set to false to avoid re-running this after an initial failure throw new Error( `No .prettierrc found in your project directory. Please run 'mcdev upgrade' to create it` ); } return true; } catch (ex) { FileFs.prettierConfig = false; Util.logger.error('Cannot apply auto-formatting to your code: ' + ex.message); return false; } } else { return false; } }, }; const FileFs = Object.assign(fs, File); export default FileFs; ================================================ FILE: lib/util/init.config.js ================================================ 'use strict'; import File from './file.js'; import config from './config.js'; import { Util } from './util.js'; import { confirm } from '@inquirer/prompts'; import path from 'node:path'; import semver from 'semver'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * CLI helper class */ const Init = { /** * helper method for this.upgradeProject that upgrades project config if needed * * @param {Mcdevrc} properties config file's json * @returns {Promise.<boolean>} returns true if worked without errors */ async fixMcdevConfig(properties) { if (!properties) { // skip if no config exists yet return true; } let updateConfigNeeded = false; const upgradeMsgs = [`Upgrading existing ${Util.configFileName}:`]; const missingFields = await config.checkProperties(properties, true); const defaultProps = await config.getDefaultProperties(); if (Array.isArray(missingFields) && missingFields.length) { for (const fieldName of missingFields) { switch (fieldName) { case 'marketList': { // @ts-expect-error - deprecated field if (properties.marketBulk) { upgradeMsgs.push(`- ✔️ converted 'marketBulk' to '${fieldName}'`); // @ts-expect-error - deprecated field properties[fieldName] = properties.marketBulk; // @ts-expect-error - deprecated field delete properties.marketBulk; } else { upgradeMsgs.push(`- ✔️ added '${fieldName}'`); this._updateLeaf(properties, defaultProps, fieldName); } break; } case 'directories.docs': { // @ts-expect-error - deprecated field if (properties.directories.badKeys) { // @ts-expect-error - deprecated field delete properties.directories.badKeys; upgradeMsgs.push(`- ✋ removed 'directories.badKeys'`); } // @ts-expect-error - deprecated field if (properties.directories.dataExtension) { // @ts-expect-error - deprecated field File.removeSync(properties.directories.dataExtension); // @ts-expect-error - deprecated field delete properties.directories.dataExtension; upgradeMsgs.push(`- ✋ removed 'directories.dataExtension'`); } // @ts-expect-error - deprecated field if (properties.directories.deltaPackage) { // @ts-expect-error - deprecated field delete properties.directories.deltaPackage; upgradeMsgs.push(`- ✋ removed 'directories.deltaPackage'`); } // @ts-expect-error - deprecated field if (properties.directories.roles) { // @ts-expect-error - deprecated field delete properties.directories.roles; upgradeMsgs.push(`- ✋ removed 'directories.roles'`); } // @ts-expect-error - deprecated field if (properties.directories.users) { // @ts-expect-error - deprecated field delete properties.directories.users; upgradeMsgs.push(`- ✋ removed 'directories.users'`); } this._updateLeaf(properties, defaultProps, fieldName); upgradeMsgs.push(`- ✔️ added '${fieldName}'`); break; } case 'metaDataTypes.documentOnRetrieve': { if (properties.options.documentOnRetrieve) { this._updateLeaf(properties, defaultProps, fieldName); } else { properties.metaDataTypes.documentOnRetrieve = []; } delete properties.options.documentOnRetrieve; upgradeMsgs.push( `- ✔️ converted 'options.documentOnRetrieve' to '${fieldName}'` ); break; } case 'options.deployment.commitHistory': { if (properties.options.commitHistory) { upgradeMsgs.push( `- ✔️ converted 'options.commitHistory' to '${fieldName}'` ); properties.options.deployment.commitHistory = properties.options.commitHistory; delete properties.options.commitHistory; } else { upgradeMsgs.push(`- ✔️ added '${fieldName}'`); this._updateLeaf(properties, defaultProps, fieldName); } break; } case 'options.exclude': { if (properties.options.filter) { upgradeMsgs.push(`- ✔️ converted 'options.filter' to '${fieldName}'`); properties.options.exclude = properties.options.filter; delete properties.options.filter; } else { upgradeMsgs.push(`- ✔️ added '${fieldName}'`); this._updateLeaf(properties, defaultProps, fieldName); } break; } case 'version': { // do nothing other than ensure we re-save the config (with the new version) upgradeMsgs.push(`- ✔️ version updated`); break; } default: { this._updateLeaf(properties, defaultProps, fieldName); upgradeMsgs.push(`- ✔️ added '${fieldName}'`); } } } updateConfigNeeded = true; } // ensure we document dataExtensions and automations on retrieve as they should now be in the retrieve folder if (this._updateLeaf(properties, defaultProps, 'metaDataTypes.documentOnRetrieve')) { upgradeMsgs.push( `- ✔️ updated 'metaDataTypes.documentOnRetrieve' to include all available types` ); updateConfigNeeded = true; } // check if metaDataTypes.retrieve is set to default values and if not, launch selectTypes const defaultRetrieveArr = Util.getTypeChoices('typeRetrieveByDefault'); let reselectDefaultRetrieve = false; const toBeRemovedRetrieve = properties.metaDataTypes.retrieve.filter( (type) => !defaultRetrieveArr.includes(type) ); const toBeAddedRetrieve = defaultRetrieveArr.filter( (type) => !properties.metaDataTypes.retrieve.includes(type) ); if (toBeRemovedRetrieve.length || toBeAddedRetrieve.length) { reselectDefaultRetrieve = true; updateConfigNeeded = true; } // check if metaDataTypes.retrieve is set to default values and if not, launch selectTypes const defaultCdpArr = Util.getTypeChoices('typeCdpByDefault'); let reselectDefaultCdp = false; const toBeRemovedCdp = properties.metaDataTypes.createDeltaPkg.filter( (type) => !defaultCdpArr.includes(type) ); const toBeAddedCdp = defaultCdpArr.filter( (type) => !properties.metaDataTypes.createDeltaPkg.includes(type) ); if (toBeRemovedCdp.length || toBeAddedCdp.length) { reselectDefaultCdp = true; updateConfigNeeded = true; } // move to version 4 uses integers for MIDs for (const cred in properties.credentials) { let credentialMidsUpdated = false; if (typeof properties.credentials[cred].eid === 'string') { properties.credentials[cred].eid = Number.parseInt( properties.credentials[cred].eid ); credentialMidsUpdated = true; } for (const bu in properties.credentials[cred].businessUnits) { if (typeof properties.credentials[cred].businessUnits[bu] === 'string') { properties.credentials[cred].businessUnits[bu] = Number.parseInt( properties.credentials[cred].businessUnits[bu] ); credentialMidsUpdated = true; } } if (credentialMidsUpdated) { updateConfigNeeded = true; upgradeMsgs.push(`- ✔️ updated Business Unit format (${cred})`); } } // update config if (updateConfigNeeded) { for (const msg of upgradeMsgs) { Util.logger.info(msg); } if (reselectDefaultCdp) { // run selectTypes here as it _also_ runs File.saveConfigFile() Util.logger.warn( 'Your metaDataTypes.createDeltaPkg list is not set to standard values. Resetting config.' ); Util.logger.warn(''); if (toBeAddedCdp.length) { Util.logger.warn('Adding types:'); for (const type of toBeAddedCdp) { Util.logger.warn(` - ${type}`); } Util.logger.warn(''); } if (toBeRemovedCdp.length) { Util.logger.warn('Removing types:'); for (const type of toBeRemovedCdp) { Util.logger.warn(` - ${type}`); } Util.logger.warn(''); } properties.metaDataTypes.createDeltaPkg = Util.summarizeSubtypes( 'typeCdpByDefault', defaultCdpArr ); } if (reselectDefaultRetrieve) { // run selectTypes here as it _also_ runs File.saveConfigFile() Util.logger.warn( 'Your metaDataTypes.retrieve list is not set to standard values. Resetting config.' ); Util.logger.warn(''); if (toBeAddedRetrieve.length) { Util.logger.warn('Adding types:'); for (const type of toBeAddedRetrieve) { Util.logger.warn(` - ${type}`); } Util.logger.warn(''); } if (toBeRemovedRetrieve.length) { Util.logger.warn('Removing types:'); for (const type of toBeRemovedRetrieve) { Util.logger.warn(` - ${type}`); } Util.logger.warn(''); } properties.metaDataTypes.retrieve = Util.summarizeSubtypes( 'typeRetrieveByDefault', defaultRetrieveArr ); } // update config await File.saveConfigFile(properties); } else { Util.logger.info(`✔️ No problems found in existing ${Util.configFileName}`); } return true; }, /** * handles creation/update of all config file from the boilerplate * * @param {string} versionBeforeUpgrade 'x.y.z' * @returns {Promise.<boolean>} status of config file creation */ async createIdeConfigFiles(versionBeforeUpgrade) { Util.logger.info('Checking configuration files (existing files will not be changed):'); const creationLog = []; await File.ensureDir('deploy/'); await File.ensureDir('src/cloudPages'); const relevantForced = await this._getForcedUpdateList(versionBeforeUpgrade); await this._removeIdeConfigFiles(relevantForced); // copy in .gitignore (cant be retrieved via npm install directly) const gitignoreFileName = path.resolve( __dirname, Util.boilerplateDirectory, 'gitignore-template' ); if (await File.pathExists(gitignoreFileName)) { const fileContent = await File.readFile(gitignoreFileName, 'utf8'); creationLog.push( await this._createIdeConfigFile( ['.' + path.sep, '', '.gitignore'], relevantForced, fileContent ) ); } else { Util.logger.debug(`Dependency file not found in ${gitignoreFileName}`); return false; } // load file list from boilerplate dir and initiate copy process const boilerPlateFilesPath = path.resolve(__dirname, Util.boilerplateDirectory, 'files'); // ! do not switch to readDirectories before merging the two custom methods. Their logic is different! const directories = await File.readDirectoriesSync(boilerPlateFilesPath, 10, false); if (directories) { for (const subdir of directories) { // walk thru the root of our boilerplate-files directory and all sub folders const curDir = path.join(boilerPlateFilesPath, subdir); for (const file of await File.readdir(curDir)) { // read all files in these directories if (!(await File.lstat(path.join(curDir, file))).isDirectory()) { // filter entries that are actually folders const fileArr = file.split('.'); const ext = '.' + fileArr.pop(); // awaiting the result here due to interactive optional overwrite creationLog.push( await this._createIdeConfigFile( [subdir + path.sep, fileArr.join('.'), ext], relevantForced ) ); } } } } if (creationLog.includes(false) && creationLog.includes(true)) { Util.logger.warn('✋ Configuration files creation partially failed.'); return true; } else if (creationLog.includes(false)) { Util.logger.error('❌ Configuration files creation failed.'); return false; } else { Util.logger.info('✔️ Configuration files done.'); return true; } }, /** * recursive helper for {@link Init.fixMcdevConfig} that adds missing settings * * @param {object} propertiersCur current sub-object of project settings * @param {object} defaultPropsCur current sub-object of default settings * @param {string} fieldName dot-concatenated object-path that needs adding * @returns {boolean} was something updated or not */ _updateLeaf(propertiersCur, defaultPropsCur, fieldName) { if (fieldName.includes('.')) { const fieldNameArr = fieldName.split('.'); const curKey = fieldNameArr[0]; let updated = false; if (!propertiersCur[curKey]) { updated = true; propertiersCur[curKey] = {}; } fieldNameArr.splice(0, 1); return ( this._updateLeaf( propertiersCur[curKey], defaultPropsCur[curKey], fieldNameArr.join('.') ) || updated ); } else if (Util.isEqual(propertiersCur[fieldName], defaultPropsCur[fieldName])) { return false; } else { propertiersCur[fieldName] = defaultPropsCur[fieldName]; return true; } }, /** * returns list of files that need to be updated * * @param {string} projectVersion version found in config file of the current project * @returns {Promise.<{updates:string[],deletes:string[]}>} relevant files with path that need to be updated */ async _getForcedUpdateList(projectVersion) { // list of files that absolutely need to get overwritten, no questions asked, when upgrading from a version lower than the given. let forceIdeConfigUpdate; const updates = []; const deletes = []; if (await File.pathExists(Util.configFileName)) { forceIdeConfigUpdate = await File.readJSON( path.resolve(__dirname, Util.boilerplateDirectory, 'forcedUpdates.json') ); // return all if no project version was found or only changes from "newer" versions otherwise for (const element of forceIdeConfigUpdate) { if (!projectVersion || semver.gt(element.version, projectVersion)) { updates.push( // adapt it for local file systems ...element.files.map((item) => path.normalize(item)) ); if (element.filesRemove) { deletes.push( // adapt it for local file systems ...element.filesRemove.map((item) => path.normalize(item)) ); } } else { continue; } } } return { updates, deletes }; }, /** * handles creation/update of one config file from the boilerplate at a time * * @param {string[]} fileNameArr 0: path, 1: filename, 2: extension with dot * @param {{updates:string[],deletes:string[]}} relevantForced if fileNameArr is in this list we require an override * @param {string} [boilerplateFileContent] in case we cannot copy files 1:1 this can be used to pass in content * @returns {Promise.<boolean>} install successful or error occured */ async _createIdeConfigFile(fileNameArr, relevantForced, boilerplateFileContent) { const fileName = fileNameArr.join(''); const boilerplateFileName = path.resolve( __dirname, Util.boilerplateDirectory, 'files', fileName ); boilerplateFileContent ||= await File.readFile(boilerplateFileName, 'utf8'); /** @type {string} */ let todo; if (await File.pathExists(fileName)) { if (relevantForced.deletes.includes(path.normalize(fileName))) { Util.logger.info( `- ✋ ${fileName} found but it is required to delete it. Commencing rename instead for your convenience:` ); // eslint-disable-next-line no-useless-assignment todo = 'delete'; } else { const existingFileContent = await File.readFile(fileName, 'utf8'); if (existingFileContent === boilerplateFileContent) { Util.logger.info(`- ✔️ ${fileName} found. No update needed`); return true; } } if (relevantForced.updates.includes(path.normalize(fileName))) { Util.logger.info( `- ✋ ${fileName} found but an update is required. Commencing with override:` ); todo = 'update'; } else { Util.logger.info( `- ✋ ${fileName} found with differences to the new standard version. We recommend updating it.` ); if (Util.skipInteraction) { todo = 'update'; } else { const overrideFile = await confirm({ message: 'Would you like to update (override) it?', default: true, }); if (overrideFile) { todo = 'update'; } else { // skip override without error return true; } } } // ensure our update is not leading to data loss in case config files were not versioned correctly by the user await File.rename(fileName, fileName + '.BAK'); } else if (!relevantForced.deletes.includes(path.normalize(fileName))) { todo = 'create'; } if (todo === 'create' || todo === 'update') { const saveStatus = await File.writeToFile( fileNameArr[0], fileNameArr[1], fileNameArr[2].slice(1), boilerplateFileContent ); if (saveStatus) { Util.logger.info( `- ✔️ ${fileName} ${ todo === 'update' ? `updated (we created a backup of the old file under ${fileName + '.BAK'})` : 'created' }` ); return true; } else { Util.logger.warn( `- ❌ ${fileName} ${todo === 'update' ? 'update' : 'creation'} failed` ); return false; } } else if (todo === 'delete') { await File.rename(fileName, fileName + '.BAK'); Util.logger.info(`- ✔️ ${fileName} removed (renamed to ${fileName + '.BAK'})`); return true; } }, /** * handles deletion of no longer needed config files * * @param {{updates:string[],deletes:string[]}} relevantForced if file is in .deletes, we require deleting/renaming it * @returns {Promise.<boolean>} deletion successful or error occured */ async _removeIdeConfigFiles(relevantForced) { for (const fileName of relevantForced.deletes) { if (await File.pathExists(fileName)) { Util.logger.info( `- ✋ ${fileName} found but it is required to delete it. Commencing rename instead for your convenience:` ); await File.rename(fileName, fileName + '.BAK'); Util.logger.info(`- ✔️ ${fileName} removed (renamed to ${fileName + '.BAK'})`); } } return true; }, /** * helper method for this.upgradeProject that upgrades project config if needed * * @returns {Promise.<boolean>} returns true if worked without errors */ async upgradeAuthFile() { if (await File.pathExists(Util.authFileName)) { const existingAuth = await File.readJSON(Util.authFileName); // if has credentials key then is old format if (existingAuth.credentials) { const newAuth = {}; for (const cred in existingAuth.credentials) { newAuth[cred] = { client_id: existingAuth.credentials[cred].clientId, client_secret: existingAuth.credentials[cred].clientSecret, auth_url: `https://${existingAuth.credentials[cred].tenant}.auth.marketingcloudapis.com/`, account_id: Number.parseInt(existingAuth.credentials[cred].eid), }; } await File.writeJSONToFile( './', Util.authFileName.replace(/(.json)+$/, ''), newAuth ); Util.logger.info(`- ✔️ upgraded credential file`); } } return true; }, }; export default Init; ================================================ FILE: lib/util/init.git.js ================================================ 'use strict'; import File from './file.js'; import { confirm, input } from '@inquirer/prompts'; import { Util } from './util.js'; import commandExists from 'command-exists'; import { simpleGit } from 'simple-git'; const git = simpleGit(); /** * CLI helper class */ const Init = { /** * check if git repo exists and otherwise create one * * @returns {Promise.<{status: string, repoName: string}>} success flag */ async initGitRepo() { const result = { status: null, repoName: null }; // check if git is installed (https://www.npmjs.com/package/command-exists) if (!commandExists.sync('git')) { Util.logger.error('Git installation not found.'); Util.logger.error( 'Please follow our tutorial on installing Git: https://github.com/Accenture/sfmc-devtools#212-install-the-git-command-line' ); result.status = 'error'; return result; } // 3. test if in git repo const gitRepoFoundInCWD = await File.pathExists('.git'); /** @type {boolean} */ let newRepoInitialized; if (gitRepoFoundInCWD) { Util.logger.info(`✔️ Git repository found`); newRepoInitialized = false; } else { Util.logger.warn('No Git repository found. Initializing git:'); Util.execSync('git', ['init', '--initial-branch=' + Util.defaultGitBranch]); if (await File.pathExists('.git')) { newRepoInitialized = true; } else { Util.logger.error( 'We detected a problem initializing your Git repository. Please run "git init" manually' ); result.status = 'error'; return result; } } Util.logger.info('Ensuring long file paths are not causing issues with git:'); try { Util.execSync('git', ['config', '--local', 'core.longpaths', 'true']); } catch { Util.logger.warn( `Updating your git config failed. We recommend running the above command manually yourself to avoid issues.` ); } Util.logger.info('Ensuring checkout (git pull) as-is and commit Unix-style line endings:'); try { Util.execSync('git', ['config', '--local', 'core.autocrlf', 'input']); } catch { Util.logger.warn( `Updating your git config failed. We recommend running the above command manually yourself to avoid issues.` ); } // offer to update local user.name and user.email await this._updateGitConfigUser(); if (newRepoInitialized) { // offer to insert git remote url now result.repoName = await this._addGitRemote(); } Util.logger.info('✔️ Git initialization done.'); result.status = newRepoInitialized ? 'init' : 'update'; return result; }, /** * offer to push the new repo straight to the server * * @returns {Promise.<void>} - */ async gitPush() { const skipInteraction = Util.skipInteraction; const gitRemotes = (await git.getRemotes(true)).filter((item) => item.name === 'origin'); if (gitRemotes.length && gitRemotes[0].refs.push) { // check if remote repo is still empty (otherwise to risky to blindly push) let remoteBranchesExist; Util.logger.info('Checking remote Git repository for existing branches...'); try { // First, we need to update our local copy of the repo await git.fetch(); // Then, we can check how many remote branches 'git fetch' has found remoteBranchesExist = (await git.branch(['-r'])).all.length > 0; } catch (ex) { Util.logger.error('Could not contact remote git server: ' + ex.message); } if (remoteBranchesExist === false) { // offer git push if no remote branches found Util.logger.info( `Your remote Git repository is still empty and ready to store your initial backup. Hint: This is the server version of the repo which you share with your team.` ); let gitPush; if (!skipInteraction) { gitPush = await confirm({ message: `Would you like to 'push' your backup to the remote Git repo?`, default: true, }); } if (skipInteraction?.gitPush === 'true' || gitPush) { Util.execSync('git', ['push', '-u', 'origin', 'master']); } } else if (remoteBranchesExist === true) { Util.logger.info( 'Your remote Git repository already contains data. Please execute a git push manually.' ); } } }, /** * offers to add the git remote origin * * @returns {Promise.<string>} repo name (optionally) */ async _addGitRemote() { const skipInteraction = Util.skipInteraction; // #1 ask if the user wants to do it now let gitOriginKnown; if (!skipInteraction) { gitOriginKnown = await confirm({ message: `Do you know the remote/clone URL of your Git repo (starts with ssh:// or http:// and ends on '.git')?`, default: true, }); } if (skipInteraction || gitOriginKnown) { // #2 if yes, guide the user to input the right url let answers = {}; if (skipInteraction) { answers = skipInteraction; } else { answers.gitRemoteUrl = await input({ message: 'Git Remote URL', validate: (value) => { value = value.trim(); if (!value || value.length < 10) { return 'Please enter a valid remote URL'; } else if (!value.startsWith('http') && !value.startsWith('ssh')) { return `Your Git Remote URL should start with 'http' or 'ssh'`; } else if (value.endsWith('.git')) { // all good return true; } else { return `Your Git Remote URL should end with '.git'`; } }, }); } if (typeof answers.gitRemoteUrl === 'string') { answers.gitRemoteUrl = answers.gitRemoteUrl.trim(); Util.execSync('git', ['remote', 'add', 'origin', answers.gitRemoteUrl]); return answers.gitRemoteUrl.split('/').pop().split('.')[0]; } } }, /** * checks global config and ask to config the user info and then store it locally * * @returns {Promise.<void>} - */ async _updateGitConfigUser() { const skipInteraction = Util.skipInteraction; const gitUser = (await this._getGitConfigUser()) || {}; Util.logger.info( `Please confirm your Git user name & email. It should be in the format 'FirstName LastName' and 'your.email@accenture.com'. The current (potentially wrong) values are provided as default. If correct, confirm with ENTER, otherwise please update:` ); let responses; /* eslint-disable unicorn/prefer-ternary */ if (skipInteraction) { responses = { name: gitUser['user.name'], email: gitUser['user.email'], }; } else { responses = { name: await input({ message: 'Git user.name', default: gitUser['user.name'] || null, // eslint-disable-next-line jsdoc/require-jsdoc validate: function (value) { if ( !value || value.trim().length < 4 || value.includes('"') || value.includes("'") ) { return 'Please enter valid name'; } return true; }, }), email: await input({ message: 'Git user.email', default: gitUser['user.email'] || null, // eslint-disable-next-line jsdoc/require-jsdoc validate: function (value) { value = value.trim(); const regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!value || !regex.test(String(value).toLowerCase())) { return 'Please enter valid email'; } return true; }, }), }; } /* eslint-enable unicorn/prefer-ternary */ if (responses.name && responses.email) { // name can contain spaces - wrap it in quotes const name = `"${responses.name.trim()}"`; const email = responses.email.trim(); try { Util.execSync('git', ['config', '--local', 'user.name', name]); Util.execSync('git', ['config', '--local', 'user.email', email]); } catch (ex) { // if project folder is not a git folder then using --local will lead to a fatal error Util.logger.warn('- Could not update git user name and email'); Util.logger.debug(ex.message); } } }, /** * retrieves the global user.name and user.email values * * @returns {Promise.<{'user.name': string, 'user.email': string}>} user.name and user.email */ async _getGitConfigUser() { const names = await git.getConfig('user.name'); const emails = await git.getConfig('user.email'); return { 'user.name': names.value || '', 'user.email': emails.value || '' }; }, }; export default Init; ================================================ FILE: lib/util/init.js ================================================ 'use strict'; import Cli from './cli.js'; import File from './file.js'; import config from './config.js'; import InitGit from './init.git.js'; import InitNpm from './init.npm.js'; import InitConfig from './init.config.js'; import { confirm, input, select } from '@inquirer/prompts'; import { Util } from './util.js'; import fs from 'node:fs'; import path from 'node:path'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo */ /** * CLI helper class */ const Init = { /** * Creates template file for properties.json * * @param {Mcdevrc} properties config file's json * @param {string} [credentialName] identifying name of the installed package / project; if set, will update this credential * @param {boolean} [refreshBUs] if this was triggered by mcdev join, do not refresh BUs * @returns {Promise.<void>} - */ async initProject(properties, credentialName, refreshBUs = true) { if (!(await Init._checkPathForCloud())) { return; } const skipInteraction = Util.skipInteraction; if (!properties) { // try to get cached properties because we return null in case of a crucial error properties = config.properties; } const missingCredentials = this._getMissingCredentials(properties); if ((await File.pathExists(Util.configFileName)) && properties) { // config exists if (credentialName) { // update-credential mode if (!properties.credentials[credentialName]) { Util.logger.error( `Could not update credential '${credentialName}' because it was not found in your config. Please check your spelling and try again.` ); Cli.logExistingCredentials(properties); if (skipInteraction) { return; } const response = await Cli._selectBU(properties, null, true); credentialName = response.credential; } Util.logger.info(`Updating existing credential '${credentialName}'`); let error; do { error = false; try { const success = await Cli.updateCredential(properties, credentialName); if (success) { Util.logger.info(`✔️ Credential '${credentialName}' updated.`); } else { error = true; } } catch (ex) { if (skipInteraction) { Util.logger.error(ex.message); return; } else { // retry error = true; } } } while (error && !skipInteraction); Util.logger.debug('reloading config'); // eslint-disable-next-line no-useless-assignment properties = await config.getProperties(true); } else if (missingCredentials.length) { // forced update-credential mode - user likely cloned repo and is missing mcdev-auth.json Util.logger.warn( `We found ${missingCredentials.length} credential${ missingCredentials.length > 1 ? 's' : '' } in your ${Util.configFileName} that ${ missingCredentials.length > 1 ? 'are' : 'is' } missing details.` ); for (const badCredName of missingCredentials) { let error; do { error = false; try { const success = await Cli.updateCredential( properties, badCredName, refreshBUs ); if (success) { Util.logger.info(`✔️ Credential '${badCredName}' updated.`); } else { error = true; } } catch { error = true; } } while (error); Util.logger.debug('reloading config'); properties = await config.getProperties(true); } Util.logger.info('✔️ All credentials updated.'); // assume node dependencies are not installed Util.execSync('npm', ['install']); Util.logger.info('✔️ Dependencies installed.'); Util.logger.info('You can now start using Accenture SFMC DevTools.'); } else if (!missingCredentials.length) { // add-credential mode Util.logger.warn(Util.configFileName + ' found in root'); let isAddCredential; if (skipInteraction) { if ( skipInteraction.client_id && skipInteraction.client_secret && skipInteraction.auth_url && skipInteraction.account_id && skipInteraction.credentialName ) { // assume automated input; only option here is to add a new credential // requires skipInteraction=={client_id,client_secret,auth_url,account_id,credentialName} // will be checked inside of Cli.addExtraCredential() Util.logger.info('Adding another credential'); } else { throw new Error( '--skipInteraction flag found but missing required input for client_id,client_secret,auth_url,account_id,credentialName' ); } } else { isAddCredential = await confirm({ message: 'Do you want to add another credential instead?', default: false, }); } let credentialName; if (skipInteraction || isAddCredential) { credentialName = await Cli.addExtraCredential(properties); } if (credentialName) { await this._downloadAllBUs(`${credentialName}/*`, 'update'); } } } else { // config does not exist // assuming it's the first time this command is run for this project // initialize git repo const initGit = await InitGit.initGitRepo(); if (initGit.status === 'error') { return; } // set up IDE files and load npm dependencies if (!(await this.upgradeProject(properties, true, initGit.repoName))) { return; } // ask for credentials and create mcdev config if (!(await Cli.initMcdevConfig())) { return; } // set up markets and market lists initially await Init._initMarkets(); // create first commit to backup the project configuration if (initGit.status === 'init') { Util.logger.info(`Committing initial setup to Git:`); Util.execSync('git', ['add', '.']); Util.execSync('git', ['commit', '-n', '-m', '"Initial commit"', '--quiet']); Util.logger.info(`✔️ Configuration committed`); } // do initial retrieve * await this._downloadAllBUs('"*"', initGit.status); // backup to server await InitGit.gitPush(); // all done Util.logger.info('You are now ready to work with Accenture SFMC DevTools!'); Util.logger.warn( 'If you use VSCode, please restart it now to install recommended extensions.' ); } }, /** * Creates template file for properties.json * * @returns {Promise.<void>} - */ async joinProject() { if (!(await Init._checkPathForCloud())) { return; } const isJoin = await confirm({ message: 'Do you want to join an existing project for which you have a Git-Repository URL?', default: true, }); if (isJoin) { const gitRepoQs = { gitRepoUrl: await input({ message: 'Please enter the Git-Repository URL', }), gitBranch: await input({ message: 'If you were asked to work on a specific branch, please enter it now (or leave empty for default)', }), }; const repoName = gitRepoQs.gitRepoUrl.split('/').pop().replace('.git', ''); // clone repo into current folder Util.logger.info( 'Cloning initiated. You might be asked for your Git credentials in a pop-up window in a few seconds.' ); Util.execSync( 'git', [ 'clone', gitRepoQs.gitBranch ? `--branch ${gitRepoQs.gitBranch}` : null, '--config core.longpaths=true', '--config core.autocrlf=input', gitRepoQs.gitRepoUrl, ].filter(Boolean) ); if (!fs.existsSync(repoName)) { Util.logger.error( 'Could not clone repository. Please check your Git-Repository URL as well as your credentials and try again.' ); Util.logger.info( 'Check if you need an "API-Token" instead of your normal user password to authenticate' ); return; } // make sure we switch to the new subfolder or else the rest will fail process.chdir(repoName); // check if the branch looks good const properties = await config.getProperties(true, true); if (!properties) { Util.logger.error( 'Could not find .mcdevrc.json file in project folder. Please check your Git repository and branch.' ); return; } // get name and email that's to be used for git commits await InitGit._updateGitConfigUser(); // ask the user to enter the server credentials await this.initProject(properties, null, false); } else { return; } }, /** * helper for {@link Init.initProject} that optionally creates markets and market lists for all BUs */ async _initMarkets() { const skipInteraction = Util.skipInteraction; const properties = await config.getProperties(true); // get list of business units const firstCredentialName = Object.keys(properties.credentials)[0]; const businessUnits = Object.keys( properties.credentials[firstCredentialName].businessUnits ); // set up empty markets for them const markets = {}; for (const bu of businessUnits) { markets[bu] = { suffix: '_' + bu }; } properties.markets = markets; let sourceBuName; // set up default deployment market lists if (skipInteraction) { // don't ask, list all BUs in deployment-target and set deployment-source to ??? if (!businessUnits.includes(skipInteraction.developmentBu)) { Util.logger.warn( `Could not find developmentBu=${skipInteraction.developmentBu} in business units. Skipping.` ); delete skipInteraction.developmentBu; } sourceBuName = skipInteraction.developmentBu || '???'; if (!skipInteraction.developmentBu) { Util.logger.info( 'Market List "deployment-source" will need to be set up manually. Marking all BUs as target BUs in "deployment-target".' ); } } else { sourceBuName = await select({ message: 'Please select your development business unit:', choices: businessUnits.map((bu) => ({ name: bu, value: bu })), }); } // set source list properties.marketList['deployment-source'][firstCredentialName + '/' + sourceBuName] = sourceBuName; // set target list for (const bu of businessUnits) { // filter out source BU & parent BU to ensure they dont get deployed to automatically if (bu !== sourceBuName && bu !== '_ParentBU_') { properties.marketList['deployment-target'][firstCredentialName + '/' + bu] = bu; } } await File.saveConfigFile(properties); }, /** * helper for {@link Init.initProject} * * @param {string} bu cred/bu or cred/* or * * @param {string} gitStatus signals what state the git repo is in * @returns {Promise.<void>} - */ async _downloadAllBUs(bu, gitStatus) { const skipInteraction = Util.skipInteraction; let initialRetrieveAll; if (!skipInteraction) { initialRetrieveAll = await confirm({ message: 'Do you want to start downloading all Business Units (recommended)?', default: true, }); } if (skipInteraction?.downloadBUs === 'true' || initialRetrieveAll) { Util.execSync('mcdev', ['retrieve', bu]); if (gitStatus === 'init') { Util.logger.info(`Committing first backup of your SFMC instance:`); Util.execSync('git', ['add', '.']); Util.execSync('git', ['commit', '-n', '-m', '"First instance backup"', '--quiet']); Util.logger.info(`✔️ SFMC instance backed up`); } else if (gitStatus === 'update') { Util.logger.warn( 'Please manually commit this backup according to your projects guidelines.' ); // TODO create guided commit: // 1. ask if commit with all changes shall be created // 2. ask if that should be done to current branch (show which one we are on) or a new branch // a. if new: ask off of which we shall branch off of (show list) and then auto-create new branch and switch to it // 3. create commit } } }, /** * wrapper around npm dependency & configuration file setup * * @param {Mcdevrc} properties config file's json * @param {boolean} [initial] print message if not part of initial setup * @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init * @returns {Promise.<boolean>} success flag */ async upgradeProject(properties, initial, repoName) { if (!(await Init._checkPathForCloud())) { return; } let status; const versionBeforeUpgrade = properties?.version || '0.0.0'; if (!initial) { Util.logger.info( 'Upgrading project with newest configuration, npm dependencies & other project configurations:' ); // ensure an existing config is up to current specs status = await InitConfig.fixMcdevConfig(properties); if (!status) { return false; } // version 4 release to simplify auth status = await InitConfig.upgradeAuthFile(); if (!status) { return false; } } // create files before installing dependencies to ensure .gitignore is properly set up status = await InitConfig.createIdeConfigFiles(versionBeforeUpgrade); if (!status) { return false; } // install node dependencies status = await InitNpm.installDependencies(repoName); if (!status) { return false; } return true; }, /** * check if git repo is being saved on a cloud service and warn the user * * @private * @returns {Promise.<boolean>} true if path is good; false if project seems to be in a cloud service folder */ async _checkPathForCloud() { const absolutePath = path.resolve(''); // popular cloud services and their respective default name for the absolute path // * CloudDocs is the default folder name for iCloud const cloudServices = ['Dropbox', 'OneDrive', 'Google Drive', 'iCloud', 'CloudDocs']; let cloudServiceFound = false; for (const variable in cloudServices) { if (absolutePath.includes(cloudServices[variable])) { Util.logger.warn( `It seems your project folder will be synchronized via '${ cloudServices[variable] === 'CloudDocs' ? 'iCloud' : cloudServices[variable] }'. This can reduce the overall performance of your computer due to conflicts with Git.` ); Util.logger.warn( `We strongly recommend moving your project folder outside of the '${ cloudServices[variable] === 'CloudDocs' ? 'iCloud' : cloudServices[variable] }' folder.` ); cloudServiceFound = true; } } if (!cloudServiceFound && absolutePath.includes(process.env.USERPROFILE)) { // warn user to not place project folder into user profile folder Util.logger.warn( `It seems your project folder is located in your user profile's default folder which is often synchronized to webservices like ${cloudServices.join( ', ' )}. This can reduce the overall performance of your computer due to conflicts between with Git.` ); Util.logger.warn( `We strongly recommend moving your project folder outside of this folder.` ); cloudServiceFound = true; } if (cloudServiceFound) { const ignoreCloudWarning = await confirm({ message: 'Do you want to continue anyways?', default: false, }); if (!ignoreCloudWarning) { Util.logger.error('Exiting due to cloud service warning'); return false; } } return true; }, /** * finds credentials that are set up in config but not in auth file * * @private * @param {Mcdevrc} properties javascript object in .mcdevrc.json * @returns {string[]} list of credential names */ _getMissingCredentials(properties) { let missingCredentials; if (properties?.credentials) { // reload auth file because for some reason we didnt want that in our main properties object let auth; try { auth = File.readJsonSync(Util.authFileName); } catch { // file not found auth = []; } // walk through config credentials and check if the matching credential in the auth file is missing something missingCredentials = Object.keys(properties.credentials).filter( (cred) => !auth[cred] || !auth[cred].account_id || properties.credentials[cred].eid != auth[cred].account_id || !auth[cred].client_id || !auth[cred].client_secret || !auth[cred].auth_url ); } return missingCredentials || []; }, }; export default Init; ================================================ FILE: lib/util/init.npm.js ================================================ 'use strict'; import File from './file.js'; import path from 'node:path'; import { Util } from './util.js'; import semver from 'semver'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * CLI helper class */ const Init = { /** * initiates npm project and then * takes care of loading the pre-configured dependency list * from the boilerplate directory to them as dev-dependencies * * @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init * @returns {Promise.<boolean>} install successful or error occured */ async installDependencies(repoName) { let fileContent; let projectPackageJson; if (await File.pathExists('package.json')) { try { fileContent = await File.readFile('package.json', 'utf8'); } catch (ex) { Util.logger.error( 'Your package.json was found but seems to be corrupted: ' + ex.message ); } if (fileContent) { projectPackageJson = JSON.parse(fileContent); this._getDefaultPackageJson(projectPackageJson); await File.writeJSON('./package.json', projectPackageJson, { spaces: 2 }); Util.logger.info('✔️ package.json found'); } } else { Util.logger.warn('No package.json found. Initializing node project:'); // make sure the npm project name is compliant with npm rules const currentFolderName = path.basename(path.resolve()); const standardNpmName = repoName || currentFolderName .toLowerCase() .replaceAll(/[^a-z0-9 ]/gi, '') .replaceAll(/ /gi, '-'); projectPackageJson = { name: standardNpmName }; this._getDefaultPackageJson(projectPackageJson); await File.writeToFile('./', 'package', 'json', JSON.stringify(projectPackageJson)); // execute "no questions asked" npm init Util.execSync('npm', ['init', '--yes'], true); try { fileContent = await File.readFile('package.json', 'utf8'); if (fileContent) { projectPackageJson = JSON.parse(fileContent); } // type="module" is solely required for the new flat configs of ESLint >=9 Util.execSync('npm', ['pkg', 'set', 'type="module"'], true); Util.logger.info('✔️ package.json created'); } catch { Util.logger.error('No package.json found. Please run "npm init" manually'); return false; } } // ensure npm dependencies are loaded const dependencyFile = path.resolve( __dirname, Util.boilerplateDirectory, 'npm-dependencies.json' ); if (!(await File.pathExists(dependencyFile))) { Util.logger.debug(`Dependency file not found in ${dependencyFile}`); return false; } const defaultDependencies = await File.readJSON(dependencyFile); const versionsDefault = {}; for (const name of defaultDependencies) { // check mcdev.devDependencies first versionsDefault[name] = Object.keys(Util.packageJsonMcdev.dependencies).includes(name) ? Util.packageJsonMcdev.dependencies[name] : // then check mcdev.devDependencies Object.keys(Util.packageJsonMcdev.devDependencies).includes(name) ? Util.packageJsonMcdev.devDependencies[name] : // fallback to using latest version if not found 'latest'; } const versionsProject = {}; if (projectPackageJson.devDependencies) { for (const name of defaultDependencies) { // check project.devDependencies versionsProject[name] = Object.keys(projectPackageJson.devDependencies).includes( name ) ? projectPackageJson.devDependencies[name].replace(/^[\^~]/, '') : // fallback to invalid version if not found '0.0.0'; } } const loadDependencies = defaultDependencies.filter( (name) => !projectPackageJson || !projectPackageJson.devDependencies || !projectPackageJson.devDependencies[name] || versionsDefault[name] == 'latest' || // filters out file:.. references instead of versions that would otherwise lead to an error in semver.gt() !semver.valid(versionsProject[name]) || semver.gt(versionsDefault[name], versionsProject[name]) ); if (loadDependencies.length) { Util.logger.info('Installing/Updating Dependencies:'); const args = ['install', '--save-dev'].concat( loadDependencies.map((name) => `${name}@${versionsDefault[name]}`) ); Util.execSync('npm', args); Util.logger.info('✔️ Dependencies installed.'); } else { Util.logger.info( `✔️ All default dependencies are already installed: ` + defaultDependencies.map((name) => `${name}@${versionsProject[name]}`).join(', ') ); } return true; }, /** * ensure we have certain default values in our config * * @param {object} [currentContent] what was read from existing package.json file * @returns {Promise.<{script: object, author: string, license: string}>} extended currentContent */ async _getDefaultPackageJson(currentContent) { currentContent ||= {}; // #1 scripts const predefinedCommandList = { build: 'sfmc-build all', 'build-cp': 'sfmc-build cloudPages', 'build-email': 'sfmc-build emails', 'eslint-check': 'eslint', }; if (!currentContent.scripts) { currentContent.scripts = {}; } for (const key in predefinedCommandList) { currentContent.scripts[key] = predefinedCommandList[key]; } // #2 Author if (!currentContent.author || currentContent.author === '') { currentContent.author = 'Accenture'; } // #3 License if (!currentContent.license || currentContent.license === 'ISC') { currentContent.license = 'UNLICENSED'; } if (!currentContent.type || currentContent.type !== 'module') { // type="module" is solely required for the new flat configs of ESLint >=9 currentContent.type = 'module'; } return currentContent; }, }; export default Init; ================================================ FILE: lib/util/replaceContentBlockReference.js ================================================ 'use strict'; import auth from './auth.js'; import cache from './cache.js'; import File from './file.js'; import { Util } from '../util/util.js'; import Folder from '../metadataTypes/Folder.js'; import Asset from '../metadataTypes/Asset.js'; /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').McdevLogger} McdevLogger * @typedef {import('../../types/mcdev.d.js').Logger} Logger * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SkipInteraction} SkipInteraction * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError * * @typedef {import('../../types/mcdev.d.js').AssetMap} AssetMap * @typedef {import('../../types/mcdev.d.js').AssetItemSimple} AssetItemSimple * @typedef {import('../../types/mcdev.d.js').AssetItemSimpleMap} AssetItemSimpleMap * @typedef {import('../../types/mcdev.d.js').AssetItemIdSimpleMap} AssetItemIdSimpleMap * @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes */ /** * Util that contains logger and simple util methods */ export default class ReplaceContentBlockReference { /** @type {{id: AssetItemIdSimpleMap, key: AssetItemSimpleMap, name: AssetItemSimpleMap}} */ static assetCacheMap = { id: {}, key: {}, name: {}, }; /** @type {Object.<string, {id: RegExp[], key: RegExp[], name: RegExp[]}>} */ static #regexBy = { // TODO: handle cases in which variables or functions are passed into ContentBlockByX amp: { id: [ /ContentBlockById\(\s*"([0-9]+)"\s*\)/gim, /ContentBlockById\(\s*'([0-9]+)'\s*\)/gim, /ContentBlockById\(\s*([0-9]+)\s*\)/gim, ], key: [ /ContentBlockByKey\(\s*"([a-z0-9-/._][ a-z0-9-/._]+[a-z0-9-/._])"\s*\)/gim, /ContentBlockByKey\(\s*'([a-z0-9-/._][ a-z0-9-/._]+[a-z0-9-/._])'\s*\)/gim, ], name: [ /ContentBlockByName\(\s*"([ a-z0-9-\\._)(]+)"\s*\)/gim, /ContentBlockByName\(\s*'([ a-z0-9-\\._)(]+)'\s*\)/gim, ], }, ssjs: { id: [ /Platform.Function.ContentBlockById\(\s*"([0-9]+)"\s*\)/gim, /Platform.Function.ContentBlockById\(\s*'([0-9]+)'\s*\)/gim, /Platform.Function.ContentBlockById\(\s*([0-9]+)\s*\)/gim, ], key: [ /Platform.Function.ContentBlockByKey\(\s*"([a-z0-9-/._][ a-z0-9-/._]+[a-z0-9-/._])"\s*\)/gim, /Platform.Function.ContentBlockByKey\(\s*'([a-z0-9-/._][ a-z0-9-/._]+[a-z0-9-/._])'\s*\)/gim, ], name: [ /Platform.Function.ContentBlockByName\(\s*"([ a-z0-9-\\._)(]+)"\s*\)/gim, /Platform.Function.ContentBlockByName\(\s*'([ a-z0-9-\\._)(]+)'\s*\)/gim, ], }, }; /** * helper for tests */ static resetCacheMap() { this.assetCacheMap = { id: {}, key: {}, name: {}, }; } /** * used to equalize the reference in the code to whatever is set in the "to" field * * @param {string} str full code string * @param {string} parentName name of the object that was passed in; used in error message only * @param {Set.<string>} [findAssetKeys] list of keys that were found referenced via ContentBlockByX; if set, method only gets keys and runs no updates * @returns {string} replaced string */ static replaceReference(str, parentName, findAssetKeys) { if (!str) { const ex = new Error('No string provided'); // @ts-expect-error custom error object ex.code = 200; throw ex; } /** @type {ContentBlockConversionTypes[]} */ const fromList = Util.OPTIONS.referenceFrom; /** @type {ContentBlockConversionTypes} */ const to = Util.OPTIONS.referenceTo; let result = str; let changes = 0; const languages = [ { name: 'ssjs', isSsjs: true }, { name: 'amp', isSsjs: false }, ]; for (const from of fromList) { for (const lang of languages) { for (const regex of this.#regexBy[lang.name][from]) { result = result.replaceAll(regex, (match, identifier) => { const referencedAsset = this.#getAssetBy( from, identifier, parentName, lang.isSsjs, !!findAssetKeys ); if (referencedAsset && referencedAsset[to]) { // make sure we not only found the asset but also have a replacement for it (folder issue could block swap to ContentBlockByName) changes++; if (findAssetKeys) { findAssetKeys.add(referencedAsset.key); return; } else { return this.#replaceWith(referencedAsset, to, lang.isSsjs); } } else { if (referencedAsset && !referencedAsset[to]) { // this is expected to only happen if to=="name" Util.logger.error( ` - ${parentName}: Asset ${from} ${identifier} has no valid ${to} reference` ); } else if (!referencedAsset && findAssetKeys) { const newError = new Error(`${identifier}`); // @ts-expect-error custom error object newError.code = 404; throw newError; } return match; } }); } } } if (!changes) { const ex = new Error('No changes made to the code.'); // @ts-expect-error custom error object ex.code = 200; throw ex; } return result; } /** * * @param {ContentBlockConversionTypes} from replace with * @param {string|number} identifier id, key or name of asset * @param {string} parentName name of the object that was passed in; used in error message only * @param {boolean} [isSsjs] replaces backslashes with double backslashes in name if true * @param {boolean} [handleOutside] don not print error message if asset not found * @returns {AssetItemSimple} asset object */ static #getAssetBy(from, identifier, parentName, isSsjs = false, handleOutside = false) { let reference; switch (from) { case 'id': { reference = ReplaceContentBlockReference.assetCacheMap.id[identifier]; break; } case 'key': { reference = ReplaceContentBlockReference.assetCacheMap.key[identifier]; break; } case 'name': { if (isSsjs && typeof identifier === 'string') { identifier = identifier.replaceAll('\\\\', '\\'); } reference = ReplaceContentBlockReference.assetCacheMap.name[identifier]; break; } } if (!reference && !handleOutside) { Util.logger.error(` - ${parentName}: Asset not found for ${from} ${identifier}`); } return reference; } /** * * @param {AssetItemSimple} asset asset object * @param {ContentBlockConversionTypes} to replace with * @param {boolean} [isSsjs] replaces backslashes with double backslashes in name if true * @returns {string} replaced string */ static #replaceWith(asset, to, isSsjs = false) { switch (to) { case 'id': { return `${isSsjs ? 'Platform.Function.' : ''}ContentBlockById(${asset.id})`; } case 'key': { return `${isSsjs ? 'Platform.Function.' : ''}ContentBlockByKey("${asset.key}")`; } case 'name': { return `${isSsjs ? 'Platform.Function.' : ''}ContentBlockByName("${isSsjs ? asset.name.replaceAll('\\', '\\\\') : asset.name}")`; } } } /** * ensures we cache the right things from disk and if required from server * * @param {Mcdevrc} properties properties for auth * @param {BuObject} buObject properties for auth * @param {boolean} [retrieveSharedOnly] for --dependencies only, do not have to re-retrieve local assets * @returns {Promise.<void>} - */ static async createCache(properties, buObject, retrieveSharedOnly = false) { const { localAssets, sharedAssets } = await ReplaceContentBlockReference._retrieveCache( buObject, properties, retrieveSharedOnly ); ReplaceContentBlockReference.createCacheForMap(localAssets); ReplaceContentBlockReference.createCacheForMap(sharedAssets); } /** * helper for {@link ReplaceContentBlockReference.createCache} that converts AssetMap into AssetItemSimple entries in this.assetCacheMap * * @param {AssetMap} metadataMap list of local or shared assets */ static createCacheForMap(metadataMap) { for (const element of Object.values(metadataMap)) { // create actual cache map /** @type {AssetItemSimple} */ const simpleAsset = { id: element.id, key: element.customerKey, // ! note that ContentBlockByName expects backslashes between folders and file name, not forward slashes name: element.r__folder_Path ? element.r__folder_Path.replaceAll('/', '\\') + '\\' + element.name : null, }; // if this method was filled by Asset.upsert it might have been run before with more accurate (retrieved) data including the id that we do not want to override this.assetCacheMap.key[simpleAsset.key] ||= simpleAsset; if (simpleAsset.id) { // if this method was filled by Asset.upsert it won't have ids this.assetCacheMap.id[simpleAsset.id] = simpleAsset; } if (simpleAsset.name) { // while asset without path could still be found via search, it would no longer referencable via ContentBlockByName // if this method was filled by Asset.upsert it might have been run before with more accurate (retrieved) data including the id that we do not want to override this.assetCacheMap.name[simpleAsset.name] ||= simpleAsset; } } } /** * helper for {@link ReplaceContentBlockReference.createCache} * * @param {BuObject} buObject references credentials * @param {Mcdevrc} properties central properties object * @param {boolean} [retrieveSharedOnly] for --dependencies only, do not have to re-retrieve local assets * @returns {Promise.<{localAssets: AssetMap, sharedAssets: AssetMap}>} - */ static async _retrieveCache(buObject, properties, retrieveSharedOnly = false) { const client = auth.getSDK(buObject); if (!cache.getCache()) { cache.initCache(buObject); } Util.logger.info(' - Caching folders'); Folder.buObject = buObject; Folder.properties = properties; Folder.client = client; const resultFolder = await Folder.retrieveForCache(null, ['asset', 'asset-shared']); cache.setMetadata('folder', resultFolder.metadata); let localAssets; if (retrieveSharedOnly) { Util.logger.debug(' - Caching assets locally'); if (!Asset.getJsonFromFSCache) { // avoid re-reading the same files in every recursive iteration Asset.getJsonFromFSCache = await Asset.getJsonFromFS( File.normalizePath([ properties.directories.retrieve, buObject.credential, buObject.businessUnit, Asset.definition.type, ]) ); } localAssets = Asset.getJsonFromFSCache; cache.setMetadata('asset', Asset.getJsonFromFSCache); } else { Util.logger.info(' - Caching assets from server'); Asset.buObject = buObject; Asset.properties = properties; Asset.client = client; const resultAsset = await Asset.retrieveForCache( undefined, Asset.definition.crosslinkedSubTypes ); for (const element of Object.values(resultAsset.metadata)) { // ensure we got the folder-path in our cache Asset.setFolderPath(element); } localAssets = resultAsset.metadata; cache.setMetadata('asset', resultAsset.metadata); } // get shared assets Util.logger.info(' - Caching shared assets from server (not stored on disk)'); Asset.buObject = buObject; Asset.properties = properties; Asset.client = client; const sharedAssets = ( await Asset.retrieveForCache( undefined, Asset.definition.crosslinkedSubTypes, undefined, true ) )?.metadata; // lets not put the shared assets into our cache to avoid confusing the system... for (const element of Object.values(sharedAssets)) { // ensure we got the folder-path in our cache Asset.setFolderPath(element); } return { localAssets, sharedAssets }; } } ================================================ FILE: lib/util/util.js ================================================ 'use strict'; import MetadataDefinitions from './../MetadataTypeDefinitions.js'; import process from 'node:process'; import toposort from 'toposort'; import winston from 'winston'; import child_process from 'node:child_process'; import path from 'node:path'; // import just to resolve cyclical - TO DO consider if could move to file or context import { readJsonSync } from 'fs-extra/esm'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * @typedef {import('../../types/mcdev.d.js').AuthObject} AuthObject * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject * @typedef {import('../../types/mcdev.d.js').Cache} Cache * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract * @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem * @typedef {import('../../types/mcdev.d.js').DeltaPkgItem} DeltaPkgItem * @typedef {import('../../types/mcdev.d.js').McdevLogger} McdevLogger * @typedef {import('../../types/mcdev.d.js').Logger} Logger * @typedef {import('../../types/mcdev.d.js').Mcdevrc} Mcdevrc * @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff * @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj * @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap * @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeList} MultiMetadataTypeList * @typedef {import('../../types/mcdev.d.js').MultiMetadataTypeMap} MultiMetadataTypeMap * @typedef {import('../../types/mcdev.d.js').SkipInteraction} SkipInteraction * @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams * @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap * @typedef {import('../../types/mcdev.d.js').TypeKeyCombo} TypeKeyCombo * @typedef {import('../../types/mcdev.d.js').SDKError} SDKError */ /** * Util that contains logger and simple util methods */ export const Util = { authFileName: '.mcdev-auth.json', boilerplateDirectory: '../../boilerplate', configFileName: '.mcdevrc.json', defaultGitBranch: 'main', parentBuName: '_ParentBU_', standardizedSplitChar: '/', /** used to replace '/' in folder names to avoid confusion with the path separator */ folderNameSlashEscapeChar: '\u2215', /** @type {SkipInteraction} */ skipInteraction: null, packageJsonMcdev: readJsonSync(path.join(__dirname, '../../package.json')), OPTIONS: {}, changedKeysMap: {}, matchedByName: {}, /** * helper that allows filtering an object by its keys * * @param {Object.<string,*>} originalObj object that you want to filter * @param {string[]} [whitelistArr] positive filter. if not provided, returns originalObj without filter * @returns {Object.<string,*>} filtered object that only contains keys you provided */ filterObjByKeys(originalObj, whitelistArr) { if (!whitelistArr || !Array.isArray(whitelistArr)) { return originalObj; } return Object.keys(originalObj) .filter((key) => whitelistArr.includes(key)) .reduce((obj, key) => { obj[key] = originalObj[key]; return obj; }, {}); }, /** * extended Array.includes method that allows check if an array-element starts with a certain string * * @param {string[]} arr your array of strigns * @param {string} search the string you are looking for * @returns {boolean} found / not found */ includesStartsWith(arr, search) { return this.includesStartsWithIndex(arr, search) >= 0; }, /** * extended Array.includes method that allows check if an array-element starts with a certain string * * @param {string[]} arr your array of strigns * @param {string} search the string you are looking for * @returns {number} array index 0..n or -1 of not found */ includesStartsWithIndex(arr, search) { return Array.isArray(arr) ? arr.findIndex((el) => el.startsWith(search)) : -1; }, /** * check if a market name exists in current mcdev config * * @param {string} market market localizations * @param {Mcdevrc} properties local mcdev config * @returns {boolean} found market or not */ checkMarket(market, properties) { if (properties.markets[market]) { return true; } else { Util.logger.error(`Could not find the market '${market}' in your configuration file.`); const marketArr = Object.keys(properties.markets); if (marketArr.length) { Util.logger.info('Available markets are: ' + marketArr.join(', ')); } return false; } }, /** * check if a market name exists in current mcdev config * * @param {string[]} marketArr market localizations * @param {Mcdevrc} properties local mcdev config * @returns {boolean} found market or not */ checkMarketList(marketArr, properties) { if (marketArr[0] !== '__clone__') { // if __clone__ is passed, we don't want to actually change anything but simply clone the metadata as-is for (const market of marketArr) { if (!Util.checkMarket(market, properties)) { return false; } } } return true; }, /** * ensure provided MarketList exists and it's content including markets and BUs checks out * * @param {string} mlName name of marketList * @param {Mcdevrc} properties General configuration to be used in retrieve */ verifyMarketList(mlName, properties) { if (properties.marketList[mlName]) { // ML exists, check if it is properly set up // check if BUs in marketList are valid let buCounter = 0; for (const businessUnit in properties.marketList[mlName]) { if (businessUnit !== 'description' && businessUnit !== 'filter') { buCounter++; Util.isValidBU(properties, businessUnit, true); if (!Util.isValidBU(properties, businessUnit, true)) { throw new Error(`'${businessUnit}' in Market ${mlName} is not defined.`); } // check if markets are valid let marketArr = properties.marketList[mlName][businessUnit]; if ('string' === typeof marketArr) { marketArr = [marketArr]; } for (const market of marketArr) { if (properties.markets[market]) { // * markets can be empty or include variables. Nothing we can test here } else { throw new Error(`Market '${market}' is not defined.`); } } } } if (!buCounter) { throw new Error(`No BUs defined in marketList ${mlName}`); } } else { // ML does not exist throw new Error(`Market List ${mlName} is not defined`); } }, /** * * @param {string | TypeKeyCombo} selectedTypes supported metadata type * @param {string[]} [keyArr] name/key of the metadata * @param {string} [commandName] for log output only * @returns {TypeKeyCombo | undefined} true if everything is valid; false otherwise */ checkAndPrepareTypeKeyCombo(selectedTypes, keyArr, commandName) { if ('string' === typeof selectedTypes) { // ensure we have TypeKeyCombo here /** @type {TypeKeyCombo} */ selectedTypes = this.createTypeKeyCombo(selectedTypes, keyArr); } // check if types are valid for (const type of Object.keys(selectedTypes)) { if (!this._isValidType(type)) { return; } if (!Array.isArray(selectedTypes[type]) || !selectedTypes[type].length) { this.logger.error( 'You need to define keys, not just types to run ' + (commandName || '') ); // we need an array of keys here return; } // ensure keys are sorted to enhance log readability selectedTypes[type].sort(); } return selectedTypes; }, /** * used to ensure the program tells surrounding software that an unrecoverable error occured * * @returns {void} */ signalFatalError() { // Util.logger.debug('Util.signalFataError() sets process.exitCode = 1 unless already set'); process.exitCode ||= 1; }, /** * SFMC accepts multiple true values for Boolean attributes for which we are checking here. * The same problem occurs when evaluating boolean CLI flags * * @param {*} attrValue value * @returns {boolean} attribute value == true ? true : false */ isTrue(attrValue) { return ['true', 'TRUE', 'True', '1', 1, 'Y', 'y', true].includes(attrValue); }, /** * SFMC accepts multiple false values for Boolean attributes for which we are checking here. * The same problem occurs when evaluating boolean CLI flags * * @param {*} attrValue value * @returns {boolean} attribute value == false ? true : false */ isFalse(attrValue) { return ['false', 'FALSE', 'False', '0', 0, 'N', 'n', false].includes(attrValue); }, /** * helper to test if two variables are equal * * @param {string | number | boolean | Array | object} item1 - * @param {string | number | boolean | Array | object} item2 - * @returns {boolean} equal or not */ isEqual: function (item1, item2) { if (item1 === item2) { return true; } if (typeof item1 !== typeof item2) { return false; } if (Array.isArray(item1) && Array.isArray(item2)) { return this._isEqualArray(item1, item2); } if (typeof item1 === 'object') { return this._isEqualObject(item1, item2); } return false; }, /** * helper to test if two arrays are equal * * @param {Array} array1 - * @param {Array} array2 - * @returns {boolean} equal or not */ _isEqualArray: function (array1, array2) { return ( array1.length === array2.length && array1.every((val) => array2.includes(val)) && array2.every((val) => array1.includes(val)) ); }, /** * helper to test if two objects are equal * * @param {object} item1 - * @param {object} item2 - * @returns {boolean} equal or not */ _isEqualObject: function (item1, item2) { if (!this._isEqualArray(Object.keys(item1), Object.keys(item2))) { return false; } for (const key in item1) { if (!this.isEqual(item1[key], item2[key])) { return false; } } return true; }, /** * helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy * * @param {string} selectedType type or type-subtype * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {boolean} type ok or not */ _isValidType(selectedType, handleOutside) { const { type, subType } = Util.getTypeAndSubType(selectedType); if (type && !MetadataDefinitions[type]) { if (!handleOutside) { Util.logger.error(`:: '${type}' is not a valid metadata type`); } return false; } else if ( type && subType && (!MetadataDefinitions[type] || !MetadataDefinitions[type].subTypes.includes(subType)) ) { if (!handleOutside) { Util.logger.error(`:: '${selectedType}' is not a valid metadata type`); } return false; } return true; }, /** * helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy * * @param {Mcdevrc} properties javascript object in .mcdevrc.json * @param {string} businessUnit name of BU * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method * @returns {boolean} bu found or not */ isValidBU(properties, businessUnit, handleOutside) { const [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; if (!properties.credentials[cred]) { if (!handleOutside) { Util.logger.error(`Credential not found`); } return false; } else if (!properties.credentials[cred].businessUnits[bu]) { if (!handleOutside) { Util.logger.error(`BU not found in credential`); } return false; } return true; }, /** * helper that deals with extracting type and subtype * * @param {string} selectedType "type" or "type-subtype" * @returns {{type:string, subType:string}} first elem is type, second elem is subType */ getTypeAndSubType(selectedType) { if (selectedType) { const temp = selectedType.split('-'); const type = temp.shift(); // remove first item which is the main typ const subType = temp.join('-'); // subType can include "-" return { type, subType }; } else { return { type: null, subType: null }; } }, /** * helper for getDefaultProperties() * * @param {'typeRetrieveByDefault'|'typeCdpByDefault'} field relevant field in type definition * @returns {string[]} type choices */ getTypeChoices(field) { const typeChoices = []; for (const el in MetadataDefinitions) { if ( Array.isArray(MetadataDefinitions[el][field]) || MetadataDefinitions[el][field] === true ) { // complex types like assets are saved as array but to ease upgradability we // save the main type only unless the user deviates from our pre-selection. // Types that dont have subtypes set this field to true or false typeChoices.push(MetadataDefinitions[el].type); } } typeChoices.sort((a, b) => { if (a.toLowerCase() < b.toLowerCase()) { return -1; } if (a.toLowerCase() > b.toLowerCase()) { return 1; } return 0; }); return typeChoices.filter(Boolean); }, /** * helper for cli.selectTypes and init.config.fixMcdevConfig that converts subtypes back to main type if all and only defaults were selected * this keeps the config automatically upgradable when we add new subtypes or change what is selected by default * * @param {'typeRetrieveByDefault'|'typeCdpByDefault'} field relevant field in type definition * @param {string[]} selectedTypes what types the user selected * @param {'asset'} [type] metadata type * @returns {string[]} filtered selectedTypes */ summarizeSubtypes(field, selectedTypes, type = 'asset') { const selectedAssetSubtypes = selectedTypes.filter((str) => str.includes(type + '-')); /** @type {string[]|boolean} */ const config = MetadataDefinitions[type][field]; if (Array.isArray(config) && selectedAssetSubtypes.length === config.length) { const nonDefaultSelectedAssetSubtypes = selectedAssetSubtypes .map((subtype) => subtype.replace(type + '-', '')) .filter((subtype) => !config.includes(subtype)); if (!nonDefaultSelectedAssetSubtypes.length) { // found all defaults and nothing else. replace with main type selectedTypes = selectedTypes.filter((str) => !str.includes(type + '-')); selectedTypes.push(type); } } selectedTypes.sort(); return selectedTypes; }, /** @type {string} last used timestamp to create log filename with */ logFileName: null, /** * wrapper around our standard winston logging to console and logfile * * @param {boolean} [noLogFile] optional flag to indicate if we should log to file; CLI logs are always on * @returns {object} initiated logger for console and file */ _createNewLoggerTransport: function (noLogFile = false) { // { // error: 0, // warn: 1, // info: 2, // http: 3, // verbose: 4, // debug: 5, // silly: 6 // } if ( process.env.FORK_PROCESS_ID || // run via Git-Fork process.env.PATH.toLowerCase().includes('sourcetree') // run via Atlassian SourceTree ) { Util.OPTIONS.noLogColors = true; } Util.logFileName = new Date().toISOString().split(':').join('.'); const transports = { console: new winston.transports.Console({ // Write logs to Console level: Util.OPTIONS.loggerLevel || 'info', format: winston.format.combine( Util.OPTIONS.noLogColors ? winston.format.uncolorize() : winston.format.colorize(), winston.format.timestamp({ format: 'HH:mm:ss' }), winston.format.simple(), winston.format.printf( (info) => `${info.timestamp} ${info.level}: ${info.message}` ) ), }), }; if (!noLogFile) { transports.file = new winston.transports.File({ // Write logs to logfile filename: 'logs/' + Util.logFileName + '.log', level: 'debug', // log everything format: winston.format.combine( winston.format.uncolorize(), winston.format.timestamp({ format: 'HH:mm:ss.SSS' }), winston.format.simple(), winston.format.printf( (info) => `${info.timestamp} ${info.level}: ${info.message}` ) ), }); if (Util.OPTIONS.errorLog) { // used by CI/CD solutions like Copado to quickly show the error message to admins/users transports.fileError = new winston.transports.File({ // Write logs to additional error-logfile for better visibility of errors filename: 'logs/' + Util.logFileName + '-errors.log', level: 'error', // only log errors lazy: true, // if true, log files will be created on demand, not at the initialization time. format: winston.format.combine( winston.format.uncolorize(), winston.format.timestamp({ format: 'HH:mm:ss.SSS' }), winston.format.simple(), winston.format.printf( (info) => `${info.timestamp} ${info.level}: ${info.message}` ) ), }); } } return transports; }, loggerTransports: null, /** * Logger that creates timestamped log file in 'logs/' directory * * @type {Logger} */ logger: null, /** * initiate winston logger * * @param {boolean} [restart] if true, logger will be restarted; otherwise, an existing logger will be used * @param {boolean} [noLogFile] if false, logger will log to file; otherwise, only to console * @returns {void} */ startLogger: function (restart = false, noLogFile = false) { if ( !( Util.loggerTransports === null || restart || (!Util.loggerTransports?.file && !noLogFile && !Util.OPTIONS?.noLogFile) ) ) { // logger already started return; } Util.loggerTransports = this._createNewLoggerTransport( noLogFile || Util.OPTIONS?.noLogFile ); const myWinston = winston.createLogger({ level: Util.OPTIONS.loggerLevel, levels: winston.config.npm.levels, transports: Object.values(Util.loggerTransports), }); const winstonError = myWinston.error; /** @type {McdevLogger} */ const winstonExtension = { /** * helper that prints better stack trace for errors * * @param {SDKError} ex the error * @param {string} [message] optional custom message to be printed as error together with the exception's message * @returns {void} */ errorStack: function (ex, message) { if (message) { // ! this method only sets exitCode=1 if message-param was set // if not, then this method purely outputs debug information and should not change the exitCode winstonError(`${message}: ${ex.message}${ex.code ? ' (' + ex.code + ')' : ''}`); if (ex.endpoint) { // ex.endpoint is only available if 'ex' is of type RestError winstonError(' endpoint: ' + ex.endpoint); } Util.signalFatalError(); } else { myWinston.debug(`${ex.message}${ex.code ? ' (' + ex.code + ')' : ''}`); if (ex.endpoint) { // ex.endpoint is only available if 'ex' is of type RestError myWinston.debug(' endpoint: ' + ex.endpoint); } } let stack; /* eslint-disable unicorn/prefer-ternary */ if ( [ 'ETIMEDOUT', 'EHOSTUNREACH', 'ENOTFOUND', 'ECONNRESET', 'ECONNABORTED', ].includes(ex.code) ) { // the stack would just return a one-liner that does not help stack = new Error().stack; // eslint-disable-line unicorn/error-message } else { stack = ex.stack; } /* eslint-enable unicorn/prefer-ternary */ myWinston.debug(stack); }, /** * errors should cause surrounding applications to take notice * hence we overwrite the default error function here * * @param {string} msg - the message to log * @returns {void} */ error: function (msg) { winstonError(msg); Util.signalFatalError(); }, }; Util.logger = Object.assign(myWinston, winstonExtension); const processArgv = process.argv.slice(2); Util.logger.debug( `:: mcdev ${Util.packageJsonMcdev.version} :: ⚡ mcdev ${processArgv.join(' ')}` ); }, /** * Logger helper for Metadata functions * * @param {string} level of log (error, info, warn) * @param {string} type of metadata being referenced * @param {string} method name which log was called from * @param {*} payload generic object which details the error * @param {string} [source] key/id of metadata which relates to error * @returns {void} */ metadataLogger: function (level, type, method, payload, source) { let prependSource = ''; if (source) { prependSource = source + ' - '; } if (payload instanceof Error) { // extract error message Util.logger[level](`${type}.${method}: ${prependSource}${payload.message}`); } else if (typeof payload === 'string') { // print out simple string Util.logger[level](`${type} ${method}: ${prependSource}${payload}`); } else { // Print out JSON String as default. Util.logger[level](`${type}.${method}: ${prependSource}${JSON.stringify(payload)}`); } }, /** * replaces values in a JSON object string, based on a series of * key-value pairs (obj) * * @param {string | object} str JSON object or its stringified version, which has values to be replaced * @param {TemplateMap} obj key value object which contains keys to be replaced and values to be replaced with * @returns {string | object} replaced version of str */ replaceByObject: function (str, obj) { let convertType = false; if ('string' !== typeof str) { convertType = true; str = JSON.stringify(str); } // sort by value length const sortable = []; for (const key in obj) { // only push in value if not null if (obj[key]) { sortable.push([key, obj[key]]); } } sortable.sort((a, b) => b[1].length - a[1].length); for (const pair of sortable) { const escVal = pair[1].toString().replaceAll(/[-/\\^$*+?.()|[\]{}]/g, String.raw`\$&`); const regString = new RegExp(escVal, 'g'); str = str.replace(regString, '{{{' + pair[0] + '}}}'); } if (convertType) { str = JSON.parse(str); } return str; }, /** * get key of an object based on the first matching value * * @param {object} objs object of objects to be searched * @param {string | number} val value to be searched for * @returns {string} key */ inverseGet: function (objs, val) { for (const obj in objs) { if (objs[obj] === val) { return obj; } } throw new Error(`${val} not found in object`); }, /** *helper for Mcdev.fixKeys. Retrieve dependent metadata * * @param {string} fixedType type of the metadata passed as a parameter to fixKeys function * @returns {string[]} array of types that depend on the given type */ getDependentMetadata(fixedType) { const dependencies = new Set(); for (const dependentType of Object.keys(MetadataDefinitions)) { if (MetadataDefinitions[dependentType].dependencies.includes(fixedType)) { // fixedType was found as a dependency of dependentType dependencies.add(dependentType); } else if ( MetadataDefinitions[dependentType].dependencies.some((dependency) => dependency.startsWith(fixedType + '-') ) ) { // if MetadataTypeDefinitions[dependentType].dependencies start with type then also add dependentType to the set; use some to check if any of the dependencies start with type dependencies.add(dependentType); } } return [...dependencies]; }, /** * Returns Order in which metadata needs to be retrieved/deployed * * @param {string[]} typeArr which should be retrieved/deployed * @returns {Object.<string, string[]>} retrieve/deploy order as array */ getMetadataHierachy(typeArr) { const dependencies = []; // loop through all metadata types which are being retrieved/deployed const subTypeDeps = {}; for (const typeSubType of typeArr) { const type = typeSubType.split('-')[0]; // if they have dependencies then add a dependency pair for each type if (MetadataDefinitions[type].dependencies.length > 0) { dependencies.push( ...MetadataDefinitions[type].dependencies.map((dep) => { if (dep.includes('-')) { // log subtypes to be able to replace them if main type is also present subTypeDeps[dep.split('-')[0]] ||= new Set(); subTypeDeps[dep.split('-')[0]].add(dep); } return [dep, typeSubType]; }) ); } // if they have no dependencies then just add them with undefined. else { dependencies.push([undefined, typeSubType]); } } const allDeps = dependencies.map((dep) => dep[0]); // remove subtypes if main type is in the list for (const type of Object.keys(subTypeDeps) // only look at subtype deps that are also supposed to be retrieved or cached fully .filter((type) => typeArr.includes(type) || allDeps.includes(type))) { // convert set into array to walk its elements for (const subType of subTypeDeps[type]) { for (const item of dependencies) { if (item[0] === subType) { // if subtype recognized, replace with main type item[0] = type; } } } } // sort list & remove the undefined dependencies const flatList = toposort(dependencies).filter((a) => !!a); /** @type {Object.<string, null | Set.<string>>} */ const setList = {}; // group subtypes per type for (const flatType of flatList) { if (flatType.includes('-')) { const { type, subType } = Util.getTypeAndSubType(flatType); if (setList[type] === null) { // if main type is already required, then don't filter by subtypes continue; } else if (setList[type] && subType) { // add another subtype to the set setList[type].add(subType); continue; } else { // create a new set with the first subtype; subKey will be always set here setList[type] = new Set([subType]); } if (subTypeDeps[type]) { // check if there are depndent subtypes that need to be added /** @type {string[]} */ const temp = [...subTypeDeps[type]].map((a) => { const temp = a.split('-'); temp.shift(); // remove first item which is the main type return temp.join('-'); // subType can include "-" }); for (const item of temp) { setList[type].add(item); } } } else { setList[flatType] = null; } } // convert sets into arrays /** @type {Object.<string, string[]>} */ const finalList = {}; for (const type of Object.keys(setList)) { finalList[type] = setList[type] instanceof Set ? [...setList[type]] : null; } return finalList; }, /** * let's you dynamically walk down an object and get a value * * @param {string} path 'fieldA.fieldB.fieldC' * @param {object} obj some parent object * @returns {any} value of obj.path */ resolveObjPath(path, obj) { return path.split('.').reduce((prev, curr) => (prev ? prev[curr] : null), obj); }, /** * helper to run other commands as if run manually by user * * @param {string} cmd to be executed command * @param {string[]} [args] list of arguments * @param {boolean} [hideOutput] if true, output of command will be hidden from CLI * @returns {string|void} output of command if hideOutput is true */ execSync(cmd, args, hideOutput) { args ||= []; Util.logger.info('⚡ ' + cmd + ' ' + args.join(' ')); try { if (hideOutput) { // no output displayed to user but instead returned to parsed elsewhere return child_process .execSync(cmd + ' ' + args.join(' ')) .toString() .trim(); } else { // the following options ensure the user sees the same output and // interaction options as if the command was manually run child_process.execSync(cmd + ' ' + args.join(' '), { stdio: [0, 1, 2] }); return null; } } catch { // avoid errors from execSync to bubble up return null; } }, /** * standardize check to ensure only one result is returned from template search * * @param {MetadataTypeItem[]} results array of metadata * @param {string} keyToSearch the field which contains the searched value * @param {string} searchValue the value which is being looked for * @returns {MetadataTypeItem} metadata to be used in building template */ templateSearchResult(results, keyToSearch, searchValue) { const matching = results.filter((item) => item[keyToSearch] === searchValue); if (matching.length === 0) { throw new Error(`No metadata found with name "${searchValue}"`); } else if (matching.length > 1) { throw new Error( `Multiple metadata with name "${searchValue}" please rename to be unique to avoid issues` ); } else { return matching[0]; } }, /** * configures what is displayed in the console * * @param {object} argv list of command line parameters given by user * @param {boolean} [argv.silent] only errors printed to CLI * @param {boolean} [argv.verbose] chatty user CLI output * @param {boolean} [argv.debug] enables developer output & features * @returns {void} */ setLoggingLevel(argv) { if (argv.silent) { // only errors printed to CLI Util.OPTIONS.loggerLevel = 'error'; Util.logger.debug('CLI logger set to: silent'); } else if (argv.verbose) { // chatty user cli logs Util.OPTIONS.loggerLevel = 'verbose'; Util.logger.debug('CLI logger set to: verbose'); } else { // default user cli logs Util.OPTIONS.loggerLevel = 'info'; Util.logger.debug('CLI logger set to: info / default'); } if (argv.debug) { // enables developer output & features. no change to actual logs Util.OPTIONS.loggerLevel = 'debug'; Util.logger.debug('CLI logger set to: debug'); } if (Util.loggerTransports?.console) { Util.loggerTransports.console.level = Util.OPTIONS.loggerLevel; } if (Util.logger) { Util.logger.level = Util.OPTIONS.loggerLevel; } }, /** * outputs a warning that the given type is still in beta * * @param {string} type api name of the type thats in beta */ logBeta(type) { Util.logger.warn( ` - 🚧 ${type} support is currently still in beta. Please report any issues here: https://github.com/Accenture/sfmc-devtools/issues/new/choose` ); }, /** * outputs a warning that the given method is deprecated * * @param {string} method name of the method * @param {string} [useInstead] optionally specify which method to use instead */ logDeprecated(method, useInstead = '') { Util.logger.warn( ` 💥 '${method}' is deprecated and will be sunset in a future version. ${useInstead ? `Please use ${useInstead} instead.` : ''}` ); }, /** * helper for MetadataType class to issue a similar error message for unsupported methods * * @param {any} definition type definition object * @param {string} method name of the method thats not supported * @param {MetadataTypeItem} [item] metadata item */ logNotSupported: function (definition, method, item) { Util.logger.error( ` ☇ skipping ${item ? Util.getTypeKeyName(definition, item) : definition.type}: ${method} is not supported for ${definition.type}` ); }, // defined colors for logging things in different colors color: { reset: '\x1B[0m', dim: '\x1B[2m', bright: '\x1B[1m', underscore: '\x1B[4m', blink: '\x1B[5m', reverse: '\x1B[7m', hidden: '\x1B[8m', fgBlack: '\x1B[30m', fgRed: '\x1B[31m', fgGreen: '\x1B[32m', fgYellow: '\x1B[33m', fgBlue: '\x1B[34m', fgMagenta: '\x1B[35m', fgCyan: '\x1B[36m', fgWhite: '\x1B[37m', fgGray: '\x1B[90m', bgBlack: '\x1B[40m', bgRed: '\x1B[41m', bgGreen: '\x1B[42m', bgYellow: '\x1B[43m', bgBlue: '\x1B[44m', bgMagenta: '\x1B[45m', bgCyan: '\x1B[46m', bgWhite: '\x1B[47m', bgGray: '\x1B[100m', }, /** * helper that wraps a message in the correct color codes to have them printed gray * * @param {string} msg log message that should be wrapped with color codes * @returns {string} gray msg */ getGrayMsg(msg) { return `${Util.color.dim}${msg}${Util.color.reset}`; }, /** * helper that returns the prefix of item specific log messages * * @param {any} definition metadata definition * @param {MetadataTypeItem} metadataItem metadata item * @returns {string} msg prefix */ getMsgPrefix(definition, metadataItem) { return ` - ${Util.getTypeKeyName(definition, metadataItem)}`; }, /** * helper that returns the prefix of item specific log messages * * @param {any} definition metadata definition * @param {MetadataTypeItem} metadataItem metadata item * @returns {string} key or key/name combo */ getTypeKeyName(definition, metadataItem) { return `${definition.type}: ${Util.getKeyName(definition, metadataItem)}`; }, /** * helper that returns the prefix of item specific log messages * * @param {any} definition metadata definition * @param {MetadataTypeItem} metadataItem metadata item * @returns {string} key or key/name combo */ getKeyName(definition, metadataItem) { const key = metadataItem[definition.keyField] || metadataItem[definition.nameField]; const name = metadataItem[definition.nameField]; return !name || name == key ? key : key + ` / ` + name; }, /** * helper to print the subtypes we filtered by * * @param {string[]} subTypeArr list of subtypes to be printed * @param {string} [indent] optional prefix of spaces to be added to the log message * @returns {void} */ logSubtypes(subTypeArr, indent = '') { if (subTypeArr && subTypeArr.length > 0) { Util.logger.info( Util.getGrayMsg( `${indent} - Subtype${subTypeArr.length > 1 ? 's' : ''}: ${[...subTypeArr].toSorted().join(', ')}` ) ); } }, /** * helper to print the subtypes we filtered by * * @param {string[] | string} keyArr list of subtypes to be printed * @param {boolean} [isId] optional flag to indicate if key is an id * @returns {string} string to be appended to log message */ getKeysString(keyArr, isId) { if (!keyArr) { return ''; } if (!Array.isArray(keyArr)) { // if only one key, make it an array keyArr = [keyArr]; } if (keyArr.length > 0) { return Util.getGrayMsg( ` - ${isId ? 'ID' : 'Key'}${keyArr.length > 1 ? 's' : ''}: ${keyArr.join(', ')}` ); } return ''; }, /** * pause execution of code; useful when multiple server calls are dependent on each other and might not be executed right away * * @param {number} ms time in miliseconds to wait * @returns {Promise.<void>} - promise to wait for */ async sleep(ms) { if (Util.OPTIONS._runningTest) { Util.logger.debug('Skipping sleep in test mode'); return; } return new Promise((resolve) => { setTimeout(resolve, ms); }); }, /** * helper for Asset.extractCode and Script.prepExtractedCode to determine if a code block is a valid SSJS block * * @example the following is invalid: * <script runat="server"> * // 1 * </script> * <script runat="server"> * // 2 * </script> * * the following is valid: * <script runat="server"> * // 3 * </script> * @param {string} code code block to check * @returns {string} the SSJS code if code block is a valid SSJS block, otherwise null */ getSsjs(code) { if (!code) { return null; } // \s* whitespace characters, zero or more times // [^>]*? any character that is not a >, zero or more times, un-greedily // (.*) capture any character, zero or more times // /s dotall flag // ideally the code looks like <script runat="server">...</script> // regex that matches <script runat="server">...</script>, <script runat="server" language="javascript">...</script> or <script language="JavaScript" runat="server">...</script>, but it may not match <script language="ampscript" runat="server">...</script> and it may also not match <script runat="server" language="ampscript">...</script> const scriptRegex = /^<\s*script\s*(language=["']{1}javascript["']{1})?\s?[^>]*?runat\s*=\s*["']{1}server["']{1}\s*?(language=["']{1}javascript["']{1})?\s*>(.*)<\/\s*script\s*>$/is; code = code.trim(); const regexMatches = scriptRegex.exec(code); // regexMatches indexes: // 1: first optional language block // 2: second optional language block // 3: the actual code if (regexMatches?.length > 1 && regexMatches[3]) { // script found /* eslint-disable unicorn/prefer-ternary */ if (regexMatches[3].includes('<script')) { // nested script found return null; } else { // no nested script found: return the assumed SSJS-code return regexMatches[3]; } /* eslint-enable unicorn/prefer-ternary */ } // no script found return null; }, /** * allows us to filter just like with SQL's LIKE operator * * @param {string} testString field value to test * @param {string} search search string in SQL LIKE format * @returns {boolean} true if testString matches search */ stringLike(testString, search) { if (typeof search !== 'string' || this === null) { return false; } // Remove special chars search = search.replaceAll( new RegExp(String.raw`([\.\\\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:\-])`, 'g'), String.raw`\$1` ); // Replace % and _ with equivalent regex // Replace % with .* search = search.replaceAll('%', '.*'); // Replace _ with . only if not surrounded by [ and ] search = search.replaceAll(/(?<!\[)_+(?!\])/g, (match) => '.'.repeat(match.length)); // replace [_] with _ search = search.replaceAll(String.raw`\[_\]`, '_'); // Check matches return new RegExp('^' + search + '$', 'gi').test(testString); }, /** * returns true if no LIKE filter is defined or if all filters match * * @param {MetadataTypeItem} metadata a single metadata item * @param {object} definition type definition * @param {object} [filters] only used in recursive calls * @returns {boolean} true if no LIKE filter is defined or if all filters match */ fieldsLike(metadata, definition, filters) { if (metadata.json && metadata.codeArr) { // Compensate for CodeExtractItem format metadata = metadata.json; } // ensure we only convert "key" and "name" fields on the first call to this method const checkDefaultKeyAndName = filters ? false : true; filters ||= Util.OPTIONS.like; if (!filters) { return true; } const fields = Object.keys(filters); return fields.every((field) => { // to allow passing in an array via cli, e.g. --like=field1,field2, we need to convert comma separated lists into arrays const filter = typeof filters[field] === 'string' && filters[field].includes(',') ? filters[field].split(',') : filters[field]; if (Array.isArray(metadata[field])) { return metadata[field].some((f) => Util.fieldsLike(f, definition, filter)); } else { let fieldName; if (field === 'key' && checkDefaultKeyAndName) { fieldName = definition.keyField; } else if (field === 'name' && checkDefaultKeyAndName) { fieldName = definition.nameField; } if (typeof filter === 'string') { return Util.stringLike(metadata[fieldName || field], filter); } else if (Array.isArray(filter)) { return filter.some((f) => Util.stringLike(metadata[field], f)); } else if (typeof filter === 'object') { return Util.fieldsLike(metadata[field], definition, filter); } } return false; }); }, /** * helper used by SOAP methods to ensure the type always uses an upper-cased first letter * * @param {string} str string to capitalize * @returns {string} str with first letter capitalized */ capitalizeFirstLetter(str) { return str.charAt(0).toUpperCase() + str.slice(1); }, /** * helper for Retriever and Deployer class * * @param {string | string[]} typeArr - * @param {string[]} keyArr - * @param {boolean} [returnEmpty] returns array with null element if false/not set; Retriever needs this to be false; Deployer needs it to be true * @returns {TypeKeyCombo} - */ createTypeKeyCombo(typeArr, keyArr, returnEmpty = false) { if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { // no keys were provided, ensure we retrieve all keyArr = returnEmpty ? null : [null]; } /** @type {TypeKeyCombo} */ const typeKeyMap = {}; if ('string' === typeof typeArr) { typeArr = [typeArr]; } // no keys or array of keys was provided (likely called via CLI or to retrieve all) // transform into TypeKeyCombo to iterate over it for (const type of typeArr) { typeKeyMap[type] = keyArr; } return typeKeyMap; }, /** * helper that converts TypeKeyCombo objects into a string with all relevant -m parameters * * @param {TypeKeyCombo} [selectedTypes] selected metadata types & key * @returns {string} object converted into --metadata parameters */ convertTypeKeyToCli(selectedTypes) { return selectedTypes ? Object.keys(selectedTypes) .reduce((previousValue, type) => { previousValue.push( ...selectedTypes[type].map((key) => key === null ? `-m ${type}` : `-m "${type}:${key}"` ) ); return previousValue; }, []) .join(' ') : ''; }, /** * helper that converts TypeKeyCombo objects into a string with all relevant -m parameters * * @param {TypeKeyCombo} [selectedTypes] selected metadata types & key * @returns {string} object converted into --metadata parameters */ convertTypeKeyToString(selectedTypes) { return selectedTypes ? Object.keys(selectedTypes) .reduce((previousValue, type) => { previousValue.push( selectedTypes[type] .map((key, index) => { let response = ''; if (index === 0) { response += `${type}`; } if (key !== null && index === 0) { response += ' ('; } response += key === null ? `` : `"${key}"`; if (key !== null && index === selectedTypes[type].length - 1) { response += ')'; } return response; }) .join(', ') ); return previousValue; }, []) .join(', ') : ''; }, /** * helper that checks how many keys are defined in TypeKeyCombo object * * @param {TypeKeyCombo} [selectedTypes] selected metadata types & key * @returns {number} amount of keys across all types */ getTypeKeyCount(selectedTypes) { return Object.keys(selectedTypes).reduce( (previousValue, type) => previousValue + (selectedTypes[type] ? selectedTypes[type].length : 0), 0 ); }, /** * async version of Array.find() * returns the first element in the provided array that satisfies the provided testin function * * @param {Array} arr your test array * @param {Function} asyncCallback callback * @returns {Promise.<any | undefined>} first element that passed the test */ async findAsync(arr, asyncCallback) { for (const element of arr) { if (await asyncCallback(element)) { return element; } } }, /** * * @param {Array} array array to be chunked * @param {number} chunk_size integer > 0 * @returns {Array[]} array of arrays with max chunk_size members per element, last element might have less */ chunk(array, chunk_size) { return array.length == 0 ? [] : [array.splice(0, chunk_size)].concat(this.chunk(array, chunk_size)); }, /** * recursively find all values of the given key in the object * * @param {any} object data to search in * @param {string} key attribute to find * @returns {Array} all values of the given key */ findLeafVals(object, key) { const values = []; Object.keys(object).map((k) => { if (k === key) { values.push(object[k]); return true; } if (object[k] && typeof object[k] === 'object') { values.push(...this.findLeafVals(object[k], key)); } }); return [...new Set(values.toSorted())]; }, /** * helper that returns a new object with sorted attributes of the given object * * @param {object} obj object with unsorted attributes * @returns {object} obj but with sorted attributes */ sortObjectAttributes(obj) { return Object.keys(obj) .toSorted() .reduce((acc, key) => { acc[key] = obj[key]; return acc; }, {}); }, }; Util.startLogger(false, true); ================================================ FILE: lib/util/validations.js ================================================ 'use strict'; import path from 'node:path'; import { Util } from './util.js'; /** * @typedef {import('../../types/mcdev.d.js').validationRuleList} validationRuleList * @typedef {import('../../types/mcdev.d.js').validationRuleFix} validationRuleFix * @typedef {import('../../types/mcdev.d.js').validationRuleTest} validationRuleTest * @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract */ /** @type {validationRuleList} */ let customRules = {}; let customRuleImport; /** * helper for validation * * @returns {Promise.<void>} - */ async function loadCustomRules() { try { customRuleImport = await import( 'file://' + path.join(process.cwd(), '.mcdev-validations.js') ); } catch (ex) { if (ex instanceof SyntaxError) { Util.logger.error('SyntaxError in .mcdev-validations.js: ' + ex.message); } else if (ex.code === 'ERR_MODULE_NOT_FOUND') { Util.logger.debug('.mcdev-validations.js not found'); } else { Util.logger.errorStack( ex, 'Could not load custom validation rules from .mcdev-validations.js' ); } } } /** * * @param {any} definition type definition * @param {any} item MetadataItem * @param {string} targetDir folder in which the MetadataItem is deployed from (deploy/cred/bu) * @param {CodeExtract[]} [codeExtractItemArr] array of code snippets * @returns {Promise.<validationRuleList>} MetadataItem */ export default async function validation(definition, item, targetDir, codeExtractItemArr) { try { if (!customRuleImport) { // we might need to re-run this for mocha tests await loadCustomRules(); } customRules = customRuleImport ? await customRuleImport.validation( definition, item, targetDir, codeExtractItemArr, Util ) : {}; } catch (ex) { Util.logger.errorStack( ex, 'Could not load custom validation rules from .mcdev-validations.js' ); } /** @type {validationRuleList} */ const defaultRules = { noGuidKeys: { failedMsg: 'Please update the key to a readable value. Currently still in GUID format.', /** * @type {validationRuleFix} */ fix: function () { // to fix we skip the component return this.passed() || null; }, /** * @type {validationRuleTest} */ passed: function () { const key = item[definition.keyField]; if (key) { const regex = /^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$/i; return !regex.test(String(key).toLowerCase()); } else { Util.logger.debug('validation-noGuidKeys: key not found'); return true; } }, }, noRootFolder: { failedMsg: 'Root folder not allowed. Current folder: ' + item.r__folder_Path, /** * @type {validationRuleFix} */ fix: function () { // to fix we skip the component return this.passed() || null; }, /** * @type {validationRuleTest} */ passed: function () { /** @type {string} */ const folderPath = item.r__folder_Path; if (!folderPath) { // some types do not support folders return true; } const doNotEvaluate = [ 'automation', 'attributeSet', 'dataFilter', 'list', 'filter', ]; if ( doNotEvaluate.includes(definition.type) || (definition.type === 'asset' && item?.assetType?.name === 'webpage') || (definition.type === 'dataExtension' && item.r__folder_Path === 'Synchronized Data Extensions') ) { // this subtype is not visible in the interface and hence always technically sits in the root return true; } return folderPath.includes('/'); }, }, noAmpscriptHtmlTag: { failedMsg: 'Please use %%[]%% instead of <script runat="server" language="ampscript"></script> for AMPscript', /** * @type {validationRuleFix} */ fix: function () { // to fix we skip the component return this.passed() || null; }, /** * @type {validationRuleTest} */ passed: function () { if (definition.type === 'asset' && Array.isArray(codeExtractItemArr)) { for (const codeExtractItem of codeExtractItemArr) { if ( codeExtractItem.content.includes( '<script runat="server" language="ampscript">' ) ) { return false; } } return true; } else { return true; // test case should pass since non-asset metadatatypes get a pass } }, }, }; return Object.assign({}, defaultRules, customRules); } ================================================ FILE: package.json ================================================ { "name": "mcdev", "version": "9.0.3", "description": "Accenture Salesforce Marketing Cloud DevTools", "author": "Accenture: joern.berkefeld, douglas.midgley, robert.zimmermann, maciej.barnas", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/Accenture/sfmc-devtools.git" }, "homepage": "https://github.com/Accenture/sfmc-devtools/wiki", "bugs": { "url": "https://github.com/Accenture/sfmc-devtools/issues", "email": "joern.berkefeld@accenture.com" }, "funding": { "type": "corporate", "url": "https://github.com/Accenture/sfmc-devtools" }, "keywords": [ "sfmc", "ide", "devops", "developer", "exacttarget", "salesforce", "marketing cloud", "package manager", "fuel", "soap", "rest" ], "main": "./lib/index.js", "exports": { ".": { "types": "./@types/lib/index.d.ts", "default": "./lib/index.js" }, "./*": { "types": "./@types/lib/*.d.ts", "default": "./lib/*.js" } }, "bin": { "mcdev": "./lib/cli.js" }, "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" }, "scripts": { "start": "node lib/cli.js", "mcdev": "node lib/cli.js", "build": "run-s lint:fix docs test", "debug": "node --nolazy --inspect-brk=9229 lib/cli.js", "lint:fix": "eslint --fix lib/**/*.js types/*.js test/**/*.js", "lint": "eslint lib/**/*.js types/*.js test/**/*.js", "lint-ts": "tsc -p tsconfig.npmScripts.json", "prepare": "husky || true", "lint-and-test": "run-s lint test", "test": "mocha --reporter-option maxDiffSize=25000", "coverage": "c8 npm run test", "prepare-release:audit-fix": "npm audit fix", "prepare-release:git": "node prepare-release.js", "prepare-release": "run-s --continue-on-error prepare-release:audit-fix lint-ts lint:fix prepare-release:git", "version:major": "npm version --no-commit-hooks major", "version:minor": "npm version --no-commit-hooks minor", "version:patch": "npm version --no-commit-hooks patch" }, "dependencies": { "beauty-amp-core2": "0.4.9", "cli-progress": "3.12.0", "command-exists": "1.2.9", "conf": "15.1.0", "console.table": "0.10.0", "deep-equal": "2.2.3", "fs-extra": "11.3.4", "inquirer": "13.3.2", "json-to-table": "4.2.1", "mustache": "4.2.0", "p-limit": "7.3.0", "prettier": "3.8.1", "prettier-plugin-sql": "0.20.0", "semver": "7.7.4", "sfmc-sdk": "3.0.3", "simple-git": "3.33.0", "toposort": "2.0.2", "update-notifier": "7.3.1", "winston": "3.19.0", "yargs": "18.0.0", "yocto-spinner": "1.1.0" }, "devDependencies": { "@eslint/js": "10.0.1", "@types/fs-extra": "11.0.4", "@types/inquirer": "9.0.9", "@types/mocha": "10.0.8", "@types/node": "25.5.0", "@types/yargs": "17.0.35", "assert": "2.1.0", "axios-mock-adapter": "2.0.0", "c8": "11.0.0", "chai": "6.2.2", "chai-files": "1.4.0", "eslint": "10.1.0", "eslint-config-ssjs": "2.0.0", "eslint-plugin-jsdoc": "62.8.0", "eslint-plugin-mocha": "11.2.0", "eslint-plugin-prettier": "5.5.5", "eslint-plugin-unicorn": "63.0.0", "fast-xml-parser": "5.5.9", "globals": "17.4.0", "husky": "9.1.7", "lint-staged": "16.4.0", "mocha": "11.7.5", "mock-fs": "5.3.0", "npm-run-all": "4.1.5", "prettier-eslint": "16.4.2", "typescript": "5.9.3" }, "optionalDependencies": { "fsevents": "*" }, "lint-staged": { "*.js": [ "eslint --fix" ] }, "type": "module" } ================================================ FILE: prepare-release.js ================================================ /* eslint-disable no-console */ import { exec } from 'node:child_process'; console.log('> git status --porcelain'); exec('git status --porcelain', (err, stdout, stderr) => { if (err) { console.error(`Error executing git status: ${stderr}`); return; } if (stdout) { console.log( ' Found changes:', '\n - ' + stdout.split('\n').filter(Boolean).join('\n - ') ); console.log('> git add .'); exec('git add .', (err, stdout, stderr) => { if (err) { console.error(`Error executing git add: ${stderr}`); return; } console.log('> git commit -n -m "prepare-release changes"'); exec('git commit -n -m "prepare-release changes"', (err, stdout, stderr) => { if (err) { console.error(`Error executing git commit: ${stderr}`); return; } else { console.log('✅ Changes committed successfully.'); } }); }); } else { console.log('✅ No untracked files to commit.'); } }); /* eslint-enable no-console */ ================================================ FILE: test/general.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('GENERAL', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('ReplaceContentBlockByX ================', () => { describe('with types specified ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { journey: null, senderProfile: null, }, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right journeys that need updating' ); assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-name'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_senderProfile_rcb', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-name'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 48, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { journey: null, senderProfile: null, }, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right journeys that need updating' ); assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-id'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_senderProfile_rcb', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-id'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 48, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { journey: null, senderProfile: null, }, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-key'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_senderProfile_rcb', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-key'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 48, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('without types specified ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', undefined, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].asset, [ 'testExisting_asset_htmlblock', 'testExisting_htmlblock1', 'testExisting_htmlblock 3 spaces', 'testExisting_asset_message', ], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].script, [ 'testExisting_script_ampscript', 'testExisting_script_ampincluded', 'testExisting_script_mixed', ], 'should have found the right scripts that need updating' ); assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-name'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_senderProfile_rcb', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-name'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 84, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', undefined, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].asset, [ 'testExisting_htmlblock1', 'testExisting_htmlblock 3 spaces', 'testExisting_asset_message', ], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].script, ['testExisting_script_ampscript', 'testExisting_script_mixed'], 'should have found the right scripts that need updating' ); assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-id'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_senderProfile_rcb', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-id'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 84, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', undefined, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].asset, [ 'testExisting_asset_htmlblock', 'testExisting_htmlblock1', 'testExisting_asset_message', ], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right assets that need updating' ); assert.deepEqual( replace['testInstance/testBU'].script, ['testExisting_script_ampscript', 'testExisting_script_ampincluded'], 'should have found the right scripts that need updating' ); assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-key'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_senderProfile_rcb', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-key'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 84, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); describe('with --metadata ================', () => { describe('retrieve --metadata ~~~', () => { it('retrieve single type without keys', async () => { const argvMetadata = ['dataExtract']; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.retrieve(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); const retrievedTypes = Object.keys(result[buName]); assert.equal(retrievedTypes.length, 1, 'retrieve should have returned 1 type'); assert.equal( retrievedTypes[0], 'dataExtract', 'retrieve should have returned 1 type' ); assert.equal( testUtils.getAPIHistoryLength(), 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('retrieve multiple type without keys', async () => { const argvMetadata = ['dataExtension', 'senderProfile']; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.retrieve(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); const retrievedTypes = Object.keys(result[buName]); assert.equal(retrievedTypes.length, 2, 'retrieve should have returned 2 types'); assert.equal( retrievedTypes[0], 'dataExtension', 'retrieve should have returned dataExtension' ); assert.equal( retrievedTypes[1], 'senderProfile', 'retrieve should have returned senderProfile' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 3, 'retrieve should have returned 3 senderProfile' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('retrieve multiple type with keys', async () => { const argvMetadata = [ 'dataExtension', 'dataExtract:wrong-key', 'senderProfile:Default', 'query:testExisting_query', 'query:key:testExisting_query2', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.retrieve(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); const retrievedTypes = Object.keys(result[buName]); assert.equal(retrievedTypes.length, 4, 'retrieve should have returned 4 types'); assert.equal( retrievedTypes.includes('dataExtension'), true, 'retrieve should have returned dataExtension' ); assert.equal( retrievedTypes.includes('dataExtract'), true, 'retrieve should have returned dataExtract' ); assert.equal( retrievedTypes.includes('senderProfile'), true, 'retrieve should have returned senderProfile' ); assert.equal( retrievedTypes.includes('query'), true, 'retrieve should have returned query' ); assert.equal( Object.keys(result[buName]['dataExtension']).length, 8, 'retrieve should have returned 7 dataExtension' ); assert.equal( Object.keys(result[buName]['dataExtract']).length, 0, 'retrieve should have returned 0 dataExtracts' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 1, 'retrieve should have returned 1 senderProfile' ); assert.equal( Object.keys(result[buName]['query']).length, 2, 'retrieve should have returned 2 query' ); assert.equal( testUtils.getAPIHistoryLength(), 18, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); }); describe('deploy --metadata ~~~', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('deploy single type without keys', async () => { const argvMetadata = ['dataExtract']; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.deploy(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); const deployedTypes = Object.keys(result[buName]); assert.equal(deployedTypes.length, 1, 'deploy should have returned 1 type'); assert.equal(deployedTypes[0], 'dataExtract', 'deploy should have returned 1 type'); assert.equal( testUtils.getAPIHistoryLength(), 13, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('deploy multiple type without keys', async () => { const argvMetadata = ['dataExtension', 'senderProfile']; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.deploy(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); const deployedTypes = Object.keys(result[buName]); assert.equal(deployedTypes.length, 2, 'deploy should have returned 2 types'); assert.equal( deployedTypes[0], 'dataExtension', 'deploy should have returned dataExtension' ); assert.equal( deployedTypes[1], 'senderProfile', 'deploy should have returned senderProfile' ); assert.equal( Object.keys(result[buName]['dataExtension']).length, 2, 'deploy should have returned 2 dataExtension' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 2, 'deploy should have returned 2 senderProfile' ); assert.equal( testUtils.getAPIHistoryLength(), 20, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('deploy multiple type with keys', async () => { const argvMetadata = [ 'dataExtension', 'dataExtract:wrong-key', 'senderProfile:testExisting_senderProfile', 'query:testExisting_query', 'query:key:wrong-key2', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.deploy(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); const deployedTypes = Object.keys(result[buName]); assert.equal(deployedTypes.length, 3, 'deploy should have returned 3 types'); assert.equal( deployedTypes.includes('dataExtension'), true, 'deploy should have returned dataExtension' ); assert.equal( deployedTypes.includes('dataExtract'), false, 'deploy should have returned dataExtract' ); assert.equal( deployedTypes.includes('senderProfile'), true, 'deploy should have returned senderProfile' ); assert.equal( deployedTypes.includes('query'), true, 'deploy should have returned query' ); assert.equal( Object.keys(result[buName]['dataExtension']).length, 2, 'deploy should have returned 2 dataExtension' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 1, 'deploy should have returned 1 senderProfile' ); assert.equal( Object.keys(result[buName]['query']).length, 1, 'deploy should have returned 1 query' ); assert.equal( testUtils.getAPIHistoryLength(), 19, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('deploy multiple type with keys and --noUpdate', async () => { handler.setOptions({ noUpdate: true }); const argvMetadata = [ 'dataExtension', 'dataExtract:wrong-key', 'senderProfile:testExisting_senderProfile', 'query:testExisting_query', 'query:key:wrong-key2', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; const result = await handler.deploy(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); const deployedTypes = Object.keys(result[buName]); assert.equal(deployedTypes.length, 3, 'deploy should have returned 3 types'); assert.equal( deployedTypes.includes('dataExtension'), true, 'deploy should have returned dataExtension' ); assert.equal( deployedTypes.includes('dataExtract'), false, 'deploy should have returned dataExtract' ); assert.equal( deployedTypes.includes('senderProfile'), true, 'deploy should have returned senderProfile' ); assert.equal( deployedTypes.includes('query'), true, 'deploy should have returned query' ); assert.equal( Object.keys(result[buName]['dataExtension']).length, 1, 'deploy should have returned 1 dataExtension' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 0, 'deploy should have returned 0 senderProfile' ); assert.equal( Object.keys(result[buName]['query']).length, 0, 'deploy should have returned 0 query' ); assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('skip deploy event with bad filename or bad extension', async () => { testUtils.copyToDeploy('event-deploy', 'event'); const argvMetadata = [ 'event:testNew_event_badExtension', 'event:testNew_event_badName', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); const buName = 'testInstance/testBU'; await handler.deploy(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 1, 'deploy should not have thrown an error'); assert.equal( testUtils.getAPIHistoryLength(), 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('skip deploy asset with bad filename or bad extension', async () => { testUtils.copyToDeploy('asset-deploy', 'asset'); const argvMetadata = [ 'asset:testNew_asset_badExtension', 'asset:testNew_asset_badName', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); const buName = 'testInstance/testBU'; await handler.deploy(buName, typeKeyCombo); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); assert.equal( testUtils.getAPIHistoryLength(), 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('skip deploy based on validation rule "filterPrefixByBu" with --fix without error', async () => { testUtils.copyToDeploy('asset-deploy2', 'asset'); testUtils.copyToDeploy('dataExtension-deploy', 'dataExtension'); const buName = 'testInstance/testBU'; handler.setOptions({ fix: true }); await handler.deploy(buName, { asset: ['testBlacklist_asset_htmlblock'], dataExtension: ['testBlacklist_dataExtension'], }); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('skip deploy based on validation rule "filterPrefixByBu" without --fix but with error', async () => { testUtils.copyToDeploy('asset-deploy2', 'asset'); testUtils.copyToDeploy('dataExtension-deploy', 'dataExtension'); const buName = 'testInstance/testBU'; await handler.deploy(buName, { asset: ['testBlacklist_asset_htmlblock'], dataExtension: ['testBlacklist_dataExtension'], }); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); }); describe('template --metadata ~~~', () => { it('buildTemplate + buildDefinition for multiple types with keys', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['automation', 'query']); const expectedApiCallsRetrieve = 37; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; // *** buildTemplate *** const templateResult = await handler.buildTemplate( buName, typeKeyCombo, undefined, ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // check automation assert.equal( templateResult.automation ? Object.keys(templateResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // check query assert.equal( templateResult.query ? Object.keys(templateResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** const definitionResult = await handler.buildDefinition( buName, typeKeyCombo, undefined, ['testTargetMarket'] ); assert.equal( process.exitCode, 0, 'buildDefinition should not have thrown an error' ); // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('buildTemplate + buildDefinition for multiple types with keys and --retrieve', async () => { const expectedApiCallsRetrieve = 34; // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; handler.setOptions({ retrieve: true }); // *** buildTemplate *** const templateResult = await handler.buildTemplate( buName, typeKeyCombo, undefined, ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // check automation assert.equal( templateResult.automation ? Object.keys(templateResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // check query assert.equal( templateResult.query ? Object.keys(templateResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** const definitionResult = await handler.buildDefinition( buName, typeKeyCombo, undefined, ['testTargetMarket'] ); assert.equal( process.exitCode, 0, 'buildDefinition should not have thrown an error' ); // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('buildTemplate + buildDefinition for multiple types with keys and --dependencies', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU'); const expectedApiCallsRetrieve = 111; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; // set skipInteraction to true to skip re-retrieving question handler.setOptions({ dependencies: true, skipInteraction: true }); // *** buildTemplate *** const templateResult = await handler.buildTemplate( buName, typeKeyCombo, undefined, ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // check type list assert.deepEqual( Object.keys(templateResult), [ 'automation', 'dataExtension', 'dataExtract', 'domainVerification', 'emailSend', 'fileTransfer', 'importFile', 'query', 'script', 'sendClassification', 'senderProfile', 'verification', ], 'did not create deployment packages for all relevant types' ); // check automation assert.equal( templateResult.automation ? Object.keys(templateResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // check query assert.equal( templateResult.query ? Object.keys(templateResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** const definitionResult = await handler.buildDefinition( buName, typeKeyCombo, undefined, ['testTargetMarket'] ); assert.equal( process.exitCode, 0, 'buildDefinition should not have thrown an error' ); // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('buildTemplate + buildDefinition for multiple types with keys and --dependencies and --retrieve', async () => { // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; handler.setOptions({ dependencies: true, retrieve: true }); // *** buildTemplate *** const templateResult = await handler.buildTemplate( buName, typeKeyCombo, undefined, ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // check type list assert.deepEqual( Object.keys(templateResult), [ 'automation', 'dataExtension', 'dataExtract', 'domainVerification', 'emailSend', 'fileTransfer', 'importFile', 'query', 'script', 'sendClassification', 'senderProfile', 'verification', ], 'did not create deployment packages for all relevant types' ); // check automation assert.equal( templateResult.automation ? Object.keys(templateResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // check query assert.equal( templateResult.query ? Object.keys(templateResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** const definitionResult = await handler.buildDefinition( buName, typeKeyCombo, undefined, ['testTargetMarket'] ); assert.equal( process.exitCode, 0, 'buildDefinition should not have thrown an error' ); // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); const expectedApiCallsRetrieve = 115; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('buildTemplate + buildDefinitionBulk multiple type with keys', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['automation', 'query']); const expectedApiCallsRetrieve = 37; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; // *** buildTemplate *** const templateResult = await handler.buildTemplate( buName, typeKeyCombo, undefined, ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // check automation assert.equal( templateResult.automation ? Object.keys(templateResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // check query assert.equal( templateResult.query ? Object.keys(templateResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinitionBulk chained *** const definitionResult = await handler.buildDefinitionBulk( 'deployment-target', typeKeyCombo ); assert.equal( process.exitCode, 0, 'buildDefinitionBulk should not have thrown an error' ); // check automation assert.equal( definitionResult.automation?.['testInstance/testBU']?.testSourceMarket ? Object.keys( definitionResult.automation?.['testInstance/testBU']?.testSourceMarket ).length : 0, 1, 'only one automation expected' ); assert.equal( definitionResult.automation?.['testInstance/testBU']?.testTargetMarket ? Object.keys( definitionResult.automation?.['testInstance/testBU']?.testTargetMarket ).length : 0, 1, 'only one automation expected' ); assert.equal( definitionResult.automation?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.automation?.['testInstance/_ParentBU_'] ?.testTargetMarket ).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check if files were also created for other BU-market combos // testBU: testSourceMarket expect( await testUtils.getActualDeployFile( 'testExisting_automation', 'automation', 'json' ) ).to.exist; // _ParentBU_: testTargetMarket expect( await testUtils.getActualDeployFile( 'testTemplated_automation', 'automation', 'json', '_ParentBU_' ) ).to.exist; // check query assert.equal( definitionResult.query?.['testInstance/testBU']?.testSourceMarket ? Object.keys( definitionResult.query?.['testInstance/testBU']?.testSourceMarket ).length : 0, 1, 'only one query expected' ); assert.equal( definitionResult.query?.['testInstance/testBU']?.testTargetMarket ? Object.keys( definitionResult.query?.['testInstance/testBU']?.testTargetMarket ).length : 0, 1, 'only one query expected' ); assert.equal( definitionResult.query?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.query?.['testInstance/_ParentBU_']?.testTargetMarket ).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); // check if files were also created for other BU-market combos // testBU: testSourceMarket expect(await testUtils.getActualDeployFile('testExisting_query', 'query', 'json')) .to.exist; expect(await testUtils.getActualDeployFile('testExisting_query', 'query', 'sql')).to .exist; // _ParentBU_: testTargetMarket expect( await testUtils.getActualDeployFile( 'testTemplated_query', 'query', 'json', '_ParentBU_' ) ).to.exist; expect( await testUtils.getActualDeployFile( 'testTemplated_query', 'query', 'sql', '_ParentBU_' ) ).to.exist; assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('clone multiple type with keys', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['automation', 'query']); const expectedApiCallsRetrieve = 37; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; handler.setOptions({ skipInteraction: true, purge: false }); // *** build: buildTemplate and buildDefinition chained *** const definitionResult = await handler.clone(buName, buName, typeKeyCombo); assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // *** buildTemplate *** // cannot be checked in build anymore because it writes templates into a temporary folder and deletes them afterwards // *** buildDefinition *** // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'clone'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'clone'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'clone', 'sql')); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('build multiple type with keys', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['automation', 'query']); const expectedApiCallsRetrieve = 37; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; handler.setOptions({ skipInteraction: true, purge: false }); // *** build: buildTemplate and buildDefinition chained *** const definitionResult = await handler.build( buName, buName, typeKeyCombo, ['testSourceMarket'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // *** buildTemplate *** // check automation // assert.deepEqual( // await testUtils.getActualTemporaryTemplateJson( // 'testExisting_automation', // 'automation' // ), // await testUtils.getExpectedJson('9999999', 'automation', 'template'), // 'returned template was not equal expected' // ); // // check query // assert.deepEqual( // await testUtils.getActualTemporaryTemplateJson('testExisting_query', 'query'), // await testUtils.getExpectedJson('9999999', 'query', 'template'), // 'returned template JSON of retrieveAsTemplate was not equal expected' // ); // expect( // await testUtils.getActualTemporaryTemplateFile( // 'testExisting_query', // 'query', // 'sql' // ) // ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('build multiple type with keys and --dependencies', async () => { // download everything before we test buildTemplate await handler.retrieve('testInstance/testBU'); const expectedApiCallsRetrieve = 111; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; // set skipInteraction to true to skip re-retrieving question handler.setOptions({ dependencies: true, skipInteraction: true, purge: true }); // *** build: buildTemplate and buildDefinition chained *** const definitionResult = await handler.build( buName, buName, typeKeyCombo, ['testSourceMarket'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // *** buildTemplate *** // // check automation // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), // await testUtils.getExpectedJson('9999999', 'automation', 'template'), // 'returned template was not equal expected' // ); // // check query // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_query', 'query'), // await testUtils.getExpectedJson('9999999', 'query', 'template'), // 'returned template JSON of retrieveAsTemplate was not equal expected' // ); // expect( // await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') // ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** // check type list assert.deepEqual( Object.keys(definitionResult), [ 'automation', 'dataExtension', 'dataExtract', 'domainVerification', 'emailSend', 'fileTransfer', 'importFile', 'query', 'script', 'sendClassification', 'senderProfile', 'verification', ], 'did not create deployment packages for all relevant types' ); // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('build multiple type with keys and --dependencies and --retrieve', async () => { // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; handler.setOptions({ dependencies: true, retrieve: true, skipInteraction: true, purge: true, }); // *** build: buildTemplate and buildDefinition chained *** const definitionResult = await handler.build( buName, buName, typeKeyCombo, ['testSourceMarket'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // *** buildTemplate *** // check automation // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), // await testUtils.getExpectedJson('9999999', 'automation', 'template'), // 'returned template was not equal expected' // ); // // check query // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_query', 'query'), // await testUtils.getExpectedJson('9999999', 'query', 'template'), // 'returned template JSON of retrieveAsTemplate was not equal expected' // ); // expect( // await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') // ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinition *** // check type list assert.deepEqual( Object.keys(definitionResult), [ 'automation', 'dataExtension', 'dataExtract', 'domainVerification', 'emailSend', 'fileTransfer', 'importFile', 'query', 'script', 'sendClassification', 'senderProfile', 'verification', ], 'did not create deployment packages for all relevant types' ); // check automation assert.equal( definitionResult.automation ? Object.keys(definitionResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check query assert.equal( definitionResult.query ? Object.keys(definitionResult.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); const expectedApiCallsRetrieve = 115; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('build multiple type with keys and --bulk', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['automation', 'query']); const expectedApiCallsRetrieve = 37; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; handler.setOptions({ skipInteraction: true, purge: false }); // *** build: buildTemplate and buildDefinition chained *** const definitionResult = await handler.build( buName, 'ignored', typeKeyCombo, ['testSourceMarket'], ['deployment-target'], true ); assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // *** buildTemplate *** // // check automation // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), // await testUtils.getExpectedJson('9999999', 'automation', 'template'), // 'returned template was not equal expected' // ); // // check query // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_query', 'query'), // await testUtils.getExpectedJson('9999999', 'query', 'template'), // 'returned template JSON of retrieveAsTemplate was not equal expected' // ); // expect( // await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') // ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinitionBulk *** // check automation assert.equal( definitionResult.automation?.['testInstance/testBU']?.testSourceMarket ? Object.keys( definitionResult.automation?.['testInstance/testBU']?.testSourceMarket ).length : 0, 1, 'only one automation expected' ); assert.equal( definitionResult.automation?.['testInstance/testBU']?.testTargetMarket ? Object.keys( definitionResult.automation?.['testInstance/testBU']?.testTargetMarket ).length : 0, 1, 'only one automation expected' ); assert.equal( definitionResult.automation?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.automation?.['testInstance/_ParentBU_'] ?.testTargetMarket ).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check if files were also created for other BU-market combos // testBU: testSourceMarket expect( await testUtils.getActualDeployFile( 'testExisting_automation', 'automation', 'json' ) ).to.exist; // _ParentBU_: testTargetMarket expect( await testUtils.getActualDeployFile( 'testTemplated_automation', 'automation', 'json', '_ParentBU_' ) ).to.exist; // check query assert.equal( definitionResult.query?.['testInstance/testBU']?.testSourceMarket ? Object.keys( definitionResult.query?.['testInstance/testBU']?.testSourceMarket ).length : 0, 1, 'only one query expected' ); assert.equal( definitionResult.query?.['testInstance/testBU']?.testTargetMarket ? Object.keys( definitionResult.query?.['testInstance/testBU']?.testTargetMarket ).length : 0, 1, 'only one query expected' ); assert.equal( definitionResult.query?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.query?.['testInstance/_ParentBU_']?.testTargetMarket ).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); // check if files were also created for other BU-market combos // testBU: testSourceMarket expect(await testUtils.getActualDeployFile('testExisting_query', 'query', 'json')) .to.exist; expect(await testUtils.getActualDeployFile('testExisting_query', 'query', 'sql')).to .exist; // _ParentBU_: testTargetMarket expect( await testUtils.getActualDeployFile( 'testTemplated_query', 'query', 'json', '_ParentBU_' ) ).to.exist; expect( await testUtils.getActualDeployFile( 'testTemplated_query', 'query', 'sql', '_ParentBU_' ) ).to.exist; assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('build multiple type with keys and --bulk and --dependencies', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU'); const expectedApiCallsRetrieve = 111; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation const argvMetadata = [ 'automation:testExisting_automation', 'query:testExisting_query', 'query:bad', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); assert.notEqual( typeof typeKeyCombo, 'undefined', 'typeKeyCombo should not be undefined' ); const buName = 'testInstance/testBU'; // set skipInteraction to true to skip re-retrieving question handler.setOptions({ dependencies: true, skipInteraction: true, purge: true }); // *** build: buildTemplate and buildDefinition chained *** const definitionResult = await handler.build( buName, 'ignored', typeKeyCombo, ['testSourceMarket'], ['deployment-target'], true ); assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // *** buildTemplate *** // // check automation // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), // await testUtils.getExpectedJson('9999999', 'automation', 'template'), // 'returned template was not equal expected' // ); // // check query // assert.deepEqual( // await testUtils.getActualTemplateJson('testExisting_query', 'query'), // await testUtils.getExpectedJson('9999999', 'query', 'template'), // 'returned template JSON of retrieveAsTemplate was not equal expected' // ); // expect( // await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') // ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // *** buildDefinitionBulk *** // check type list assert.deepEqual( Object.keys(definitionResult), [ 'automation', 'dataExtension', 'dataExtract', 'domainVerification', 'emailSend', 'fileTransfer', 'importFile', 'query', 'script', 'sendClassification', 'senderProfile', 'verification', ], 'did not create deployment packages for all relevant types' ); // check automation assert.equal( definitionResult.automation?.['testInstance/testBU']?.testSourceMarket ? Object.keys( definitionResult.automation?.['testInstance/testBU']?.testSourceMarket ).length : 0, 1, 'only one automation expected' ); assert.equal( definitionResult.automation?.['testInstance/testBU']?.testTargetMarket ? Object.keys( definitionResult.automation?.['testInstance/testBU']?.testTargetMarket ).length : 0, 1, 'only one automation expected' ); assert.equal( definitionResult.automation?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.automation?.['testInstance/_ParentBU_'] ?.testTargetMarket ).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); // check if files were also created for other BU-market combos // testBU: testSourceMarket expect( await testUtils.getActualDeployFile( 'testExisting_automation', 'automation', 'json' ) ).to.exist; // _ParentBU_: testTargetMarket expect( await testUtils.getActualDeployFile( 'testTemplated_automation', 'automation', 'json', '_ParentBU_' ) ).to.exist; // check query assert.equal( definitionResult.query?.['testInstance/testBU']?.testSourceMarket ? Object.keys( definitionResult.query?.['testInstance/testBU']?.testSourceMarket ).length : 0, 1, 'only one query expected' ); assert.equal( definitionResult.query?.['testInstance/testBU']?.testTargetMarket ? Object.keys( definitionResult.query?.['testInstance/testBU']?.testTargetMarket ).length : 0, 1, 'only one query expected' ); assert.equal( definitionResult.query?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.query?.['testInstance/_ParentBU_']?.testTargetMarket ).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); // check if files were also created for other BU-market combos // testBU: testSourceMarket expect(await testUtils.getActualDeployFile('testExisting_query', 'query', 'json')) .to.exist; expect(await testUtils.getActualDeployFile('testExisting_query', 'query', 'sql')).to .exist; // _ParentBU_: testTargetMarket expect( await testUtils.getActualDeployFile( 'testTemplated_query', 'query', 'json', '_ParentBU_' ) ).to.exist; expect( await testUtils.getActualDeployFile( 'testTemplated_query', 'query', 'sql', '_ParentBU_' ) ).to.exist; assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('build but error after buildTemplate step because keys were not found', async () => { const buName = 'testInstance/testBU'; const typeKeyCombo = { asset: ['404'], dataExtension: ['404'], }; // handler.setOptions({ skipInteraction: true, purge: false, fix: true }); await handler.build( buName, 'ignored', typeKeyCombo, ['testSourceMarket'], ['parent'], true ); // THEN assert.equal(process.exitCode, 1, 'build should not have thrown an error'); assert.equal( testUtils.getAPIHistoryLength(), 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('skip build based on validation rule "filterPrefixByBu" with --fix without error', async () => { const buName = 'testInstance/testBU'; const typeKeyCombo = { asset: ['testExisting_asset_htmlblock'], dataExtension: ['testExisting_dataExtension'], }; await handler.retrieve(buName, typeKeyCombo); const expectedApiCallsRetrieve = 11; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); handler.setOptions({ skipInteraction: true, purge: false, fix: true }); const definitionResult = await handler.build( buName, 'ignored', typeKeyCombo, ['testSourceMarket'], ['parent'], true ); // THEN assert.equal(process.exitCode, 0, 'build should not have thrown an error'); // confirm that no deployment package was created assert.equal( definitionResult.asset?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.asset?.['testInstance/_ParentBU_']?.testTargetMarket ).length : 0, 0, '0 asset expected' ); assert.equal( definitionResult.dataExtension?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.dataExtension?.['testInstance/_ParentBU_'] ?.testTargetMarket ).length : 0, 0, '0 dataExtension expected' ); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('skip deploy based on validation rule "filterPrefixByBu" without --fix but with error', async () => { const buName = 'testInstance/testBU'; const typeKeyCombo = { asset: ['testExisting_asset_htmlblock'], dataExtension: ['testExisting_dataExtension'], }; await handler.retrieve(buName, typeKeyCombo); const expectedApiCallsRetrieve = 11; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); handler.setOptions({ skipInteraction: true, purge: false }); const definitionResult = await handler.build( buName, 'ignored', typeKeyCombo, ['testSourceMarket'], ['parent'], true ); // THEN assert.equal(process.exitCode, 1, 'build should have thrown an error'); // confirm that no deployment package was created assert.equal( definitionResult.asset?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.asset?.['testInstance/_ParentBU_']?.testTargetMarket ).length : 0, 0, '0 asset expected' ); assert.equal( definitionResult.dataExtension?.['testInstance/_ParentBU_']?.testTargetMarket ? Object.keys( definitionResult.dataExtension?.['testInstance/_ParentBU_'] ?.testTargetMarket ).length : 0, 0, '0 dataExtension expected' ); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); }); describe('Delete --metadata ~~~', () => { it('Should delete the items', async () => { const argvMetadata = [ 'asset:testExisting_asset', 'automation:testExisting_automation', 'journey:testExisting_journey_Quicksend/1', 'journey:testExisting_journey_Multistep/1', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); // WHEN const isDeleted = await handler.deleteByKey('testInstance/testBU', typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); describe('Publish --metadata ~~~', () => { it('Should publish the journey', async () => { handler.setOptions({ skipStatusCheck: true }); const argvMetadata = [ 'journey:testExisting_journey_Multistep', 'journey:testExisting_temail_notPublished', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); // WHEN const publish = await handler.publish('testInstance/testBU', typeKeyCombo); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); assert.deepEqual( publish['testInstance/testBU']?.journey, ['testExisting_journey_Multistep', 'testExisting_temail_notPublished'], 'should have published the right journey' ); return; }); }); describe('Execute/Start --metadata ~~~', () => { it('Should execute the item', async () => { const argvMetadata = [ 'query:testExisting_query', 'automation:testExisting_automation', ]; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); // WHEN const executedKeys = await handler.execute('testInstance/testBU', typeKeyCombo); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); // query assert.equal( executedKeys['testInstance/testBU']?.query?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( executedKeys['testInstance/testBU']?.query[0], 'testExisting_query', 'returned keys do not correspond to expected fixed keys' ); // automation assert.equal( executedKeys['testInstance/testBU']?.automation?.length, 1, 'automation was supposed to be executed' ); assert.equal( executedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); }); describe('Pause --metadata ~~~', () => { it('Should pause the item', async () => { const argvMetadata = ['automation:testExisting_automation_pause']; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); // WHEN const pausedKeys = await handler.pause('testInstance/testBU', typeKeyCombo); assert.equal(process.exitCode, 0, 'pause should not have thrown an error'); // automation assert.equal( pausedKeys['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( pausedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation_pause', 'returned keys do not correspond to expected fixed keys' ); return; }); }); describe('Schedule --metadata ~~~', () => { it('Should schedule the item', async () => { const argvMetadata = ['automation:testExisting_automation']; const typeKeyCombo = handler.metadataToTypeKey(argvMetadata); // WHEN const scheduled = await handler.schedule('testInstance/testBU', typeKeyCombo); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); // automation assert.equal( scheduled['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( scheduled['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); }); }); describe('without --metadata ================', () => { describe('retrieve without --metadata ~~~', () => { it('retrieve multiple type with keys', async () => { const buName = 'testInstance/testBU'; const result = await handler.retrieve( buName, ['dataExtract', 'senderProfile'], ['wrong-key', 'Default'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); const retrievedTypes = Object.keys(result[buName]); assert.equal(retrievedTypes.length, 2, 'retrieve should have returned 2 types'); assert.equal( retrievedTypes.includes('dataExtract'), true, 'retrieve should have returned dataExtract' ); assert.equal( retrievedTypes.includes('senderProfile'), true, 'retrieve should have returned senderProfile' ); assert.equal( Object.keys(result[buName]['dataExtract']).length, 0, 'retrieve should have returned 0 dataExtracts' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 1, 'retrieve should have returned 1 senderProfile' ); assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); }); describe('deploy without --metadata ~~~', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('deploy multiple type without keys', async () => { const argvMetadata = ['dataExtension', 'senderProfile']; const buName = 'testInstance/testBU'; const result = await handler.deploy(buName, argvMetadata); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); const deployedTypes = Object.keys(result[buName]); assert.equal(deployedTypes.length, 2, 'deploy should have returned 2 types'); assert.equal( deployedTypes[0], 'dataExtension', 'deploy should have returned dataExtension' ); assert.equal( deployedTypes[1], 'senderProfile', 'deploy should have returned senderProfile' ); assert.equal( Object.keys(result[buName]['dataExtension']).length, 2, 'deploy should have returned 2 dataExtension' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 2, 'deploy should have returned 2 senderProfile' ); assert.equal( testUtils.getAPIHistoryLength(), 20, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); it('deploy multiple type with keys', async () => { const buName = 'testInstance/testBU'; const result = await handler.deploy( buName, ['dataExtension', 'dataExtract', 'senderProfile', 'query'], ['wrong-key', 'wrong-key2', 'testExisting_senderProfile', 'testExisting_query'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); const deployedTypes = Object.keys(result[buName]); assert.equal(deployedTypes.length, 2, 'deploy should have returned 2 types'); assert.equal( deployedTypes.includes('dataExtension'), false, 'deploy should have returned dataExtension' ); assert.equal( deployedTypes.includes('dataExtract'), false, 'deploy should have returned dataExtract' ); assert.equal( deployedTypes.includes('senderProfile'), true, 'deploy should have returned senderProfile' ); assert.equal( deployedTypes.includes('query'), true, 'deploy should have returned query' ); assert.equal( Object.keys(result[buName]['senderProfile']).length, 1, 'deploy should have returned 1 senderProfile' ); assert.equal( Object.keys(result[buName]['query']).length, 1, 'deploy should have returned 1 query' ); assert.equal( testUtils.getAPIHistoryLength(), 13, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); }); }); describe('Refresh ================', () => { it('Should not refresh anything due to missing type', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', null); // THEN assert.equal(process.exitCode, 1, 'refresh should have thrown an error'); // retrieve result assert.deepEqual( Object.keys(replace).length, 0, 'should not have replaced anything' ); assert.equal( testUtils.getAPIHistoryLength(), 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); describe('init ================', () => { it('should init a local project without downloading BUs'); it('should init a local project and download all BUs'); }); describe('join ================', () => { it('should clone a project from git'); }); describe('upgrade ================', () => { it('should upgrade a project to the latest version'); }); describe('reloadBUs ================', () => { it('should load all BUs from the server and refresh the config'); }); describe('selectTypes ================', () => { it('should change which types are selected for default retrieval'); }); describe('explainTypes ================', () => { it('without options', () => { handler.explainTypes(); assert.equal(process.exitCode, 0, 'explainTypes should not have thrown an error'); return; }); it('with --json set', () => { handler.setOptions({ json: true }); const typeArr = handler.explainTypes(); assert.equal( process.exitCode, 0, 'explainTypes --json should not have thrown an error' ); // check if properties are all there expect(typeArr[0]).to.have.all.keys( 'name', 'apiName', 'retrieveByDefault', 'description', 'supports' ); expect(typeArr[0].supports).to.have.all.keys( 'retrieve', 'create', 'update', 'delete', 'changeKey', 'buildTemplate', 'retrieveAsTemplate' ); // check if certain types were returned assert.equal( typeArr.find((type) => type.apiName === 'dataExtension')?.apiName, 'dataExtension', 'Expected to find dataExtension type' ); return; }); }); describe('createDeltaPkg ================', () => { it('should show diff to master branch'); // mcdev createDeltaPkg master # resolves to master..HEAD it('should show diff between master and develop branch'); // mcdev createDeltaPkg master..develop it( 'should show diff between master and develop branch and filter the results to only show MyProject/BU1' ); // mcdev createDeltaPkg master..develop --filter 'MyProject/BU1' }); }); ================================================ FILE: test/mockRoot/.mcdev-auth.json ================================================ { "testInstance": { "client_id": "71fzp43cyb1aksgflc159xxx", "client_secret": "oDZE354QsMXzcFqKQlGgDxxx", "auth_url": "https://mct0l7nxfq2r988t1kxfy8sc4xxx.auth.marketingcloudapis.com/", "account_id": 1111111 } } ================================================ FILE: test/mockRoot/.mcdev-validations.js ================================================ /* eslint-disable no-unused-vars */ 'use strict'; /** * @typedef {Object.<string, any>} MetadataTypeItem generic metadata item * * @typedef {object} CodeExtract * @property {string[]} subFolder mostly set to null, otherwise subfolders path split into elements * @property {string} fileName name of file w/o extension * @property {string} fileExt file extension * @property {string} content file content * @property {'base64'} [encoding] optional for binary files * * @callback validationRuleFix * @returns {boolean|null} true = test passed; false = test failed & fixed; null = test failed & item removed to fix * * @callback validationRuleTest * @returns {boolean} true = test passed; false = test failed * * @typedef {object} validationRule * @property {string} failedMsg error message to display in case of a failed test * @property {validationRuleTest} passed test to run * @property {validationRuleFix} [fix] test to run * * @typedef {Object.<string, validationRule>} validationRuleList key=rule name */ /** @type {Object.<string, string[]>} */ const buPrefixBlacklistMap = { testBU: ['testBlacklist_'], _ParentBU_: ['testBlacklist_'], }; /** * * @param {any} definition type definition * @param {MetadataTypeItem} item MetadataItem * @param {string} targetDir folder in which the MetadataItem is deployed from (deploy/cred/bu) * @param {CodeExtract[]} codeExtractItemArr array of code snippets * @param {any} Util utility functions * @returns {validationRuleList} MetadataItem */ export function validation(definition, item, targetDir, codeExtractItemArr, Util) { const bu = (targetDir.includes('/') ? targetDir.split('/').pop() : targetDir.split('\\').pop()) || 'not-found'; const prefixBlacklist = buPrefixBlacklistMap[bu] || []; const temp = codeExtractItemArr; return { filterPrefixByBu: { /** * @returns {string} failedMsg */ get failedMsg() { return `Prefix not allowed on this BU. Blacklisted prefixes: ${prefixBlacklist.join(', ')}`; }, /** @type {validationRuleFix} */ fix: function () { // to fix we skip the component return this.passed() || null; }, /** @type {validationRuleTest} */ passed: function () { // this rule aims to prevent deploying things that dont belong on a BU if (prefixBlacklist.length === 0) { // no blacklist defined for current BU return true; } for (const prefix of prefixBlacklist) { // most components have the brand prefixes in the key if ( item[definition.keyField] && ('' + item[definition.keyField]).startsWith(prefix) ) { // return false to issue an error or null to skip the item entirely (which is the "fix" of this rule) return false; } // some components have unreadable keys and hence only have the brand prefix in the name if ( item[definition.nameField] && ('' + item[definition.nameField]).startsWith(prefix) ) { // return false to issue an error or null to skip the item entirely (which is the "fix" of this rule) return false; } } // not found return true; }, }, }; } ================================================ FILE: test/mockRoot/.mcdevrc.json ================================================ { "credentials": { "testInstance": { "eid": 1111111, "businessUnits": { "_ParentBU_": 1111111, "testBU": 9999999 } } }, "options": { "formatOnSave": true, "formatErrorLog": false, "deployment": { "commitHistory": 10, "sourceTargetMapping": { "deployment-source": "deployment-target" }, "branchSourceTargetMapping": { "sit": { "deployment-sit-source": "deployment-sit-target" }, "uat": { "deployment-uat-source": "deployment-uat-target" }, "prod": { "deployment-prod-source": "deployment-prod-target" } }, "targetBranchBuMapping": { "release/*": "MySandbox/QA-DE", "master": ["MyProduction/PROD-DE", "MyProduction/PROD-NL"] } }, "validation": { "retrieve": { "noAmpscriptHtmlTag": "warn", "noGuidKeys": "warn", "noRootFolder": "warn" }, "buildDefinition": { "noAmpscriptHtmlTag": "warn", "noGuidKeys": "warn", "noRootFolder": "warn", "filterPrefixByBu": "error" }, "deploy": { "noAmpscriptHtmlTag": "warn", "noGuidKeys": "warn", "noRootFolder": "warn", "filterPrefixByBu": "error", "overrides": [ { "type": ["journey"], "options": { "noGuidKeys": "warn" } } ] } }, "documentType": "md", "exclude": {}, "include": {}, "serverTimeOffset": -6, "documentStandardRoles": false }, "directories": { "businessUnits": "businessUnits/", "deploy": "deploy/", "docs": "docs/", "retrieve": "retrieve/", "template": "template/", "templateBuilds": ["retrieve/", "deploy/"] }, "markets": { "testSourceMarket": { "mid": "9999999", "buName": "testBU", "secret": "secret", "sharedFolder": "/Shared Data Extensions/test", "suffix": "_test", "prefix": "testExisting_", "prefixUpper": "TESTEXISTING_", "description": "bla bla", "countryCodeIn": "'test'" }, "testTargetMarket": { "mid": "1111111", "buName": "testBUTarget", "secret": "target secret", "sharedFolder": "/Shared Data Extensions/test target", "suffix": "_testTarget", "prefix": "testTemplated_", "prefixUpper": "TESTTEMPLATED_", "description": "foobar", "countryCodeIn": "'testTarget'" }, "testBlacklistMarket": { "mid": "1111111", "buName": "testBUTarget", "secret": "target secret", "sharedFolder": "/Shared Data Extensions/test target", "suffix": "_testTarget", "prefix": "testBlacklist_", "prefixUpper": "TESTTEMPLATED_", "description": "foobar", "countryCodeIn": "'testTarget'" } }, "marketList": { "deployment-source": { "description": "Define one 1:1 BU-Market combo here to as source for automated creation of deployment packages; you can create more than one source market list", "testInstance/testBU": "testSourceMarket" }, "deployment-target": { "description": "Define n BU-Market combo here to as target for automated creation of deployment packages; you can create more than one target market list and they can be as complex as you like", "testInstance/testBU": ["testSourceMarket", "testTargetMarket"], "testInstance/_ParentBU_": ["testTargetMarket"] }, "parent": { "testInstance/_ParentBU_": ["testBlacklistMarket"] } }, "metaDataTypes": { "documentOnRetrieve": ["user", "automation", "dataExtension", "role"], "retrieve": [ "asset", "attributeGroup", "attributeSet", "automation", "dataExtension", "dataExtract", "dataFilter", "domainVerification", "emailSend", "event", "fileLocation", "fileTransfer", "filter", "importFile", "journey", "list", "mobileCode", "mobileKeyword", "mobileMessage", "query", "role", "script", "sendClassification", "senderProfile", "transactionalEmail", "transactionalPush", "transactionalSMS", "verification" ], "createDeltaPkg": [ "asset", "automation", "dataExtension", "dataExtract", "dataFilter", "emailSend", "event", "fileTransfer", "filter", "importFile", "journey", "mobileCode", "mobileKeyword", "mobileMessage", "query", "script", "sendClassification", "senderProfile", "transactionalPush", "transactionalSMS", "verification" ] }, "version": "9.0.3" } ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testExisting_dataExtensionShared.dataExtension-meta.json ================================================ { "CustomerKey": "testExisting_dataExtensionShared", "Name": "testExisting_dataExtensionShared", "Description": "Container for my test emails", "IsSendable": true, "IsTestable": true, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "Name": "FirstName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 55, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "EmailAddress", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "newField", "DefaultValue": "", "MaxLength": 254, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "ContactKey", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" } ], "c__dataRetentionPeriodUnitOfMeasure": "Days", "c__retainUntil": "2024-5-9", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "shared_dataextension", "r__folder_Path": "Shared Items/Shared Data Extensions" } ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testNew_dataExtensionShared.dataExtension-meta.json ================================================ { "CustomerKey": "testNew_dataExtensionShared", "Name": "testNew_dataExtensionShared", "Description": "", "IsSendable": false, "IsTestable": false, "Fields": [ { "Name": "testField", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "Text" } ], "c__retentionPolicy": "none", "r__folder_ContentType": "shared_dataextension", "r__folder_Path": "Shared Items/Shared Data Extensions" } ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/query/testNew_query.query-meta.json ================================================ { "name": "testNew_query", "key": "testNew_query", "description": "created on deploy", "r__dataExtension_key": "testExisting_dataExtensionShared", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/query/testNew_query.query-meta.sql ================================================ SELECT SubscriberKey as testField FROM _Subscribers ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/user/testBlocked_user.user-meta.json ================================================ { "CreatedDate": "2019-09-06T01:59:07.097", "ModifiedDate": "2022-06-21T01:43:02.64", "CustomerKey": "testBlocked_user", "UserID": "user_test@accenture.asgr", "Name": "user test", "Email": "user_test@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "LastSuccessfulLogin": "2023-02-23T10:14:11.443", "IsAPIUser": false, "NotificationEmailAddress": "user_test@accenture.com", "DefaultBusinessUnit": 9999999, "c__type": "User", "c__AssociatedBusinessUnits": [9999999], "c__RoleNamesGlobal": [ "Administrator", "Distributed Sending User", "Marketing Cloud Administrator" ], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/user/testExisting_user.user-meta.json ================================================ { "CreatedDate": "2019-09-06T01:59:07.097", "ModifiedDate": "2022-06-21T01:43:02.64", "CustomerKey": "testExisting_user", "UserID": "user_test@accenture.asgr", "Name": "user test", "Email": "user_test@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "UserPermissions": [ { "ID": 2 }, { "ID": 3 } ], "LastSuccessfulLogin": "2023-02-23T10:14:11.443", "IsAPIUser": false, "NotificationEmailAddress": "user_test@accenture.com", "DefaultBusinessUnit": 9999999, "c__type": "User", "c__AssociatedBusinessUnits": [9999999], "c__RoleNamesGlobal": [ "Administrator", "Distributed Sending User", "Individual role for 700301950" ], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/mockRoot/deploy/testInstance/_ParentBU_/user/testNew_user.user-meta.json ================================================ { "CreatedDate": "2019-09-06T01:59:07.097", "ModifiedDate": "2022-06-21T01:43:02.64", "CustomerKey": "testNew_user", "UserID": "testNew_user@accenture.asgr", "Name": "new user", "Email": "testNew_user@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "UserPermissions": [ { "ID": 2 }, { "ID": 3 } ], "LastSuccessfulLogin": "2023-02-23T10:14:11.443", "IsAPIUser": false, "NotificationEmailAddress": "testNew_user@accenture.com", "DefaultBusinessUnit": 1111111, "c__type": "User", "c__AssociatedBusinessUnits": [1111111, 9999999], "c__RoleNamesGlobal": ["Administrator", "Distributed Sending User"], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_html-matchNamFail.asset-block-meta.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%; " class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner"> <div>my 1st html</div> %%[ /* my ampscript */ ]%% <script runat="server"> // my ssjs </script> <div>my 2nd html</div> <div>%%=ContentBlockById(1295065)=%%</div> </td> </tr> </table> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_html-matchNamFail.asset-block-meta.json ================================================ { "customerKey": "testExisting_asset_html-matchNamFail", "assetType": { "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock_matchName" }, "name": "testExisting_htmlblock_matchName", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "memberId": 9999999, "status": { "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_html-matchName.asset-block-meta.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%; " class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner"> <div>my 1st html</div> %%[ /* my ampscript */ ]%% <script runat="server"> // my ssjs </script> <div>my 2nd html</div> <div>%%=ContentBlockById(1295065)=%%</div> </td> </tr> </table> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_html-matchName.asset-block-meta.json ================================================ { "customerKey": "testExisting_asset_html-matchName", "assetType": { "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "memberId": 9999999, "status": { "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_html-matchNameAdd.asset-block-meta.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%; " class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner"> <div>my 1st html</div> %%[ /* my ampscript */ ]%% <script runat="server"> // my ssjs </script> <div>my 2nd html</div> <div>%%=ContentBlockById(1295065)=%%</div> </td> </tr> </table> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_html-matchNameAdd.asset-block-meta.json ================================================ { "customerKey": "testExisting_asset_html-matchNameAdd", "assetType": { "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_asset_html-matchNameAdd" }, "name": "testExisting_asset_html-matchNameAdd", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "memberId": 9999999, "status": { "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset.asset-block-meta.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%" class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner">foobar</td> </tr> </table> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset.asset-block-meta.json ================================================ { "customerKey": "testNew_asset", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset" }, "name": "testNew_asset", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 1111111, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_htmlblock.asset-block-meta.html ================================================ <html></html> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_htmlblock.asset-block-meta.json ================================================ { "customerKey": "testNew_asset_htmlblock", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_htmlblock" }, "name": "testNew_asset_htmlblock", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_notexisting.asset-block-meta.html ================================================ %%[ ContentBlockByKey("testNew_asset_htmlblock") ]%% ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_notexisting.asset-block-meta.json ================================================ { "customerKey": "testNew_asset_withCBBK_notexisting", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_withCBBK_notexisting" }, "name": "testNew_asset_withCBBK_notexisting", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_preexisting.asset-block-meta.html ================================================ %%[ ContentBlockByKey("testExisting_asset_htmlblock") ]%% ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_preexisting.asset-block-meta.json ================================================ { "customerKey": "testNew_asset_withCBBK_preexisting", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_withCBBK_preexisting" }, "name": "testNew_asset_withCBBK_preexisting", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/test_slash.asset-block-meta.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%" class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner">test</td> </tr> </table> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/block/test_slash.asset-block-meta.json ================================================ { "customerKey": "test_slash", "assetType": { "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "test_slash" }, "name": "test_slash", "createdBy": {}, "modifiedBy": {}, "memberId": "9999999", "status": { "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder/bla∕blub" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_assetMessage/testNew_assetMessage.asset-message-meta.json ================================================ { "customerKey": "testNew_assetMessage", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "name": "templatebasedemail", "displayName": "Template-Based Email" }, "fileProperties": { "fileName": "testNew_assetMessage" }, "name": "testNew_assetMessage", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-11-08T09:59:30.727-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-08-07T06:12:40.75-06:00", "modifiedBy": { "name": "Jörn Berkefeld" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "globalStyles": { "isLocked": false, "template": { "background-color": "#FFFFFF", "border-width": "0px", "border-style": "solid" }, "body": { "background-color": "#FFFFFF", "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#000000", "line-height": 1, "padding": "0px", "content-padding-top": "0px", "content-padding-right": "0px", "content-padding-bottom": "0px", "content-padding-left": "0px" }, "h1": { "font-family": "Arial,helvetica,sans-serif", "font-size": "28px", "color": "#808080", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h2": { "font-family": "Arial,helvetica,sans-serif", "font-size": "22px", "color": "#808080", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h3": { "font-family": "Arial,helvetica,sans-serif", "font-size": "20px", "color": "#808080", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "links": { "font-weight": "normal", "color": "#808080", "text-decoration": "none" }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "background-color": "#5D5D5D", "border-radius": "3px", "padding": "10px", "border-color": "#5D5D5D", "border-width": "1px", "border-style": "solid" }, "mobile": { "body": { "padding": "0px", "font-size": "16px", "line-height": 1.5 }, "h1": { "font-size": "22px", "line-height": 1 }, "h2": { "font-size": "20px", "line-height": 1 }, "h3": { "font-size": "18px", "line-height": 1 }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "padding": "10px" } } } }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "A note", "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "preheader": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "availableViews": [], "slots": { "banner": { "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"background-color: transparent; min-width: 100%; \" class=\"slot-styling\"><tr><td style=\"padding: 0px; \" class=\"slot-styling camarker-inner\"><div data-type=\"block\" data-key=\"ms2rjhckdsr\"></div><div data-type=\"block\" data-key=\"vlh4b2my8gp\"></div><div data-type=\"block\" data-key=\"x0ecuu93q1k\"></div><div data-type=\"block\" data-key=\"8uflrc8ao4r\"></div><div data-type=\"block\" data-key=\"1bd95vemqf4\"></div></td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"background-color: transparent; min-width: 100%; \" class=\"slot-styling\"><tr><td style=\"padding: 0px; \" class=\"slot-styling camarker-inner\"><p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true, "columnOrder": "ltr" }, "styling": { "background-color": "transparent", "margin": "0px", "padding": "0px" } } }, "availableViews": [], "blocks": { "vlh4b2my8gp": { "assetType": { "id": 196, "name": "textblock" }, "name": "sample content block", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"background-color: transparent; min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td style=\"padding: 20px; \" class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\" style=\"height:150px; overflow:hidden;\"><p class=\"textblock\" style=\"margin:0; padding:0; overflow:hidden; display:block;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vestibulum nunc feugiat porta consectetur. Sed vehicula vel ante suscipit sagittis. Ut metus metus, feugiat ut laoreet blandit, viverra non mi. Phasellus convallis, mauris ac vehicula posuere, ligula magna mattis ipsum, in sollicitudin nibh lacus eget sapien. Mauris ultricies laoreet ex, a viverra leo ornare eu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris commodo scelerisque arcu, id semper sem pharetra vel. Sed ut erat auctor lectus pretium blandit gravida vitae enim. Nullam eget ex et enim molestie porttitor. Duis vitae est fringilla, placerat nisi condimentum, tristique purus. Fusce lobortis mauris quis iaculis ultrices. In tempor ligula ac ex tempor rutrum. Pellentesque quis convallis mi.<br><br>Duis mattis, ex a hendrerit ullamcorper, eros massa consectetur elit, vel lobortis justo arcu ac mi magna, blandit sit amet eros id, dapibus cursus justo. Suspendisse mauris odio, aliquet ut ligula in, porta mollis risus. Ut ultrices lectus dolor, sed euismod nulla ultrices ac. Phasellus laoreet ultricies facilisis. Fusce imperdiet maximus ipsum vitae rutrum. Maecenas faucibus vestibulum lorem sit amet varius. Vivamus et ultricies ligula. Mauris semper scelerisque ante id fermentum. Curabitur non odio pellentesque, consectetur odio eu, commodo risus. Mauris egestas elit vel ipsum sagittis fermentum. Cras varius quam ac enim eleifend, eu porttitor odio finibus. Aenean quis finibus dolor. Nunc bibendum aliquam auctor.</p></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true, "columnOrder": "ltr" }, "styling": { "background-color": "transparent", "margin": "0px", "padding": "20px" } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2, "r__asset_key": "testNew_asset_htmlblock" }, "ms2rjhckdsr": { "assetType": { "id": 199, "name": "imageblock" }, "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"><div style=\"width:100%;height:150px;background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABuoAAACWBAMAAADK78OEAAAAKlBMVEUFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwhamwL+AAAADXRSTlMwmGPLQ97yfrGki3G+5/n17AAACcpJREFUeF7s2kGL00AYh/FJNhLrKrSy4KlQZBEvhUrOhS6wy168CQiYi/QaWOl5QbwXehaEfoQF/BqCpqSC8P8uBpxjtFs6KTPx+X2E981DZkJMwAAAAAAAAAAAAAAAAAAAQHJujgpAVJr/FEB1yDJzVKA6SMYXoDqqA9WB6kB1MdU5BaqjOlAd1VEdqO6U6jBodkZ1LYmoDmpWmpZQ3YjqHKI6qqM6UB3VUR3VUR3VYZGpWZWtqK4NVIeh/mpCdQ5QHajOAar7MJAGz8xOSGdU54VobUI3VW1jdsK46Z6mfyl9rC4Jv7q+8U7STnXIyy5UF2cmdD0Pq3vYSnWIVHWgunga/q5PPKzuyayN6nAl9YOvLlmK6towvmujOkylMvTqfi5FdZYVj4wLw9VeXzBz1apdXzHxSFIVeHU9ieosK8319unMHGw62fdNd49d4Eq1fkNz4XSXOjrXXAwaHLO6lcvoatWrr+ZAxfdOVbfIbowPvqk2D7m6NHe06bEaHLO6icORWJvPI3OAWGWnqhuqbzxwaqcUbnVpLqprHIn17uyQ+8cPc1+9rJC1zVZUt+uAKa2Dre6iUFequ3xjnIhzZ8t6vMdYT/z9f8lKni/16dyXA6Y0D7E6G11XqkvyamZciNwt64G2Haou8uTRjfXHJtDqrgt1prpL6b1v1b2WRlTnftPWXZDVXUudqS4upO2NZ9XdSmuqc+2LrHmI1b1Uh6p7odovz6pbSh+pzrHf7N1BS9tgHMdxFisVx8Ayr0JIRXYRZA96zoTBLoJIwVMB3WCAFLzsKDjYVfAljN0F38BuuwpVTbWuv/cy1dk/jQ2J6dPmn+T3PduQNPlgkjxP6uCpXg7V1VEgdU4L9x3qUtcENhOaM2uQ8NlEuaO6afQ7zZ26Omyqe5Xxti7hoZ6vSV0FwFXCYdII1aa6+AnjX/Km7huKpK7awmMNTepeA7imOrs5kLo5U+egUOoO8L+Oq0KdLKlLdZHVzX3pTzABNzt1VFdFvz1F6qYABFQXcydglDcSNbJTR3UHkPZVqBNKSa40171lhLrwFqluSJUWJHTFYqLaVGetKiR0Rx1Wv2pjA+SoOk17+/eiJOpeNj9lCgO5WamjuhNIwLHlVypejLasOapLuNkp9jU2LaijOgtSVtSoO3u2OlRnJNPEQMlPMKVzqhuM6lrPdjTVIbpkszhCuSVVF7/NbjnVOQk+TnWSd5cfM9foBKG2PKqTQHWzuO+20Oocb7DFVOok9+VnVDlXR3VVY5r2jv4ZGaIb04faAkKd1+bzoG4qvNpUR3U2rk4vRhum25nMU/JauCKqc94iXFCjOglUtyFbP351CFc0dbIK4eOW6iSq+42H9lWoq9T6zRdTHdVRncx5PlShzkG/wC2qOqqjuiYe2tSmDnt61f3ySqWO6qrGrNpUV8FjV+rU4adadcBk1VGd4w00aXWvrA6uka/479jVOcYYhDN3HUfs8Bvfirq6MWuK1VFdiiMv3+pked3xq0NEK1F/07CibhmAHnVUR3Vy8hUoVNdxC6iO6qhONkehOlyPSd1l7XnzStWte5KvTp0jA+yoLsXsMVehOhzbUhdfZ06fuvBnbnxF6uSIOC+6Ou+dXXUy/3IuA3Wx9fyJqUPgqleHHT8DdVQH2FUna7WiUR02J6cOl3I/VZW69Oyozmm9/JKF6toTUSetKFeHbaoDkOa1KWlfu051VIdtReoA6Fb3CaHS/I4d1VEd3lNdUnWVJsLtUh3VJVGXlh3VLUEaZZwh1VEdflBdomYhpX76QnVUl5wd1VWOMKxG9urW+2u25edFHdV15qkuvo8YWsfNXN0G+rma1FGdfNvp2FFdK4pK5uqmZUfm5wyT6hDsU11cUKtuBk/18qCO6oRdQdQ5nueXTZ3c5rkdnzqqC7yHjuypQ+AWQ90b4LvM+iiHOkcWMC51VCdZVIdLtyDqnuqclkWdXHK2c6POPPan5OrQ84ulDu1cqqtJtaSP4M/y97xOTrHKrQ43fvbqqC7NHlnIrTrslV0dzn1V6qgOjYmqm8Kw3HGpix5SV18FgMCUQh12fFXqqC5wi6VOXsce/f9cjKEc6vBVlTqqw659df/Yu6OVBIIoDMAUUnSnBHQVyEIQQVAOEQHCFtB9EnQlRPUAvYBg0APso/gIAT2AruwKwXmXaFOPeFxm3XVHx/n/y5nBmXXO5wIrs+tVJz/g0Xl19LRg+prMkRl1UBf3tk+d/i91t+2k59IVddTS7BLDMaAO6ihcu7oPfvi5KnXao/uaSUfVGXXUKK4O6uQsVqrjhIXUaYo4gDr6XkZdpSZTt1jdgZomMKQO6oY+1FE3k7r0XajaqE4W3oUhdVBHLaijvkF1PGLgrDqoi3tm1UEd1EEd/SyjDuoqh6LvoZ5FnTeTM8fVQR19ZlMHdbw4ec16dU05bQnq5NNGfxPVQV3kL3jjc9dmdaGX5NxBdXL19ezqiPqG1EEdvSwomTdb1BUP1HGG6saMOqiL3+WRFKM86jjWqku7R8ZKqWB71XGGpauDOvl253tKEjmqTnMfX5U6qIM6+uIldnizbFMHdbxXG6wO6mTZtcdNXQvUQR3HXnVQx5M8a9RBHdRVvNn41qgLvXFO1qtOnu852gZ1UDc5tu+4DHU7c7zLVMd96ep2+QdAqFs2kfrPlQl1e/zt268O6jgOqONrqRZWxzGhrjNt86FuLi3vL6dQJ3qKqYM6ro0A6nQprg7qoG5fKW57VY3c6qAO6pRS11CnGyUHhu6pg7qoNk1OdZxBbnU1kXR1d94kJ0Ldbzt3j9JAEAZgGELAwmpAsJUFrQMDdinS24TUqaytPEcgF/AI3sUkIGnmLhIRN+usNib7kzzvEb6dhx1mYFIl6gaxbNlrdXm9VJfXorqU9Zu6PwdEXbXKD2F0tuqoo24Q0l7TK+qoo+74Z5gps3AkdZXbx8dYNqJu1yTsuqaOuiZ6o64c+oY66g4bddRtQwh9Vkcddauw6Ly6vAbVUUfduthbnZNQaZGp+3fUUUdd2apmyn1SRx111FFHHXXUUUcddcV3t9TlUUddC1FHHXXtRx111FFHHXXUzWIcN6OOOuqoK+unOurW5YNALagbnoc66qjLa03dXbPqqKOOuovUZXXUbcNX49NRR91LJ9VRl9eAumaWHXUPqR1126IoXs9RHXXUDeepK1FH3am3iZ/dpzNRRx11oi6POlFHHXXUUVfWZ3XPMcb045XKG+qoy2/NDqSOuvrPSx11NVFH3QGjjjrqqLt8oo66BtN7jPPU26ijTtRRJ+qoq93LzJZHUydRl2obnYQ6UUedRN0qhJBqm4awSBJ1HUyiTtIHMv/VI7tXCZsAAAAASUVORK5CYII=) repeat-x 0 0\"></div></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "1bd95vemqf4": { "assetType": { "id": 195, "name": "freeformblock", "displayName": "Free Form Block" }, "fileProperties": { "fileName": "Footer" }, "name": "Footer", "owner": { "id": 710265361, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710265361" }, "createdDate": "2022-06-27T07:17:04Z", "createdBy": { "id": 710265361, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710265361" }, "modifiedDate": "2022-06-27T07:19:07Z", "modifiedBy": { "id": 710265361, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710265361" }, "enterpriseId": 510004860, "memberId": 510006764, "status": { "id": 1, "name": "Draft" }, "category": { "id": 4795, "name": "Content Builder", "parentId": 0 }, "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\" style=\"height:150px; overflow:hidden;\"><p class=\"textblock\" style=\"margin:0; padding:0; overflow:hidden;\"><span style=\"float:left; margin: 0 6px 6px 0; width:50%; height: 75px; overflow:hidden; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2sAAABLCAMAAADZL+8JAAAAS1BMVEUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGt0wPNAAAAGHRSTlMw51fNi5ilsr9K83HZPWR+N/rhxmq4rESzSUQKAAAGxElEQVR4XuzYW46DMAxAUUMDacK7pcX7X+lMNX+IoUgF5Kj3rMBSdKPE8j0AAAAAAACAIGcAcDEwA6bsLscDrSFoLfaB1npaOwVorem/uDW03aKW1g4Qmi9uDVdd5OUAtBZoLWm0Zh+toYuDLhriSGu7y3NJmys0c6Osw9Ixh0L/5SZam6G1LW8eVHGhHa8rSnOtNcWUeGutvZH2bg1Npo/EW+td1CBJa0dzqRWynXP6Uq++IvFU1WreX7jqCm9qQ93cMtXkW6tkL+F5Kbu8lw+5u2wXZ5sza7pysnDI+iubteP1jUKsmMqoukNrIS7I5Sxjt1tpg74MtXftJ1fiI24f3g/6R2++t7lTN/Af/mHfbpeUBQEwDL8iaAACfvac/5G+W02xlqVtqGjcv9cZRa4R2MlWONVtz5qbWX6s4bEFXxD1NKJd6Wu1n0x/egoXivCkHZVAtf6UzXBJb9EaaQHswprxNaTe/hnKAboXazyI1S3BJVR2c9b0AdiJNQoArQ3JmgHaiX+ZK7jQ5jxaG8i6Uco2Zq1JAX/WWJpiIJV2i1ED0iIgax2QvLU0cpG9W7PFqXenGFxkU9Y6wKe1A56k/s2eewsVD8eaejqm0ZrBqTfvoYRL2etOUusaI+Var7suP+zHWoZbQn92BkCIL2sFAJgpd58I3JUkzTdYY9cmXZMOfqsoJiWjNS8xuFASD2tRH9Yadzr9uhwDyf1ZoweXQq8/vJqSfKm1QsoUT0qk9PgBH5+sMhBrDABUtDZlW0V/si8vbqhAP0X5V1ojeJneiDVCMn/W0qnn99rUuIsZ/uZJQ79FrNGkn/m7tfGRygTuE812rUVrAvBmzZY41SxxNpICr9dkTqFHawz96AzWXNkTPtFatKZxjoVgjeBWXaxtLVqL1ojWPq1RnEtnt0a0VrhL/1QMv56Ke7HGCen8WkOynLVoTdLf6YWtJRgs/2x4Szu3tWR8dpH+NseHtQOA7VqL1lL8Ltu2NeGePSxrAJ3HmsofI0Fao8x1DMyaZj/JXVuzhVdrbkToWtYSdatCv9x6sjZeprUmoVkTcJWsCMoacyMdorX+k5gP9nz+rEl3/eLWxuMLWHOlIVsDBLXBWKO0DtmabdGrpNHaSNFav8SEYg1AwNa4Aj5ZIkVr0RpQyWhttEbgMcVXt2ZwCa0Nx1q0ps2pEo8pHa29jmIwQVa2ZnFLhmAtWhu/h5rswprl3M5iLcVwbO3vmsK14zzWorWWnaq9WQNavgNrGqjzc1mxC2vT+VQb2a8Zda7m27Dm8mgN6I47sHaLbdBal7vMm2cj7UfWJBtIz2GNvfqxLTdnM3L31lCyYk1r0ZqAC8z/OeR/du5tWUEQCsBwIihCCNGu4f2fdI9UYi5T09Z44r/FaQrWd5HOCK31jjT7qTXJfRY+M4EQd2pt8HGbKmEE3Vq05nKzsLW8rPqVNQZW7wa+HtIv6J1aG3zcJqe8byBa07SOTLPm6ALWQGKutZt4dOnAobr3udynNZiVX1gjHJRt19o1eXWfbS0BFx3R2oCWhBzbmku/sFZ2rQ1bg8j4ktbgDXSOYC1agwk51lq0ZsBXE8UYazpr5D+RYFgr5Ft/460ZpdCtRWvwBsys/2vKd1vSWpr7LIK1E4VnM8YaHDmKYY2BXR5pzVqXaG3QrUVr7mbArzlPsRaabw0/aI1xzjvHTAhR7tVaqMC3Fq25HM4KOaC11H1uhdY4bw44A+vRWitJnqULWuPhln84k5VZi9Zg/daE9lkEayVvxDCtEVZleq0Z8kzNnyPxzKFbCycmTLTWTJOqbEPWYPOtmfzR2wUppjXt11SvtaI+JIQ5QrJmKA17dqckWgMd3JpyIGDtSilVC1vLqs5rttbaSYZoTdGQ2rC1S9bKbtdaUneZZi1UTLRWnNslH61J/upaM88enf7bt8NWB0EoAMN0bctjpy4VF/z/v/QyNqYDCcbBlex9vwqU4oMgGFNnPdeGfPpurGhNYkoatVauWWt5x1grz7hsbfc5YwPW0pLlB7L/7O9izemtX6xhrWZYe+7B/i1rW781ZS2oavyANaxhbXWZtb/upZisGTqttVR9a1jDWmoofLd9a1jDGtaCPluwlsIa1upntzZNU1VrWMMa1lLNWcPaqqrhIGtjwBrWDI3zPLt61trPZW/TTmoNa+HRYrB2fFiTe0Os0+a97/bvKkJMYW03rJkjrKn33n2JtUlEcmu9iNisEdYq1XmvDVu7FAYya4S1JRisVQlr9ugico2nC2tYo3asYe26lgZ+3rdG5B51sRDWNJYaDdaIsGaNCGtE9A9/OsOIx1k7gwAAAABJRU5ErkJggg==) repeat-x 0 0\"></span>In viverra et dui id fermentum. Nulla tortor libero, aliquam in dictum id, vestibulum nec lacus. Curabitur sit amet accumsan magna. Mauris mollis eu lorem sodales mattis. Mauris et iaculis odio. Suspendisse et metus maximus, dapibus lectus in, placerat est. Praesent sit amet lacinia ligula. Donec non magna dictum, feugiat arcu vel, volutpat augue. In hac habitasse platea dictumst. Nunc eleifend nulla elit, vel condimentum lectus dictum sit amet. Aliquam ante nulla, dapibus ut nisi vitae, convallis malesuada mauris. Duis mattis, ex a hendrerit ullamcorper, eros massa consectetur elit, vel lobortis justo arcu ac mi magna, blandit sit amet eros id, dapibus cursus justo. Suspendisse mauris odio, aliquet ut ligula in, porta mollis risus. Ut ultrices lectus dolor, sed euismod nulla ultrices ac. Phasellus laoreet ultricies facilisis. Fusce imperdiet maximus ipsum vitae rutrum. Maecenas faucibus vestibulum lorem sit amet varius. Vivamus et ultricies ligula. Mauris semper scelerisque ante id fermentum. Curabitur non odio pellentesque, consectetur odio eu, commodo risus. Mauris egestas elit vel ipsum sagittis fermentum. Cras varius quam ac enim eleifend, eu porttitor odio finibus. Aenean quis finibus dolor. Nunc bibendum aliquam auctor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vestibulum nunc feugiat porta consectetur. Sed vehicula vel ante suscipit sagittis. Ut metus metus, feugiat ut laoreet blandit, viverra non mi. Phasellus convallis, mauris ac vehicula posuere, ligula magna mattis ipsum, in sollicitudin nibh lacus eget sapien.</p></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "x0ecuu93q1k": { "assetType": { "id": 223, "name": "referenceblock" }, "design": "<div class=\"default-design\"><div style=\"width:100%;height:150px;background-size:cover;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADawAAAEtCAIAAADRXFFBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAALyhJREFUeNrs3ftvI+l+J2aOSF27JbWu7Z72nPEJdrOws5ss9hcj58R/vWEDQYLAhjdeZHfhcbeGYosiRfFWrHuFPZpty30btcRLFfk8IASKIt+q+r6UVMX61Pt+13r3rgYAAAAAAAAAAABQNY2rd1eqAAAAAAAAAAAAAFTOhhIAAAAAAAAAAAAAVSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUkhAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAAADg4drt9ngSTe88290+Pz9XEAAAAIAlMhIkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFRSo7Rr1mxexmn26eO///EH3QYAAAAAAAAAAAAYCRIAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvSicKAIAMG9CkAAAAAAAAADA7MVxoggAwLwJQQIAAAAAAAAAs5fnmSIAAPMmBAkAAAAAAAAAzF5kJEgAYP6EIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYiyicKAIAMFdCkAAAAAAAAADAXMRxoggAwFwJQQIAAAAAAAAAAACV1FACAAAAmLlm8zJOM3X4yOnR4f7BgToAAAAAAACzYiRIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvaIo8jxTBwBgrhpKAAAAAAAAAADMXJpm0XeJOgAAc2UkSAAAAAAAAAAAAKCShCABAAAAAAAAAACAShKCBAAAAAAAAAAAACqpoQQAAADwFMF4lGX5Rw9meaEyn4qiqDYYfPTg3t5uvbGpOAAAAAAAwCMIQQIAAMCT9G4HcZqpw0MMg3B6++jB01pt/0AIEgAAAAAAeAzTYQMAAAAAAAAAAACVJAQJAAAAAAAAAMxFkqSKAADMlRAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAADwVFmaKAIAAAAAH8nyQhEAgHlrlGElfnpz8cQnP9vdPj8/150AAACLNxwMbm77P/7uB6UAAAAA4L4sz+sbdXUAAOaqoQQAAAA8WpYmN7f9vKi12+31uTit2byM00zvz0qn15/ePnx7enS4f3CgLAAAAAAAwEOYDhsAAIDH63Rv7iY1Gk+iYDxSEACAr+jf9qJwog4AAABQUcPBQBFKSAgSAACAxx/qB2H84dvOTV9NAAC+tOPUbF7e9EdxnKgGALBWksx8GgCsjsHQeBBlZDpsAAAAHqnXH97/NsvztZoUGwDgIYaDwWA4ilPn/gGANVUUagDAiojCyfQAf/p1e2dXNUpFCBIAAIDHaLfbWZ5/9GAQRg7+AQDuTPeLbnq3YZwqBQAAAKyAMAynX8fjwHmQshGCBAAA4JsF49F4En36eFHUOt3e69cO/gGAtSb+CAAAAKsnjOLp1yR1vF86QpAAAAB8s85N/0s/itOsc319enamSgDAGsrSpHvT++zlIgAAAEClRb9c7hi56LF8hCABAAD4Np3r608nwr5vNAn3TYoNAKyZu/hjEEZFoRgAAACwggf+dydHpl+n9+uNTTUpjw0lAAAA4OGicDKahF9/zt2k2GoFAKyPzvX1xeW78UQCEgAAAFZTEEw+3B+NRgpSKkaCBAAA4Bt0ur2HnNqP06x/2zt8caRiAMBqu+l2h+Mgl30EAPhEliZ3dyJzhsCyTX8Nb3q3Gxsb9Y2N7e3t/YMDNYFvNQn/ZYSIKE4UpFQWGoIcDgbz2nnKss82vre3a+hRAACAWelcX8dp9sAn9waj58+fOygDAFbYeBIpAgDAl3wYMSuOEyFIWJa7+GMYpx8eGQZhp9ff+K622Ziq7+7sbG1t+iWF35Qk6WfvUwYLDUFO/4bOqeXpH+sw/kzjp7Xa/oHzbQAAADOQpclvToR9X1HUrtqd779/pXQAwCoZDgZhZLwHAACg7D6NP96XF7UoSae3u4u7vvuutlmvb242GvX6zs723rPnCggfuT9IxMMHjGAxTIcNAADAg1y1O8U3zvMYJWmlJ8Vut9uGd1q8Tq//2asof//jD4oDwHLddLujIMzyXCngiaJwEq/Z5HH1+oYkAQCwyN2tr8QfP6so3oe67nJd/VFQ6/TqGxubjemtsb29bSJW+HSO4ukjZpYvDyFIAAAAflv/thc9anKHW5NiAwDVd9PtDsdBXqgEzOj4YjBct8uNthp1IUgAYAEeEX/8kizPszifNjUMwtq96bO3tzZ3dnZMn83a/XJF0aeP7KtLaQhBAsDqa7fbn9kJqNePT04UB4CHyNKkNxg97rV5Uet0b16+fKmMAEAV94L677Na4o8AAEDZzTD++Fn/avrs/vuPi7ca9UajvtlobG5uGg+PlRd/Mk5EnKTKUh5CkACw+j57Yf30sERlAHigR0yEfV8QxmaFAACqJUuT7k0vCKNC/BEAACi3eccfv+R/TJ8dT+93ev36xkajvtFo1Hd3dkyfzeqJ0/Q3H2GJhCABAAD4muFgED35csab276PvQCAShB/BAAAqmJZ8cfPH0zl+fT261CRvf5339U26/XNzcb21ubU3rPn+otK/659+inB9JFgPPLeLgkhSAAAAL4oS5Ob2/7T2zEpNgBQfnenD6MkFX8EAJitSRiaJATmcfxSkvjjZ00PrO6Givx1zrpO7/D53vHJib6jisbj4LOPh2EkBFkScwxBNpuXS9+8Xn84GI7uP3L04sCbDwAA4IE63Zt8RiGAIIxdEwkAlFP5Tx8CAFRRnmd3dwpXmYDjl1otzTLdR1V/7+L4mx5n8eYYgozT5f/x+mWs3X/9yEffAwAA8AXDwSAIZ3kA37np/04IEgAo2Q7PaDwWfwQAmLlgPOoNfh2xKAjjm27XCHAwE5dXHUWABYuT9JseZ/FMhw0AAMDnzWQi7PuyPG+32+fn52oLACzdcDAYDEdluJgfAGD19G97vcHo/viP/VGQpOnLly8VB4BqydLkS1NmTR+Pwsn2zq4qLZ0QJACsmptu9yGDyU+f02637z+yu7Ozf3CggADcmf6byOcwT9F4EpkUGwBYLvFHAIC5uul2+6Pg08eDMG61Wudnp/XGpioBUBWj0egrPw3DUAiyDIQgAWDVTMLoISdy8uJ9DOWjB4UgAbgTjEef/puYld7tQAgSAFiKm253OA7mcaUHAAAf9rg+m4C8E8Zps9V+/epcDhKAqgij+Os/PVSjEthQAgAAAD7SuenPr/E4zTrX14oMACzSTbf75u1FfyQBCQAw352uryQg72R5/vPlu2A8Ui4AKiGK00f/lIUxEiQAAAD/SrvdzvJ8rosYTcL9cGKGCABg3rI06d70JmEk+wgAMG8PSUDeme6btbu981rNbCEAlN/Xz5jM+3wKD2QkSAAAAP5FFE7mNxH2B0VR63R7qg0AzE+WJu12++Ly3XTfRgISAGDerq6uHpiAvFMUtatO76bbVToAymw4GMzkOcybECQAAAD/YmHZRJNiAwBzEoWTD/HHQvwRAGD+Wq1WEMaPeGF/FEz33BQQgNKahOFMnsO8mQ4bAACAX3Wur+M0W9jiRpPwKE3qjU2VBwBmIgonN73bME6VAgBgYVqt1lN2wMaTaNrCq1evVBKAEkqSdCbPYd6MBAkAAMB7UTgZTRZ6teL7aY/aHZUHAGayJ9NqtS6vOhKQAACL9MQE5J1pC28vmlmaqCcAZZNkvz1yxCJHl+BLjAQJAADAe51ub/HzRUZJ2r/tHb44Un8A4HGGg8FgOHK+Acrm63ObruFAKWmWfb0m5+fn3jZAtWRp0r6e2SUoWZ43W+3T48O9Z8/VFoCSCMajB543mT7Tv7DlemoIcjgYdHr9Cm3wdG0/u8Jbjfrr1997QwAAAOupf9tbVnSgNxg9f/7cpNgAwLcSf4QyG08iRbgvL9QEWClZmjRb7SzPZ9lmnre7vfNaTYgEgJIIgsnDn+n/13IZCRIAAGDdZWnSG4yWtfSiqLWvO69evdIRAMAD3XS7kzASfwQAWIp5JCDvvP+YqNs7CKPjkxN1BmDp4gePYR+v32j3ZSMECQAAsO6u2p3FT4R9Xxinw8Fg/+BAXwAAX3fT7Q7HQV6oBADAcswvAXmnKGr9UZDn+enZmWoDsFxJms78mczJhhIAAACss/5tLyrBFYo3t/0sTXQHAPCVnZY3by/enxGXgAQAWJJ5JyA/GAZhq9VScACWKAonD/8IYvrM6fMVbYmEIAEAANZXlia3y5sI+768qHW6N3oEAPiS0Xgi/ggAsETBePTz5bsFJCDvhHHabF66aBaAZRmPg7k+n9kSggQAAFhfne5NecIEQRgPBwOdAgAAAFA2wXjU7vYW/DlSnGbNVtvAWgAsxbfOcB3FsaItUUMJAACgDK6urtI0e0oLr19/r4x8k+FgEITlOia/ue3vHxzoGgAAAIDyuEtAFsu4kjbL81a7c35ytPfsuY4AYJGi+NtCkEmaK9oSCUECAEAppGkWPy0ECd8kS5Ob237Z1iovau12+/z8XAcBAAAAlMESE5B3pouersBRkhy+ONIdACxGliZZ/m2hxunzp6+qNzZVbylMhw0AALCOSjUR9n3jSRSMRzoIAAAAYOmGg8FyE5B3pitw0x/ddLt6BIDFGI1GC3sVM2EkSAAAgLUTjEdlmwj7vs5N/3cLmeFoWocs+9qlnFlmfNYSGQ4GX3/C3t6uq2wBAABgVm663f4oKM/6TFcmiuNXr17pGgDmLYqTR7wqjOJDtVsSIUgAAIC107npl3n1sjxfzKTYvduBaeir9L7t/cb79rRW2z8QggQAAIAZKFsC8k4Yp5eXrZfnpy6DZLX99OZCEWC5kiR9xKtSZxyW56EhyGbzcrXPDE237kv/RX7/4w/eKAAAwMpot9tZnpd8JceTKAon2zu7+gsAAABgwcqZgLwTJWmz1X796lwOEoD5eVxMzrALS2QkSAAAWBHtdntBRxH1+vHJiYJXVDAejSdRJVa10+29fi0ECQAAALBQ/dteaROQd7I8v7h89+r81AW0AMzDcDB4ymv3Dw7UcPGEIAEAYEUsLNm21airdnX1bgdVWdU4zTrX16dnZ3oNAAAAYGGiOCn/ShZFLY4TIUgA5mEShk95rRDkUmwoAQAAwJroXF9Xay6G0SSMwomOAwAAAAAAFiN9wpmU1IzYS2IkSAAA1lEwHmVZXqpVyvJCvzBXUTgZTcJqrXNRmBQbAAAAAABYnDhNl/JankIIEgCAddS7HcSuxGLNdLq9ooJR2+mvav+2d/jiSA8CAAAAAABzFYxHTzmZMn3ttIW9Z89VcsGEIAEAAFZf5SbCvq83GD1//rze2NSPAABQHldXVyZ6m6Fm8/IrP339+nslAgCABQjD6IktBMFECHLxhCABAABWXJYmlZsI+76iqF21O99//0pXAgBAeaRpZo6FGVJMAAAogyiOn9hCYkbsZdhQAgAAgNV21e5UcSLs+6Ik7d/2dCUAAAAAADA/cZIuvQUeQQgSAABglfVve9FKHG/3BqMsTXQoAAAAAAAwD1E4yZ88qMS0hWk7irlgpsMGAAC+TZxmP725+KaXnB4d7h8cKN0CtNvt8SRayU0ritrb5jtvLQAAAACg6oLxKMtydYCyCcNwJu2Mx8H2zq56LpIQJAAAAAAAAAAALEjvdhCnmTpA2YRRPJN2ktSM2IsmBAkAVFizeVndld/d2T4+OdGJAAAAAAAAAEsXxWmp2uHhHhqCfP36+88+vjJTrW016l/aRgCgtCp9kdxm5go/AAAAAAAAgOXL0iTLZzNP/bSdaWv1xqaqLsyGEgAAAAAAAAAAALC2gmBS2tb4TabDhser9Bys9xkGFQBgZRwe7O/u7NzdH43H4SpOuHB6dPjh/t7erk4HAAAAAACeaBKGs21t/+BAVRdGCBIer9JzsAIAsJK2d3ant3uH6ysYgvSpAQAAAAAAMFtJkpa2NX6T6bABAAAAAAAAAABYX7MdCs3AagsmBAkAAAAAAAAAAMCaCsajmbc5HAwUdmFMhw1UW7vdXtait7c2D18c6QIAAAAAAAAAgOoKgsnM24yiaF9lF0UIEqi28SRa4qKDSfjq1Su9AAAAAAAAAABQUXGSVqJNvsR02ACPF8Zps3mZpYlSAAAAAAAAAABUUZymlWiTLzESJMAT/2llP1++Ozs52nv2XDUAAAAAAAAA1tlNt5tm2def85tPABYpCidFMftmp21OW97e2VXhBRCCBHiqvKi1u72jJDl8caQaAPD5o8coqg0GHz24tbXpwA8AAAAAgFUyCaM4lXGEKhmPg/m17FzYYghBAsxAUdRu+qMoTs7Pz1UDAD41DMLp7aMHn+1unzvwAwAAAAAAYHmiOK5cy3xkQwkAZmU8iVqtVpYmSgEAAAAAAAAAUH5xklauZT5iJEj4jCicxPEa5diGn8xN+Zv29nbrjU1vlU+FcdpstV+eHRvQGAAAAAAA+Kyf3lxUZVV//+MP+gsAWGFZmuTFvBqftjxtX8BmAYQg4TP6g+F4Eq3P9nZ6/W99yWmttn/gb/QX/kHmeavdOT852nv2XDXg0Sr0ISAAAAAAAAAAVTQajebd/uGLI3WeN9NhA8xeUdSuOr2bblcpAAAAAAAAAADKKYziSrfPHSFIgHnpj4Krqyt1AAAAAAAAAAAooTTN5tp+FKeKvABCkABzFIRxs3mZpYlSAAAAAAAAAACUSjznEGSW54q8AEKQAHP/f9lstYPxSCkAAAAAAAAAAEpiOBiszFLWnBAkwNxled7u9vq3PaUAAAAAAAAAACiDSRiuzFLWXEMJABagKGo3/VGSpKdnZ6oB/I+d3ajZvFyHLd3Y+O787LTe2NTpAKynUl3mu39woEcAqKgonPQHw0e//PBgf3tnVxkBAAD4IEnSlVnKmhOCBFicYRAmrZYkEHAnL2pxmq3Jxl5cvnu+uyMIDsB66vT65VmZm9v+/rO945MT/QJA5cRxMp5Ej3757s6OECQAAAD3JVm2MktZc0KQAAsVxmmz1X796lwOElgrRfE+CB41L09PjpxzAoAlyotafxRMwuhg/7lRIQEAAACeYjgYfDrLbSrtBBURjEdFsYgFTZcyXdbes+dqPj9CkMBjjMbjT3fmeKAszy8u352fHPkPB6ybOM1a7c7ezvb5+blqAMBy/yl3ev3BcCQKCQAAAPBokzB8ymjlwHIFwWSRyxIRmSshSOAxwjit1VJ1eLSiqLW7vYMwMgkdsIZ/AMeT6O1F8/T40I4+ACzXXRRyNB4fH70wVDMAAAAAsFbyxYwDufBlrSchSIDlKH6ZhC5J05cvX6oGsG6yPL/q9PZG4+++++6hu631uuA4AMxDGKeXV52drYYoJAAAAMF4FEZJJVZ1NB6b3AAAuLOgEOTm5uYf//CXLw4Pn9hOkqR//Td/OxgM9RywIkeSYdy5vj49O1MKYD3/Bj78yVuNuooBwPyEcdpqd/Z2tk+Oj+qNTQUBAABYQ/3bXm8wqspIVdMj2bcXzdevzh3GAgAbi1nMTBKQtfdhysZf/fEPe3uGJQBWh0GPAQCAMpgemown0cXlu3a7naWJggAAAKyV6cHgTX9UrdNWWZ5PD2OD8Uj3AcCaW9BIkDNJQN7Z3Gzs7e4GweT+g7/709d/+sOfTu/8fPHz25+b+hUAAADgEe6ikJPLd/vP9o5PThQEAABg5WVpctXuREla0cPYq07vMIwcwwLAOmuswDb87k9f/6f/9B/v7nc6XZ0KAAAA8BR5UeuPguE4EIUEYMF+enOhCACwSMF4dN3t5RWft2x6DBvF8fnZqamxAWA9bVR9A+4nIKdSszUBAAAAzMJdFLLZvBwOBqoBAACwem663Xb1E5B3wjhtttpRONGtALCGqh2C/CgB+c9v3v7TT290KgAAAMCsxGnW6fVFIQEAAFbM1dVVfxQUxepsUZbnrXbH0SsArKEKT4f9UQIySdIgmPzP//bf3H2bpsm7q/b0EX0MAAAA8ER3UcjReHx89GJ7Z1dBAAAAqit7fzL9enqgt3qbVhS16dFrFEWnZ2c6GgDWR4VDkPcTkFObm42/+PN/d/+R//U/1P7xv/x///W//XfdDAAAAPB0YZxeXnV2thqikAAAABUVjEfXqzIF9pcMgzBptc7PTuuNTT0OAOtgY7U37y/+/N/9L3/x57oZAAAAYFbCOG21O+12O0sT1QAAAKiQm263veoJyA+Hrs1WOwpNHQkAa6HCIcgkSR/ytH/7b/6nvT0jEwAAAADMTFHUxpPo4vKdKCQAAEBVXF1d9UdBUazL9mZ53mp3hoOBrgeAlVfh6bD/+m/+9q/++IfNzV83IUnS6SODwXB6/+Bg//6P/uTl+T/99EZnAwAAAMzQXRRycvlu/9ne8cmJggAAAJRTlibvrq7jNFvD49ZOrx9F0enZmbcBAKywCo8EORgM//pv/vbDeJCbm42/+uMfDg72P/zowzMbjU09DQAAADAPeVHrj4I3by9uul3VAAAAKJtgPPr58t0aJiA/GAZhq9UyjwEArLCNSq/9pznIP3n58sOP9C4AAADAYtxFIZvNSxONAQAAlMdNt9vu9vJi3esQxmmz1Y7CibcEAO12u9m8nN4mYbSwhU6XdbfQ6dJ1wTxsVH0DPspBAgAAALAscZp1en1RSAAAgDK4urrqj4KiUIn3sjxvtTsOVwGo/fIx5vS2yIsEpsu6W6jiz0ljBbbhLgd5Nwbkzc2NTgUAAABYorso5HA0Pjl+sb2zqyAAAAALlqXJu6trSYuPFEVtergaRdHp2ZlqAKyt3Z2d8SRa4tJ1wTwsKAT5z2/e/tmPv5tVU53ux0nHwWBo/msAAABgtq6urlJnjB4rStLLq87OVuP4SBQSAABggYdj4eRdu2MK7C8ZBmF2dfXyl1GWAFhD+wcHnV5/iUvXBfOwoBDk3/39PwwGg0Zj84ntpGnyTz+90W0AAADAAqQmKHmyMH4fhXy2u31yfFR/8kdDAAAA/KY4TiQgf/N4XxEA1tlWo76UD36ny1X8OVncdNjCiwAAAADraTyJgst3ezuikAAAAADAkm1uNpYSgpwuV/HnZEMJAAAAAJi3ongfhby4fHfT7aoGAAAAALAsuzs7a7XcdSAECQAAAMCCFEWtPwrevL0QhQQAAAAAlmJvb3etlrsOjLEJAAAAwELlv0QhR0F4dLi/f3CgIAAA3yQYj3q3g6884fXr71UJAAC+pN7YrG9sZHm+0IVubEyXq/hzsqAQ5Obm5n/83/7D9OsT20mS5O/+/h+mX/UcAAAAQKVled7p9QfD0cH+c1FIAIBv2I/K8jjN1AEAAB5te6sRhPGCl6js87Og4v7xD3/54vBwJk09e7b3N3/7f8pBAgAArKd2uz2rptLMWUNYvjjNOr3+cDQ+OX6xvWM6GACAGWg2L+fR7OZm4/z8XHkBAFgBO9tbCw5BTpeo7POzoBDkrBKQd00dHux3ujc6DwAAYA2NJ5EiwOqJkvTyqrOz1Tg+EoUEAHiqOY0TOW327UXz9Phw79lzRQYAoNKeP39+0x8teInKPj+LHmYzCILROHjEC7e2NmeYpAQAAACgbML4fRTy2e72yfFRvbGpIAAAZZPl+VWntzcav3z5UjUAAKiuemNz47taXixocdNl+cBzrhYdgvznNxf/9b/990e88PTk+P/44/+uwwAqKgon/cFw5s1ub20evjhSXgAAWCXjSRRcvtvbEYUEACipBc8bCAAA87C12QjjdGHLUvC5Ul8AFiGOk3nMXDltM4xi1xwDAMCKKYpfo5AHz/aOT04UBAAAAGB9/PTmolTr8913tfOTo71n5jJeNfV6vVZLF7gs5mhjVTdsc9M4AQBrIQjjy8tWliZKAQAAK6Yoav1R8ObtxU23qxoAAAAALEVR1K46PZ9QQZmtZghyc3Pzj3/4S70LsCaiJG222sF4pBQAALB68l+ikG8vmsPBQDUAAAAAWIr+KOhcX6sDlFMlp8P+9//+L+L4ayN+PX+2N/Xh23dXV3oaYLVled7u9k6yfP/gQDUAAGAl9/k7vf5gODrYf263HwAAAIDFGwZh0mq9evVKKaBsKhmCfHF4+PAnt687g8GwbJsQjEdZlq/ne65e39h79tzvHjBzRVHr9PpRFJ2enakGAACspDjNprv9w9H45PjF9s6uggAAAACwSGGctlqt87PTemNTNaA8Gqu9ebf9/v/1f/8/JVyx3u0gTrP1fM9tNepCkMD8rOfFN+12+/63afbIfzFJkt5vqlGvH5+ceFMBAFA2UZJeXnV2thrHR6KQAAAAACxUGKfNVvv1q3M5SCiPSoYgb/v9r0+Hfefdu3cXP18mSaKbAdZtp/PtRXOtdjrHk2gm7cRpdj+jv9WoezsBAFDmPf/Lq86z3e2T4yOfOAMAAACwMFmeN1vtl2fHLtCFkqhkCPI//+d/7HRvdB4AX9npvLh8d35yZOhZAABYbeNJFFy+29sRhQQAAABgcbI8b7U7TklDSSw6BPlnP/5wevqYiTW3tnyKDbAgw8Gg0+tXfSuKotbu9g7CyITOAACw2qY7/3dRyINne/b/AQAAAFiMu1PSR0ly+OJINWC5Fh2C3PuFugOwmJ3O/ihIs+z8/Fw1AABgHfb/h+Ngf9WjkFmaBMFkrTp3/+DAOxwAAAAooaKo3fRHWZa7NBeWa0EhyH9+8/bPfvzdTJq67ff7g6GeA+CBxpPo8rL18vzU1HgAALDy8l+ikKMgPDrcX9XkXBBMVmDw/m8iBAkAAACUmaF5YOkWFIL8u7//hyRJDw+f+nllkiS/NJXoOQAeLkrSZqv98ux4e2d3JTfw2e723Z3xJHp6axvf1XZ33jfYqNe9eQAAqKIszzu9/mA4Oth/Lj8HAAAAwLyNJ1Hn+vr07EwpYCkWNx32//uP/0W5AViWLM9b7c7Ji8OVPAP64aKin95czGDnoF53lRIAACsgTrNOrz8cjU+OX6zqBVEAAAAAlEReFIoAy9JQAhYszbJ2u/2kd229fnxyopLAt5ruc3Z6/SRJ/A0BAID1ESXp5VVnZ6txfCQKCQAAAI/UbF7Gabb01dhq1F+//l53APARIUgWLS+eOlvrdLdGGYFH64+CKI5fvXqlFAAAsD7C+H0U8tnu9snxUb2xqSAAAAAAACtDCBKgekpyoVV1hXH69qL5+tW5c58AALBWxpMouHy3tyMKCQAA1XDT7U7CaFlLbzTqL1++1AsAAOUnBAnAOsry/OfLd2cnR3vPnqsGAACsj6L4NQr5fHfn9OxMQfjIT28uVn4bf//jDzoaAKiKNMuMCgEAwG/aUAIA1lNe1NrdXv+2pxQAALBuiqI2DMI3by9uul3VAAAAAACoNCNBArC+iqJ20x9FcXJ+fq4aAACwbvKi1h8FxycnSgHwCFE46Q+Gj3hho173txcAAACYISFIANbdeBK1Wq3zs9N6Y1M1AAAAAB4ijpPxJHrEC7caddUDAAAAZsh02ABQC+O02WpH4UQpAAAAAAAAAAAqRAgSAN7L8rzV7gTjkVIAAAAAAAAAAFSFECQA/Kooaled3k23qxQAAAAAAAAAAJXQUAIAuK8/CqI4fvXqlVIAAACsm9Ojw7s7vf4wy/OV2a76xsbR4b7+BQAAAGAlCUECwMfCOG02L//k5Vm9sakaAAAA62P/4ODuzmA4ylYnA1mrb3z3YdOooqurqzTNyrZWWV48+oXDweD9O7O+sffsuf4FAAAAnkgIEgA+I06zZqt9enzos3gAAABgudI0i8sXgny0LM87vf70zlaj7oMXWENROOkPhlVc892dHRcVAABAOQlBAsDnZXne7vaOkuTwxZFqAAAAAAA8XRwn40lU0ZUXglxbw8FgEoZf+unhwf72zq4qAQAskRAkAHxRUdRu+qMkSU/Pzsq/tnczST1dnGZZmpgKHAAAAAAApiZh+JXw7u7OjhAkAMByCUECwG8YBmHSap2fnZY8Fzgaj2fVVK93W4ncJwDAv9qH6Q8Hw9Fs20yyTGEBAADWU5pl7Xb7/bFhkqoGAECZCUECwG8L47TZar9+dV7aHGSWJtOVnFVrQRjrdACgcrI8z3JlAAAAYDbyovaQ2ds7vf709tkfnR4dmkUdAGABhCAB4EGyPL+4fHd+crT37HkJV6/Xu53txgbjUTm3lLWVZFmzeTnbBlUVAKAShoPBQ55Wr284igEAAACANSQECQAPVRS1q07vMIyOT07Ktm7jSTjbBvuDodOHlO0XME7FFgGAVfPAeN99URStW5W+NKzOR7YadUcxAAAAALCGhCAB4Nv0R0GSpi9fvizPKg0Hg7yYcZtRkmZpUtrpvwEAYDU8MN4HAAAAAMCXbCgBAHyrIIwvL1tZmpRkfUbj8czbLIpavz/Q1wAAAAAAAABAmRkJEgAeI0rSZqt9eny49NnWsjQJ43QeLY+C8PhEVwMAAAAAD5KlSRBMvv6cKIoUCgAAmC0hSAB4pCzP293eea223Bzk/MZrnG5gMB4tPeUJAAAAAFRCEEw6vb46AAAACyYECQCPVxS10ThYbkxwFITza7w/GApBAgAAAMByNZuX97/N8kJNAAAAPhCCBIAKC8ajLM/n136UpIoMAAAAAMsVp5kiAAAAfMmGEgBAdfUHw7m2XxS1m25XnQEAAAAAAACAchKCBICqytJkASM1TsJIqQEAAAAAAACAcjIdNgBUVb8/KIq5LyVOsyicbO/sKjgAAAAAAMC3ajYv4zQr7er9/scf9BEwWzfdbpo96e/e4cG+M9R8EyHIX2V5MRwMFrk4NQfgiUZBuJgF3fYHL+1iAgAAAABrbBJGzealOgAAPGTH6Ynh792dHSFIvokQ5K+yPO/0+upQkc6ae2I1yzJ1BkouGI+m/7wWtJMaxQoOAAAAAKyzvKiVeSA3AAB4tHa7PZ5E817K6dHh/sHBnBoXgqR6JFYBpoaj8cKWVRTvRyw/PjlRdgAAAAAAAACgVIQgAaCSFjw64ySM1BwAAAAAAFhJN93u/E6FJOYhBIA5E4IEgEoeihfFQpcYp1kUTrZ3dhUfAAAAAABYMWmWmfIeAKpLCBIAqmcp4zL2B8NzIUgAAKCs4jT76c2FOgAAAADAutlQAgColiicLOViRDNiAwAAAAAAAABlYyRIACijLE2CYPLZH43G46WsUl7UOtfX29vbn/3p/sGBXgMAAAAAAGB+srwYDgYPfPLW1ua2Wc4A1oMQJACUURBMOr1+2dZqGITT22d/JAQJAAAAAADAXGV5/vAzaM92t8+FIAHWg+mwAQAAAAAAAAAAgEoyEiQAAAAAAAAAzFin1y/hpE8AlEq73V69jUqzTM+yYI1m89K7FgAAKI9gPMqyfOmrsbW1uW2qFABgJSRZ9sTPgUuyFboSAACAFTOeRIrAnZ/eXKz2Bvb6w8FwNKfGG3HqkyMAAKBMh0C3gzIcpzzb3T4XggQAVkJR1HwODAAAAMASZXk+v1FQNtQXAAAAAAAAAAAAqCIhSAAAAAAAAAAAAKCShCABAAAAAAAAAACASmooAQCU0N7e7um9b0fjcRinpVrDna3G82fP9BQAAAAAAAAAsERCkABQRvXG5v7B5odvJ2FYq5UrBFmv1/cPDvQU8BRZlg0Hg888nhdlXr1l2dvbnf538LYBAAAAAACA+4QgAQCA5QjjNIz7Vu+BTmu1+/l4AACAD66urtI0m0lTuzvbxycnSgoAAECFCEECAAAAAABUWJpm8YxCkJtZpp4AAABUy4YSAAAAAAAAAAAAAFUkBAkAAAAAAAAAAABUkumwAQAAAAAAAACAOZqEUbN5qQ7APAhBAgAAAAAAAAAAc5QXtTjN1AGYByFIAAAAAAAA4Bv89OZCEQAAgJLYUAIAAAAAAAAAAACgiowECQAAAAAALFqWF8PBoIQrFoxHvdtBtYqZZGYVBAAAYH0JQQIAAAAAAIuW5Xmn1y/jimV5nMoUAgAAQGWYDhsAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkhpKAAAAAAAAAMCn2u32EpeeJKkuAADgNwlBAgAAAAAAAPAZ40mkCAAAlJzpsAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkoQgAQAAAAAAAAAAgEpqKAEAAAAAAAAAwBpqt9sPeVqaZWoFQGkJQQIAAAAAAAAArKPxJFIEAKrOdNgAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAym80Hk/C8JtekiSpugGUVpYm7euOOgAAAAAAPJEQJAAAQAWEcVqrCTUCrIgsTZqtdpbnSgEAAAAA8ERCkAAAAACwOMF41O72ikIlAAAAAABmQAgSAAAAABbkptvtjwJ1AAAAAACYFSFIAAAAAFiEq6urIIzVAQAAAAC+otPrT2/qwMMJQQIAAADAfGVpctXuREmqFAAAAAAAsyUECbBkSZK22+1vekmaZeoGAABQFVE4ubq+yfJcKQAAAAAAZk4IEmDJ4jSb3tQBAABgJQXjUbvbKwqVAAAAAACYCyFIAAAAAJiLm263PwrUAaAMRuPxJAwf8szMNCwAAABQKUKQAAAAADB7rVYrjFN1AD7S6fWnN3VYvF/+JvuzDAAAACtICBIAAAAAZilLk3dX13FqIDEAAAAAgLkTggQAAABgfTWblzNvM82yvFBaAAAAAIBFEIIEAAAA4P9n745a2gbDMAwXKbgdqAg7HcP//6NERMEg25quNE2+N7XiiQiyupA1r70uelJaaPu0J4WbfMfL9RoBAAAAGC4ilnVtBzgIESQAAAAAAAAAAMC/a9rStAs7wEGcmAAAAAAAAAAAAADISAQJAAAAAAAAAAAApOQ4bAAAAAAAAAAAABhFRCzr2g7jEUECAAAAAAAAAADAKJq2NO3CDuNxHDYAAAAAAAAAAACQkitBAsDBXN/c5n3zq/Vm//d/9eO7rxsAAAAAAJiC6LdvziSNCLMAQF4iSAAAAAAAAADgWETfP/5yJikAfB6OwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAHxAlC76rR0AAACYgrkJAAAAAAAA2NOyrn/+XmggAQAAmAgRJAAAAAAAAH8XpXuoHjddMQUAAADTIYIEAAAAAADg2brZ3N3dv/doF7F1AUgAAAAmRgQJAAAAAADAs347a0vYAQAAgEROTAAAAAAAAAAAAABkJIIEAAAAAAAAAAAAUhJBAgAAAAAAAAAAACnNTQAAAAAAAAAAwGfSdaWqqrFfws4AUyCCBID/ZPcva7XeHOdnv765fX332+XF2fm5nwQAAAAAAAAjaUvsbnYAOAaOwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgpbkJAGCIritVVe35THO9+LNarZvGDgAAAAAAAADAQCJIABikLbG72eFDmrbMZpJQAAAAAAAAAGAox2EDAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgJREkAAAAAAAAAAAAkJIIEgAAAAAAAAAAAEhp/vXLqRUAAAAAAAAAAACAdJ4EGAD0UiXBHYVPBAAAAABJRU5ErkJggg==)\"></div></div>", "meta": { "options": { "id": 760, "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "8uflrc8ao4r": { "assetType": { "id": 223, "name": "referenceblock" }, "design": "<div class=\"default-design\"><div style=\"width:100%;height:150px;background-size:cover;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADawAAAEtCAIAAADRXFFBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAALyhJREFUeNrs3ftvI+l+J2aOSF27JbWu7Z72nPEJdrOws5ss9hcj58R/vWEDQYLAhjdeZHfhcbeGYosiRfFWrHuFPZpty30btcRLFfk8IASKIt+q+r6UVMX61Pt+13r3rgYAAAAAAAAAAABQNY2rd1eqAAAAAAAAAAAAAFTOhhIAAAAAAAAAAAAAVSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUkhAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAAADg4drt9ngSTe88290+Pz9XEAAAAIAlMhIkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFRSo7Rr1mxexmn26eO///EH3QYAAAAAAAAAAAAYCRIAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvSicKAIAMG9CkAAAAAAAAADA7MVxoggAwLwJQQIAAAAAAAAAs5fnmSIAAPMmBAkAAAAAAAAAzF5kJEgAYP6EIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYiyicKAIAMFdCkAAAAAAAAADAXMRxoggAwFwJQQIAAAAAAAAAAACV1FACAAAAmLlm8zJOM3X4yOnR4f7BgToAAAAAAACzYiRIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvaIo8jxTBwBgrhpKAAAAAAAAAADMXJpm0XeJOgAAc2UkSAAAAAAAAAAAAKCShCABAAAAAAAAAACAShKCBAAAAAAAAAAAACqpoQQAAADwFMF4lGX5Rw9meaEyn4qiqDYYfPTg3t5uvbGpOAAAAAAAwCMIQQIAAMCT9G4HcZqpw0MMg3B6++jB01pt/0AIEgAAAAAAeAzTYQMAAAAAAAAAAACVJAQJAAAAAAAAAMxFkqSKAADMlRAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAADwVFmaKAIAAAAAH8nyQhEAgHlrlGElfnpz8cQnP9vdPj8/150AAACLNxwMbm77P/7uB6UAAAAA4L4sz+sbdXUAAOaqoQQAAAA8WpYmN7f9vKi12+31uTit2byM00zvz0qn15/ePnx7enS4f3CgLAAAAAAAwEOYDhsAAIDH63Rv7iY1Gk+iYDxSEACAr+jf9qJwog4AAABQUcPBQBFKSAgSAACAxx/qB2H84dvOTV9NAAC+tOPUbF7e9EdxnKgGALBWksx8GgCsjsHQeBBlZDpsAAAAHqnXH97/NsvztZoUGwDgIYaDwWA4ilPn/gGANVUUagDAiojCyfQAf/p1e2dXNUpFCBIAAIDHaLfbWZ5/9GAQRg7+AQDuTPeLbnq3YZwqBQAAAKyAMAynX8fjwHmQshGCBAAA4JsF49F4En36eFHUOt3e69cO/gGAtSb+CAAAAKsnjOLp1yR1vF86QpAAAAB8s85N/0s/itOsc319enamSgDAGsrSpHvT++zlIgAAAEClRb9c7hi56LF8hCABAAD4Np3r608nwr5vNAn3TYoNAKyZu/hjEEZFoRgAAACwggf+dydHpl+n9+uNTTUpjw0lAAAA4OGicDKahF9/zt2k2GoFAKyPzvX1xeW78UQCEgAAAFZTEEw+3B+NRgpSKkaCBAAA4Bt0ur2HnNqP06x/2zt8caRiAMBqu+l2h+Mgl30EAPhEliZ3dyJzhsCyTX8Nb3q3Gxsb9Y2N7e3t/YMDNYFvNQn/ZYSIKE4UpFQWGoIcDgbz2nnKss82vre3a+hRAACAWelcX8dp9sAn9waj58+fOygDAFbYeBIpAgDAl3wYMSuOEyFIWJa7+GMYpx8eGQZhp9ff+K622Ziq7+7sbG1t+iWF35Qk6WfvUwYLDUFO/4bOqeXpH+sw/kzjp7Xa/oHzbQAAADOQpclvToR9X1HUrtqd779/pXQAwCoZDgZhZLwHAACg7D6NP96XF7UoSae3u4u7vvuutlmvb242GvX6zs723rPnCggfuT9IxMMHjGAxTIcNAADAg1y1O8U3zvMYJWmlJ8Vut9uGd1q8Tq//2asof//jD4oDwHLddLujIMzyXCngiaJwEq/Z5HH1+oYkAQCwyN2tr8QfP6so3oe67nJd/VFQ6/TqGxubjemtsb29bSJW+HSO4ukjZpYvDyFIAAAAflv/thc9anKHW5NiAwDVd9PtDsdBXqgEzOj4YjBct8uNthp1IUgAYAEeEX/8kizPszifNjUMwtq96bO3tzZ3dnZMn83a/XJF0aeP7KtLaQhBAsDqa7fbn9kJqNePT04UB4CHyNKkNxg97rV5Uet0b16+fKmMAEAV94L677Na4o8AAEDZzTD++Fn/avrs/vuPi7ca9UajvtlobG5uGg+PlRd/Mk5EnKTKUh5CkACw+j57Yf30sERlAHigR0yEfV8QxmaFAACqJUuT7k0vCKNC/BEAACi3eccfv+R/TJ8dT+93ev36xkajvtFo1Hd3dkyfzeqJ0/Q3H2GJhCABAAD4muFgED35csab276PvQCAShB/BAAAqmJZ8cfPH0zl+fT261CRvf5339U26/XNzcb21ubU3rPn+otK/659+inB9JFgPPLeLgkhSAAAAL4oS5Ob2/7T2zEpNgBQfnenD6MkFX8EAJitSRiaJATmcfxSkvjjZ00PrO6Givx1zrpO7/D53vHJib6jisbj4LOPh2EkBFkScwxBNpuXS9+8Xn84GI7uP3L04sCbDwAA4IE63Zt8RiGAIIxdEwkAlFP5Tx8CAFRRnmd3dwpXmYDjl1otzTLdR1V/7+L4mx5n8eYYgozT5f/x+mWs3X/9yEffAwAA8AXDwSAIZ3kA37np/04IEgAo2Q7PaDwWfwQAmLlgPOoNfh2xKAjjm27XCHAwE5dXHUWABYuT9JseZ/FMhw0AAMDnzWQi7PuyPG+32+fn52oLACzdcDAYDEdluJgfAGD19G97vcHo/viP/VGQpOnLly8VB4BqydLkS1NmTR+Pwsn2zq4qLZ0QJACsmptu9yGDyU+f02637z+yu7Ozf3CggADcmf6byOcwT9F4EpkUGwBYLvFHAIC5uul2+6Pg08eDMG61Wudnp/XGpioBUBWj0egrPw3DUAiyDIQgAWDVTMLoISdy8uJ9DOWjB4UgAbgTjEef/puYld7tQAgSAFiKm253OA7mcaUHAAAf9rg+m4C8E8Zps9V+/epcDhKAqgij+Os/PVSjEthQAgAAAD7SuenPr/E4zTrX14oMACzSTbf75u1FfyQBCQAw352uryQg72R5/vPlu2A8Ui4AKiGK00f/lIUxEiQAAAD/SrvdzvJ8rosYTcL9cGKGCABg3rI06d70JmEk+wgAMG8PSUDeme6btbu981rNbCEAlN/Xz5jM+3wKD2QkSAAAAP5FFE7mNxH2B0VR63R7qg0AzE+WJu12++Ly3XTfRgISAGDerq6uHpiAvFMUtatO76bbVToAymw4GMzkOcybECQAAAD/YmHZRJNiAwBzEoWTD/HHQvwRAGD+Wq1WEMaPeGF/FEz33BQQgNKahOFMnsO8mQ4bAACAX3Wur+M0W9jiRpPwKE3qjU2VBwBmIgonN73bME6VAgBgYVqt1lN2wMaTaNrCq1evVBKAEkqSdCbPYd6MBAkAAMB7UTgZTRZ6teL7aY/aHZUHAGayJ9NqtS6vOhKQAACL9MQE5J1pC28vmlmaqCcAZZNkvz1yxCJHl+BLjAQJAADAe51ub/HzRUZJ2r/tHb44Un8A4HGGg8FgOHK+Acrm63ObruFAKWmWfb0m5+fn3jZAtWRp0r6e2SUoWZ43W+3T48O9Z8/VFoCSCMajB543mT7Tv7DlemoIcjgYdHr9Cm3wdG0/u8Jbjfrr1997QwAAAOupf9tbVnSgNxg9f/7cpNgAwLcSf4QyG08iRbgvL9QEWClZmjRb7SzPZ9lmnre7vfNaTYgEgJIIgsnDn+n/13IZCRIAAGDdZWnSG4yWtfSiqLWvO69evdIRAMAD3XS7kzASfwQAWIp5JCDvvP+YqNs7CKPjkxN1BmDp4gePYR+v32j3ZSMECQAAsO6u2p3FT4R9Xxinw8Fg/+BAXwAAX3fT7Q7HQV6oBADAcswvAXmnKGr9UZDn+enZmWoDsFxJms78mczJhhIAAACss/5tLyrBFYo3t/0sTXQHAPCVnZY3by/enxGXgAQAWJJ5JyA/GAZhq9VScACWKAonD/8IYvrM6fMVbYmEIAEAANZXlia3y5sI+768qHW6N3oEAPiS0Xgi/ggAsETBePTz5bsFJCDvhHHabF66aBaAZRmPg7k+n9kSggQAAFhfne5NecIEQRgPBwOdAgAAAFA2wXjU7vYW/DlSnGbNVtvAWgAsxbfOcB3FsaItUUMJAACgDK6urtI0e0oLr19/r4x8k+FgEITlOia/ue3vHxzoGgAAAIDyuEtAFsu4kjbL81a7c35ytPfsuY4AYJGi+NtCkEmaK9oSCUECAEAppGkWPy0ECd8kS5Ob237Z1iovau12+/z8XAcBAAAAlMESE5B3pouersBRkhy+ONIdACxGliZZ/m2hxunzp6+qNzZVbylMhw0AALCOSjUR9n3jSRSMRzoIAAAAYOmGg8FyE5B3pitw0x/ddLt6BIDFGI1GC3sVM2EkSAAAgLUTjEdlmwj7vs5N/3cLmeFoWocs+9qlnFlmfNYSGQ4GX3/C3t6uq2wBAABgVm663f4oKM/6TFcmiuNXr17pGgDmLYqTR7wqjOJDtVsSIUgAAIC107npl3n1sjxfzKTYvduBaeir9L7t/cb79rRW2z8QggQAAIAZKFsC8k4Yp5eXrZfnpy6DZLX99OZCEWC5kiR9xKtSZxyW56EhyGbzcrXPDE237kv/RX7/4w/eKAAAwMpot9tZnpd8JceTKAon2zu7+gsAAABgwcqZgLwTJWmz1X796lwOEoD5eVxMzrALS2QkSAAAWBHtdntBRxH1+vHJiYJXVDAejSdRJVa10+29fi0ECQAAALBQ/dteaROQd7I8v7h89+r81AW0AMzDcDB4ymv3Dw7UcPGEIAEAYEUsLNm21airdnX1bgdVWdU4zTrX16dnZ3oNAAAAYGGiOCn/ShZFLY4TIUgA5mEShk95rRDkUmwoAQAAwJroXF9Xay6G0SSMwomOAwAAAAAAFiN9wpmU1IzYS2IkSAAA1lEwHmVZXqpVyvJCvzBXUTgZTcJqrXNRmBQbAAAAAABYnDhNl/JankIIEgCAddS7HcSuxGLNdLq9ooJR2+mvav+2d/jiSA8CAAAAAABzFYxHTzmZMn3ttIW9Z89VcsGEIAEAAFZf5SbCvq83GD1//rze2NSPAABQHldXVyZ6m6Fm8/IrP339+nslAgCABQjD6IktBMFECHLxhCABAABWXJYmlZsI+76iqF21O99//0pXAgBAeaRpZo6FGVJMAAAogyiOn9hCYkbsZdhQAgAAgNV21e5UcSLs+6Ik7d/2dCUAAAAAADA/cZIuvQUeQQgSAABglfVve9FKHG/3BqMsTXQoAAAAAAAwD1E4yZ88qMS0hWk7irlgpsMGAAC+TZxmP725+KaXnB4d7h8cKN0CtNvt8SRayU0ritrb5jtvLQAAAACg6oLxKMtydYCyCcNwJu2Mx8H2zq56LpIQJAAAAAAAAAAALEjvdhCnmTpA2YRRPJN2ktSM2IsmBAkAVFizeVndld/d2T4+OdGJAAAAAAAAAEsXxWmp2uHhHhqCfP36+88+vjJTrW016l/aRgCgtCp9kdxm5go/AAAAAAAAgOXL0iTLZzNP/bSdaWv1xqaqLsyGEgAAAAAAAAAAALC2gmBS2tb4TabDhser9Bys9xkGFQBgZRwe7O/u7NzdH43H4SpOuHB6dPjh/t7erk4HAAAAAACeaBKGs21t/+BAVRdGCBIer9JzsAIAsJK2d3ant3uH6ysYgvSpAQAAAAAAMFtJkpa2NX6T6bABAAAAAAAAAABYX7MdCs3AagsmBAkAAAAAAAAAAMCaCsajmbc5HAwUdmFMhw1UW7vdXtait7c2D18c6QIAAAAAAAAAgOoKgsnM24yiaF9lF0UIEqi28SRa4qKDSfjq1Su9AAAAAAAAAABQUXGSVqJNvsR02ACPF8Zps3mZpYlSAAAAAAAAAABUUZymlWiTLzESJMAT/2llP1++Ozs52nv2XDUAAAAAAAAA1tlNt5tm2def85tPABYpCidFMftmp21OW97e2VXhBRCCBHiqvKi1u72jJDl8caQaAPD5o8coqg0GHz24tbXpwA8AAAAAgFUyCaM4lXGEKhmPg/m17FzYYghBAsxAUdRu+qMoTs7Pz1UDAD41DMLp7aMHn+1unzvwAwAAAAAAYHmiOK5cy3xkQwkAZmU8iVqtVpYmSgEAAAAAAAAAUH5xklauZT5iJEj4jCicxPEa5diGn8xN+Zv29nbrjU1vlU+FcdpstV+eHRvQGAAAAAAA+Kyf3lxUZVV//+MP+gsAWGFZmuTFvBqftjxtX8BmAYQg4TP6g+F4Eq3P9nZ6/W99yWmttn/gb/QX/kHmeavdOT852nv2XDXg0Sr0ISAAAAAAAAAAVTQajebd/uGLI3WeN9NhA8xeUdSuOr2bblcpAAAAAAAAAADKKYziSrfPHSFIgHnpj4Krqyt1AAAAAAAAAAAooTTN5tp+FKeKvABCkABzFIRxs3mZpYlSAAAAAAAAAACUSjznEGSW54q8AEKQAHP/f9lstYPxSCkAAAAAAAAAAEpiOBiszFLWnBAkwNxled7u9vq3PaUAAAAAAAAAACiDSRiuzFLWXEMJABagKGo3/VGSpKdnZ6oB/I+d3ajZvFyHLd3Y+O787LTe2NTpAKynUl3mu39woEcAqKgonPQHw0e//PBgf3tnVxkBAAD4IEnSlVnKmhOCBFicYRAmrZYkEHAnL2pxmq3Jxl5cvnu+uyMIDsB66vT65VmZm9v+/rO945MT/QJA5cRxMp5Ej3757s6OECQAAAD3JVm2MktZc0KQAAsVxmmz1X796lwOElgrRfE+CB41L09PjpxzAoAlyotafxRMwuhg/7lRIQEAAACeYjgYfDrLbSrtBBURjEdFsYgFTZcyXdbes+dqPj9CkMBjjMbjT3fmeKAszy8u352fHPkPB6ybOM1a7c7ezvb5+blqAMBy/yl3ev3BcCQKCQAAAPBokzB8ymjlwHIFwWSRyxIRmSshSOAxwjit1VJ1eLSiqLW7vYMwMgkdsIZ/AMeT6O1F8/T40I4+ACzXXRRyNB4fH70wVDMAAAAAsFbyxYwDufBlrSchSIDlKH6ZhC5J05cvX6oGsG6yPL/q9PZG4+++++6hu631uuA4AMxDGKeXV52drYYoJAAAAMF4FEZJJVZ1NB6b3AAAuLOgEOTm5uYf//CXLw4Pn9hOkqR//Td/OxgM9RywIkeSYdy5vj49O1MKYD3/Bj78yVuNuooBwPyEcdpqd/Z2tk+Oj+qNTQUBAABYQ/3bXm8wqspIVdMj2bcXzdevzh3GAgAbi1nMTBKQtfdhysZf/fEPe3uGJQBWh0GPAQCAMpgemown0cXlu3a7naWJggAAAKyV6cHgTX9UrdNWWZ5PD2OD8Uj3AcCaW9BIkDNJQN7Z3Gzs7e4GweT+g7/709d/+sOfTu/8fPHz25+b+hUAAADgEe6ikJPLd/vP9o5PThQEAABg5WVpctXuREla0cPYq07vMIwcwwLAOmuswDb87k9f/6f/9B/v7nc6XZ0KAAAA8BR5UeuPguE4EIUEYMF+enOhCACwSMF4dN3t5RWft2x6DBvF8fnZqamxAWA9bVR9A+4nIKdSszUBAAAAzMJdFLLZvBwOBqoBAACwem663Xb1E5B3wjhtttpRONGtALCGqh2C/CgB+c9v3v7TT290KgAAAMCsxGnW6fVFIQEAAFbM1dVVfxQUxepsUZbnrXbH0SsArKEKT4f9UQIySdIgmPzP//bf3H2bpsm7q/b0EX0MAAAA8ER3UcjReHx89GJ7Z1dBAAAAqit7fzL9enqgt3qbVhS16dFrFEWnZ2c6GgDWR4VDkPcTkFObm42/+PN/d/+R//U/1P7xv/x///W//XfdDAAAAPB0YZxeXnV2thqikAAAABUVjEfXqzIF9pcMgzBptc7PTuuNTT0OAOtgY7U37y/+/N/9L3/x57oZAAAAYFbCOG21O+12O0sT1QAAAKiQm263veoJyA+Hrs1WOwpNHQkAa6HCIcgkSR/ytH/7b/6nvT0jEwAAAADMTFHUxpPo4vKdKCQAAEBVXF1d9UdBUazL9mZ53mp3hoOBrgeAlVfh6bD/+m/+9q/++IfNzV83IUnS6SODwXB6/+Bg//6P/uTl+T/99EZnAwAAAMzQXRRycvlu/9ne8cmJggAAAJRTlibvrq7jNFvD49ZOrx9F0enZmbcBAKywCo8EORgM//pv/vbDeJCbm42/+uMfDg72P/zowzMbjU09DQAAADAPeVHrj4I3by9uul3VAAAAKJtgPPr58t0aJiA/GAZhq9UyjwEArLCNSq/9pznIP3n58sOP9C4AAADAYtxFIZvNSxONAQAAlMdNt9vu9vJi3esQxmmz1Y7CibcEAO12u9m8nN4mYbSwhU6XdbfQ6dJ1wTxsVH0DPspBAgAAALAscZp1en1RSAAAgDK4urrqj4KiUIn3sjxvtTsOVwGo/fIx5vS2yIsEpsu6W6jiz0ljBbbhLgd5Nwbkzc2NTgUAAABYorso5HA0Pjl+sb2zqyAAAAALlqXJu6trSYuPFEVtergaRdHp2ZlqAKyt3Z2d8SRa4tJ1wTwsKAT5z2/e/tmPv5tVU53ux0nHwWBo/msAAABgtq6urlJnjB4rStLLq87OVuP4SBQSAABggYdj4eRdu2MK7C8ZBmF2dfXyl1GWAFhD+wcHnV5/iUvXBfOwoBDk3/39PwwGg0Zj84ntpGnyTz+90W0AAADAAqQmKHmyMH4fhXy2u31yfFR/8kdDAAAA/KY4TiQgf/N4XxEA1tlWo76UD36ny1X8OVncdNjCiwAAAADraTyJgst3ezuikAAAAADAkm1uNpYSgpwuV/HnZEMJAAAAAJi3ongfhby4fHfT7aoGAAAAALAsuzs7a7XcdSAECQAAAMCCFEWtPwrevL0QhQQAAAAAlmJvb3etlrsOjLEJAAAAwELlv0QhR0F4dLi/f3CgIAAA3yQYj3q3g6884fXr71UJAAC+pN7YrG9sZHm+0IVubEyXq/hzsqAQ5Obm5n/83/7D9OsT20mS5O/+/h+mX/UcAAAAQKVled7p9QfD0cH+c1FIAIBv2I/K8jjN1AEAAB5te6sRhPGCl6js87Og4v7xD3/54vBwJk09e7b3N3/7f8pBAgAArKd2uz2rptLMWUNYvjjNOr3+cDQ+OX6xvWM6GACAGWg2L+fR7OZm4/z8XHkBAFgBO9tbCw5BTpeo7POzoBDkrBKQd00dHux3ujc6DwAAYA2NJ5EiwOqJkvTyqrOz1Tg+EoUEAHiqOY0TOW327UXz9Phw79lzRQYAoNKeP39+0x8teInKPj+LHmYzCILROHjEC7e2NmeYpAQAAACgbML4fRTy2e72yfFRvbGpIAAAZZPl+VWntzcav3z5UjUAAKiuemNz47taXixocdNl+cBzrhYdgvznNxf/9b/990e88PTk+P/44/+uwwAqKgon/cFw5s1ub20evjhSXgAAWCXjSRRcvtvbEYUEACipBc8bCAAA87C12QjjdGHLUvC5Ul8AFiGOk3nMXDltM4xi1xwDAMCKKYpfo5AHz/aOT04UBAAAAGB9/PTmolTr8913tfOTo71n5jJeNfV6vVZLF7gs5mhjVTdsc9M4AQBrIQjjy8tWliZKAQAAK6Yoav1R8ObtxU23qxoAAAAALEVR1K46PZ9QQZmtZghyc3Pzj3/4S70LsCaiJG222sF4pBQAALB68l+ikG8vmsPBQDUAAAAAWIr+KOhcX6sDlFMlp8P+9//+L+L4ayN+PX+2N/Xh23dXV3oaYLVled7u9k6yfP/gQDUAAGAl9/k7vf5gODrYf263HwAAAIDFGwZh0mq9evVKKaBsKhmCfHF4+PAnt687g8GwbJsQjEdZlq/ne65e39h79tzvHjBzRVHr9PpRFJ2enakGAACspDjNprv9w9H45PjF9s6uggAAAACwSGGctlqt87PTemNTNaA8Gqu9ebf9/v/1f/8/JVyx3u0gTrP1fM9tNepCkMD8rOfFN+12+/63afbIfzFJkt5vqlGvH5+ceFMBAFA2UZJeXnV2thrHR6KQAAAAACxUGKfNVvv1q3M5SCiPSoYgb/v9r0+Hfefdu3cXP18mSaKbAdZtp/PtRXOtdjrHk2gm7cRpdj+jv9WoezsBAFDmPf/Lq86z3e2T4yOfOAMAAACwMFmeN1vtl2fHLtCFkqhkCPI//+d/7HRvdB4AX9npvLh8d35yZOhZAABYbeNJFFy+29sRhQQAAABgcbI8b7U7TklDSSw6BPlnP/5wevqYiTW3tnyKDbAgw8Gg0+tXfSuKotbu9g7CyITOAACw2qY7/3dRyINne/b/AQAAAFiMu1PSR0ly+OJINWC5Fh2C3PuFugOwmJ3O/ihIs+z8/Fw1AABgHfb/h+Ngf9WjkFmaBMFkrTp3/+DAOxwAAAAooaKo3fRHWZa7NBeWa0EhyH9+8/bPfvzdTJq67ff7g6GeA+CBxpPo8rL18vzU1HgAALDy8l+ikKMgPDrcX9XkXBBMVmDw/m8iBAkAAACUmaF5YOkWFIL8u7//hyRJDw+f+nllkiS/NJXoOQAeLkrSZqv98ux4e2d3JTfw2e723Z3xJHp6axvf1XZ33jfYqNe9eQAAqKIszzu9/mA4Oth/Lj8HAAAAwLyNJ1Hn+vr07EwpYCkWNx32//uP/0W5AViWLM9b7c7Ji8OVPAP64aKin95czGDnoF53lRIAACsgTrNOrz8cjU+OX6zqBVEAAAAAlEReFIoAy9JQAhYszbJ2u/2kd229fnxyopLAt5ruc3Z6/SRJ/A0BAID1ESXp5VVnZ6txfCQKCQAAAI/UbF7Gabb01dhq1F+//l53APARIUgWLS+eOlvrdLdGGYFH64+CKI5fvXqlFAAAsD7C+H0U8tnu9snxUb2xqSAAAAAAACtDCBKgekpyoVV1hXH69qL5+tW5c58AALBWxpMouHy3tyMKCQAA1XDT7U7CaFlLbzTqL1++1AsAAOUnBAnAOsry/OfLd2cnR3vPnqsGAACsj6L4NQr5fHfn9OxMQfjIT28uVn4bf//jDzoaAKiKNMuMCgEAwG/aUAIA1lNe1NrdXv+2pxQAALBuiqI2DMI3by9uul3VAAAAAACoNCNBArC+iqJ20x9FcXJ+fq4aAACwbvKi1h8FxycnSgHwCFE46Q+Gj3hho173txcAAACYISFIANbdeBK1Wq3zs9N6Y1M1AAAAAB4ijpPxJHrEC7caddUDAAAAZsh02ABQC+O02WpH4UQpAAAAAAAAAAAqRAgSAN7L8rzV7gTjkVIAAAAAAAAAAFSFECQA/Kooaled3k23qxQAAAAAAAAAAJXQUAIAuK8/CqI4fvXqlVIAAACsm9Ojw7s7vf4wy/OV2a76xsbR4b7+BQAAAGAlCUECwMfCOG02L//k5Vm9sakaAAAA62P/4ODuzmA4ylYnA1mrb3z3YdOooqurqzTNyrZWWV48+oXDweD9O7O+sffsuf4FAAAAnkgIEgA+I06zZqt9enzos3gAAABgudI0i8sXgny0LM87vf70zlaj7oMXWENROOkPhlVc892dHRcVAABAOQlBAsDnZXne7vaOkuTwxZFqAAAAAAA8XRwn40lU0ZUXglxbw8FgEoZf+unhwf72zq4qAQAskRAkAHxRUdRu+qMkSU/Pzsq/tnczST1dnGZZmpgKHAAAAAAApiZh+JXw7u7OjhAkAMByCUECwG8YBmHSap2fnZY8Fzgaj2fVVK93W4ncJwDAv9qH6Q8Hw9Fs20yyTGEBAADWU5pl7Xb7/bFhkqoGAECZCUECwG8L47TZar9+dV7aHGSWJtOVnFVrQRjrdACgcrI8z3JlAAAAYDbyovaQ2ds7vf709tkfnR4dmkUdAGABhCAB4EGyPL+4fHd+crT37HkJV6/Xu53txgbjUTm3lLWVZFmzeTnbBlUVAKAShoPBQ55Wr284igEAAACANSQECQAPVRS1q07vMIyOT07Ktm7jSTjbBvuDodOHlO0XME7FFgGAVfPAeN99URStW5W+NKzOR7YadUcxAAAAALCGhCAB4Nv0R0GSpi9fvizPKg0Hg7yYcZtRkmZpUtrpvwEAYDU8MN4HAAAAAMCXbCgBAHyrIIwvL1tZmpRkfUbj8czbLIpavz/Q1wAAAAAAAABAmRkJEgAeI0rSZqt9eny49NnWsjQJ43QeLY+C8PhEVwMAAAAAD5KlSRBMvv6cKIoUCgAAmC0hSAB4pCzP293eea223Bzk/MZrnG5gMB4tPeUJAAAAAFRCEEw6vb46AAAACyYECQCPVxS10ThYbkxwFITza7w/GApBAgAAAMByNZuX97/N8kJNAAAAPhCCBIAKC8ajLM/n136UpIoMAAAAAMsVp5kiAAAAfMmGEgBAdfUHw7m2XxS1m25XnQEAAAAAAACAchKCBICqytJkASM1TsJIqQEAAAAAAACAcjIdNgBUVb8/KIq5LyVOsyicbO/sKjgAAAAAAMC3ajYv4zQr7er9/scf9BEwWzfdbpo96e/e4cG+M9R8EyHIX2V5MRwMFrk4NQfgiUZBuJgF3fYHL+1iAgAAAABrbBJGzealOgAAPGTH6Ynh792dHSFIvokQ5K+yPO/0+upQkc6ae2I1yzJ1BkouGI+m/7wWtJMaxQoOAAAAAKyzvKiVeSA3AAB4tHa7PZ5E817K6dHh/sHBnBoXgqR6JFYBpoaj8cKWVRTvRyw/PjlRdgAAAAAAAACgVIQgAaCSFjw64ySM1BwAAAAAAFhJN93u/E6FJOYhBIA5E4IEgEoeihfFQpcYp1kUTrZ3dhUfAAAAAABYMWmWmfIeAKpLCBIAqmcp4zL2B8NzIUgAAKCs4jT76c2FOgAAAADAutlQAgColiicLOViRDNiAwAAAAAAAABlYyRIACijLE2CYPLZH43G46WsUl7UOtfX29vbn/3p/sGBXgMAAAAAAGB+srwYDgYPfPLW1ua2Wc4A1oMQJACUURBMOr1+2dZqGITT22d/JAQJAAAAAADAXGV5/vAzaM92t8+FIAHWg+mwAQAAAAAAAAAAgEoyEiQAAAAAAAAAzFin1y/hpE8AlEq73V69jUqzTM+yYI1m89K7FgAAKI9gPMqyfOmrsbW1uW2qFABgJSRZ9sTPgUuyFboSAACAFTOeRIrAnZ/eXKz2Bvb6w8FwNKfGG3HqkyMAAKBMh0C3gzIcpzzb3T4XggQAVkJR1HwODAAAAMASZXk+v1FQNtQXAAAAAAAAAAAAqCIhSAAAAAAAAAAAAKCShCABAAAAAAAAAACASmooAQCU0N7e7um9b0fjcRinpVrDna3G82fP9BQAAAAAAAAAsERCkABQRvXG5v7B5odvJ2FYq5UrBFmv1/cPDvQU8BRZlg0Hg888nhdlXr1l2dvbnf538LYBAAAAAACA+4QgAQCA5QjjNIz7Vu+BTmu1+/l4AACAD66urtI0m0lTuzvbxycnSgoAAECFCEECAAAAAABUWJpm8YxCkJtZpp4AAABUy4YSAAAAAAAAAAAAAFUkBAkAAAAAAAAAAABUkumwAQAAAAAAAACAOZqEUbN5qQ7APAhBAgAAAAAAAAAAc5QXtTjN1AGYByFIAAAAAAAA4Bv89OZCEQAAgJLYUAIAAAAAAAAAAACgiowECQAAAAAALFqWF8PBoIQrFoxHvdtBtYqZZGYVBAAAYH0JQQIAAAAAAIuW5Xmn1y/jimV5nMoUAgAAQGWYDhsAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkhpKAAAAAAAAAMCn2u32EpeeJKkuAADgNwlBAgAAAAAAAPAZ40mkCAAAlJzpsAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkoQgAQAAAAAAAAAAgEpqKAEAAAAAAAAAwBpqt9sPeVqaZWoFQGkJQQIAAAAAAAAArKPxJFIEAKrOdNgAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAym80Hk/C8JtekiSpugGUVpYm7euOOgAAAAAAPJEQJAAAQAWEcVqrCTUCrIgsTZqtdpbnSgEAAAAA8ERCkAAAAACwOMF41O72ikIlAAAAAABmQAgSAAAAABbkptvtjwJ1AAAAAACYFSFIAAAAAFiEq6urIIzVAQAAAAC+otPrT2/qwMMJQQIAAADAfGVpctXuREmqFAAAAAAAsyUECbBkSZK22+1vekmaZeoGAABQFVE4ubq+yfJcKQAAAAAAZk4IEmDJ4jSb3tQBAABgJQXjUbvbKwqVAAAAAACYCyFIAAAAAJiLm263PwrUAaAMRuPxJAwf8szMNCwAAABQKUKQAAAAADB7rVYrjFN1AD7S6fWnN3VYvF/+JvuzDAAAACtICBIAAAAAZilLk3dX13FqIDEAAAAAgLkTggQAAABgfTWblzNvM82yvFBaAAAAAIBFEIIEAAAA4P9n745a2gbDMAwXKbgdqAg7HcP//6NERMEg25quNE2+N7XiiQiyupA1r70uelJaaPu0J4WbfMfL9RoBAAAAGC4ilnVtBzgIESQAAAAAAAAAAMC/a9rStAs7wEGcmAAAAAAAAAAAAADISAQJAAAAAAAAAAAApOQ4bAAAAAAAAAAAABhFRCzr2g7jEUECAAAAAAAAAADAKJq2NO3CDuNxHDYAAAAAAAAAAACQkitBAsDBXN/c5n3zq/Vm//d/9eO7rxsAAAAAAJiC6LdvziSNCLMAQF4iSAAAAAAAAADgWETfP/5yJikAfB6OwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAHxAlC76rR0AAACYgrkJAAAAAAAA2NOyrn/+XmggAQAAmAgRJAAAAAAAAH8XpXuoHjddMQUAAADTIYIEAAAAAADg2brZ3N3dv/doF7F1AUgAAAAmRgQJAAAAAADAs347a0vYAQAAgEROTAAAAAAAAAAAAABkJIIEAAAAAAAAAAAAUhJBAgAAAAAAAAAAACnNTQAAAAAAAAAAwGfSdaWqqrFfws4AUyCCBID/ZPcva7XeHOdnv765fX332+XF2fm5nwQAAAAAAAAjaUvsbnYAOAaOwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgpbkJAGCIritVVe35THO9+LNarZvGDgAAAAAAAADAQCJIABikLbG72eFDmrbMZpJQAAAAAAAAAGAox2EDAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgJREkAAAAAAAAAAAAkJIIEgAAAAAAAAAAAEhp/vXLqRUAAAAAAAAAAACAdJ4EGAD0UiXBHYVPBAAAAABJRU5ErkJggg==)\"></div></div>", "meta": { "options": { "id": 761, "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "template": { "id": 0, "assetType": { "id": 214, "name": "defaulttemplate" }, "name": "CONTENTTEMPLATES_BLANK_PAGE", "meta": { "contentHash": -765177524 }, "availableViews": [], "slots": { "banner": { "locked": false, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" } } }, "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_assetMessage/views.html.content.asset-message-meta.html ================================================ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> ReadMsgBody{ width: 100%;} .ExternalClass {width: 100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} body {-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;margin:0 !important;} p { margin: 1em 0;} table td { border-collapse: collapse;} img {outline:0;} a img {border:none;} @-ms-viewport{ width: device-width;} </style> <style type="text/css"> @media only screen and (max-width: 480px) { .container {width: 100% !important;} .footer { width:auto !important; margin-left:0; } .mobile-hidden { display:none !important; } .logo { display:block !important; padding:0 !important; } img { max-width:100% !important; height:auto !important; max-height:auto !important;} .header img{max-width:100% !important;height:auto !important; max-height:auto !important;} .photo img { width:100% !important; max-width:100% !important; height:auto !important;} .drop { display:block !important; width: 100% !important; float:left; clear:both;} .footerlogo { display:block !important; width: 100% !important; padding-top:15px; float:left; clear:both;} .nav4, .nav5, .nav6 { display: none !important; } .tableBlock {width:100% !important;} .responsive-td {width:100% !important; display:block !important; padding:0 !important; } .fluid, .fluid-centered { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; } .fluid-centered { margin-left: auto !important; margin-right: auto !important; } /* MOBILE GLOBAL STYLES - DO NOT CHANGE */ body { padding: 0px !important; font-size: 16px !important; line-height: 150% !important;} h1 { font-size: 22px !important; line-height: normal !important;} h2 { font-size: 20px !important; line-height: normal !important;} h3 { font-size: 18px !important; line-height: normal !important;} .buttonstyles { font-family:arial,helvetica,sans-serif !important; font-size: 16px !important; color: #FFFFFF !important; padding: 10px !important; } /* END OF MOBILE GLOBAL STYLES - DO NOT CHANGE */ } @media only screen and (max-width: 640px) { .container { width:100% !important; } .mobile-hidden { display:none !important; } .logo { display:block !important; padding:0 !important; } .photo img { width:100% !important; height:auto !important;} .nav5, .nav6 { display: none !important;} .fluid, .fluid-centered { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; } .fluid-centered { margin-left: auto !important; margin-right: auto !important; } } </style> <!--[if mso]> <style type="text/css"> /* Begin Outlook Font Fix */ body, table, td { font-family: Arial, Helvetica, sans-serif ; font-size:16px; color:#000000; line-height:1; } /* End Outlook Font Fix */ </style> <![endif]--> </head> <body bgcolor="#ffffff" text="#000000" style="background-color: #ffffff; color: #000000; padding: 0px; -webkit-text-size-adjust:none; font-size: 16px; font-family:arial,helvetica,sans-serif;"> <div style="font-size:0; line-height:0;"><custom name="opencounter" type="tracking"><custom name="usermatch" type="tracking" /></div> <table width="100%" border="0" cellpadding="0" cellspacing="0" align="center"> <tr> <td align="center" valign="top"> <custom type="header"/> </td> </tr> <tr> <td align="center"> <table cellspacing="0" cellpadding="0" border="0" width="600" class="container" align="center"> <tr> <td> <table class="tb_properties border_style" style="background-color:#FFFFFF;" cellspacing="0" cellpadding="0" bgcolor="#ffffff" width="100%"> <tr> <td align="center" valign="top"> <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <!-- added padding here --> <td class="content_padding" style=""> <!-- end of comment --> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <!-- top slot --> <td align="center" class="header" valign="top"> <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td align="left" valign="top"> <table cellspacing="0" cellpadding="0" style="width:100%"> <tbody> <tr> <td class="responsive-td" valign="top" style="width: 100%;"> <div data-type="slot" data-key="banner"> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> <tr> <td valign="top"> <custom type="footer" /> </td> </tr> </table> </body> </html> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_asset_templatebasedemail/testNew_asset_templatebasedemail.asset-message-meta.json ================================================ { "customerKey": "testNew_asset_templatebasedemail", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": "testNew_asset_templatebasedemail", "description": "", "createdBy": {}, "modifiedBy": {}, "memberId": "9999999", "status": { "name": "Draft" }, "meta": { "globalStyles": { "isLocked": false, "template": { "background-color": "#FFFFFF", "border-color": "", "border-width": "0px", "border-style": "solid" }, "body": { "background-color": "#FFFFFF", "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#000000", "line-height": 1, "margin": "0px", "padding": "0px", "content-padding-top": "0px", "content-padding-right": "0px", "content-padding-bottom": "0px", "content-padding-left": "0px" }, "h1": { "font-family": "Arial,helvetica,sans-serif", "font-size": "28px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h2": { "font-family": "Arial,helvetica,sans-serif", "font-size": "22px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h3": { "font-family": "Arial,helvetica,sans-serif", "font-size": "20px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "links": { "font-weight": "normal", "color": "#0176d3", "text-decoration": "none" }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "background-color": "#5D5D5D", "border-radius": "3px", "padding": "10px", "border-color": "#5D5D5D", "border-width": "1px", "border-style": "solid" }, "mobile": { "body": { "padding": "0px", "font-size": "16px", "line-height": 1.5 }, "h1": { "font-size": "22px", "line-height": 1 }, "h2": { "font-size": "20px", "line-height": 1 }, "h3": { "font-size": "18px", "line-height": 1 }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "padding": "10px" } } } }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "my subject", "meta": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "preheader": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "availableViews": [], "slots": { "banner": { "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "availableViews": [], "blocks": {}, "slots": {}, "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 } }, "template": { "content": "", "meta": { "contentHash": 1850388723 }, "slots": { "banner": { "locked": false, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 } }, "r__asset_key": "testNew_asset_template" }, "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "html", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "attributes": [ { "displayName": "__AdditionalEmailAttribute1", "name": "__AdditionalEmailAttribute1", "value": "", "order": 1, "channel": "email", "attributeType": "AdditionalEmailAttribute" }, { "displayName": "__AdditionalEmailAttribute2", "name": "__AdditionalEmailAttribute2", "value": "", "order": 2, "channel": "email", "attributeType": "AdditionalEmailAttribute" }, { "displayName": "__AdditionalEmailAttribute3", "name": "__AdditionalEmailAttribute3", "value": "", "order": 3, "channel": "email", "attributeType": "AdditionalEmailAttribute" }, { "displayName": "__AdditionalEmailAttribute4", "name": "__AdditionalEmailAttribute4", "value": "", "order": 4, "channel": "email", "attributeType": "AdditionalEmailAttribute" }, { "displayName": "__AdditionalEmailAttribute5", "name": "__AdditionalEmailAttribute5", "value": "", "order": 5, "channel": "email", "attributeType": "AdditionalEmailAttribute" } ] } }, "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_asset_templatebasedemail/views.html.content.asset-message-meta.html ================================================ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> ReadMsgBody{ width: 100%;} .ExternalClass {width: 100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} body {-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;margin:0 !important;} p { margin: 1em 0;} table td { border-collapse: collapse;} img {outline:0;} a img {border:none;} @-ms-viewport{ width: device-width;} </style> <style type="text/css"> @media only screen and (max-width: 480px) { .container {width: 100% !important;} .footer { width:auto !important; margin-left:0; } .mobile-hidden { display:none !important; } .logo { display:block !important; padding:0 !important; } img { max-width:100% !important; height:auto !important; max-height:auto !important;} .header img{max-width:100% !important;height:auto !important; max-height:auto !important;} .photo img { width:100% !important; max-width:100% !important; height:auto !important;} .drop { display:block !important; width: 100% !important; float:left; clear:both;} .footerlogo { display:block !important; width: 100% !important; padding-top:15px; float:left; clear:both;} .nav4, .nav5, .nav6 { display: none !important; } .tableBlock {width:100% !important;} .responsive-td {width:100% !important; display:block !important; padding:0 !important; } .fluid, .fluid-centered { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; } .fluid-centered { margin-left: auto !important; margin-right: auto !important; } /* MOBILE GLOBAL STYLES - DO NOT CHANGE */ body { padding: 0px !important; font-size: 16px !important; line-height: 150% !important;} h1 { font-size: 22px !important; line-height: normal !important;} h2 { font-size: 20px !important; line-height: normal !important;} h3 { font-size: 18px !important; line-height: normal !important;} .buttonstyles { font-family:arial,helvetica,sans-serif !important; font-size: 16px !important; color: #FFFFFF !important; padding: 10px !important; } /* END OF MOBILE GLOBAL STYLES - DO NOT CHANGE */ } @media only screen and (max-width: 640px) { .container { width:100% !important; } .mobile-hidden { display:none !important; } .logo { display:block !important; padding:0 !important; } .photo img { width:100% !important; height:auto !important;} .nav5, .nav6 { display: none !important;} .fluid, .fluid-centered { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; } .fluid-centered { margin-left: auto !important; margin-right: auto !important; } } </style> <!--[if mso]> <style type="text/css"> /* Begin Outlook Font Fix */ body, table, td { font-family: Arial, Helvetica, sans-serif ; font-size:16px; color:#000000; line-height:1; } /* End Outlook Font Fix */ </style> <![endif]--> </head> <body bgcolor="#ffffff" text="#000000" style="background-color: #ffffff; color: #000000; padding: 0px; -webkit-text-size-adjust:none; font-size: 16px; font-family:arial,helvetica,sans-serif;"> <div style="font-size:0; line-height:0;"><custom name="opencounter" type="tracking"><custom name="usermatch" type="tracking" /></div> <table width="100%" border="0" cellpadding="0" cellspacing="0" align="center"> <tr> <td align="center" valign="top"> <custom type="header"/> </td> </tr> <tr> <td align="center"> <table cellspacing="0" cellpadding="0" border="0" width="600" class="container" align="center"> <tr> <td> <table class="tb_properties border_style" style="background-color:#FFFFFF;" cellspacing="0" cellpadding="0" bgcolor="#ffffff" width="100%"> <tr> <td align="center" valign="top"> <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <!-- added padding here --> <td class="content_padding" style=""> <!-- end of comment --> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <!-- top slot --> <td align="center" class="header" valign="top"> <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td align="left" valign="top"> <table cellspacing="0" cellpadding="0" style="width:100%"> <tbody> <tr> <td class="responsive-td" valign="top" style="width: 100%;"> <div data-type="slot" data-key="banner"> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> <tr> <td valign="top"> <custom type="footer" /> </td> </tr> </table> </body> </html> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/template/testNew_asset_template/content.asset-template-meta.html ================================================ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> ReadMsgBody{ width: 100%;} .ExternalClass {width: 100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} body {-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;margin:0 !important;} p { margin: 1em 0;} table td { border-collapse: collapse;} img {outline:0;} a img {border:none;} @-ms-viewport{ width: device-width;} </style> <style type="text/css"> @media only screen and (max-width: 480px) { .container {width: 100% !important;} .footer { width:auto !important; margin-left:0; } .mobile-hidden { display:none !important; } .logo { display:block !important; padding:0 !important; } img { max-width:100% !important; height:auto !important; max-height:auto !important;} .header img{max-width:100% !important;height:auto !important; max-height:auto !important;} .photo img { width:100% !important; max-width:100% !important; height:auto !important;} .drop { display:block !important; width: 100% !important; float:left; clear:both;} .footerlogo { display:block !important; width: 100% !important; padding-top:15px; float:left; clear:both;} .nav4, .nav5, .nav6 { display: none !important; } .tableBlock {width:100% !important;} .responsive-td {width:100% !important; display:block !important; padding:0 !important; } .fluid, .fluid-centered { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; } .fluid-centered { margin-left: auto !important; margin-right: auto !important; } /* MOBILE GLOBAL STYLES - DO NOT CHANGE */ body { padding: 0px !important; font-size: 16px !important; line-height: 150% !important;} h1 { font-size: 22px !important; line-height: normal !important;} h2 { font-size: 20px !important; line-height: normal !important;} h3 { font-size: 18px !important; line-height: normal !important;} .buttonstyles { font-family:arial,helvetica,sans-serif !important; font-size: 16px !important; color: #FFFFFF !important; padding: 10px !important; } /* END OF MOBILE GLOBAL STYLES - DO NOT CHANGE */ } @media only screen and (max-width: 640px) { .container { width:100% !important; } .mobile-hidden { display:none !important; } .logo { display:block !important; padding:0 !important; } .photo img { width:100% !important; height:auto !important;} .nav5, .nav6 { display: none !important;} .fluid, .fluid-centered { width: 100% !important; max-width: 100% !important; height: auto !important; margin-left: auto !important; margin-right: auto !important; } .fluid-centered { margin-left: auto !important; margin-right: auto !important; } } </style> <!--[if mso]> <style type="text/css"> /* Begin Outlook Font Fix */ body, table, td { font-family: Arial, Helvetica, sans-serif ; font-size:16px; color:#000000; line-height:1; } /* End Outlook Font Fix */ </style> <![endif]--> </head> <body bgcolor="#ffffff" text="#000000" style="background-color: #ffffff; color: #000000; padding: 0px; -webkit-text-size-adjust:none; font-size: 16px; font-family:arial,helvetica,sans-serif;"> <div style="font-size:0; line-height:0;"><custom name="opencounter" type="tracking"><custom name="usermatch" type="tracking" /></div> <table width="100%" border="0" cellpadding="0" cellspacing="0" align="center"> <tr> <td align="center" valign="top"> <custom type="header"/> </td> </tr> <tr> <td align="center"> <table cellspacing="0" cellpadding="0" border="0" width="600" class="container" align="center"> <tr> <td> <table class="tb_properties border_style" style="background-color:#FFFFFF;" cellspacing="0" cellpadding="0" bgcolor="#ffffff" width="100%"> <tr> <td align="center" valign="top"> <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <!-- added padding here --> <td class="content_padding" style=""> <!-- end of comment --> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <!-- top slot --> <td align="center" class="header" valign="top"> <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td align="left" valign="top"> <table cellspacing="0" cellpadding="0" style="width:100%"> <tbody> <tr> <td class="responsive-td" valign="top" style="width: 100%;"> <div data-type="slot" data-key="banner"> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </td> </tr> <tr> <td valign="top"> <custom type="footer" /> </td> </tr> </table> </body> </html> ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/asset/template/testNew_asset_template/testNew_asset_template.asset-template-meta.json ================================================ { "customerKey": "testNew_asset_template", "assetType": { "name": "template", "displayName": "Template" }, "fileProperties": { "fileName": "testNew_asset_template" }, "name": "testNew_asset_template", "createdBy": {}, "modifiedBy": {}, "memberId": "9999999", "status": { "name": "Draft" }, "meta": { "globalStyles": { "isLocked": false, "template": { "background-color": "#FFFFFF", "border-color": "", "border-width": "0px", "border-style": "solid" }, "body": { "background-color": "#FFFFFF", "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#000000", "line-height": 1, "margin": "0px", "padding": "0px", "content-padding-top": "0px", "content-padding-right": "0px", "content-padding-bottom": "0px", "content-padding-left": "0px" }, "h1": { "font-family": "Arial,helvetica,sans-serif", "font-size": "28px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h2": { "font-family": "Arial,helvetica,sans-serif", "font-size": "22px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h3": { "font-family": "Arial,helvetica,sans-serif", "font-size": "20px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "links": { "font-weight": "normal", "color": "#0176d3", "text-decoration": "none" }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "background-color": "#5D5D5D", "border-radius": "3px", "padding": "10px", "border-color": "#5D5D5D", "border-width": "1px", "border-style": "solid" }, "mobile": { "body": { "padding": "0px", "font-size": "16px", "line-height": 1.5 }, "h1": { "font-size": "22px", "line-height": 1 }, "h2": { "font-size": "20px", "line-height": 1 }, "h3": { "font-size": "18px", "line-height": 1 }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "padding": "10px" } } } }, "availableViews": [], "slots": { "banner": { "thumbnail": {}, "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "modelVersion": 2 } }, "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json ================================================ { "description": "updated on deploy", "key": "testExisting_automation", "name": "testExisting_automation", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" } ], "name": "" } ], "notifications": [ { "email": ["error-updated@test.accenture.com"], "message": "test updated", "type": "Error" } ], "type": "scheduled" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json ================================================ { "description": "created on deploy", "key": "testNew_automation", "name": "testNew_automation", "r__folder_Path": "my automations", "schedule": { "startDate": "2020-05-14T02:30:32.11", "endDate": "2079-06-06T21:00:00", "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", "timezoneName": "W. Europe Standard Time" }, "status": "Scheduled", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" }, { "r__key": "testNew_automation__s1.7", "r__type": "verification" } ], "name": "" } ], "type": "scheduled" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-meta.json ================================================ { "CustomerKey": "testExisting_dataExtension", "Name": "testExisting_dataExtension", "Description": "Container for my test emails", "IsSendable": true, "IsTestable": true, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "Name": "FirstName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 55, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "EmailAddress", "Name_new": "Email", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "testField", "DefaultValue": "", "MaxLength": 254, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "ContactKey", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" } ], "c__dataRetentionPeriodUnitOfMeasure": "Days", "c__retainUntil": "2024-5-9", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/dataExtension/testNew_dataExtension.dataExtension-meta.json ================================================ { "CustomerKey": "testNew_dataExtension", "Name": "testNew_dataExtension", "Description": "", "IsSendable": false, "IsTestable": false, "Fields": [ { "Name": "testField", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "Text" } ], "c__retentionPolicy": "none", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/dataExtract/testExisting_dataExtract.dataExtract-meta.json ================================================ { "name": "testExisting_dataExtract", "key": "testExisting_dataExtract", "description": "updated on deploy", "r__dataExtractType_name": "Data Extension Extract", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string", "value": "testExisting_dataExtension" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ] } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/dataExtract/testNew_dataExtract.dataExtract-meta.json ================================================ { "name": "testNew_dataExtract", "key": "testNew_dataExtract", "description": "created via deploy", "r__dataExtractType_name": "Data Extension Extract", "fileSpec": "testNew-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string", "value": "testExisting_dataExtension" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ] } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/dataFilter/testExisting_dataFilter.dataFilter-meta.json ================================================ { "description": "updated on deploy", "key": "testExisting_dataFilter", "name": "testExisting_dataFilter", "isSendable": true, "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Begins", "Value": "testExisting_", "r__dataExtensionField_name": "LastName" } } }, "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "testExisting_dataExtension" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/dataFilter/testNew_dataFilter.dataFilter-meta.json ================================================ { "description": "created via deploy", "key": "testNew_dataFilter", "name": "testNew_dataFilter", "isSendable": true, "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Begins", "Value": "testNew_", "r__dataExtensionField_name": "LastName" } } }, "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "testExisting_dataExtension" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/domainVerification/joern.berkefeld.New@accenture.com.domainVerification-meta.json ================================================ { "domain": "joern.berkefeld.New@accenture.com", "status": "Verified", "domainType": "UserDomain", "isSendable": true } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/domainVerification/joern.berkefeld@accenture.com.domainVerification-meta.json ================================================ { "domain": "joern.berkefeld@accenture.com", "status": "Verified", "domainType": "UserDomain", "isSendable": true } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/domainVerification/mcdev.accenture.com.domainVerification-meta.json ================================================ { "domain": "mcdev.accenture.com", "status": "Verified", "domainType": "SAP", "isSendable": true } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/emailSend/testExisting_emailSend.emailSend-meta.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CreatedDate": "2022-11-14T12:27:29.963", "CustomerKey": "testExisting_emailSend", "DeduplicateByEmail": false, "Description": "updated on deploy", "DynamicEmailSubject": "someSubject", "EmailSubject": "someSubject", "ExclusionFilter": "", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "ModifiedDate": "2022-11-14T12:27:29.963", "Name": "testExisting_emailSend", "SendDefinitionList": [ { "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "SendDefinitionListType": "SourceList", "r__dataExtension_key": "testExisting_dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/emailSend/testNew_emailSend.emailSend-meta.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CreatedDate": "2022-11-14T12:27:29.963", "CustomerKey": "testNew_emailSend", "DeduplicateByEmail": false, "Description": "created on deploy", "DynamicEmailSubject": "testExisting_asset_email", "EmailSubject": "testExisting_asset_email", "ExclusionFilter": "", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "ModifiedDate": "2022-11-14T12:27:29.963", "Name": "testNew_emailSend", "SendDefinitionList": [ { "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "SendDefinitionListType": "SourceList", "r__dataExtension_key": "testExisting_dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/event/testExisting_event.event-meta.json ================================================ { "type": "APIEvent", "name": "testExisting_event", "description": "updated on deploy", "mode": "Production", "eventDefinitionKey": "testExisting_event", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": 18, "isNullable": false, "isPrimaryKey": true }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Datestamp", "dataType": "Date", "defaultValue": "GetDate()", "isNullable": true, "isPrimaryKey": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "AddedField", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "isVisibleInPicker": true, "r__dataExtension_key": "testExisting_event - 2024-07-05T080154625" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/event/testNew_event_withExistingDE.event-meta.json ================================================ { "type": "APIEvent", "name": "testNew_event_withExistingDE", "description": "created on deploy", "createdDate": "0001-01-01T00:00:00", "createdBy": 0, "modifiedDate": "0001-01-01T00:00:00", "modifiedBy": 0, "eventDefinitionKey": "testNew_event_withExistingDE", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "arguments": { "serializedObjectType": 11 }, "metaData": {}, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000", "r__dataExtension_key": "testExisting_event - 2024-07-05T080154625" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/event/testNew_event_withSchema.event-meta.json ================================================ { "type": "APIEvent", "name": "testNew_event_withSchema", "description": "created on deploy", "mode": "Production", "eventDefinitionKey": "testNew_event_withSchema", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": 18, "isNullable": false, "isPrimaryKey": true }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Datestamp", "dataType": "Date", "defaultValue": "GetDate()", "isNullable": true, "isPrimaryKey": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "isVisibleInPicker": true } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/fileLocation/ExactTarget Enhanced FTP.fileLocation-meta.json ================================================ { "name": "ExactTarget Enhanced FTP", "customerKey": "ExactTarget Enhanced FTP", "c__locationType": "Enhanced FTP Site Import Directory" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/fileLocation/testExisting_fileLocation_aws.fileLocation-meta.json ================================================ { "name": "testExisting_fileLocation_aws_name", "customerKey": "testExisting_fileLocation_aws", "description": "updated via deploy", "awsFileTransferLocation": { "regionName": "eucentral1", "transferAccelerationEnabled": false, "accessKeyId": "key-id", "relativePath": "my/path", "bucketName": "bucket-name", "authType": "AccessKey" }, "c__locationType": "Amazon Simple Storage Service" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/fileLocation/testExisting_fileLocation_exsftp.fileLocation-meta.json ================================================ { "name": "testExisting_fileLocation_exsftp_name", "customerKey": "testExisting_fileLocation_exsftp", "description": "updated via deploy", "sFtpFileTransferLocation": { "portNumber": 22, "userName": "abc", "url": "sftp://test.com", "authType": "Password" }, "c__locationType": "External SFTP Site" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/fileTransfer/testExisting_fileTransfer.fileTransfer-meta.json ================================================ { "createdDate": "2022-11-09T05:31:56.477", "customerKey": "testExisting_fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%% updated via deploy", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "modifiedDate": "2022-11-17T07:13:20.05", "name": "testExisting_fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/fileTransfer/testNew_fileTransfer.fileTransfer-meta.json ================================================ { "createdDate": "2022-11-09T05:31:56.477", "customerKey": "testNew_fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%% created on deploy", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "modifiedDate": "2022-11-17T07:13:20.05", "name": "testNew_fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/filter/testExisting_filter.filter-meta.json ================================================ { "customerKey": "testExisting_filter", "name": "testExisting_filter", "description": "updated on deploy", "statusId": 1, "r__dataFilter_key": "testExisting_dataFilter", "r__destination_dataExtension_key": "testExisting_dataExtension_exclusion", "r__source_dataExtension_key": "testExisting_dataExtension", "r__folder_Path": "Filter" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/filter/testNew_filter.filter-meta.json ================================================ { "customerKey": "testNew_filter", "name": "testNew_filter", "description": "created via deploy", "modifiedDate": "2026-01-28T10:14:46.717", "statusId": 1, "r__dataFilter_key": "testExisting_dataFilter", "r__destination_dataExtension_key": "testExisting_dataExtension_exclusion", "r__source_dataExtension_key": "testExisting_dataExtension", "r__folder_Path": "Filter/filterSubfolder" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/importFile/testExisting_importFile.importFile-meta.json ================================================ { "allowErrors": true, "createdDate": "2022-11-09T05:32:30.533", "customerKey": "testExisting_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "updated on deploy", "encodingName": "utf-8", "fieldMappingType": "InferFromColumnHeadings", "fieldMappings": [], "fileNamingPattern": "blabla", "fileTransferLocationTypeId": 0, "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "modifiedDate": "2022-11-17T07:13:03.95", "name": "testExisting_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "c__blankFileProcessing": "Process", "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/importFile/testNew_importFile.importFile-meta.json ================================================ { "allowErrors": true, "createdDate": "2022-11-09T05:32:30.533", "customerKey": "testNew_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "created via deploy", "fieldMappingType": "InferFromColumnHeadings", "fieldMappings": [], "fileNamingPattern": "blabla", "fileTransferLocationTypeId": 0, "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "modifiedDate": "2022-11-17T07:13:03.95", "name": "testNew_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "c__subscriberImportType": "DataExtension", "c__dataAction": "AddUpdate", "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testExisting_journey_Multistep.journey-meta.json ================================================ { "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "r__triggeredSend_key": "testExisting_triggeredSend", "triggeredSend": { "autoAddSubscribers": false, "autoUpdateSubscribers": false, "bccEmail": [], "ccEmail": [], "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "You are successfully unsubscribed", "emailSubject": "You are successfully unsubscribed", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": false, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "suppressTracking": false, "triggeredSendStatus": "New", "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "Medium", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message", "r__triggeredSend_key": "testExisting_triggeredSend" } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testExisting_journey_Quicksend.journey-meta.json ================================================ { "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "updated on deploy", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "id": "e20dcaa3-a750-44cf-9ce8-42d00378b8b4", "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "description": "my activity info text", "dynamicEmailSubject": "testExisting_ email subject", "emailSubject": "testExisting_ email subject", "exclusionFilter": "/* insert ampscript here */", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/testExisting_suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["testExisting_DomainExclusion"] }, "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "High", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "eventDefinitionKey": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testExisting_journey_updatecontact.journey-meta.json ================================================ { "key": "testExisting_journey_updatecontact", "name": "testExisting_journey_updatecontact", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "r__dataExtension_key": "testExisting_dataExtension", "r__dataExtensionField_name": "LastName", "value": "TEST" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testExisting_journey_updatecontact_sharedDE.journey-meta.json ================================================ { "key": "testExisting_journey_updatecontact_sharedDE", "name": "testExisting_journey_updatecontact_sharedDE", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "r__dataExtension_key": "testExisting_dataExtensionShared", "r__dataExtensionField_name": "LastName", "value": "TEST" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testExisting_temail.journey-meta.json ================================================ { "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2022-03-24T02:20:32.74", "modifiedDate": "2022-03-24T02:20:40.45", "activities": [ { "id": "9606bcb0-9246-4610-9800-963bc77fc20a", "key": "EMAILV2-4", "name": "testExisting_temail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "1f44021a-74ac-49be-a07c-67862228214d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [], "ccEmail": [], "created": {}, "domainExclusions": [], "dynamicEmailSubject": "test email", "emailSubject": "test email", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "Default", "r__sendClassification_key": "Default Transactional", "c__priority": "Medium", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "r__transactionalEmail_key": "testExisting_temail" }, "metaData": { "highThroughput": { "r__dataExtension_key": "testExisting_dataExtension" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "status": "Published", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testExisting_temail_notPublished.journey-meta.json ================================================ { "activities": [ { "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "r__transactionalEmail_key": "testExisting_temail_notPublished", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [], "c__priority": "Medium", "ccEmail": [], "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isMultipart": true, "isSalesforceTracking": true, "isSendLogging": false, "isStoppedOnJobError": false, "isTrackingClicks": true, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__sendClassification_key": "Default Transactional", "r__senderProfile_key": "Default", "throttleCloses": "1/1/0001 12:00:00 AM", "throttleOpens": "1/1/0001 12:00:00 AM" } }, "description": "", "id": "4ae63473-ea1e-4963-a257-6fea45a9038a", "key": "EMAILV2-3", "metaData": { "highThroughput": { "r__dataExtension_key": "testExisting_temail_notPublished" }, "isConfigured": true, "sections": {} }, "name": "my email activity", "outcomes": [ { "arguments": {}, "key": "067f20ba-af36-4401-99d8-934100e1935d", "metaData": { "invalid": false } } ], "schema": { "arguments": { "activityId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "contactId": { "access": "Hidden", "dataType": "Number", "direction": "In", "isNullable": true, "readOnly": false }, "contactKey": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": false, "readOnly": false }, "customObjectKey": { "access": "Hidden", "dataType": "LongNumber", "direction": "In", "isNullable": true, "readOnly": true }, "definitionId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": true }, "definitionInstanceId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": false, "readOnly": false }, "emailAddress": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": false, "readOnly": false }, "emailSubjectDataBound": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": true }, "eventData": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "fieldType": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "messageKey": { "access": "Hidden", "dataType": "Text", "direction": "Out", "isNullable": true, "readOnly": false }, "obfuscationProperties": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "requestID": { "access": "Hidden", "dataType": "Text", "direction": "Out", "isNullable": true, "readOnly": false }, "sourceCustomObjectId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "sourceCustomObjectKey": { "access": "Hidden", "dataType": "LongNumber", "direction": "In", "isNullable": true, "readOnly": false } } }, "type": "EMAILV2" } ], "channel": "email", "createdDate": "2024-08-23T01:29:33.233", "defaults": { "properties": {} }, "definitionType": "Transactional", "description": "", "entryMode": "MultipleEntries", "executionMode": "Production", "exits": [], "goals": [], "key": "testExisting_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "modifiedDate": "2024-08-23T02:00:44.57", "name": "testExisting_temail_notPublished", "notifiers": [], "r__folder_Path": "my journeys", "scheduledStatus": "Draft", "status": "Published", "triggers": [ { "arguments": {}, "configurationArguments": {}, "description": "", "key": "TRIGGER", "metaData": { "category": "Transactional", "chainType": "none", "configurationRequired": false, "entrySourceGroupConfigUrl": "null", "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event" }, "name": "TRIGGER", "outcomes": [], "type": "transactional-api" } ], "version": 1, "workflowApiVersion": 1 } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/journey/testNew_temail_notPublished.journey-meta.json ================================================ { "key": "testNew_temail_notPublished", "name": "testNew_temail_notPublished", "description": "", "workflowApiVersion": 1, "modifiedDate": "2024-12-06T19:36:30.563", "activities": [ { "id": "848d91be-faa5-4307-94d7-22c9a5bcfb1d", "key": "EMAILV2-1", "name": "testNew_temail_notPublished_24Q3", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "920e8b4c-1598-48d0-b2c4-8a5072e0b738", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [], "c__priority": "Medium", "ccEmail": [], "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isMultipart": true, "isSalesforceTracking": true, "isSendLogging": false, "isStoppedOnJobError": false, "isTrackingClicks": true, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "r__asset_key": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile", "throttleCloses": "1/1/0001 12:00:00 AM", "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM" }, "r__transactionalEmail_key": "testNew_temail_notPublished" }, "metaData": { "highThroughput": { "r__dataExtension_key": "testExisting_dataExtension" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileKeyword/4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.amp ================================================ line1 line2 ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileKeyword/4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.json ================================================ { "c__codeKeyword": "4912312345678.TESTNEW_KEYWORD", "r__mobileCode_key": "4912312345678", "status": "Active", "restriction": "NONE", "keywordType": "STOP", "isInherited": false } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileKeyword/4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.amp ================================================ line1 line2 ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileKeyword/4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.json ================================================ { "c__codeKeyword": "4912312345678.TESTNEW_KEYWORD_BLOCKED", "r__mobileCode_key": "4912312345678", "status": "Active", "restriction": "NONE", "keywordType": "NORMAL", "isInherited": false } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.amp ================================================ test message jb new ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.json ================================================ { "id": "NTIzOjc4OjA", "lastUpdated": "2023-03-08T16:30:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testExisting_mobileMessage", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "r__campaign_key": ["testExisting_campaign"], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileMessage/new.mobileMessage-meta.amp ================================================ New Task Available ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/mobileMessage/new.mobileMessage-meta.json ================================================ { "id": "new", "lastUpdated": "2020-07-03T06:39:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testNew_mobileMessage", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "r__campaign_key": ["testExisting_campaign"], "mtSendDate": "2017-07-03T14:03:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "OneUserOneDevice_DEV - 93", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "M09MU3o1YnRMVS1GNHppZTdCRDVCdzo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "58d59e53-f85f-e711-80cc-1402ec7222b4", "fromName": "PMI_DEV", "concatenateMessage": false, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json ================================================ { "name": "testExisting_query", "key": "testExisting_query", "description": "updated on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.sql ================================================ SELECT SubscriberKey as testField FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json ================================================ { "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixKeys", "description": "updated on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql ================================================ SELECT SubscriberKey as testField FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/query/testNew_query.query-meta.json ================================================ { "name": "testNew_query", "key": "testNew_query", "description": "created on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/query/testNew_query.query-meta.sql ================================================ SELECT SubscriberKey as testField FROM _Subscribers ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json ================================================ { "description": "updated on deploy", "key": "testExisting_script", "name": "testExisting_script", "r__folder_Path": "Scripts" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs ================================================ // dummy updated ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json ================================================ { "description": "created on deploy", "key": "testNew_script", "name": "testNew_script", "r__folder_Path": "Scripts" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs ================================================ // dummy created ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/sendClassification/testExisting_sendClassification.sendClassification-meta.json ================================================ { "CustomerKey": "testExisting_sendClassification", "Name": "testExisting_sendClassification", "Description": "updated on deploy", "c__classification": "Commercial", "r__senderProfile_key": "testExisting_senderProfile", "r__deliveryProfile_key": "Default" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/sendClassification/testNew_sendClassification.sendClassification-meta.json ================================================ { "CustomerKey": "testNew_sendClassification", "Name": "testNew_sendClassification", "Description": "created on deploy", "c__classification": "Commercial", "r__senderProfile_key": "testExisting_senderProfile", "r__deliveryProfile_key": "Default" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/senderProfile/testExisting_senderProfile.senderProfile-meta.json ================================================ { "CustomerKey": "testExisting_senderProfile", "Name": "testExisting_senderProfile", "Description": "updated via deploy", "FromName": "Jörn Berkefeld", "FromAddress": "joern.berkefeld@accenture.com", "FallbackFromAddress": "", "UseDefaultRMMRules": false, "AutoForwardToEmailAddress": "joern.berkefeld@accenture.com", "AutoForwardToName": "Jörn Berkefeld", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/senderProfile/testNew_senderProfile.senderProfile-meta.json ================================================ { "CustomerKey": "testNew_senderProfile", "Name": "testNew_senderProfile", "Description": "created on deploy", "FromName": "Jörn Berkefeld", "FromAddress": "joern.berkefeld@accenture.com", "FallbackFromAddress": "joern.berkefeld.New@accenture.com", "UseDefaultRMMRules": false, "AutoForwardToEmailAddress": "joern.berkefeld@accenture.com", "AutoForwardToName": "Jörn Berkefeld", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json ================================================ { "name": "testExisting_temail", "definitionKey": "testExisting_temail", "description": "updated via deploy", "classification": "Default Transactional", "status": "Active", "createdDate": "2020-09-10T03:29:00", "modifiedDate": "2020-09-10T03:29:00", "subscriptions": { "dataExtension": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__journey_key": "testExisting_interaction", "r__asset_key": "testExisting_asset_message" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testNew_temail.transactionalEmail-meta.json ================================================ { "name": "testNew_temail", "definitionKey": "testNew_temail", "description": "created on deploy", "classification": "Default Transactional", "status": "Active", "createdDate": "2020-09-10T03:29:00", "modifiedDate": "2020-09-10T03:29:00", "subscriptions": { "dataExtension": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__asset_key": "testExisting_asset_message" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalPush/testExisting_tpush.transactionalPush-meta.json ================================================ { "definitionKey": "testExisting_tpush", "name": "testExisting_tpush", "status": "Active", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "description": "updated via deploy; note that applicationId can only be manually set up in Setup - Mobile Push", "r__asset_key": "mobileMessage_test", "options": { "sound": "temp.wmv", "badge": "1", "customKeys": [ { "key": "key1", "value": "value1" }, { "key": "key2", "value": "value2" } ] } } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalPush/testNew_tpush.transactionalPush-meta.json ================================================ { "definitionKey": "testNew_tpush", "name": "testNew_tpush", "status": "Active", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "description": "created on deploy; note that applicationId can only be manually set up in Setup - Mobile Push", "r__asset_key": "mobileMessage_test", "options": { "sound": "temp.wmv", "badge": "1", "customKeys": [ { "key": "key1", "value": "value1" }, { "key": "key2", "value": "value2" } ] } } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testExisting_tsms.transactionalSMS-meta.amp ================================================ %%[ SET @key = 'secret' ]%% ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testExisting_tsms.transactionalSMS-meta.json ================================================ { "name": "testExisting_tsms", "definitionKey": "testExisting_tsms", "description": "bla bla", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.TESTEXISTING_KEYWORD" } } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testNew_tsms.transactionalSMS-meta.amp ================================================ %%[ SET @key = 'secret' ]%% ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testNew_tsms.transactionalSMS-meta.json ================================================ { "name": "testNew_tsms", "definitionKey": "testNew_tsms", "description": "created on deploy", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.TESTEXISTING_KEYWORD" } } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/triggeredSend/testExisting_triggeredSend.triggeredSend-meta.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testExisting_triggeredSend", "Description": "updated on deploy", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testExisting_triggeredSend", "NewSlotTrigger": 0, "Priority": 4, "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__email_name": "Sporting Goods for September", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/triggeredSend/testNew_triggeredSend.triggeredSend-meta.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testNew_triggeredSend", "Description": "created on deploy", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testNew_triggeredSend", "NewSlotTrigger": 0, "Priority": 4, "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__email_name": "Sporting Goods for September", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/verification/testExisting_automation__s1.7.verification-meta.json ================================================ { "c__automation_step": "testExisting_automation__s1.7", "notificationEmailAddress": "test@accenture.com", "notificationEmailMessage": "", "r__dataExtension_key": "testExisting_dataExtension", "shouldEmailOnFailure": true, "shouldStopOnFailure": true, "value1": 1, "value2": 0, "verificationType": "IsEqualTo" } ================================================ FILE: test/mockRoot/deploy/testInstance/testBU/verification/testNew_automation__s1.7.verification-meta.json ================================================ { "c__automation_step": "testNew_automation__s1.7", "notificationEmailAddress": "", "notificationEmailMessage": "", "r__dataExtension_key": "testExisting_dataExtension", "shouldEmailOnFailure": false, "shouldStopOnFailure": false, "value1": 2, "value2": 0, "verificationType": "IsEqualTo" } ================================================ FILE: test/resourceFactory.js ================================================ import fs from 'fs-extra'; import path from 'node:path'; import { XMLParser } from 'fast-xml-parser'; import { Util } from '../lib/util/util.js'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const projectRootHelper = __dirname.split(path.sep); projectRootHelper.pop(); const projectRoot = projectRootHelper.join(path.sep) + path.sep; const parser = new XMLParser(); const attributeParser = new XMLParser({ ignoreAttributes: false }); /** @type {typeof Util.color} */ const color = Util.color; export const tWarn = `${color.bgYellow}${color.fgBlack}TEST-WARNING${color.reset}`; export const tError = `${color.bgRed}${color.fgBlack}TEST-ERROR${color.reset}`; const loadingFile = 'loading server file:///'; /** * gets mock SOAP metadata for responding * * @param {string} mcdevAction SOAP action * @param {string} type metadata Type * @param {string} mid of Business Unit * @param {object|string} filter likely for customer key * @param {boolean} [QueryAllAccounts] get data from other BUs or not * @returns {Promise.<string>} relevant metadata stringified */ async function loadSOAPRecords(mcdevAction, type, mid, filter, QueryAllAccounts) { type = type[0].toLowerCase() + type.slice(1); const testPath = path.join('test', 'resources', mid.toString(), type, mcdevAction); const filterPath = getFilterPath(filter, QueryAllAccounts); if (await fs.pathExists(testPath + filterPath + '-response.xml')) { console.log(loadingFile + projectRoot + testPath + filterPath + '-response.xml'); // eslint-disable-line no-console return fs.readFile(testPath + filterPath + '-response.xml', { encoding: 'utf8', }); } else if (await fs.pathExists(testPath + '-response.xml')) { if (filterPath) { /* eslint-disable no-console */ console.log( `${tWarn}: You are loading your reponse from ${ testPath + '-response.xml' } instead of the more specific ${ testPath + filterPath + '-response.xml' }. Make sure this is intended` ); /* eslint-enable no-console */ } console.log(loadingFile + projectRoot + testPath + '-response.xml'); // eslint-disable-line no-console return fs.readFile(testPath + '-response.xml', { encoding: 'utf8', }); } /* eslint-disable no-console */ console.log( `${tError}: Please create file ${ filterPath ? testPath + filterPath + '-response.xml or ' : '' }${testPath + '-response.xml'}` ); /* eslint-enable no-console */ // return error process.exitCode = 404; return fs.readFile(path.join('test', 'resources', mcdevAction + '-response.xml'), { encoding: 'utf8', }); } /** * helper for {@link loadSOAPRecords} to get the filter path * * @param {object|string} filter likely for customer key * @param {boolean} [QueryAllAccounts] get data from other BUs or not * @param {number} [shorten] number of characters to shorten filters by to match windows max file length of 256 chars * @returns {string} filterPath value */ function getFilterPath(filter, QueryAllAccounts, shorten) { const filterPath = (typeof filter === 'string' && filter ? '-' + filter : filterToPath(filter, shorten)) + (QueryAllAccounts ? '-QAA' : ''); if ((filterPath + '-response.xml').length > 256) { shorten ||= 10; return getFilterPath(filter, QueryAllAccounts, shorten - 1); } else { return filterPath; } } /** * main filter to path function * * @param {object} filter main filter object * @param {string} filter.Property field name * @param {string} filter.SimpleOperator string representation of the comparison method * @param {string} filter.Value field value to check for * @param {object} filter.LeftOperand contains a filter object itself * @param {'AND'|'OR'} filter.LogicalOperator string representation of the comparison method * @param {object} filter.RightOperand field value to check for * @param {number} [shorten] number of characters to shorten filters by to match windows max file length of 256 chars * @returns {string} string represenation of the entire filter */ export function filterToPath(filter, shorten) { if (filter) { return '-' + _filterToPath(filter, shorten); } return ''; } /** * helper for filterToPath * * @param {object} filter main filter object * @param {string} filter.Property field name * @param {string} filter.SimpleOperator string representation of the comparison method * @param {string} filter.Value field value to check for * @param {object} filter.LeftOperand contains a filter object itself * @param {'AND'|'OR'} filter.LogicalOperator string representation of the comparison method * @param {object} filter.RightOperand field value to check for * @param {number} [shorten] number of characters to shorten filters by to match windows max file length of 256 chars * @returns {string} string represenation of the entire filter */ function _filterToPath(filter, shorten) { if (filter.Property && filter.SimpleOperator) { let value; if (filter.Value === undefined) { value = ''; } else if (Array.isArray(filter.Value)) { value = shorten ? filter.Value.map((val) => val.slice(0, Math.max(0, shorten))).join(',') : filter.Value.join(','); } else { value = shorten ? filter.Value.slice(0, Math.max(0, shorten)) : filter.Value; } return `${filter.Property}${filter.SimpleOperator.replace('equals', '=')}${value}`; } else if (filter.LeftOperand && filter.LogicalOperator && filter.RightOperand) { return ( _filterToPath(filter.LeftOperand, shorten) + filter.LogicalOperator + _filterToPath(filter.RightOperand, shorten) ); } else { throw new Error('unknown filter type'); } } /** * based on request, respond with different soap data * * @param {object} config mock api request object * @returns {Promise.<Array>} status code plus response in string form */ export const handleSOAPRequest = async (config) => { const jObj = parser.parse(config.data); const fullObj = attributeParser.parse(config.data); let responseXML; switch (config.headers.SOAPAction) { case 'Retrieve': { responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), jObj.Envelope.Body.RetrieveRequestMsg.RetrieveRequest.ObjectType, jObj.Envelope.Header.fueloauth, jObj.Envelope.Body.RetrieveRequestMsg.RetrieveRequest.Filter, jObj.Envelope.Body.RetrieveRequestMsg.RetrieveRequest.QueryAllAccounts ); break; } case 'Create': { let filter = null; if (fullObj.Envelope.Body.CreateRequest.Objects['@_xsi:type'] === 'DataFolder') { filter = `ContentType=${fullObj.Envelope.Body.CreateRequest.Objects.ContentType},Name=${fullObj.Envelope.Body.CreateRequest.Objects.Name},ParentFolderID=${fullObj.Envelope.Body.CreateRequest.Objects.ParentFolder.ID}`; } responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), fullObj.Envelope.Body.CreateRequest.Objects['@_xsi:type'], jObj.Envelope.Header.fueloauth, filter ); break; } case 'Update': { responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), fullObj.Envelope.Body.UpdateRequest.Objects['@_xsi:type'], jObj.Envelope.Header.fueloauth, null ); break; } case 'Configure': { responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), fullObj.Envelope.Body.ConfigureRequestMsg.Configurations.Configuration[0][ '@_xsi:type' ], jObj.Envelope.Header.fueloauth, null ); break; } case 'Delete': { responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), fullObj.Envelope.Body.DeleteRequest.Objects['@_xsi:type'], jObj.Envelope.Header.fueloauth, null ); break; } case 'Schedule': { responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), fullObj.Envelope.Body.ScheduleRequestMsg.Interactions.Interaction['@_xsi:type'], jObj.Envelope.Header.fueloauth, fullObj.Envelope.Body.ScheduleRequestMsg.Interactions.Interaction.ObjectID ); break; } case 'Perform': { responseXML = await loadSOAPRecords( config.headers.SOAPAction.toLocaleLowerCase(), fullObj.Envelope.Body.PerformRequestMsg.Definitions.Definition['@_xsi:type'], jObj.Envelope.Header.fueloauth, fullObj.Envelope.Body.PerformRequestMsg.Definitions.Definition.ObjectID ); break; } default: { throw new Error( `The SOAP Action ${config.headers.SOAPAction} is not supported by test handler` ); } } return [200, responseXML]; }; /** * helper to return soap base URL * * @returns {string} soap URL */ export const soapUrl = 'https://mct0l7nxfq2r988t1kxfy8sc4xxx.soap.marketingcloudapis.com/Service.asmx'; /** * based on request, respond with different soap data * * @param {object} config mock api request object * @returns {Promise.<Array>} status code plus response in string form */ export const handleRESTRequest = async (config) => { try { // check if filtered const urlObj = new URL( config.baseURL + (config.url.startsWith('/') ? config.url.slice(1) : config.url) ); let filterName; let filterBody; if (urlObj.searchParams.get('$filter')) { filterName = urlObj.searchParams.get('$filter').split(' eq ')[1]; } else if (urlObj.searchParams.get('action')) { filterName = urlObj.searchParams.get('action'); } else if (urlObj.searchParams.get('mostRecentVersionOnly')) { filterName = 'mostRecentVersionOnly'; } else if (urlObj.searchParams.get('versionNumber')) { filterName = 'versionNumber'; } else if (urlObj.searchParams.get('status')) { filterName = 'status'; } else if (urlObj.searchParams.get('id')) { filterName = 'id'; } const testPath = path .join( 'test', 'resources', config.headers.Authorization.replace('Bearer ', ''), urlObj.pathname, config.method + '-response' ) .replace(':', '_'); // replace : with _ for Windows const testPathFilter = filterName ? testPath + '-' + (urlObj.searchParams.get('$filter') || urlObj.searchParams.get('action') || '') .replaceAll(' eq ', '=') .replaceAll(' ', '') + (urlObj.searchParams.get('id') ? 'id=' + urlObj.searchParams.get('id') : '') + (urlObj.searchParams.get('versionNumber') ? 'versionNumber=' + urlObj.searchParams.get('versionNumber') : '') + (urlObj.searchParams.get('mostRecentVersionOnly') ? 'mostRecentVersionOnly=' + urlObj.searchParams.get('mostRecentVersionOnly') : '') + (urlObj.searchParams.get('status') ? 'status=' + urlObj.searchParams.get('status') : '') : null; if (!testPathFilter && config.method === 'post' && config.data) { const simpleOperators = { equal: '=', in: 'IN' }; const data = JSON.parse(config.data); const myObj = data.query?.rightOperand || data.query; if (myObj) { const op = simpleOperators[myObj.simpleOperator]; filterBody = `${myObj.property}${op}${op === 'IN' ? myObj.value.join(',') : myObj.value}`; } else if (config.url === '/email/v1/category') { const data = JSON.parse(config.data); filterBody = Object.keys(data) .map((key) => `${key}=${data[key]}`) .join(','); } else if (config.url === '/asset/v1/content/assets/') { const data = JSON.parse(config.data); if (data.customerKey) { filterBody = 'key=' + data.customerKey; } } } const testPathFilterBody = filterBody ? testPath + '-' + filterBody : null; if (testPathFilter && (await fs.pathExists(testPathFilter + '.json'))) { // build filter logic to ensure templating works if (filterName) { const response = JSON.parse( await fs.readFile(testPathFilter + '.json', { encoding: 'utf8', }) ); if ( response.items && filterName !== 'mostRecentVersionOnly' && filterName !== 'versionNumber' && filterName !== 'id' && filterName !== 'status' ) { response.items = response.items.filter((def) => def.name == filterName); } console.log(loadingFile + projectRoot + testPathFilter + '.json'); // eslint-disable-line no-console return [200, JSON.stringify(response)]; } else { console.log(loadingFile + projectRoot + testPathFilter + '.json'); // eslint-disable-line no-console return [ 200, await fs.readFile(testPathFilter + '.json', { encoding: 'utf8', }), ]; } } else if (testPathFilter && (await fs.pathExists(testPathFilter + '.txt'))) { console.log(loadingFile + projectRoot + testPathFilter + '.txt'); // eslint-disable-line no-console return [ 200, await fs.readFile(testPathFilter + '.txt', { encoding: 'utf8', }), ]; } else if (testPathFilterBody && (await fs.pathExists(testPathFilterBody + '.json'))) { console.log(loadingFile + projectRoot + testPathFilterBody + '.json'); // eslint-disable-line no-console return [ 200, await fs.readFile(testPathFilterBody + '.json', { encoding: 'utf8', }), ]; } else if (testPathFilterBody && (await fs.pathExists(testPathFilterBody + '.txt'))) { console.log(loadingFile + projectRoot + testPathFilterBody + '.txt'); // eslint-disable-line no-console return [ 200, await fs.readFile(testPathFilterBody + '.txt', { encoding: 'utf8', }), ]; } else if (await fs.pathExists(testPath + '.json')) { if (testPathFilter) { /* eslint-disable no-console */ console.log( `${tWarn}: You are loading your reponse from ${ testPath + '.json' } instead of the more specific ${ testPathFilter + '.json' }. Make sure this is intended` ); /* eslint-enable no-console */ } if (testPathFilterBody) { /* eslint-disable no-console */ console.log( `${tWarn}: You are loading your reponse from ${ testPath + '.json' } instead of the more specific ${ testPathFilterBody + '.json' }. Make sure this is intended` ); /* eslint-enable no-console */ } // build filter logic to ensure templating works if ( filterName && filterName !== 'mostRecentVersionOnly' && filterName !== 'versionNumber' && filterName !== 'id' && filterName !== 'status' ) { const response = JSON.parse( await fs.readFile(testPath + '.json', { encoding: 'utf8', }) ); response.items = response.items.filter((def) => def.name == filterName); response.count = response.items.length; console.log(loadingFile + projectRoot + testPath + '.json'); // eslint-disable-line no-console return [200, JSON.stringify(response)]; } else { console.log(loadingFile + projectRoot + testPath + '.json'); // eslint-disable-line no-console return [ 200, await fs.readFile(testPath + '.json', { encoding: 'utf8', }), ]; } } else if (await fs.pathExists(testPath + '.txt')) { if (testPathFilter) { /* eslint-disable no-console */ console.log( `${tWarn}: You are loading your reponse from ${ testPath + '.txt' } instead of the more specific ${ testPathFilter + '.txt' }. Make sure this is intended` ); /* eslint-enable no-console */ } if (testPathFilterBody) { /* eslint-disable no-console */ console.log( `${tWarn}: You are loading your reponse from ${ testPath + '.txt' } instead of the more specific ${ testPathFilterBody + '.txt' }. Make sure this is intended` ); /* eslint-enable no-console */ } console.log(loadingFile + projectRoot + testPath + '.txt'); // eslint-disable-line no-console return [ 200, await fs.readFile(testPath + '.txt', { encoding: 'utf8', }), ]; } else { /* eslint-disable no-console */ console.log( `${tError}: Please create file ${testPath}.json/.txt${filterName ? ` or ${testPathFilter}.json/.txt` : testPathFilterBody ? ` or ${testPathFilterBody}.json/.txt` : ''}` ); /* eslint-enable no-console */ process.exitCode = 404; return [ 404, await fs.readFile(path.join('test', 'resources', 'rest404-response.json'), { encoding: 'utf8', }), ]; } } catch (ex) { console.log(ex); // eslint-disable-line no-console return [500, {}]; } }; /** * helper to return rest base URL * * @returns {string} test URL */ export const restUrl = 'https://mct0l7nxfq2r988t1kxfy8sc4xxx.rest.marketingcloudapis.com/'; ================================================ FILE: test/resources/1111111/accountUser/configure-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>ConfigureResponse</wsa:Action> <wsa:MessageID>urn:uuid:4838c660-b4cd-48fe-99c9-27972a520184</wsa:MessageID> <wsa:RelatesTo>urn:uuid:ec22f28d-4bc7-4ffc-b3e9-4e731f82c095</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-419f984d-fb1b-49eb-a090-b0c08d8b11f9"> <wsu:Created>2023-03-13T15:58:44Z</wsu:Created> <wsu:Expires>2023-03-13T16:03:44Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <ConfigureResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <Result> <StatusCode>OK</StatusCode> <StatusMessage>User Business Unit assignments successfully updated</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="AccountUser"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <ID>717510285</ID> <ObjectID xsi:nil="true" /> <Delete>0</Delete> <BusinessUnitAssignmentConfiguration> <BusinessUnitIds> <BusinessUnitId>1111111</BusinessUnitId> <BusinessUnitId>9999999</BusinessUnitId> </BusinessUnitIds> <IsDelete>false</IsDelete> </BusinessUnitAssignmentConfiguration> </Object> </Result> <Result> <StatusCode>OK</StatusCode> <StatusMessage>User Business Unit assignments successfully updated</StatusMessage> <OrdinalID>1</OrdinalID> <Object xsi:type="AccountUser"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <ID>700301950</ID> <ObjectID xsi:nil="true" /> <Delete>0</Delete> <BusinessUnitAssignmentConfiguration> <BusinessUnitIds> <BusinessUnitId>1111111</BusinessUnitId> </BusinessUnitIds> <IsDelete>true</IsDelete> </BusinessUnitAssignmentConfiguration> </Object> </Result> </Results> <OverallStatus>OK</OverallStatus> <OverallStatusMessage /> <RequestID>abc28dae-6dfb-4ae9-ad07-63c74963c6d9</RequestID> </ConfigureResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:545e5b90-8e55-4c57-ac1d-5d675fe15041</wsa:MessageID> <wsa:RelatesTo>urn:uuid:9c5f9d10-a638-41d2-ad35-b1d1cdc097a8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-19e06319-84b9-4b38-a12c-7c40b1eb5f3e"> <wsu:Created>2023-03-12T00:40:30Z</wsu:Created> <wsu:Expires>2023-03-12T00:45:30Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Account User Updated / Created</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <Object xsi:type="AccountUser"> <Client> <ID>1111111</ID> <ModifiedBy>123456</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <ID>717510285</ID> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_user</CustomerKey> <AccountUserID>700301950</AccountUserID> <UserID>testNew_user@accenture.asgr</UserID> <Password /> <Name>new user</Name> <Email>testNew_user@accenture.com</Email> <MustChangePassword>false</MustChangePassword> <ActiveFlag>true</ActiveFlag> <Delete>0</Delete> <IsAPIUser>false</IsAPIUser> <NotificationEmailAddress>testNew_user@accenture.com</NotificationEmailAddress> <IsLocked>false</IsLocked> <DefaultBusinessUnit>1111111</DefaultBusinessUnit> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-GB</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *</Name> </TimeZone> <Roles> <Role> <Client> <ID>1111111</ID> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <ObjectID>f1cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <Name>Administrator</Name> <AssignmentConfigurations> <AssignmentConfiguration> <AccountUserId>717510285</AccountUserId> <AssignmentConfigureType>RoleUser</AssignmentConfigureType> </AssignmentConfiguration> </AssignmentConfigurations> </Role> <Role> <Client> <ID>1111111</ID> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <ObjectID>fdcfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <Name>Distributed Sending User</Name> <AssignmentConfigurations> <AssignmentConfiguration> <AccountUserId>717510285</AccountUserId> <AssignmentConfigureType>RoleUser</AssignmentConfigureType> </AssignmentConfiguration> </AssignmentConfigurations> </Role> </Roles> </Object> </Results> <RequestID>84d01639-9b81-4a45-9928-bf438c0f86bf</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-QAA-response.xml ================================================ <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11</wsa:MessageID> <wsa:RelatesTo>urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-291db2ee-625d-49f7-8f6f-110317b081a5"> <wsu:Created>2023-03-11T13:53:00Z</wsu:Created> <wsu:Expires>2023-03-11T13:58:00Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>5347bf1d-e801-486a-b4a9-c2d46a8909b6</RequestID> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-QAA-response.xml ================================================ <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11</wsa:MessageID> <wsa:RelatesTo>urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-291db2ee-625d-49f7-8f6f-110317b081a5"> <wsu:Created>2023-03-11T13:53:00Z</wsu:Created> <wsu:Expires>2023-03-11T13:58:00Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>5347bf1d-e801-486a-b4a9-c2d46a8909b6</RequestID> <Results xsi:type="AccountUser"> <Client> <ID>1111111</ID> <ModifiedBy>123456</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-09-06T01:59:07.097</CreatedDate> <ModifiedDate>2022-06-21T01:43:02.64</ModifiedDate> <ID>700301951</ID> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_user_inactive</CustomerKey> <AccountUserID>700301951</AccountUserID> <UserID>user_test-inactive@accenture.asgr</UserID> <Name>user test-inactive</Name> <Email>user_test-inactive@accenture.com</Email> <MustChangePassword>false</MustChangePassword> <ActiveFlag>false</ActiveFlag> <UserPermissions> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <Name xsi:nil="true" /> <Value xsi:nil="true" /> <Description xsi:nil="true" /> <Delete>0</Delete> </UserPermissions> <UserPermissions> <PartnerKey xsi:nil="true" /> <ID>3</ID> <ObjectID xsi:nil="true" /> <Name xsi:nil="true" /> <Value xsi:nil="true" /> <Description xsi:nil="true" /> <Delete>0</Delete> </UserPermissions> <Delete>0</Delete> <LastSuccessfulLogin>2023-02-23T10:14:11.443</LastSuccessfulLogin> <IsAPIUser>false</IsAPIUser> <NotificationEmailAddress>user_test-inactive@accenture.com</NotificationEmailAddress> <IsLocked>false</IsLocked> <DefaultBusinessUnit>1111111</DefaultBusinessUnit> <DefaultBusinessUnitObject> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </DefaultBusinessUnitObject> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-GB</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *</Name> </TimeZone> <Roles> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f1cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_ADMIN</CustomerKey> <Name>Administrator</Name> <Description>Administrator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f4cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_CONTENT</CustomerKey> <Name>Content Creator</Name> <Description>Content Creator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-09-06T07:59:07.8</CreatedDate> <ModifiedDate>2019-09-06T07:59:07.8</ModifiedDate> <ObjectID>bd251431-7cd0-e911-a2d3-1402ec936979</ObjectID> <CustomerKey>Individual role for 700301951</CustomerKey> <Name>Individual role for 700301951</Name> <Description>Individual role for 700301951</Description> <IsPrivate>true</IsPrivate> <IsSystemDefined>false</IsSystemDefined> </Role> <Role> <Client> <ID>0</ID> <CreatedBy>0</CreatedBy> <ModifiedBy>0</ModifiedBy> <EnterpriseID>0</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2012-02-21T02:09:19.983</CreatedDate> <ModifiedDate>2013-12-23T16:48:50.533</ModifiedDate> <ObjectID>63a50610-315c-e111-beee-8e001800001f</ObjectID> <CustomerKey>SYS_DEF_IMHADMIN</CustomerKey> <Name>Marketing Cloud Administrator</Name> <Description>Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Hub Apps and Marketing Cloud Tools</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> </Roles> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-QAA-response.xml ================================================ <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11</wsa:MessageID> <wsa:RelatesTo>urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-291db2ee-625d-49f7-8f6f-110317b081a5"> <wsu:Created>2023-03-11T13:53:00Z</wsu:Created> <wsu:Expires>2023-03-11T13:58:00Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>5347bf1d-e801-486a-b4a9-c2d46a8909b6</RequestID> <Results xsi:type="AccountUser"> <Client> <ID>1111111</ID> <ModifiedBy>123456</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-09-06T01:59:07.097</CreatedDate> <ModifiedDate>2022-06-21T01:43:02.64</ModifiedDate> <ID>700301950</ID> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_user</CustomerKey> <AccountUserID>700301950</AccountUserID> <UserID>user_test@accenture.asgr</UserID> <Name>user test</Name> <Email>user_test@accenture.com</Email> <MustChangePassword>false</MustChangePassword> <ActiveFlag>true</ActiveFlag> <UserPermissions> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <Name xsi:nil="true" /> <Value xsi:nil="true" /> <Description xsi:nil="true" /> <Delete>0</Delete> </UserPermissions> <UserPermissions> <PartnerKey xsi:nil="true" /> <ID>3</ID> <ObjectID xsi:nil="true" /> <Name xsi:nil="true" /> <Value xsi:nil="true" /> <Description xsi:nil="true" /> <Delete>0</Delete> </UserPermissions> <Delete>0</Delete> <LastSuccessfulLogin>2023-02-23T10:14:11.443</LastSuccessfulLogin> <IsAPIUser>false</IsAPIUser> <NotificationEmailAddress>user_test@accenture.com</NotificationEmailAddress> <IsLocked>false</IsLocked> <DefaultBusinessUnit>1111111</DefaultBusinessUnit> <DefaultBusinessUnitObject> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </DefaultBusinessUnitObject> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-GB</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *</Name> </TimeZone> <Roles> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f1cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_ADMIN</CustomerKey> <Name>Administrator</Name> <Description>Administrator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f4cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_CONTENT</CustomerKey> <Name>Content Creator</Name> <Description>Content Creator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-09-06T07:59:07.8</CreatedDate> <ModifiedDate>2019-09-06T07:59:07.8</ModifiedDate> <ObjectID>bd251431-7cd0-e911-a2d3-1402ec936979</ObjectID> <CustomerKey>Individual role for 700301950</CustomerKey> <Name>Individual role for 700301950</Name> <Description>Individual role for 700301950</Description> <IsPrivate>true</IsPrivate> <IsSystemDefined>false</IsSystemDefined> </Role> <Role> <Client> <ID>0</ID> <CreatedBy>0</CreatedBy> <ModifiedBy>0</ModifiedBy> <EnterpriseID>0</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2012-02-21T02:09:19.983</CreatedDate> <ModifiedDate>2013-12-23T16:48:50.533</ModifiedDate> <ObjectID>63a50610-315c-e111-beee-8e001800001f</ObjectID> <CustomerKey>SYS_DEF_IMHADMIN</CustomerKey> <Name>Marketing Cloud Administrator</Name> <Description>Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Hub Apps and Marketing Cloud Tools</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> </Roles> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-QAA-response.xml ================================================ <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11</wsa:MessageID> <wsa:RelatesTo>urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-291db2ee-625d-49f7-8f6f-110317b081a5"> <wsu:Created>2023-03-11T13:53:00Z</wsu:Created> <wsu:Expires>2023-03-11T13:58:00Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>5347bf1d-e801-486a-b4a9-c2d46a8909b6</RequestID> <Results xsi:type="AccountUser"> <Client> <ID>1111111</ID> <ModifiedBy>0</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:37.42</CreatedDate> <ModifiedDate>2023-05-27T07:05:55.113</ModifiedDate> <ID>7471228</ID> <ObjectID xsi:nil="true" /> <CustomerKey>45372cbb-06e0-438e-88d8-008981f7a18b</CustomerKey> <AccountUserID>7471228</AccountUserID> <UserID>20f2d94a-9a7d-4580-9fb6-c36a1ce32fb9</UserID> <Name>igopredictiveemail app user</Name> <Email /> <MustChangePassword>false</MustChangePassword> <ActiveFlag>true</ActiveFlag> <Delete>0</Delete> <LastSuccessfulLogin></LastSuccessfulLogin> <IsAPIUser>true</IsAPIUser> <NotificationEmailAddress /> <IsLocked>false</IsLocked> <DefaultBusinessUnit>1111111</DefaultBusinessUnit> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-GB</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</Name> </TimeZone> <DefaultBusinessUnitObject> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </DefaultBusinessUnitObject> <Roles> <Role> <Client> <ID>1111111</ID> <CreatedBy>0</CreatedBy> <ModifiedBy>0</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:37.88</CreatedDate> <ModifiedDate>2016-07-22T17:52:37.88</ModifiedDate> <ObjectID>44d0b80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Individual role for 7471228</CustomerKey> <Name>Individual role for 7471228</Name> <Description>Individual role for 7471228</Description> <IsPrivate>true</IsPrivate> <IsSystemDefined>false</IsSystemDefined> </Role> </Roles> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-QAA-response.xml ================================================ <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11</wsa:MessageID> <wsa:RelatesTo>urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-291db2ee-625d-49f7-8f6f-110317b081a5"> <wsu:Created>2023-03-11T13:53:00Z</wsu:Created> <wsu:Expires>2023-03-11T13:58:00Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>5347bf1d-e801-486a-b4a9-c2d46a8909b6</RequestID> <Results xsi:type="AccountUser"> <Client> <ID>1111111</ID> <ModifiedBy>123456</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-09-06T01:59:07.097</CreatedDate> <ModifiedDate>2022-06-21T01:43:02.64</ModifiedDate> <ID>700301950</ID> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_user</CustomerKey> <AccountUserID>700301950</AccountUserID> <UserID>user_test@accenture.asgr</UserID> <Name>user test</Name> <Email>user_test@accenture.com</Email> <MustChangePassword>false</MustChangePassword> <ActiveFlag>true</ActiveFlag> <UserPermissions> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <Name xsi:nil="true" /> <Value xsi:nil="true" /> <Description xsi:nil="true" /> <Delete>0</Delete> </UserPermissions> <UserPermissions> <PartnerKey xsi:nil="true" /> <ID>3</ID> <ObjectID xsi:nil="true" /> <Name xsi:nil="true" /> <Value xsi:nil="true" /> <Description xsi:nil="true" /> <Delete>0</Delete> </UserPermissions> <Delete>0</Delete> <LastSuccessfulLogin>2023-02-23T10:14:11.443</LastSuccessfulLogin> <IsAPIUser>false</IsAPIUser> <NotificationEmailAddress>user_test@accenture.com</NotificationEmailAddress> <IsLocked>false</IsLocked> <DefaultBusinessUnit>1111111</DefaultBusinessUnit> <DefaultBusinessUnitObject> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </DefaultBusinessUnitObject> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-GB</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *</Name> </TimeZone> <Roles> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f1cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_ADMIN</CustomerKey> <Name>Administrator</Name> <Description>Administrator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f4cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_CONTENT</CustomerKey> <Name>Content Creator</Name> <Description>Content Creator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>1111111</ID> <CreatedBy>-1000</CreatedBy> <ModifiedBy>-1000</ModifiedBy> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-09-06T07:59:07.8</CreatedDate> <ModifiedDate>2019-09-06T07:59:07.8</ModifiedDate> <ObjectID>bd251431-7cd0-e911-a2d3-1402ec936979</ObjectID> <CustomerKey>Individual role for 700301950</CustomerKey> <Name>Individual role for 700301950</Name> <Description>Individual role for 700301950</Description> <IsPrivate>true</IsPrivate> <IsSystemDefined>false</IsSystemDefined> </Role> <Role> <Client> <ID>0</ID> <CreatedBy>0</CreatedBy> <ModifiedBy>0</ModifiedBy> <EnterpriseID>0</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2012-02-21T02:09:19.983</CreatedDate> <ModifiedDate>2013-12-23T16:48:50.533</ModifiedDate> <ObjectID>63a50610-315c-e111-beee-8e001800001f</ObjectID> <CustomerKey>SYS_DEF_IMHADMIN</CustomerKey> <Name>Marketing Cloud Administrator</Name> <Description>Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Hub Apps and Marketing Cloud Tools</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> </Roles> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUser/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:8ce806f1-f241-4c35-8f95-d875247b55e6</wsa:MessageID> <wsa:RelatesTo>urn:uuid:076f561c-4ba4-4917-b2ed-1d0a8e42b8a5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f579dff1-d9b3-4616-b3b4-3f724fe1a8fc"> <wsu:Created>2023-03-12T00:10:58Z</wsu:Created> <wsu:Expires>2023-03-12T00:15:58Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Account User Updated / Created</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="AccountUser"> <Client> <ID>1111111</ID> <ModifiedBy>123456</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <ID>700301950</ID> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_user</CustomerKey> <AccountUserID>700301950</AccountUserID> <UserID>user_test@accenture.asgr</UserID> <Password /> <Name>user test</Name> <Email>user_test@accenture.com</Email> <MustChangePassword>false</MustChangePassword> <ActiveFlag>true</ActiveFlag> <Delete>0</Delete> <IsAPIUser>false</IsAPIUser> <NotificationEmailAddress>user_test@accenture.com</NotificationEmailAddress> <IsLocked>false</IsLocked> <DefaultBusinessUnit>9999999</DefaultBusinessUnit> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-GB</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *</Name> </TimeZone> <Roles> <Role> <Client> <ID>1111111</ID> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <ObjectID>f1cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <Name>Administrator</Name> <AssignmentConfigurations> <AssignmentConfiguration> <AccountUserId>700301950</AccountUserId> <AssignmentConfigureType>RoleUser</AssignmentConfigureType> </AssignmentConfiguration> </AssignmentConfigurations> </Role> <Role> <Client> <ID>1111111</ID> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <ObjectID>fdcfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <Name>Distributed Sending User</Name> <AssignmentConfigurations> <AssignmentConfiguration> <AccountUserId>700301950</AccountUserId> <AssignmentConfigureType>RoleUser</AssignmentConfigureType> </AssignmentConfiguration> </AssignmentConfigurations> </Role> <Role> <Client> <ID>1111111</ID> <EnterpriseID>1111111</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <ObjectID>bd251431-7cd0-e911-a2d3-1402ec936979</ObjectID> <Name>Individual role for 700301950</Name> <AssignmentConfigurations> <AssignmentConfiguration> <AccountUserId>700301950</AccountUserId> <AssignmentConfigureType>RoleUser</AssignmentConfigureType> </AssignmentConfiguration> </AssignmentConfigurations> </Role> </Roles> </Object> </Results> <RequestID>b2f921a5-e46e-4226-a2fa-8bdbb4d99a7a</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:b9fbc10c-2775-48d0-b9bb-fddf1ed90616</wsa:MessageID> <wsa:RelatesTo>urn:uuid:11d44cfe-e1d7-4fc2-b6ad-a2c806573859</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-d8079cba-e093-43dc-9f6c-0e7d50ec95dd"> <wsu:Created>2023-03-11T13:52:52Z</wsu:Created> <wsu:Expires>2023-03-11T13:57:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>f4057c93-40e3-47d6-a953-06839e221d40</RequestID> <Results xsi:type="AccountUserAccount"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUser> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUserID>700301950</AccountUserID> <Delete>0</Delete> </AccountUser> <Account> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </Account> </Results> <Results xsi:type="AccountUserAccount"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUser> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUserID>700301950</AccountUserID> <Delete>0</Delete> </AccountUser> <Account> <PartnerKey xsi:nil="true" /> <ID>9999999</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </Account> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:b9fbc10c-2775-48d0-b9bb-fddf1ed90616</wsa:MessageID> <wsa:RelatesTo>urn:uuid:11d44cfe-e1d7-4fc2-b6ad-a2c806573859</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-d8079cba-e093-43dc-9f6c-0e7d50ec95dd"> <wsu:Created>2023-03-11T13:52:52Z</wsu:Created> <wsu:Expires>2023-03-11T13:57:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>f4057c93-40e3-47d6-a953-06839e221d40</RequestID> <Results xsi:type="AccountUserAccount"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUser> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUserID>717510285</AccountUserID> <Delete>0</Delete> </AccountUser> <Account> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </Account> </Results> <Results xsi:type="AccountUserAccount"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUser> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUserID>700301950</AccountUserID> <Delete>0</Delete> </AccountUser> <Account> <PartnerKey xsi:nil="true" /> <ID>1111111</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </Account> </Results> <Results xsi:type="AccountUserAccount"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUser> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountUserID>700301950</AccountUserID> <Delete>0</Delete> </AccountUser> <Account> <PartnerKey xsi:nil="true" /> <ID>9999999</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </Account> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/automation/v1/queries/get-response.json ================================================ { "count": 0, "page": 1, "pageSize": 50, "items": [] } ================================================ FILE: test/resources/1111111/automation/v1/queries/post-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094d-keySuffix", "name": "testNew_query", "key": "testNew_query_DEV", "description": "created on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\n", "targetName": "testExisting_dataExtensionShared", "targetKey": "testExisting_dataExtensionShared", "targetId": "21711373-72c1-ec11-b83b-shared", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n", "categoryId": 9991, "isFrozen": false } ================================================ FILE: test/resources/1111111/businessUnit/retrieve-ID=1111111-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:9e5f98fa-4112-4416-be42-4f9e6f6886e4</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b94fb623-e37d-40d3-8178-e6c8ee3b40b5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-3f974942-511e-4e57-9faa-c89493b836ba"> <wsu:Created>2022-11-29T19:42:20Z</wsu:Created> <wsu:Expires>2022-11-29T19:47:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>233a302f-6c1f-4fea-8b32-82a843ae806d</RequestID> <Results xsi:type="BusinessUnit"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> <MasterUnsubscribeBehavior>ENTIRE_ENTERPRISE</MasterUnsubscribeBehavior> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/data/v1/customobjectdata/key/testExisting_dataExtensionShared/rowset/get-response.json ================================================ { "links": { "self": "/v1/customobjectdata/token/ea0a44dc-b679-4d7d-8b77-e5d3f106e854/rowset?$page=1" }, "requestToken": "ea0a44dc-b679-4d7d-8b77-e5d3f106e854", "tokenExpireDateUtc": "2023-01-26T13:54:59.883", "customObjectId": "30400c03-0ec4-ec11-b83c-48df37d1de8b", "customObjectKey": "testExisting_dataExtensionShared", "pageSize": 1, "page": 1, "count": 0, "top": 0 } ================================================ FILE: test/resources/1111111/dataExtension/create-expected.json ================================================ { "CustomerKey": "testNew_dataExtensionShared", "Name": "testNew_dataExtensionShared", "Description": "", "IsSendable": false, "IsTestable": false, "Fields": [ { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": true, "MaxLength": 254, "Name": "testField" } ], "c__retentionPolicy": "none", "r__folder_ContentType": "shared_dataextension", "r__folder_Path": "Shared Items/Shared Data Extensions" } ================================================ FILE: test/resources/1111111/dataExtension/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:3a5f1edf-dacb-4d19-a0d3-4e0dcc9f507d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:fb395987-bf45-42d6-af73-f51816c7b73f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-b5d88471-97ad-4070-a18f-4c148a52da96"> <wsu:Created>2022-04-24T20:35:10Z</wsu:Created> <wsu:Expires>2022-04-24T20:40:10Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Data Extension created.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>shared-0ec4-ec11-b83c-48df37d1de8a</NewObjectID> <Object xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-0ec4-ec11-b83c-48df37d1de8a</ObjectID> <CustomerKey>testNew_dataExtensionShared</CustomerKey> <Name>testNew_dataExtensionShared</Name> <Description /> <IsSendable>false</IsSendable> <IsTestable>false</IsTestable> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <Fields> <Field> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>testField</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> </Field> </Fields> <CategoryID>89356</CategoryID> </Object> </Results> <RequestID>c41aa55a-90e3-4021-9f82-103796aae6da</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtension/retrieve-expected.json ================================================ { "CustomerKey": "testExisting_dataExtensionShared", "DataRetentionPeriodLength": 6, "Description": "bla bla", "Fields": [ { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 50, "Name": "FirstName" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 50, "Name": "LastName" }, { "DefaultValue": "", "FieldType": "EmailAddress", "IsPrimaryKey": false, "IsRequired": true, "MaxLength": 254, "Name": "EmailAddress" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": true, "IsRequired": true, "MaxLength": 50, "Name": "ContactKey" } ], "IsSendable": true, "IsTestable": true, "Name": "testExisting_dataExtensionShared", "ResetRetentionPeriodOnImport": false, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retentionPolicy": "individialRecords", "r__folder_ContentType": "shared_dataextension", "r__folder_Path": "Shared Items/Shared Data Extensions" } ================================================ FILE: test/resources/1111111/dataExtension/retrieve-expected.md ================================================ ## testExisting_dataExtensionShared **Description:** bla bla **Folder:** Shared Items/Shared Data Extensions/ **Fields in table:** 4 **Sendable:** Yes (`ContactKey` to `Subscriber Key`) **Testable:** Yes **Retention Policy:** individialRecords - **Retention Period:** 6 Months - **Reset Retention Period on import:** no | Name | FieldType | MaxLength | IsPrimaryKey | IsNullable | DefaultValue | | --- | --- | --- | --- | --- | --- | | FirstName | Text | 50 | - | + | | | LastName | Text | 50 | - | + | | | EmailAddress | EmailAddress | 254 | - | - | | | ContactKey | Text | 50 | + | - | | ================================================ FILE: test/resources/1111111/dataExtension/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-52fe9187-6f22-4701-bd57-d0eaa4aef215"> <wsu:Created>2022-04-21T19:21:50Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:50Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7</RequestID> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-04-21T06:56:27.927</CreatedDate> <ModifiedDate>2022-04-21T06:56:27.927</ModifiedDate> <ObjectID>21711373-72c1-ec11-b83b-shared</ObjectID> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> <Name>testExisting_dataExtensionShared</Name> <Description>bla bla</Description> <IsSendable>true</IsSendable> <IsTestable>true</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactKey</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>true</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>89356</CategoryID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtension/template_sharedDE-expected.json ================================================ { "CustomerKey": "{{{prefix}}}dataExtensionShared", "DataRetentionPeriodLength": 6, "Description": "{{{description}}}", "Fields": [ { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 50, "Name": "FirstName" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 50, "Name": "LastName" }, { "DefaultValue": "", "FieldType": "EmailAddress", "IsPrimaryKey": false, "IsRequired": true, "MaxLength": 254, "Name": "EmailAddress" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": true, "IsRequired": true, "MaxLength": 50, "Name": "ContactKey" } ], "IsSendable": true, "IsTestable": true, "Name": "{{{prefix}}}dataExtensionShared", "ResetRetentionPeriodOnImport": false, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retentionPolicy": "individialRecords", "r__folder_ContentType": "shared_dataextension", "r__folder_Path": "Shared Items/Shared Data Extensions" } ================================================ FILE: test/resources/1111111/dataExtension/update-expected.json ================================================ { "CustomerKey": "testExisting_dataExtensionShared", "Name": "testExisting_dataExtensionShared", "Description": "Container for my test emails", "IsSendable": false, "IsTestable": false, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 50, "Name": "FirstName" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 55, "Name": "LastName" }, { "DefaultValue": "", "FieldType": "EmailAddress", "IsPrimaryKey": false, "IsRequired": true, "MaxLength": 254, "Name": "EmailAddress" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": true, "IsRequired": true, "MaxLength": 50, "Name": "ContactKey" }, { "DefaultValue": "", "FieldType": "Text", "IsPrimaryKey": false, "IsRequired": false, "MaxLength": 254, "Name": "newField" } ], "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "shared_dataextension", "r__folder_Path": "Shared Items/Shared Data Extensions" } ================================================ FILE: test/resources/1111111/dataExtension/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:994e213d-1125-450d-b187-32e3870147d1</wsa:MessageID> <wsa:RelatesTo>urn:uuid:f1fc86ef-c0c8-4c17-a901-a15fc2631f76</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-88cf0bce-bf0f-4d5f-90a6-2897708181b5"> <wsu:Created>2022-04-26T20:49:03Z</wsu:Created> <wsu:Expires>2022-04-26T20:54:03Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Data Extension updated.</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <ObjectID>21711373-72c1-ec11-b83b-shared</ObjectID> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> <Name>testExisting_dataExtensionShared</Name> <Description>Container for my test emails</Description> <IsSendable>false</IsSendable> <IsTestable>false</IsTestable> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>true</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <Fields> <Field> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>testField</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> </Field> </Fields> <CategoryID>89356</CategoryID> </Object> </Results> <RequestID>dbfedcb6-a809-4101-b314-a7b920c9fb1e</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtensionShared].[TriggerUpdate_randomNumber_]-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>TriggerUpdate-8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[TriggerUpdate_randomNumber_]</CustomerKey> <Name>TriggerUpdate_randomNumber_</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionSharedORDataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtensionField/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>shared-42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtensionShared].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtensionShared</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataExtensionTemplate/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:110bbc72-d639-4e67-ab93-68e081bcf3a0</wsa:MessageID> <wsa:RelatesTo>urn:uuid:753eed05-f925-4113-8a98-e81ca69c96fd</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-a81724ab-b6f6-4825-82e8-ec523642075e"> <wsu:Created>2022-04-21T19:21:49Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:49Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>82fd5f74-ad8c-49ad-958f-867d4a4b53b0</RequestID> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>cfd6fc95-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>086D14D3-5057-462B-AF33-01CA8D1FE87A</CustomerKey> <Name>DomainExclusion</Name> <Description>Domain Exclusion Data Extension Template</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>1fd7fc95-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>B6E8AE4C-3D93-49B1-B299-E0AE734213DD</CustomerKey> <Name>TriggeredSendDataExtension</Name> <Description>Triggered Send Source Data Extension Template</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>Email Address</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_EmailAddress</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>bb1df59b-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>23471ECA-8710-4512-9296-040CA86FBD9E</CustomerKey> <Name>CONTEXTUAL_SUPPRESSION_LISTS</Name> <Description>Used to create new auto-suppression lists</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>EmailAddress</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>e61df59b-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>00A4369E-0B57-4EF2-BFFA-E3F23B4D1098</CustomerKey> <Name>SocialPages Default Template Extension</Name> <Description>Required for contacts. Used by Smart Capture for Social Pages.</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value>6</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value>5</Value> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>37d8c7f2-ad19-4084-8d18-4dda1dc36772</ObjectID> <CustomerKey>DAE95D91-762C-4124-B082-0433165ADD30</CustomerKey> <Name>AudienceBuilderResult</Name> <Description>Used for creating audience builder result destinations.</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>ContactKey</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value>0</Value> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>941cf36b-f927-4674-8468-c9a3bed7cae4</ObjectID> <CustomerKey>BE1B7591-BFA6-473F-A6CE-0E458204865B</CustomerKey> <Name>Event DE Template</Name> <Description>Event Data Extension Template</Description> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataFolder/retrieve-ContentType=queryactivity-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>9991</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataFolder/retrieve-ContentTypeINdataextension,hidden,queryactivity,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:998a6923-b781-40be-abad-0506f0f97477</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a5d518cc-9bfb-45f1-a4a7-5d11cc1a8d44</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-a6c00a2f-fcfa-4882-a72d-8b8983a8cc7e"> <wsu:Created>2025-09-05T16:29:03Z</wsu:Created> <wsu:Expires>2025-09-05T16:34:03Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ac40bccd-e8cd-4232-b1ee-e3cfbbfd0b89</RequestID> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataFolder/retrieve-ContentTypeINdataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:4d209b2f-d7ce-4e6e-916c-c8642d368866</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a850f043-1422-4d16-8443-702dd2f9f13a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-5da63531-caa7-4ead-9f10-a33d9bf66745"> <wsu:Created>2023-08-11T13:15:46Z</wsu:Created> <wsu:Expires>2023-08-11T13:20:46Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ba1b0c59-78c4-4608-8423-35dda2248d4d</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.54</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.54</ModifiedDate> <ID>93698</ID> <ObjectID xsi:nil="true" /> <CustomerKey>salesforcedataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Salesforce Data Extensions</Name> <Description /> <ContentType>salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.55</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.55</ModifiedDate> <ID>93699</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_salesforcedataextension_defau</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Salesforce Data Extensions</Name> <Description /> <ContentType>shared_salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-01-27T10:50:46.573</CreatedDate> <ModifiedDate>2020-01-27T10:50:46.573</ModifiedDate> <ID>309082</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>QueryStudioResults</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-04-17T08:14:19.763</CreatedDate> <ModifiedDate>2020-04-17T08:14:19.763</ModifiedDate> <ID>587750</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>catalyst target 1</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-07-09T02:30:12.38</CreatedDate> <ModifiedDate>2021-12-16T03:43:30.753</ModifiedDate> <ID>605618</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Audiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-12-25T06:11:40.107</CreatedDate> <ModifiedDate>2021-12-23T10:51:24.393</ModifiedDate> <ID>633441</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>System DEs</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:54:36.11</CreatedDate> <ModifiedDate>2021-01-30T11:54:36.11</ModifiedDate> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>Customer 360 Segments</Name> <Description>All Customer 360 segments will be grouped here. Each sub-folder relates to an activation profile name.</Description> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:56:38.77</CreatedDate> <ModifiedDate>2021-01-30T11:56:38.77</ModifiedDate> <ID>638815</ID> <ObjectID xsi:nil="true" /> <CustomerKey>cedd206d-178e-41cb-8965-ce255975b046</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> </ParentFolder> <Name>FirstAudience360 Segment</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-02-07T10:44:01.413</CreatedDate> <ModifiedDate>2021-12-16T03:43:33.38</ModifiedDate> <ID>639967</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>TestAudiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-04T15:17:18.533</CreatedDate> <ModifiedDate>2021-08-04T15:17:18.567</ModifiedDate> <ID>675203</ID> <ObjectID xsi:nil="true" /> <CustomerKey>A19F7E38-7369-497E-826F-D551F17FB0B4</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-10-03T05:01:37.23</CreatedDate> <ModifiedDate>2021-10-03T05:01:37.37</ModifiedDate> <ID>688352</ID> <ObjectID xsi:nil="true" /> <CustomerKey>B80AE306-55BC-4C2E-A79F-8CCA486F0BA0</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-10-26T09:48:38.293</CreatedDate> <ModifiedDate>2022-10-26T09:48:38.31</ModifiedDate> <ID>757145</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0ACB800B-AA8B-4F0F-9642-4907592C919C</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataFolder/retrieve-ContentTypeINshared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:4d209b2f-d7ce-4e6e-916c-c8642d368866</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a850f043-1422-4d16-8443-702dd2f9f13a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-5da63531-caa7-4ead-9f10-a33d9bf66745"> <wsu:Created>2023-08-11T13:15:46Z</wsu:Created> <wsu:Expires>2023-08-11T13:20:46Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ba1b0c59-78c4-4608-8423-35dda2248d4d</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.54</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.54</ModifiedDate> <ID>93698</ID> <ObjectID xsi:nil="true" /> <CustomerKey>salesforcedataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Salesforce Data Extensions</Name> <Description /> <ContentType>salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.55</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.55</ModifiedDate> <ID>93699</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_salesforcedataextension_defau</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Salesforce Data Extensions</Name> <Description /> <ContentType>shared_salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-01-27T10:50:46.573</CreatedDate> <ModifiedDate>2020-01-27T10:50:46.573</ModifiedDate> <ID>309082</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>QueryStudioResults</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-04-17T08:14:19.763</CreatedDate> <ModifiedDate>2020-04-17T08:14:19.763</ModifiedDate> <ID>587750</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>catalyst target 1</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-07-09T02:30:12.38</CreatedDate> <ModifiedDate>2021-12-16T03:43:30.753</ModifiedDate> <ID>605618</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Audiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-12-25T06:11:40.107</CreatedDate> <ModifiedDate>2021-12-23T10:51:24.393</ModifiedDate> <ID>633441</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>System DEs</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:54:36.11</CreatedDate> <ModifiedDate>2021-01-30T11:54:36.11</ModifiedDate> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>Customer 360 Segments</Name> <Description>All Customer 360 segments will be grouped here. Each sub-folder relates to an activation profile name.</Description> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:56:38.77</CreatedDate> <ModifiedDate>2021-01-30T11:56:38.77</ModifiedDate> <ID>638815</ID> <ObjectID xsi:nil="true" /> <CustomerKey>cedd206d-178e-41cb-8965-ce255975b046</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> </ParentFolder> <Name>FirstAudience360 Segment</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-04T15:17:18.533</CreatedDate> <ModifiedDate>2021-08-04T15:17:18.567</ModifiedDate> <ID>675203</ID> <ObjectID xsi:nil="true" /> <CustomerKey>A19F7E38-7369-497E-826F-D551F17FB0B4</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-10-03T05:01:37.23</CreatedDate> <ModifiedDate>2021-10-03T05:01:37.37</ModifiedDate> <ID>688352</ID> <ObjectID xsi:nil="true" /> <CustomerKey>B80AE306-55BC-4C2E-A79F-8CCA486F0BA0</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-10-26T09:48:38.293</CreatedDate> <ModifiedDate>2022-10-26T09:48:38.31</ModifiedDate> <ID>757145</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0ACB800B-AA8B-4F0F-9642-4907592C919C</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/dataFolder/retrieve-response-.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:4d209b2f-d7ce-4e6e-916c-c8642d368866</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a850f043-1422-4d16-8443-702dd2f9f13a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-5da63531-caa7-4ead-9f10-a33d9bf66745"> <wsu:Created>2023-08-11T13:15:46Z</wsu:Created> <wsu:Expires>2023-08-11T13:20:46Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ba1b0c59-78c4-4608-8423-35dda2248d4d</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.54</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.54</ModifiedDate> <ID>93698</ID> <ObjectID xsi:nil="true" /> <CustomerKey>salesforcedataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Salesforce Data Extensions</Name> <Description /> <ContentType>salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.55</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.55</ModifiedDate> <ID>93699</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_salesforcedataextension_defau</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Salesforce Data Extensions</Name> <Description /> <ContentType>shared_salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-01-27T10:50:46.573</CreatedDate> <ModifiedDate>2020-01-27T10:50:46.573</ModifiedDate> <ID>309082</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>QueryStudioResults</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-04-17T08:14:19.763</CreatedDate> <ModifiedDate>2020-04-17T08:14:19.763</ModifiedDate> <ID>587750</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>catalyst target 1</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-07-09T02:30:12.38</CreatedDate> <ModifiedDate>2021-12-16T03:43:30.753</ModifiedDate> <ID>605618</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Audiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-12-25T06:11:40.107</CreatedDate> <ModifiedDate>2021-12-23T10:51:24.393</ModifiedDate> <ID>633441</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>System DEs</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:54:36.11</CreatedDate> <ModifiedDate>2021-01-30T11:54:36.11</ModifiedDate> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>Customer 360 Segments</Name> <Description>All Customer 360 segments will be grouped here. Each sub-folder relates to an activation profile name.</Description> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:56:38.77</CreatedDate> <ModifiedDate>2021-01-30T11:56:38.77</ModifiedDate> <ID>638815</ID> <ObjectID xsi:nil="true" /> <CustomerKey>cedd206d-178e-41cb-8965-ce255975b046</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> </ParentFolder> <Name>FirstAudience360 Segment</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-02-07T10:44:01.413</CreatedDate> <ModifiedDate>2021-12-16T03:43:33.38</ModifiedDate> <ID>639967</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>TestAudiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-04T15:17:18.533</CreatedDate> <ModifiedDate>2021-08-04T15:17:18.567</ModifiedDate> <ID>675203</ID> <ObjectID xsi:nil="true" /> <CustomerKey>A19F7E38-7369-497E-826F-D551F17FB0B4</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-10-03T05:01:37.23</CreatedDate> <ModifiedDate>2021-10-03T05:01:37.37</ModifiedDate> <ID>688352</ID> <ObjectID xsi:nil="true" /> <CustomerKey>B80AE306-55BC-4C2E-A79F-8CCA486F0BA0</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-10-26T09:48:38.293</CreatedDate> <ModifiedDate>2022-10-26T09:48:38.31</ModifiedDate> <ID>757145</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0ACB800B-AA8B-4F0F-9642-4907592C919C</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/list/retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:26648e52-3bac-4eca-a5e1-ad71d38b56fe</wsa:MessageID> <wsa:RelatesTo>urn:uuid:8552cfbd-466c-447e-a232-13d945e44a5c</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c80ba907-ecc4-447d-8418-140c4ca108de"> <wsu:Created>2022-11-29T19:42:21Z</wsu:Created> <wsu:Expires>2022-11-29T19:47:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>11e9f8a8-e5e6-4082-93bd-5840060512ce</RequestID> <Results xsi:type="List"> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-01-24T06:32:34.453</CreatedDate> <ModifiedDate>2017-01-24T06:32:34.453</ModifiedDate> <ID>15</ID> <ObjectID>1f793b8b-cb23-4bb4-9ec4-1e0bf9511960</ObjectID> <CustomerKey>All Subscribers - 277</CustomerKey> <ListName>All Subscribers</ListName> <Category>277</Category> <Type>Private</Type> <Description>Contains all subscribers</Description> <ListClassification>ExactTargetList</ListClassification> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/platform/v1/setup/quickflow/data/get-response.json ================================================ { "languages": [ { "Key": "en-US", "Value": "English (United States)" }, { "Key": "fr-CA", "Value": "French (Canada)" }, { "Key": "fr-FR", "Value": "French (France)" }, { "Key": "de-DE", "Value": "German (Germany)" }, { "Key": "it-IT", "Value": "Italian (Italy)" }, { "Key": "ja-JP", "Value": "Japanese (Japan)" }, { "Key": "pt-BR", "Value": "Portuguese (Brazil)" }, { "Key": "es-419", "Value": "Spanish (Latin America)" }, { "Key": "es-ES", "Value": "Spanish (Spain)" } ], "roles": [ { "roleID": "f1cfb80f-3550-e611-96fe-38eaa7142c61", "roleName": "Administrator", "description": "Administrator" }, { "roleID": "facfb80f-3550-e611-96fe-38eaa7142c61", "roleName": "Analyst", "description": "Analyst" }, { "roleID": "f4cfb80f-3550-e611-96fe-38eaa7142c61", "roleName": "Content Creator", "description": "Content Creator" }, { "roleID": "1c564845-32d5-eb11-b82a-48df37d1deb7", "roleName": "Custom Connector", "description": "Custom Connector" }, { "roleID": "f6cfb80f-3550-e611-96fe-38eaa7142c61", "roleName": "Data Manager", "description": "Data Manager" }, { "roleID": "fdcfb80f-3550-e611-96fe-38eaa7142c61", "roleName": "Distributed Sending User", "description": "Distributed Sending User" }, { "roleID": "63a50610-315c-e111-beee-8e001800001f", "roleName": "Marketing Cloud Administrator", "description": "Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Marketing Cloud Apps and Tools." }, { "roleID": "66a50610-315c-e111-beee-8e001800001f", "roleName": "Marketing Cloud Channel Manager", "description": "Create and execute cross-channel interactive marketing campaigns and administer Social and Mobile Channels" }, { "roleID": "64a50610-315c-e111-beee-8e001800001f", "roleName": "Marketing Cloud Content Editor/Publisher", "description": "Create and deliver messages through Mobile and Sites Channel Apps" }, { "roleID": "67a50610-315c-e111-beee-8e001800001f", "roleName": "Marketing Cloud Security Administrator", "description": "Maintain Watchdog security settings and manage user activity and alerts" }, { "roleID": "65a50610-315c-e111-beee-8e001800001f", "roleName": "Marketing Cloud Viewer", "description": "View cross-channel marketing activity and results within the Marketing Cloud" } ], "timeZones": [ { "id": "2", "description": "(GMT) Casablanca *" }, { "id": "3", "description": "(GMT) Dublin, Edinburgh, Lisbon, London *" }, { "id": "4", "description": "(GMT) Monrovia, Reykjavik" }, { "id": "5", "description": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, { "id": "6", "description": "(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague *" }, { "id": "7", "description": "(GMT+01:00) Brussels, Copenhagen, Madrid, Paris *" }, { "id": "8", "description": "(GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb *" }, { "id": "9", "description": "(GMT+01:00) West Central Africa" }, { "id": "18", "description": "(GMT+01:00) Windhoek *" }, { "id": "10", "description": "(GMT+02:00) Amman *" }, { "id": "11", "description": "(GMT+02:00) Athens, Bucharest *" }, { "id": "12", "description": "(GMT+02:00) Beirut *" }, { "id": "13", "description": "(GMT+02:00) Cairo " }, { "id": "17", "description": "(GMT+02:00) E. Europe *" }, { "id": "14", "description": "(GMT+02:00) Harare, Pretoria" }, { "id": "15", "description": "(GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius *" }, { "id": "16", "description": "(GMT+02:00) Jerusalem *" }, { "id": "19", "description": "(GMT+03:00) Baghdad *" }, { "id": "20", "description": "(GMT+03:00) Kuwait, Riyadh" }, { "id": "21", "description": "(GMT+03:00) Moscow, St. Petersburg, Volgograd (RTZ 2)" }, { "id": "22", "description": "(GMT+03:00) Nairobi" }, { "id": "24", "description": "(GMT+03:30) Tehran *" }, { "id": "25", "description": "(GMT+04:00) Abu Dhabi, Muscat" }, { "id": "26", "description": "(GMT+04:00) Baku *" }, { "id": "27", "description": "(GMT+04:00) Yerevan *" }, { "id": "28", "description": "(GMT+04:00) Port Louis *" }, { "id": "23", "description": "(GMT+04:00) Tbilisi" }, { "id": "30", "description": "(GMT+04:30) Kabul" }, { "id": "31", "description": "(GMT+05:00) Ekaterinburg (RTZ 4)" }, { "id": "33", "description": "(GMT+05:00) Ashgabat, Tashkent" }, { "id": "32", "description": "(GMT+05:00) Islamabad, Karachi *" }, { "id": "34", "description": "(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi" }, { "id": "35", "description": "(GMT+05:30) Sri Jayawardenepura" }, { "id": "36", "description": "(GMT+05:45) Kathmandu" }, { "id": "38", "description": "(GMT+06:00) Astana" }, { "id": "37", "description": "(GMT+06:00) Novosibirsk (RTZ 5)" }, { "id": "39", "description": "(GMT+06:30) Yangon (Rangoon)" }, { "id": "40", "description": "(GMT+07:00) Bangkok, Hanoi, Jakarta" }, { "id": "41", "description": "(GMT+07:00) Krasnoyarsk (RTZ 6)" }, { "id": "42", "description": "(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi" }, { "id": "43", "description": "(GMT+08:00) Irkutsk (RTZ 7)" }, { "id": "44", "description": "(GMT+08:00) Kuala Lumpur, Singapore" }, { "id": "45", "description": "(GMT+08:00) Perth *" }, { "id": "46", "description": "(GMT+08:00) Taipei" }, { "id": "47", "description": "(GMT+09:00) Osaka, Sapporo, Tokyo" }, { "id": "48", "description": "(GMT+09:00) Seoul" }, { "id": "49", "description": "(GMT+09:00) Yakutsk (RTZ 8)" }, { "id": "50", "description": "(GMT+09:30) Adelaide *" }, { "id": "51", "description": "(GMT+09:30) Darwin" }, { "id": "52", "description": "(GMT+10:00) Brisbane" }, { "id": "53", "description": "(GMT+10:00) Canberra, Melbourne, Sydney *" }, { "id": "54", "description": "(GMT+10:00) Guam, Port Moresby" }, { "id": "55", "description": "(GMT+10:00) Hobart *" }, { "id": "56", "description": "(GMT+10:00) Vladivostok, Magadan (RTZ 9)" }, { "id": "57", "description": "(GMT+11:00) Solomon Is., New Caledonia" }, { "id": "58", "description": "(GMT+12:00) Auckland, Wellington *" }, { "id": "59", "description": "(GMT+12:00) Fiji *" }, { "id": "60", "description": "(GMT+13:00) Nukualofa" }, { "id": "91", "description": "(GMT+13:00)Samoa *" }, { "id": "61", "description": "(GMT-01:00) Azores *" }, { "id": "62", "description": "(GMT-01:00) Cabo Verde Is." }, { "id": "63", "description": "(GMT-02:00) Mid-Atlantic - Old *" }, { "id": "64", "description": "(GMT-03:00) Brasilia" }, { "id": "65", "description": "(GMT-03:00) Buenos Aires *" }, { "id": "67", "description": "(GMT-03:00) Greenland *" }, { "id": "68", "description": "(GMT-03:00) Montevideo *" }, { "id": "69", "description": "(GMT-03:30) Newfoundland *" }, { "id": "70", "description": "(GMT-04:00) Atlantic Time (Canada) *" }, { "id": "72", "description": "(GMT-04:00) Cuiaba " }, { "id": "66", "description": "(GMT-04:00) Georgetown, La Paz, Manaus, San Juan" }, { "id": "73", "description": "(GMT-04:00) Santiago * " }, { "id": "74", "description": "(GMT-04:30) Caracas" }, { "id": "75", "description": "(GMT-05:00) Bogota, Lima, Quito, Rio Branco" }, { "id": "76", "description": "(GMT-05:00) Eastern Time (US & Canada) *" }, { "id": "77", "description": "(GMT-05:00) Indiana (East) *" }, { "id": "78", "description": "(GMT-06:00) Central America" }, { "id": "79", "description": "(GMT-06:00) Central Time (US & Canada) *" }, { "id": "1", "description": "(GMT-06:00) Central Time (No Daylight Savings)" }, { "id": "80", "description": "(GMT-06:00) Guadalajara, Mexico City, Monterrey *" }, { "id": "82", "description": "(GMT-06:00) Saskatchewan" }, { "id": "83", "description": "(GMT-07:00) Arizona" }, { "id": "84", "description": "(GMT-07:00) Chihuahua, La Paz, Mazatlan *" }, { "id": "86", "description": "(GMT-07:00) Mountain Time (US & Canada) *" }, { "id": "88", "description": "(GMT-08:00) Baja California *" }, { "id": "87", "description": "(GMT-08:00) Pacific Time (US & Canada) *" }, { "id": "89", "description": "(GMT-09:00) Alaska *" }, { "id": "90", "description": "(GMT-10:00) Hawaii" }, { "id": "92", "description": "(GMT-12:00) International Date Line West" } ], "defaultUserData": { "defaultTimeZone": "5", "defaultLanguage": "en-GB" } } ================================================ FILE: test/resources/1111111/query/patch_keySuffix-expected.json ================================================ { "name": "testNew_query", "key": "testNew_query_DEV", "description": "created on deploy", "r__dataExtension_key": "testExisting_dataExtensionShared", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/resources/1111111/query/patch_keySuffix-expected.sql ================================================ SELECT SubscriberKey AS testField FROM _Subscribers ================================================ FILE: test/resources/1111111/role/retrieve-IsPrivate=false-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:e45d2dee-e7c7-4c09-a6fe-887dd4021950</wsa:MessageID> <wsa:RelatesTo>urn:uuid:5f970206-bed2-4006-8590-e3aa52133e4c</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c1c19a43-2495-43e6-81f4-a86863f894aa"> <wsu:Created>2023-03-11T13:52:51Z</wsu:Created> <wsu:Expires>2023-03-11T13:57:51Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e4b2d26e-c429-4856-a410-eeb2951e84e0</RequestID> <Results xsi:type="Role"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.93</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.93</ModifiedDate> <ObjectID>f1cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_ADMIN</CustomerKey> <Name>Administrator</Name> <Description>Administrator</Description> <IsSystemDefined>true</IsSystemDefined> </Results> <Results xsi:type="Role"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.953</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.953</ModifiedDate> <ObjectID>f4cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_CONTENT</CustomerKey> <Name>Content Creator</Name> <Description>Content Creator</Description> <IsSystemDefined>true</IsSystemDefined> </Results> <Results xsi:type="Role"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.97</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.97</ModifiedDate> <ObjectID>f6cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_DATA</CustomerKey> <Name>Data Manager</Name> <Description>Data Manager</Description> <IsSystemDefined>true</IsSystemDefined> </Results> <Results xsi:type="Role"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.98</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.98</ModifiedDate> <ObjectID>facfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_ANALYST</CustomerKey> <Name>Analyst</Name> <Description>Analyst</Description> <IsSystemDefined>true</IsSystemDefined> </Results> <Results xsi:type="Role"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T17:52:36.993</CreatedDate> <ModifiedDate>2016-07-22T17:52:36.993</ModifiedDate> <ObjectID>fdcfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>SYS_DEF_DS_USER</CustomerKey> <Name>Distributed Sending User</Name> <Description>Distributed Sending User</Description> <IsSystemDefined>true</IsSystemDefined> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/1111111/user/build-expected.json ================================================ { "Client": {}, "CustomerKey": "testTemplated_user", "UserID": "user_testTarget@accenture.asgr", "Name": "user test", "Email": "user_testTarget@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "IsAPIUser": false, "NotificationEmailAddress": "user_testTarget@accenture.com", "DefaultBusinessUnit": "1111111", "c__AssociatedBusinessUnits": ["1111111", "1111111"], "c__RoleNamesGlobal": ["Administrator", "Content Creator", "Marketing Cloud Administrator"], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/resources/1111111/user/create-expected.json ================================================ { "Client": { "ModifiedBy": 123456 }, "CustomerKey": "testNew_user", "UserID": "testNew_user@accenture.asgr", "Name": "new user", "Email": "testNew_user@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "IsAPIUser": false, "NotificationEmailAddress": "testNew_user@accenture.com", "DefaultBusinessUnit": 1111111, "c__type": "User", "c__AccountUserID": 700301950, "c__IsLocked_readOnly": false, "c__AssociatedBusinessUnits": [1111111, 9999999], "c__RoleNamesGlobal": ["Administrator", "Distributed Sending User"], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/resources/1111111/user/retrieve-expected.json ================================================ { "Client": { "ModifiedBy": 123456 }, "CreatedDate": "2019-09-06T01:59:07.097", "ModifiedDate": "2022-06-21T01:43:02.64", "CustomerKey": "testExisting_user", "UserID": "user_test@accenture.asgr", "Name": "user test", "Email": "user_test@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "LastSuccessfulLogin": "2023-02-23T10:14:11.443", "IsAPIUser": false, "NotificationEmailAddress": "user_test@accenture.com", "DefaultBusinessUnit": 1111111, "c__type": "User", "c__AccountUserID": 700301950, "c__IsLocked_readOnly": false, "c__AssociatedBusinessUnits": [1111111, 9999999], "c__RoleNamesGlobal": ["Administrator", "Content Creator", "Marketing Cloud Administrator"], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/resources/1111111/user/retrieve-expected.md ================================================ # User Overview - testInstance ## Users (1) | Name | Last successful Login | Active | Access Locked out | API User | Must change PW | Default BU | BU Access | Roles | Login | ID | Key | E-Mail | Notification E-Mail | Timezone | SFMC Locale | Modified Date | Modified By | Created Date | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | user test | 96 days | ✓ | - | - | - | <nobr>_ParentBU_ (1111111)</nobr> | <nobr>_ParentBU_ (1111111)</nobr>,<br> <nobr>testBU (9999999)</nobr> | <nobr>Administrator,</nobr><br> <nobr>Content Creator,</nobr><br> <nobr>Marketing Cloud Administrator</nobr> | user_test@accenture.asgr | 700301950 | testExisting_user | user_test@accenture.com | user_test@accenture.com | GMT+01:00 | en-GB | 2022-06-21 01:43:02.64 | 123456 | 2019-09-06 01:59:07.097 | ## Inactivated Users (1) | Name | Last successful Login | Active | Access Locked out | API User | Must change PW | Default BU | BU Access | Roles | Login | ID | Key | E-Mail | Notification E-Mail | Timezone | SFMC Locale | Modified Date | Modified By | Created Date | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | user test-inactive | 96 days | - | - | - | - | <nobr>_ParentBU_ (1111111)</nobr> | <nobr>_ParentBU_ (1111111)</nobr> | <nobr>Administrator,</nobr><br> <nobr>Content Creator,</nobr><br> <nobr>Marketing Cloud Administrator</nobr> | user_test-inactive@accenture.asgr | 700301951 | testExisting_user_inactive | user_test-inactive@accenture.com | user_test-inactive@accenture.com | GMT+01:00 | en-GB | 2022-06-21 01:43:02.64 | 123456 | 2019-09-06 01:59:07.097 | ## Installed Packages (1) | Name | Last successful Login | Active | Access Locked out | API User | Must change PW | Default BU | BU Access | Roles | Login | ID | Key | E-Mail | Notification E-Mail | Timezone | SFMC Locale | Modified Date | Modified By | Created Date | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | igopredictiveemail app user | never | ✓ | - | ✓ | - | <nobr>_ParentBU_ (1111111)</nobr> | <nobr>_ParentBU_ (1111111)</nobr> | <nobr></nobr> | 20f2d94a-9a7d-4580-9fb6-c36a1ce32fb9 | 7471228 | 45372cbb-06e0-438e-88d8-008981f7a18b | | | GMT+01:00 | en-GB | 2023-05-27 07:05:55.113 | n/a | 2016-07-22 11:52:37.42 | ================================================ FILE: test/resources/1111111/user/template-expected.json ================================================ { "Client": {}, "CustomerKey": "{{{prefix}}}user", "UserID": "user{{{suffix}}}@accenture.asgr", "Name": "user test", "Email": "user{{{suffix}}}@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "IsAPIUser": false, "NotificationEmailAddress": "user{{{suffix}}}@accenture.com", "DefaultBusinessUnit": "1111111", "c__AssociatedBusinessUnits": ["1111111", "{{{mid}}}"], "c__RoleNamesGlobal": ["Administrator", "Content Creator", "Marketing Cloud Administrator"], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/resources/1111111/user/update-expected.json ================================================ { "Client": { "ModifiedBy": 123456 }, "CustomerKey": "testExisting_user", "UserID": "user_test@accenture.asgr", "Name": "user test", "Email": "user_test@accenture.com", "MustChangePassword": false, "ActiveFlag": true, "IsAPIUser": false, "NotificationEmailAddress": "user_test@accenture.com", "DefaultBusinessUnit": 9999999, "c__type": "User", "c__AccountUserID": 700301950, "c__IsLocked_readOnly": false, "c__AssociatedBusinessUnits": [9999999], "c__RoleNamesGlobal": ["Administrator", "Distributed Sending User"], "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *", "c__LocaleCode": "en-GB" } ================================================ FILE: test/resources/9999999/accountUser/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:18989827-614e-4b4b-833a-ca06d03565a3</wsa:MessageID> <wsa:RelatesTo>urn:uuid:84c999df-4607-4423-8f68-77a0ebf4db2f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-7515cb13-8659-4ef9-86ba-b67d78e3e566"> <wsu:Created>2024-09-25T16:43:14Z</wsu:Created> <wsu:Expires>2024-09-25T16:48:14Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>f346a727-d497-4f83-9559-77854ecf0be3</RequestID> <Results xsi:type="AccountUser"> <Client> <ID>9999999</ID> <ModifiedBy>700301950</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-03-06T07:46:36.397</CreatedDate> <ModifiedDate>2024-09-04T06:41:51.233</ModifiedDate> <ID>700301950</ID> <ObjectID xsi:nil="true" /> <CustomerKey>99b4a407-0efa-4f9e-9dd5-af7ace87e634</CustomerKey> <AccountUserID>700301950</AccountUserID> <UserID>joern.berkefeld@accenture.com</UserID> <Name>Jörn Berkefeld</Name> <Email>joern.berkefeld@accenture.com</Email> <MustChangePassword>false</MustChangePassword> <ActiveFlag>true</ActiveFlag> <Delete>0</Delete> <LastSuccessfulLogin>2024-09-25T09:07:52.743</LastSuccessfulLogin> <IsAPIUser>false</IsAPIUser> <NotificationEmailAddress>joern.berkefeld@accenture.com</NotificationEmailAddress> <IsLocked>false</IsLocked> <DefaultBusinessUnit>510007949</DefaultBusinessUnit> <Locale> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <LocaleCode>en-US</LocaleCode> </Locale> <TimeZone> <PartnerKey xsi:nil="true" /> <ID>5</ID> <ObjectID xsi:nil="true" /> <Name>(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</Name> </TimeZone> <DefaultBusinessUnitObject> <PartnerKey xsi:nil="true" /> <ID>9999999</ID> <ObjectID xsi:nil="true" /> <AccountType>None</AccountType> <Subscription xsi:nil="true" /> </DefaultBusinessUnitObject> <Roles> <Role> <Client> <ID>9999999</ID> <CreatedBy>500000009</CreatedBy> <ModifiedBy>500000009</ModifiedBy> <EnterpriseID>9999999</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T17:55:14.7</CreatedDate> <ModifiedDate>2021-06-21T17:55:14.7</ModifiedDate> <ObjectID>f35c8ecf-b9d2-eb11-b83e-f40343c95998</ObjectID> <CustomerKey>SYS_DEF_ADMIN</CustomerKey> <Name>Administrator</Name> <Description>Administrator</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> <Role> <Client> <ID>0</ID> <CreatedBy>0</CreatedBy> <ModifiedBy>0</ModifiedBy> <EnterpriseID>0</EnterpriseID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2012-02-21T02:09:19.983</CreatedDate> <ModifiedDate>2013-12-23T16:48:50.533</ModifiedDate> <ObjectID>63a50610-315c-e111-beee-8e001800001f</ObjectID> <CustomerKey>SYS_DEF_IMHADMIN</CustomerKey> <Name>Marketing Cloud Administrator</Name> <Description>Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Hub Apps and Marketing Cloud Tools</Description> <IsPrivate>false</IsPrivate> <IsSystemDefined>true</IsSystemDefined> </Role> </Roles> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/asset/build-asset_htmlblock-expected.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%; " class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner"> <div>my 1st html</div> %%[ /* my ampscript */ ]%% <script runat="server"> // my ssjs </script> <div>my 2nd html</div> <div>%%=ContentBlockById(1295065)=%%</div> </td> </tr> </table> ================================================ FILE: test/resources/9999999/asset/build-asset_htmlblock-expected.json ================================================ { "assetType": { "displayName": "HTML Block", "name": "htmlblock" }, "availableViews": [], "createdBy": {}, "customerKey": "testTemplated_asset_htmlblock", "design": "", "fileProperties": { "fileName": "testTemplated_asset_htmlblock-Mcdev-strips-content" }, "memberId": "1111111", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "modelVersion": 2, "modifiedBy": {}, "name": "testTemplated_asset_htmlblock-Mcdev-strips-content", "r__folder_Path": "Content Builder", "status": { "name": "Draft" } } ================================================ FILE: test/resources/9999999/asset/build-templatebasedemail-expected.json ================================================ { "customerKey": "testTemplated_asset_templatebasedemail", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " testTemplated_asset_templatebasedemail", "createdBy": {}, "modifiedBy": {}, "memberId": "1111111", "status": { "name": "Draft" }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "my subject line", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "preheader": { "contentType": "application/vnd.etmc.email.View; kind=preheader", "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "availableViews": [], "slots": { "banner": { "content": "<div data-type=\"block\" data-key=\"5v1vodxyvz\"></div><div data-type=\"block\" data-key=\"c2m5fa0c6ym\"></div><div data-type=\"block\" data-key=\"cdsuxkm6kyt\"></div><div data-type=\"block\" data-key=\"7xogokk59k\"></div><div data-type=\"block\" data-key=\"sf47b6tjg2m\"></div><div data-type=\"block\" data-key=\"hy6ik0ftsb4\"></div><div data-type=\"block\" data-key=\"csscq2x1lpr\"></div>", "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "availableViews": [], "blocks": { "hy6ik0ftsb4": { "r__asset_key": "testTemplated_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testTemplated_asset_htmlblock-Mcdev-strips-content" }, "name": "testTemplated_asset_htmlblock-Mcdev-strips-content", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 99991999, "memberId": 99991999, "status": { "id": 1, "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "template": { "meta": { "contentHash": -166410261 }, "r__asset_key": "testTemplated_asset_template" }, "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" } } }, "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset/build-templatebasedemail-html-expected.html ================================================ <a href="%%ftaf_url%%" ><img src="https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif" border="0" /></a ><a href="%%profile_center_url%%" alias="Update Profile">Update Profile</a> <table cellpadding="2" cellspacing="0" width="600" id="Table5" border="0"> <tr> <td> <font face="verdana" size="1" color="#444444" >This email was sent by: <b>%%Member_Busname%%</b><br />%%Member_Addr%% %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br /></font> </td> </tr> </table> <a href="%%subscription_center_url%%" alias="Manage Subscriptions">Manage Subscriptions</a ><img src="https://www.exacttarget.com/images/Powered_By_1206.jpg" border="0" /><custom name="opencounter" type="tracking" /> ================================================ FILE: test/resources/9999999/asset/build-templatebasedemail-preheader-expected.amp ================================================ my custom preheader text ================================================ FILE: test/resources/9999999/asset/create-expected.json ================================================ { "customerKey": "testNew_asset-9999999", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset" }, "name": "testNew_asset", "description": "bla bla", "owner": { "email": "", "name": "SFMC DEVOPS app user" }, "createdDate": "2024-05-07T05:08:46.927-06:00", "createdBy": { "email": "", "name": "SFMC DEVOPS app user" }, "modifiedDate": "2024-05-07T05:08:46.927-06:00", "modifiedBy": { "email": "", "name": "SFMC DEVOPS app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset/resolveId-1234-notFound-expected.json ================================================ { "error": "id not found" } ================================================ FILE: test/resources/9999999/asset/resolveId-1295064-noPath-expected.json ================================================ { "folder": "Content Builder", "isShared": false, "key": "testExisting_asset_htmlblock", "mid": 9999999, "name": "testExisting_asset_htmlblock-Mcdev-strips-content", "path": "./retrieve/testInstance/testBU/asset/block/testExisting_asset_htmlblock.asset-block-meta.html" } ================================================ FILE: test/resources/9999999/asset/resolveId-1295064-withPath-expected.json ================================================ { "folder": "Content Builder", "isShared": false, "key": "testExisting_asset_htmlblock", "mid": 9999999, "name": "testExisting_asset_htmlblock-Mcdev-strips-content", "path": "./retrieve/testInstance/testBU/asset/block/testExisting_asset_htmlblock.asset-block-meta.html" } ================================================ FILE: test/resources/9999999/asset/retrieve-templatebasedemail-expected.json ================================================ { "customerKey": "testExisting_asset_templatebasedemail", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " testExisting_asset_templatebasedemail", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2024-04-22T06:36:03.117-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-13T07:15:29.77-06:00", "modifiedBy": { "name": "IDE - joern.berkefeld app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "my subject line", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "preheader": { "contentType": "application/vnd.etmc.email.View; kind=preheader", "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "availableViews": [], "slots": { "banner": { "content": "<div data-type=\"block\" data-key=\"5v1vodxyvz\"></div><div data-type=\"block\" data-key=\"c2m5fa0c6ym\"></div><div data-type=\"block\" data-key=\"cdsuxkm6kyt\"></div><div data-type=\"block\" data-key=\"7xogokk59k\"></div><div data-type=\"block\" data-key=\"sf47b6tjg2m\"></div><div data-type=\"block\" data-key=\"hy6ik0ftsb4\"></div><div data-type=\"block\" data-key=\"csscq2x1lpr\"></div>", "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "availableViews": [], "blocks": { "hy6ik0ftsb4": { "r__asset_key": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_asset_htmlblock-Mcdev-strips-content" }, "name": "testExisting_asset_htmlblock-Mcdev-strips-content", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 99991999, "memberId": 99991999, "status": { "id": 1, "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "template": { "meta": { "contentHash": -166410261 }, "r__asset_key": "testExisting_asset_template" }, "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" } } }, "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset/retrieve-templatebasedemail-html-expected.html ================================================ <a href="%%ftaf_url%%" ><img src="https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif" border="0" /></a ><a href="%%profile_center_url%%" alias="Update Profile">Update Profile</a> <table cellpadding="2" cellspacing="0" width="600" id="Table5" border="0"> <tr> <td> <font face="verdana" size="1" color="#444444" >This email was sent by: <b>%%Member_Busname%%</b><br />%%Member_Addr%% %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br /></font> </td> </tr> </table> <a href="%%subscription_center_url%%" alias="Manage Subscriptions">Manage Subscriptions</a ><img src="https://www.exacttarget.com/images/Powered_By_1206.jpg" border="0" /><custom name="opencounter" type="tracking" /> ================================================ FILE: test/resources/9999999/asset/retrieve-templatebasedemail-preheader-expected.amp ================================================ my custom preheader text ================================================ FILE: test/resources/9999999/asset/template-emailTemplate-expected.json ================================================ { "assetType": { "displayName": "Template", "name": "template" }, "availableViews": [], "createdBy": {}, "customerKey": "{{{prefix}}}asset_template", "fileProperties": { "fileName": " {{{prefix}}}asset_template" }, "memberId": "510009653", "modelVersion": 2, "modifiedBy": {}, "name": " {{{prefix}}}asset_template", "r__folder_Path": "Content Builder", "status": { "name": "Draft" } } ================================================ FILE: test/resources/9999999/asset/template-templatebasedemail-expected.json ================================================ { "customerKey": "{{{prefix}}}asset_templatebasedemail", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " {{{prefix}}}asset_templatebasedemail", "createdBy": {}, "modifiedBy": {}, "memberId": "{{{mid}}}", "status": { "name": "Draft" }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "my subject line", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "preheader": { "contentType": "application/vnd.etmc.email.View; kind=preheader", "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "availableViews": [], "slots": { "banner": { "content": "<div data-type=\"block\" data-key=\"5v1vodxyvz\"></div><div data-type=\"block\" data-key=\"c2m5fa0c6ym\"></div><div data-type=\"block\" data-key=\"cdsuxkm6kyt\"></div><div data-type=\"block\" data-key=\"7xogokk59k\"></div><div data-type=\"block\" data-key=\"sf47b6tjg2m\"></div><div data-type=\"block\" data-key=\"hy6ik0ftsb4\"></div><div data-type=\"block\" data-key=\"csscq2x1lpr\"></div>", "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "availableViews": [], "blocks": { "hy6ik0ftsb4": { "r__asset_key": "{{{prefix}}}asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "{{{prefix}}}asset_htmlblock-Mcdev-strips-content" }, "name": "{{{prefix}}}asset_htmlblock-Mcdev-strips-content", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 99991999, "memberId": 99991999, "status": { "id": 1, "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "template": { "meta": { "contentHash": -166410261 }, "r__asset_key": "{{{prefix}}}asset_template" }, "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" } } }, "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset/template-templatebasedemail-html-expected.html ================================================ <a href="%%ftaf_url%%" ><img src="https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif" border="0" /></a ><a href="%%profile_center_url%%" alias="Update Profile">Update Profile</a> <table cellpadding="2" cellspacing="0" width="600" id="Table5" border="0"> <tr> <td> <font face="verdana" size="1" color="#444444" >This email was sent by: <b>%%Member_Busname%%</b><br />%%Member_Addr%% %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br /></font> </td> </tr> </table> <a href="%%subscription_center_url%%" alias="Manage Subscriptions">Manage Subscriptions</a ><img src="https://www.exacttarget.com/images/Powered_By_1206.jpg" border="0" /><custom name="opencounter" type="tracking" /> ================================================ FILE: test/resources/9999999/asset/template-templatebasedemail-preheader-expected.amp ================================================ my custom preheader text ================================================ FILE: test/resources/9999999/asset/template-testExisting_asset_htmlblock-expected.json ================================================ { "assetType": { "displayName": "HTML Block", "name": "htmlblock" }, "availableViews": [], "createdBy": {}, "customerKey": "{{{prefix}}}asset_htmlblock", "design": "", "fileProperties": { "fileName": "{{{prefix}}}asset_htmlblock-Mcdev-strips-content" }, "memberId": "{{{mid}}}", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "modelVersion": 2, "modifiedBy": {}, "name": "{{{prefix}}}asset_htmlblock-Mcdev-strips-content", "r__folder_Path": "Content Builder", "status": { "name": "Draft" } } ================================================ FILE: test/resources/9999999/asset/testExisting_asset_htmlblock-retrieve-expected.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%; " class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner"> <div>my 1st html</div> %%[ /* my ampscript */ ]%% <script runat="server"> // my ssjs </script> <div>my 2nd html</div> <div>%%=ContentBlockById(1295065)=%%</div> </td> </tr> </table> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_htmlblock-retrieve-expected.json ================================================ { "customerKey": "testExisting_asset_htmlblock", "assetType": { "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_asset_htmlblock-Mcdev-strips-content" }, "name": "testExisting_asset_htmlblock-Mcdev-strips-content", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)" }, "memberId": 9999999, "status": { "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-html-rcb-id-expected.html ================================================ <a href="%%ftaf_url%%" ><img src="https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif" border="0" /></a ><a href="%%profile_center_url%%" alias="Update Profile">Update Profile</a> <table cellpadding="2" cellspacing="0" width="600" id="Table5" border="0"> <tr> <td> <font face="verdana" size="1" color="#444444" >This email was sent by: <b>%%Member_Busname%%</b ><br />%%Member_Addr%% %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br /></font> </td> </tr> </table> <a href="%%subscription_center_url%%" alias="Manage Subscriptions" >Manage Subscriptions</a ><img src="https://www.exacttarget.com/images/Powered_By_1206.jpg" border="0" /><custom name="opencounter" type="tracking" /> %%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064); </script> %%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064); </script> %%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064); </script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-html-rcb-key-expected.html ================================================ <a href="%%ftaf_url%%" ><img src="https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif" border="0" /></a ><a href="%%profile_center_url%%" alias="Update Profile">Update Profile</a> <table cellpadding="2" cellspacing="0" width="600" id="Table5" border="0"> <tr> <td> <font face="verdana" size="1" color="#444444" >This email was sent by: <b>%%Member_Busname%%</b ><br />%%Member_Addr%% %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br /></font> </td> </tr> </table> <a href="%%subscription_center_url%%" alias="Manage Subscriptions" >Manage Subscriptions</a ><img src="https://www.exacttarget.com/images/Powered_By_1206.jpg" border="0" /><custom name="opencounter" type="tracking" /> %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock"); </script> %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock"); </script> %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock"); </script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-html-rcb-name-expected.html ================================================ <a href="%%ftaf_url%%" ><img src="https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif" border="0" /></a ><a href="%%profile_center_url%%" alias="Update Profile">Update Profile</a> <table cellpadding="2" cellspacing="0" width="600" id="Table5" border="0"> <tr> <td> <font face="verdana" size="1" color="#444444" >This email was sent by: <b>%%Member_Busname%%</b ><br />%%Member_Addr%% %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br /></font> </td> </tr> </table> <a href="%%subscription_center_url%%" alias="Manage Subscriptions" >Manage Subscriptions</a ><img src="https://www.exacttarget.com/images/Powered_By_1206.jpg" border="0" /><custom name="opencounter" type="tracking" /> %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content"); </script> %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content"); </script> %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName( "Content Builder\\dont strip non ssjs content" ); </script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-id-expected.amp ================================================ %%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064);</script>%%= ContentBlockById(1295065) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064);</script>%%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064);</script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-key-expected.amp ================================================ %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script>%%= ContentBlockByKey("testExisting_htmlblock1") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-name-expected.amp ================================================ %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script>%%= ContentBlockByName("Content Builder\testExisting_htmlblock1") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-text-rcb-id-expected.amp ================================================ %%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064);</script>%%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064);</script>%%= ContentBlockById(1295064) =%% <script runat="server"> Platform.Function.ContentBlockById(1295064);</script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-text-rcb-key-expected.amp ================================================ %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%% <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script> ================================================ FILE: test/resources/9999999/asset/testExisting_asset_message-text-rcb-name-expected.amp ================================================ %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script> ================================================ FILE: test/resources/9999999/asset/test_coderesource_js-retrieve-expected.js ================================================ /* insert code here */ ================================================ FILE: test/resources/9999999/asset/test_coderesource_js-retrieve-expected.json ================================================ { "assetType": { "displayName": "Javascript Code Resource", "name": "jscoderesource" }, "availableViews": [], "contentType": "application/javascript", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2025-03-24T05:20:40.82-06:00", "customerKey": "test_coderesource_js", "data": { "site": { "content": { "url": "https://oss-test.accenture.com/test_coderesource" } } }, "description": "", "memberId": 9999999, "meta": { "cloudPages": { "c__published": true, "publishDate": "2025-03-24 06:05:23.203" } }, "modelVersion": 2, "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2025-03-25T03:03:20.603-06:00", "name": "test_coderesource_js", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "status": { "name": "Draft" }, "version": 1, "r__folder_Path": "Content Builder/Test Folder" } ================================================ FILE: test/resources/9999999/asset/test_coderesource_json-retrieve-expected.json ================================================ { "assetType": { "displayName": "JSON Code Resource", "name": "jsoncoderesource" }, "availableViews": [], "contentType": "application/json", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2025-03-25T03:15:22.72-06:00", "customerKey": "test_coderesource_json", "data": { "site": { "content": { "url": "https://oss-test.accenture.com/test_coderesource_json" } } }, "description": "", "memberId": 9999999, "meta": { "cloudPages": { "c__published": true, "publishDate": "2025-03-25 03:16:40.913" } }, "modelVersion": 2, "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2025-03-25T03:16:40.913-06:00", "name": "test_coderesource_json", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "status": { "name": "Draft" }, "version": 1, "r__folder_Path": "Content Builder/Test Folder" } ================================================ FILE: test/resources/9999999/asset/test_coderesource_json-retrieve-expected.jsonc ================================================ { "test": true } ================================================ FILE: test/resources/9999999/asset/test_coderesource_xml-retrieve-expected.json ================================================ { "assetType": { "displayName": "XML Code Resource", "name": "xmlcoderesource" }, "availableViews": [], "contentType": "application/xml", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2025-03-25T03:03:45.713-06:00", "customerKey": "test_coderesource_xml", "data": { "site": { "content": { "url": "https://oss-test.accenture.com/test_coderesource_xml" } } }, "description": "", "memberId": 9999999, "meta": { "cloudPages": { "c__published": false } }, "modelVersion": 2, "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2025-03-25T03:04:06.48-06:00", "name": "test_coderesource_xml", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "status": { "name": "Draft" }, "version": 1, "r__folder_Path": "Content Builder/Test Folder" } ================================================ FILE: test/resources/9999999/asset/test_coderesource_xml-retrieve-expected.xml ================================================ <xml>test</xml> ================================================ FILE: test/resources/9999999/asset/test_interactivecontent-retrieve-expected.json ================================================ { "assetType": { "displayName": "Interactive Email Page", "name": "interactivecontent" }, "availableViews": [], "content": { "url": "https://oss-test.accenture.com/test_interactivecontent" }, "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2025-03-25T03:02:46.823-06:00", "customerKey": "test_interactivecontent", "description": "", "memberId": 9999999, "meta": { "cloudPages": { "c__published": true, "publishDate": "2025-03-25 03:02:55.307" }, "r__asset_key": "test_interactivecontent_content" }, "modelVersion": 2, "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2025-03-25T03:02:55.307-06:00", "name": "test_interactivecontent", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "status": { "name": "Draft" }, "version": 1, "r__folder_Path": "Content Builder/Test Folder" } ================================================ FILE: test/resources/9999999/asset/test_landingpage-retrieve-expected.json ================================================ { "assetType": { "displayName": "Landing Page", "name": "landingpage" }, "availableViews": [], "content": { "url": "https://oss-test.accenture.com/test_landingpage" }, "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2025-03-25T03:17:51.88-06:00", "customerKey": "test_landingpage", "description": "", "memberId": 9999999, "meta": { "cloudPages": { "c__published": false }, "r__asset_key": "test_landingpage_content" }, "modelVersion": 2, "modifiedBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2025-03-25T03:17:52.187-06:00", "name": "test_landingpage", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "status": { "name": "Draft" }, "version": 1, "r__folder_Path": "Content Builder/Test Folder" } ================================================ FILE: test/resources/9999999/asset/test_microsite-retrieve-expected.json ================================================ { "assetType": { "displayName": "Microsite", "name": "microsite" }, "availableViews": [], "content": { "url": "https://cloud.eu.randstad.com/test_microsite" }, "createdBy": { "email": "joern.berkefeld@randstad.com", "name": "Jörn Berkefeld" }, "createdDate": "2025-03-25T03:01:05.467-06:00", "customerKey": "test_microsite", "description": "", "memberId": 9999999, "meta": { "cloudPages": { "c__published": true, "publishDate": "2025-03-25 03:12:51.850" }, "r__asset_key": "test_microsite_content" }, "modelVersion": 2, "modifiedBy": { "email": "joern.berkefeld@randstad.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2025-03-25T03:12:51.85-06:00", "name": "test_microsite", "owner": { "email": "joern.berkefeld@randstad.com", "name": "Jörn Berkefeld" }, "status": { "name": "Draft" }, "version": 1, "r__folder_Path": "Content Builder/Test Folder" } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/1209971/get-response.json ================================================ { "customerKey": "mobileMessage_test", "assetType": { "name": "jsonmessage", "displayName": "JSON Message" }, "name": "Mobile Message November 22, 2021(4:20:55 PM)", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2021-11-22T09:21:11.933-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2021-12-16T02:56:24.29-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "views": { "push": { "thumbnail": {}, "content": "<!doctype html>\n<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t<meta name=\"description\" content=\"Push Preview\">\n\t\t<style>\n\thtml,\n\tbody {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\tline-height: 1.4;\n\t}\n\n\t.push-previewer {\n\t\twidth: inherit;\n\t\theight: inherit;\n\t\tposition: relative;\n\t}\n\n\t.device {\n\t\theight: inherit;\n\t\twidth: inherit;\n\t\tbackground-size: cover;\n\t\tbackground-repeat: no-repeat;\n\t}\n</style> <style>\n\t@font-face {\n\t\tfont-family: 'SF Pro Text - Regular';\n\t\tsrc: url('https://mobilepush-device-previewer.s7.marketingcloudapps.com/fonts/SFProText-Regular.woff') format('woff');\n\t\tfont-weight: normal;\n\t\tfont-style: normal;\n\t}\n\t\n\t@font-face {\n\t\tfont-family: 'Helvetica Neue - Roman';\n\t\tsrc: url('https://mobilepush-device-previewer.s7.marketingcloudapps.com/fonts/HelveticaNeue-Roman.woff') format('woff');\n\t\tfont-weight: normal;\n\t\tfont-style: normal;\n\t}\n\t\n\t@font-face {\n\t\tfont-family: 'SF Compact Text - Light';\n\t\tsrc: url('https://mobilepush-device-previewer.s7.marketingcloudapps.com/fonts/SFCompactText-Light.woff') format('woff');\n\t\tfont-weight: normal;\n\t\tfont-style: normal;\n\t}\n\t\n\t.device.iphone.lock-screen {\n\t\tfont-family: 'SF Pro Text - Regular';\n\t\tbackground-image: url('https://image.s8.exacttarget.com/lib/fe8e1c72746d057a70/m/1/d1948d1e-93af-4b9d-8b28-a087a351e8a8.jpg');\n\t}\n\t\n\t.device.iphone.lock-screen .header {\n\t\ttext-align: center;\n\t\tmargin-bottom: 20px;\n\t}\n\t\n\t.device.iphone.lock-screen .header .time {\n\t\tcolor: #FFFFFF;\n\t\tfont-family: 'SF Compact Text - Light';\n\t\tfont-size: 60px;\n\t\theight: 70px;\n\t}\n\n\t.device.iphone.lock-screen .header .date {\n\t\tcolor: #FFFFFF;\n\t\tfont-family: 'Helvetica Neue - Roman';\n\t\tfont-size: 17px;\n\t}\n\t\n\t.device.iphone.lock-screen .body {\n\t\tbackground: rgba(240, 240, 240, 0.97);\n\t\tborder-radius: 12px;\n\t\tpadding: 10px;\n\t\tmargin: 0 4px;\n\t\topacity: 1;\n\t\tposition: relative;\n\t}\n\t\n\t.device.iphone.lock-screen .body .application {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tborder-radius: 12px 12px 0 0;\n\t\tbackground: #F0F0F0;\n\t\tmargin: -10px -10px 0 -10px;\n\t\tpadding: 10px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .application .icon {\n\t\t\n\t}\n\t\n\t.device.iphone.lock-screen .body .application .icon .icon-placeholder {\n\t\theight: 17px;\n\t\twidth: 17px;\n\t\tborder-radius: 3px;\n\t\tbackground-color: grey;\n\t\tdisplay: inline-block;\n\t\tvertical-align: middle;\n\t}\n\t\n\t.device.iphone.lock-screen .body .application .name {\n\t\tcolor: #000000;\n\t\topacity: .50;\n\t\tfont-size: 12px;\n\t\ttext-overflow: ellipsis;\n\t\toverflow: hidden;\n\t\twhite-space: nowrap;\n\t\twidth: 100%;\n\t\tpadding: 2px 5px 0 10px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .application .timestamp {\n\t\tfont-size: 11px;\n\t\topacity: .50;\n\t\tfont-weight: bold;\n\t\tmargin-left: auto;\n\t}\n\t\n\t.device.iphone.lock-screen .body .media {\n\t\tborder-radius: 3px;\n\t\twidth: 26px;\n\t\theight: 26px;\n\t\tposition: absolute;\n\t\tright: 10px;\n\t\tbottom: 10px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .media img {\n\t\theight: 100%;\n\t\tmax-height: 26px;\n\t\twidth: 100%;\n\t\tmax-width: 26px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content {\n\t\tcolor: #000000;\n\t\tfont-size: 13px;\n\t\tpadding-top: 5px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content > div {\n\t\ttext-overflow: ellipsis;\n\t\toverflow: hidden;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content .title {\n\t\tfont-weight: bold;\n\t\twhite-space: nowrap;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content .subtitle {\n\t\tfont-weight: bold;\n\t\twhite-space: nowrap;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content .message {\n\t\twhite-space: pre-wrap;\n\t\tdisplay: -webkit-box;\n\t\t-webkit-line-clamp: 4;\n\t\t-webkit-box-orient: vertical;\n\t\ttext-overflow: ellipsis;\n\t\t-o-text-overflow: ellipsis;\n\t\t-ms-text-overflow: ellipsis;\n\t\tword-break: break-word;\n\t\t-ms-word-wrap: break-word;\n\t\tword-wrap: break-word;\n\t\tmax-height: 75px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content .message.hasTitle {\n\t\tmax-height: 55px;\n\t\t-webkit-line-clamp: 3;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content .message.hasSubtitle {\n\t\tmax-height: 35px;\n\t\t-webkit-line-clamp: 2;\n\t}\n\t\n\t.device.iphone.lock-screen .body .content.hasMedia .message {\n\t\tpadding-right: 50px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .action {\n\t\tcolor: #157EBF;\n\t\tfont-size: 11px;\n\t\topacity: .3;\n\t\tmargin-top: 5px;\n\t}\n\t\n\t.device.iphone.lock-screen .body .buttons {\n\t\tdisplay: none;\n\t}\n\t\n\t.device.iphone.lock-screen .footer {\n\t\tdisplay: none;\n\t}\n</style>\n\t</head>\n\t<body>\n\t\t<div class=\"push-previewer\">\n\t\t\t<div class=\"device iphone lock-screen\">\n\t\t\t\t<div class=\"header\">\n\t\t\t\t\t<div class=\"time\">12:00 AM</div>\n\t\t\t\t\t<div class=\"date\">January 1, 2020</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"body\">\n\t\t\t\t\t<div class=\"application\">\n\t\t\t\t\t\t<div class=\"icon\">\n\t\t\t\t\t\t\t<div class=\"icon-placeholder\"></div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"name\">App Name</div>\n\t\t\t\t\t\t<div class=\"timestamp\">now</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"media\"></div>\n\t\t\t\t\t<div class=\"content \">\n\t\t\t\t\t\t<div class=\"title\">test</div>\n\t\t\t\t\t\t<div class=\"subtitle\"></div>\n\t\t\t\t\t\t<div class=\"message hasTitle \">asdfasf </div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"action\"></div>\n\t\t\t\t\t<div class=\"buttons\">\n\t\t\t\t\t\t<div class=\"button1\"></div>\n\t\t\t\t\t\t<div class=\"button2\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"footer\"></div>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>", "meta": { "options": { "customBlockData": { "display:title": "test", "channel": "push", "showTemplatePicker": false, "display:title:display": "test", "stack": "S7", "openBehavior:actionType": { "label": "Open the App", "value": "openApp", "id": "openApp_0", "localizedLabel": "Open the App" }, "display:message": "asdfasf ", "currentColumn": 0, "display:message:display": "asdfasf ", "template": "push", "uncheckedPanels": ["pushmedia", "subtitle"] } } }, "modelVersion": 2 } }, "availableViews": ["push"], "modelVersion": 2, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 } } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/1295064/get-response.json ================================================ { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "objectID": "972974ed-dc44-4df2-ab6e-53bae9070339", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_asset_htmlblock-Mcdev-strips-content" }, "name": "testExisting_asset_htmlblock-Mcdev-strips-content", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 9999999, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1295064/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div>\n my 1st html\n</div>\n\n%%[ /* my ampscript */ ]%%\n\n<script runat=\"server\">\n// my ssjs\n</script>\n\n<div>\n my 2nd html\n</div>\n<div>%%=ContentBlockById(1295065)=%%</div></td></tr></table>", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/1295064/patch-response.json ================================================ { "id": 1295064, "customerKey": "testExisting_asset_html-matchName", "objectID": "26fdf503-eeed-49eb-b428-cb3b4bc2ba48", "assetType": { "id": 196, "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset" }, "name": "testNew_asset", "description": "bla bla", "owner": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "createdDate": "2024-05-07T05:08:46.927-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2024-05-07T05:08:46.927-06:00", "modifiedBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1324776/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table\n cellpadding=\"0\"\n cellspacing=\"0\"\n width=\"100%\"\n role=\"presentation\"\n style=\"min-width: 100%\"\n class=\"stylingblock-content-wrapper\"\n>\n <tr>\n <td class=\"stylingblock-content-wrapper camarker-inner\">foobar</td>\n </tr>\n</table>\n", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/1295065/get-response.json ================================================ { "id": 1295065, "customerKey": "testExisting_htmlblock1", "objectID": "972974ed-dc44-4df2-ab6e-53bae9070335", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock1" }, "name": "testExisting_htmlblock1", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 9999999, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1295065/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div>\n my 1st html\n</div>\n\n%%[ /* my ampscript */ ]%%\n\n<script runat=\"server\">\n// my ssjs\n</script>\n\n<div>\n my 2nd html\n</div>\n<div>%%= ContentBlockById(1295066)=%%%%= ContentBlockByKey(\"testExisting_htmlblock 3 spaces\")=%%</div></td></tr></table>", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/1295066/get-response.json ================================================ { "id": 1295066, "customerKey": "testExisting_htmlblock2", "objectID": "972974ed-dc44-4df2-ab6e-53bae9070336", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock2" }, "name": "testExisting_htmlblock2", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 9999999, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1295066/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div>\n my 1st html\n</div>\n\n%%[ /* my ampscript */ ]%%\n\n<script runat=\"server\">\n// my ssjs\n</script>\n\n<div>\n my 2nd html\n</div>\n<div>%%=TreatAsContent(ContentBlockByFake(\"Content Builder\\my very long path\\Content Blocks Library\\COMMON\\some other folder\\my code snippet\"))=%%</div></td></tr></table>", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/1295067/get-response.json ================================================ { "id": 1295067, "customerKey": "testExisting_htmlblock 3 spaces", "objectID": "972974ed-dc44-4df2-ab6e-53bae9070336", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock 3 spaces" }, "name": "testExisting_htmlblock 3 spaces", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 9999999, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1295066/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div>\n my 1st html\n</div>\n\n%%[ /* my ampscript */ ]%%\n\n<script runat=\"server\">\n// my ssjs\n</script>\n\n<div>\n my 2nd html\n</div>\n<div>%%=TreatAsContent(ContentBlockByFake(\"Content Builder\\my very long path\\Content Blocks Library\\COMMON\\some other folder\\my code snippet\"))=%% %%= ContentBlockByKey(\"testExisting_htmlblock1\")=%% %%= ContentBlockByKey(\"testExisting_htmlblock1 \")=%%</div></td></tr></table>", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/16992/get-response.json ================================================ { "id": 16992, "customerKey": "test_slash", "objectID": "13f34d9c-f555-4fce-b862-26ff7f9fef7a", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "test_slash" }, "name": "test_slash", "owner": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "createdDate": "2026-03-06T07:47:11.04-06:00", "createdBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "modifiedDate": "2026-03-06T07:47:11.04-06:00", "modifiedBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/16992/thumbnail" }, "category": { "id": 38491, "name": "bla/blub", "parentId": 89397 }, "content": "<table\n cellpadding=\"0\"\n cellspacing=\"0\"\n width=\"100%\"\n role=\"presentation\"\n style=\"min-width: 100%\"\n class=\"stylingblock-content-wrapper\"\n>\n <tr>\n <td class=\"stylingblock-content-wrapper camarker-inner\">test</td>\n </tr>\n</table>\n", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/5286/get-response.json ================================================ { "id": 5286, "customerKey": "testExisting_asset_template", "objectID": "50855339-3f87-47a7-8677-a8c63eb36a43", "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "fileProperties": { "fileName": " testExisting_asset_template" }, "name": " testExisting_asset_template", "owner": { "id": 710411605, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710411605" }, "createdDate": "2024-04-22T03:33:08.253-06:00", "createdBy": { "id": 710411605, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710411605" }, "modifiedDate": "2024-05-13T07:12:13.117-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "enterpriseId": 510004860, "memberId": 510009653, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/5286/thumbnail" }, "category": { "id": 89397 }, "content": "<a href=\"%%ftaf_url%%\"\n ><img\n src=\"https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif\"\n border=\"0\" /></a\n><a href=\"%%profile_center_url%%\" alias=\"Update Profile\">Update Profile</a>\n<table cellpadding=\"2\" cellspacing=\"0\" width=\"600\" id=\"Table5\" border=\"0\">\n <tr>\n <td>\n <font face=\"verdana\" size=\"1\" color=\"#444444\"\n >This email was sent by: <b>%%Member_Busname%%</b><br />%%Member_Addr%%\n %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br\n /></font>\n </td>\n </tr>\n</table>\n<a href=\"%%subscription_center_url%%\" alias=\"Manage Subscriptions\">Manage Subscriptions</a\n><img src=\"https://www.exacttarget.com/images/Powered_By_1206.jpg\" border=\"0\" /><custom\n name=\"opencounter\"\n type=\"tracking\"\n/>\n", "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/5289/get-response.json ================================================ { "id": 5289, "customerKey": "testExisting_asset_templatebasedemail", "objectID": "26c925ba-af6e-4c2a-a04a-a67f39cceeee", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "id": 207, "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " testExisting_asset_templatebasedemail", "owner": { "id": 710369861, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710369861" }, "createdDate": "2024-04-22T06:36:03.117-06:00", "createdBy": { "id": 710369861, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710369861" }, "modifiedDate": "2024-05-13T07:15:29.77-06:00", "modifiedBy": { "id": 710420432, "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/5289/thumbnail" }, "category": { "id": 89397 }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "my subject line", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "preheader": { "contentType": "application/vnd.etmc.email.View; kind=preheader", "thumbnail": {}, "content": "my custom preheader text", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "content": "<a href=\"%%ftaf_url%%\"\n ><img\n src=\"https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif\"\n border=\"0\" /></a\n><a href=\"%%profile_center_url%%\" alias=\"Update Profile\">Update Profile</a>\n<table cellpadding=\"2\" cellspacing=\"0\" width=\"600\" id=\"Table5\" border=\"0\">\n <tr>\n <td>\n <font face=\"verdana\" size=\"1\" color=\"#444444\"\n >This email was sent by: <b>%%Member_Busname%%</b><br />%%Member_Addr%%\n %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br\n /></font>\n </td>\n </tr>\n</table>\n<a href=\"%%subscription_center_url%%\" alias=\"Manage Subscriptions\">Manage Subscriptions</a\n><img src=\"https://www.exacttarget.com/images/Powered_By_1206.jpg\" border=\"0\" /><custom\n name=\"opencounter\"\n type=\"tracking\"\n/>\n", "availableViews": [], "slots": { "banner": { "content": "<div data-type=\"block\" data-key=\"5v1vodxyvz\"></div><div data-type=\"block\" data-key=\"c2m5fa0c6ym\"></div><div data-type=\"block\" data-key=\"cdsuxkm6kyt\"></div><div data-type=\"block\" data-key=\"7xogokk59k\"></div><div data-type=\"block\" data-key=\"sf47b6tjg2m\"></div><div data-type=\"block\" data-key=\"hy6ik0ftsb4\"></div><div data-type=\"block\" data-key=\"csscq2x1lpr\"></div>", "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "availableViews": [], "blocks": { "hy6ik0ftsb4": { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "objectID": "972974ed-dc44-4df2-ab6e-53bae9070339", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_asset_htmlblock-Mcdev-strips-content" }, "name": "testExisting_asset_htmlblock-Mcdev-strips-content", "owner": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "enterpriseId": 99991999, "memberId": 99991999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1295064/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div>\n my 1st html\n</div>\n\n%%[ /* my ampscript */ ]%%\n\n<script runat=\"server\">\n// my ssjs\n</script>\n\n<div>\n my 2nd html\n</div>\n<div>%%=TreatAsContent(ContentBlockByFake(\"Content Builder\\my very long path\\Content Blocks Library\\COMMON\\some other folder\\my code snippet\"))=%%</div></td></tr></table>", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "template": { "id": 5286, "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "name": "testExisting_asset_template", "meta": { "contentHash": -166410261 }, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "legacy": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 } } }, "legacyData": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/808714/get-response.json ================================================ { "id": 808714, "customerKey": "testExisting_asset_message", "objectID": "01f883be-c5c3-4eb1-b6e1-d7036f8153d4", "contentType": "application/vnd.etmc.email.Message; kind=paste", "assetType": { "id": 208, "name": "htmlemail", "displayName": "HTML Email" }, "name": "testExisting_asset_message", "owner": { "id": 717129834, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717129834" }, "createdDate": "2020-03-06T02:35:15.677-06:00", "createdBy": { "id": 717129834, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717129834" }, "modifiedDate": "2023-08-02T07:08:00.86-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 7281698, "memberId": 7281698, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/808714/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "TEST", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "preheader": { "thumbnail": {}, "content": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%% <script runat=\"server\">\nPlatform.Function.ContentBlockByKey(\"testExisting_asset_htmlblock\");</script>%%= ContentBlockById(1295065) =%% <script runat=\"server\">\nPlatform.Function.ContentBlockById(1295064);</script>%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%% <script runat=\"server\">\nPlatform.Function.ContentBlockByName(\"Content Builder\\\\dont strip non ssjs content\");</script>", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "content": "<a href=\"%%ftaf_url%%\"\n ><img\n src=\"https://www.exacttarget.com/members/newsletters/gfx/forwardafriendicon.gif\"\n border=\"0\" /></a\n><a href=\"%%profile_center_url%%\" alias=\"Update Profile\">Update Profile</a>\n<table cellpadding=\"2\" cellspacing=\"0\" width=\"600\" id=\"Table5\" border=\"0\">\n <tr>\n <td>\n <font face=\"verdana\" size=\"1\" color=\"#444444\"\n >This email was sent by: <b>%%Member_Busname%%</b><br />%%Member_Addr%%\n %%Member_City%%, %%Member_State%%, %%Member_PostalCode%%, %%Member_Country%%<br /><br\n /></font>\n </td>\n </tr>\n</table>\n<a href=\"%%subscription_center_url%%\" alias=\"Manage Subscriptions\">Manage Subscriptions</a\n><img src=\"https://www.exacttarget.com/images/Powered_By_1206.jpg\" border=\"0\" /><custom\n name=\"opencounter\"\n type=\"tracking\"\n/>\n%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%% <script runat=\"server\">\nPlatform.Function.ContentBlockByKey(\"testExisting_asset_htmlblock\");</script>%%= ContentBlockById(1295064) =%% <script runat=\"server\">\nPlatform.Function.ContentBlockById(1295064);</script>%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%% <script runat=\"server\">\nPlatform.Function.ContentBlockByName(\"Content Builder\\\\dont strip non ssjs content\");</script>", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "content": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%% <script runat=\"server\">\nPlatform.Function.ContentBlockByKey(\"testExisting_asset_htmlblock\");</script>%%= ContentBlockById(1295064) =%% <script runat=\"server\">\nPlatform.Function.ContentBlockById(1295064);</script>%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%% <script runat=\"server\">\nPlatform.Function.ContentBlockByName(\"Content Builder\\\\dont strip non ssjs content\");</script>", "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "html", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "legacy": { "legacyId": 429827, "legacyKey": "c7308370-bb2c-4bd4-83dd-0ea422e2009d", "legacyType": "email", "legacyCategoryId": 90890 } }, "approvals": { "approvalStatus": { "id": 4, "name": "Approved", "displayName": "Approved" } } }, "legacyData": { "legacyId": 429827, "legacyKey": "c7308370-bb2c-4bd4-83dd-0ea422e2009d", "legacyType": "email", "legacyCategoryId": 90890 }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/9451/get-response.json ================================================ { "id": 9451, "customerKey": "test_coderesource_js", "objectID": "cbd96028-3fd4-49cc-910b-e3640d4686e5", "contentType": "application/javascript", "assetType": { "id": 240, "name": "jscoderesource", "displayName": "Javascript Code Resource" }, "version": 1, "name": "test_coderesource_js", "description": "", "owner": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "createdDate": "2025-03-24T05:20:40.82-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:03:20.603-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/9451/thumbnail" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "content": "/* insert code here */\n", "meta": { "cloudPages": { "publishDate": "2025-03-24 06:05:23.203" } }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource\"}" } }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/9456/get-response.json ================================================ { "id": 9456, "customerKey": "test_microsite", "objectID": "5f717219-6766-48da-9843-e514cc9aa919", "assetType": { "id": 248, "name": "microsite", "displayName": "Microsite" }, "version": 1, "name": "test_microsite", "description": "", "owner": { "id": 710420418, "email": "joern.berkefeld@randstad.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "createdDate": "2025-03-25T03:01:05.467-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@randstad.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:12:51.85-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@randstad.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/9456/thumbnail" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "content": "{\"url\":\"https://cloud.eu.randstad.com/test_microsite\"}", "meta": { "thumbnailRefAssetId": 9461, "cloudPages": { "publishDate": "2025-03-25 03:12:51.850" } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/9458/get-response.json ================================================ { "id": 9458, "customerKey": "test_interactivecontent", "objectID": "02b1c184-87fb-4c58-ba3d-22d811c6cbbd", "assetType": { "id": 249, "name": "interactivecontent", "displayName": "Interactive Email Page" }, "version": 1, "name": "test_interactivecontent", "description": "", "owner": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "createdDate": "2025-03-25T03:02:46.823-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:02:55.307-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/9458/thumbnail" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "content": "{\"url\":\"https://oss-test.accenture.com/test_interactivecontent\"}", "meta": { "thumbnailRefAssetId": 9459, "cloudPages": { "publishDate": "2025-03-25 03:02:55.307" } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/9460/get-response.json ================================================ { "id": 9460, "customerKey": "test_coderesource_xml", "objectID": "66787c5f-3d36-4a61-91a5-34e760391505", "contentType": "application/xml", "assetType": { "id": 245, "name": "xmlcoderesource", "displayName": "XML Code Resource" }, "version": 1, "name": "test_coderesource_xml", "description": "", "owner": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "createdDate": "2025-03-25T03:03:45.713-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:04:06.48-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/9460/thumbnail" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "content": "<xml>test</xml>", "meta": { "cloudPages": {} }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource_xml\"}" } }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/9463/get-response.json ================================================ { "id": 9463, "customerKey": "test_coderesource_json", "objectID": "5974959b-c531-404b-9361-e27d0d760b37", "contentType": "application/json", "assetType": { "id": 242, "name": "jsoncoderesource", "displayName": "JSON Code Resource" }, "version": 1, "name": "test_coderesource_json", "description": "", "owner": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "createdDate": "2025-03-25T03:15:22.72-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:16:40.913-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/9463/thumbnail" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "content": "{\n\"test\": true\n}", "meta": { "cloudPages": { "publishDate": "2025-03-25 03:16:40.913" } }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource_json\"}" } }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/9465/get-response.json ================================================ { "id": 9465, "customerKey": "test_landingpage", "objectID": "7e515e0c-e13e-442e-b076-fe768782b453", "assetType": { "id": 247, "name": "landingpage", "displayName": "Landing Page" }, "version": 1, "name": "test_landingpage", "description": "", "owner": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "createdDate": "2025-03-25T03:17:51.88-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:17:52.187-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/9465/thumbnail" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "content": "{\"url\":\"https://oss-test.accenture.com/test_landingpage\"}", "meta": { "thumbnailRefAssetId": 9466, "cloudPages": {} }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/950143/delete-response.txt ================================================ OK ================================================ FILE: test/resources/9999999/asset/v1/content/assets/950143/get-response.json ================================================ { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json ================================================ { "count": 1, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_assetMessage.json ================================================ { "id": 2454776, "customerKey": "testNew_assetMessage", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "name": "templatebasedemail", "displayName": "Template-Based Email" }, "fileProperties": { "fileName": "testNew_assetMessage" }, "name": "testNew_assetMessage", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-11-08T09:59:30.727-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-08-07T06:12:40.75-06:00", "modifiedBy": { "name": "Jörn Berkefeld" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "globalStyles": { "isLocked": false, "template": { "background-color": "#FFFFFF", "border-width": "0px", "border-style": "solid" }, "body": { "background-color": "#FFFFFF", "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#000000", "line-height": 1, "padding": "0px", "content-padding-top": "0px", "content-padding-right": "0px", "content-padding-bottom": "0px", "content-padding-left": "0px" }, "h1": { "font-family": "Arial,helvetica,sans-serif", "font-size": "28px", "color": "#808080", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h2": { "font-family": "Arial,helvetica,sans-serif", "font-size": "22px", "color": "#808080", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h3": { "font-family": "Arial,helvetica,sans-serif", "font-size": "20px", "color": "#808080", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "links": { "font-weight": "normal", "color": "#808080", "text-decoration": "none" }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "background-color": "#5D5D5D", "border-radius": "3px", "padding": "10px", "border-color": "#5D5D5D", "border-width": "1px", "border-style": "solid" }, "mobile": { "body": { "padding": "0px", "font-size": "16px", "line-height": 1.5 }, "h1": { "font-size": "22px", "line-height": 1 }, "h2": { "font-size": "20px", "line-height": 1 }, "h3": { "font-size": "18px", "line-height": 1 }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "padding": "10px" } } } }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "A note", "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "preheader": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "availableViews": [], "slots": { "banner": { "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"background-color: transparent; min-width: 100%; \" class=\"slot-styling\"><tr><td style=\"padding: 0px; \" class=\"slot-styling camarker-inner\"><div data-type=\"block\" data-key=\"ms2rjhckdsr\"></div><div data-type=\"block\" data-key=\"vlh4b2my8gp\"></div><div data-type=\"block\" data-key=\"x0ecuu93q1k\"></div><div data-type=\"block\" data-key=\"8uflrc8ao4r\"></div><div data-type=\"block\" data-key=\"1bd95vemqf4\"></div></td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"background-color: transparent; min-width: 100%; \" class=\"slot-styling\"><tr><td style=\"padding: 0px; \" class=\"slot-styling camarker-inner\"><p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true, "columnOrder": "ltr" }, "styling": { "background-color": "transparent", "margin": "0px", "padding": "0px" } } }, "availableViews": [], "blocks": { "vlh4b2my8gp": { "assetType": { "id": 196, "name": "textblock" }, "name": "sample content block", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"background-color: transparent; min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td style=\"padding: 20px; \" class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\" style=\"height:150px; overflow:hidden;\"><p class=\"textblock\" style=\"margin:0; padding:0; overflow:hidden; display:block;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vestibulum nunc feugiat porta consectetur. Sed vehicula vel ante suscipit sagittis. Ut metus metus, feugiat ut laoreet blandit, viverra non mi. Phasellus convallis, mauris ac vehicula posuere, ligula magna mattis ipsum, in sollicitudin nibh lacus eget sapien. Mauris ultricies laoreet ex, a viverra leo ornare eu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris commodo scelerisque arcu, id semper sem pharetra vel. Sed ut erat auctor lectus pretium blandit gravida vitae enim. Nullam eget ex et enim molestie porttitor. Duis vitae est fringilla, placerat nisi condimentum, tristique purus. Fusce lobortis mauris quis iaculis ultrices. In tempor ligula ac ex tempor rutrum. Pellentesque quis convallis mi.<br><br>Duis mattis, ex a hendrerit ullamcorper, eros massa consectetur elit, vel lobortis justo arcu ac mi magna, blandit sit amet eros id, dapibus cursus justo. Suspendisse mauris odio, aliquet ut ligula in, porta mollis risus. Ut ultrices lectus dolor, sed euismod nulla ultrices ac. Phasellus laoreet ultricies facilisis. Fusce imperdiet maximus ipsum vitae rutrum. Maecenas faucibus vestibulum lorem sit amet varius. Vivamus et ultricies ligula. Mauris semper scelerisque ante id fermentum. Curabitur non odio pellentesque, consectetur odio eu, commodo risus. Mauris egestas elit vel ipsum sagittis fermentum. Cras varius quam ac enim eleifend, eu porttitor odio finibus. Aenean quis finibus dolor. Nunc bibendum aliquam auctor.</p></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true, "columnOrder": "ltr" }, "styling": { "background-color": "transparent", "margin": "0px", "padding": "20px" } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2, "id": 1322777, "objectID": "26fdf503-eeed-49eb-b428-cb3ghbc2ba49" }, "ms2rjhckdsr": { "assetType": { "id": 199, "name": "imageblock" }, "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"><div style=\"width:100%;height:150px;background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABuoAAACWBAMAAADK78OEAAAAKlBMVEUFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwgFBwhamwL+AAAADXRSTlMwmGPLQ97yfrGki3G+5/n17AAACcpJREFUeF7s2kGL00AYh/FJNhLrKrSy4KlQZBEvhUrOhS6wy168CQiYi/QaWOl5QbwXehaEfoQF/BqCpqSC8P8uBpxjtFs6KTPx+X2E981DZkJMwAAAAAAAAAAAAAAAAAAAQHJujgpAVJr/FEB1yDJzVKA6SMYXoDqqA9WB6kB1MdU5BaqjOlAd1VEdqO6U6jBodkZ1LYmoDmpWmpZQ3YjqHKI6qqM6UB3VUR3VUR3VYZGpWZWtqK4NVIeh/mpCdQ5QHajOAar7MJAGz8xOSGdU54VobUI3VW1jdsK46Z6mfyl9rC4Jv7q+8U7STnXIyy5UF2cmdD0Pq3vYSnWIVHWgunga/q5PPKzuyayN6nAl9YOvLlmK6towvmujOkylMvTqfi5FdZYVj4wLw9VeXzBz1apdXzHxSFIVeHU9ieosK8319unMHGw62fdNd49d4Eq1fkNz4XSXOjrXXAwaHLO6lcvoatWrr+ZAxfdOVbfIbowPvqk2D7m6NHe06bEaHLO6icORWJvPI3OAWGWnqhuqbzxwaqcUbnVpLqprHIn17uyQ+8cPc1+9rJC1zVZUt+uAKa2Dre6iUFequ3xjnIhzZ8t6vMdYT/z9f8lKni/16dyXA6Y0D7E6G11XqkvyamZciNwt64G2Haou8uTRjfXHJtDqrgt1prpL6b1v1b2WRlTnftPWXZDVXUudqS4upO2NZ9XdSmuqc+2LrHmI1b1Uh6p7odovz6pbSh+pzrHf7N1BS9tgHMdxFisVx8Ayr0JIRXYRZA96zoTBLoJIwVMB3WCAFLzsKDjYVfAljN0F38BuuwpVTbWuv/cy1dk/jQ2J6dPmn+T3PduQNPlgkjxP6uCpXg7V1VEgdU4L9x3qUtcENhOaM2uQ8NlEuaO6afQ7zZ26Omyqe5Xxti7hoZ6vSV0FwFXCYdII1aa6+AnjX/Km7huKpK7awmMNTepeA7imOrs5kLo5U+egUOoO8L+Oq0KdLKlLdZHVzX3pTzABNzt1VFdFvz1F6qYABFQXcydglDcSNbJTR3UHkPZVqBNKSa40171lhLrwFqluSJUWJHTFYqLaVGetKiR0Rx1Wv2pjA+SoOk17+/eiJOpeNj9lCgO5WamjuhNIwLHlVypejLasOapLuNkp9jU2LaijOgtSVtSoO3u2OlRnJNPEQMlPMKVzqhuM6lrPdjTVIbpkszhCuSVVF7/NbjnVOQk+TnWSd5cfM9foBKG2PKqTQHWzuO+20Oocb7DFVOok9+VnVDlXR3VVY5r2jv4ZGaIb04faAkKd1+bzoG4qvNpUR3U2rk4vRhum25nMU/JauCKqc94iXFCjOglUtyFbP351CFc0dbIK4eOW6iSq+42H9lWoq9T6zRdTHdVRncx5PlShzkG/wC2qOqqjuiYe2tSmDnt61f3ySqWO6qrGrNpUV8FjV+rU4adadcBk1VGd4w00aXWvrA6uka/479jVOcYYhDN3HUfs8Bvfirq6MWuK1VFdiiMv3+pked3xq0NEK1F/07CibhmAHnVUR3Vy8hUoVNdxC6iO6qhONkehOlyPSd1l7XnzStWte5KvTp0jA+yoLsXsMVehOhzbUhdfZ06fuvBnbnxF6uSIOC+6Ou+dXXUy/3IuA3Wx9fyJqUPgqleHHT8DdVQH2FUna7WiUR02J6cOl3I/VZW69Oyozmm9/JKF6toTUSetKFeHbaoDkOa1KWlfu051VIdtReoA6Fb3CaHS/I4d1VEd3lNdUnWVJsLtUh3VJVGXlh3VLUEaZZwh1VEdflBdomYhpX76QnVUl5wd1VWOMKxG9urW+2u25edFHdV15qkuvo8YWsfNXN0G+rma1FGdfNvp2FFdK4pK5uqmZUfm5wyT6hDsU11cUKtuBk/18qCO6oRdQdQ5nueXTZ3c5rkdnzqqC7yHjuypQ+AWQ90b4LvM+iiHOkcWMC51VCdZVIdLtyDqnuqclkWdXHK2c6POPPan5OrQ84ulDu1cqqtJtaSP4M/y97xOTrHKrQ43fvbqqC7NHlnIrTrslV0dzn1V6qgOjYmqm8Kw3HGpix5SV18FgMCUQh12fFXqqC5wi6VOXsce/f9cjKEc6vBVlTqqw659df/Yu6OVBIIoDMAUUnSnBHQVyEIQQVAOEQHCFtB9EnQlRPUAvYBg0APso/gIAT2AruwKwXmXaFOPeFxm3XVHx/n/y5nBmXXO5wIrs+tVJz/g0Xl19LRg+prMkRl1UBf3tk+d/i91t+2k59IVddTS7BLDMaAO6ihcu7oPfvi5KnXao/uaSUfVGXXUKK4O6uQsVqrjhIXUaYo4gDr6XkZdpSZTt1jdgZomMKQO6oY+1FE3k7r0XajaqE4W3oUhdVBHLaijvkF1PGLgrDqoi3tm1UEd1EEd/SyjDuoqh6LvoZ5FnTeTM8fVQR19ZlMHdbw4ec16dU05bQnq5NNGfxPVQV3kL3jjc9dmdaGX5NxBdXL19ezqiPqG1EEdvSwomTdb1BUP1HGG6saMOqiL3+WRFKM86jjWqku7R8ZKqWB71XGGpauDOvl253tKEjmqTnMfX5U6qIM6+uIldnizbFMHdbxXG6wO6mTZtcdNXQvUQR3HXnVQx5M8a9RBHdRVvNn41qgLvXFO1qtOnu852gZ1UDc5tu+4DHU7c7zLVMd96ep2+QdAqFs2kfrPlQl1e/zt268O6jgOqONrqRZWxzGhrjNt86FuLi3vL6dQJ3qKqYM6ro0A6nQprg7qoG5fKW57VY3c6qAO6pRS11CnGyUHhu6pg7qoNk1OdZxBbnU1kXR1d94kJ0Ldbzt3j9JAEAZgGELAwmpAsJUFrQMDdinS24TUqaytPEcgF/AI3sUkIGnmLhIRN+usNib7kzzvEb6dhx1mYFIl6gaxbNlrdXm9VJfXorqU9Zu6PwdEXbXKD2F0tuqoo24Q0l7TK+qoo+74Z5gps3AkdZXbx8dYNqJu1yTsuqaOuiZ6o64c+oY66g4bddRtQwh9Vkcddauw6Ly6vAbVUUfduthbnZNQaZGp+3fUUUdd2apmyn1SRx111FFHHXXUUUcddcV3t9TlUUddC1FHHXXtRx111FFHHXXUzWIcN6OOOuqoK+unOurW5YNALagbnoc66qjLa03dXbPqqKOOuovUZXXUbcNX49NRR91LJ9VRl9eAumaWHXUPqR1126IoXs9RHXXUDeepK1FH3am3iZ/dpzNRRx11oi6POlFHHXXUUVfWZ3XPMcb045XKG+qoy2/NDqSOuvrPSx11NVFH3QGjjjrqqLt8oo66BtN7jPPU26ijTtRRJ+qoq93LzJZHUydRl2obnYQ6UUedRN0qhJBqm4awSBJ1HUyiTtIHMv/VI7tXCZsAAAAASUVORK5CYII=) repeat-x 0 0\"></div></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "1bd95vemqf4": { "assetType": { "id": 195, "name": "freeformblock", "displayName": "Free Form Block" }, "fileProperties": { "fileName": "Footer" }, "name": "Footer", "owner": { "id": 710265361, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710265361" }, "createdDate": "2022-06-27T07:17:04Z", "createdBy": { "id": 710265361, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710265361" }, "modifiedDate": "2022-06-27T07:19:07Z", "modifiedBy": { "id": 710265361, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710265361" }, "enterpriseId": 510004860, "memberId": 510006764, "status": { "id": 1, "name": "Draft" }, "category": { "id": 4795, "name": "Content Builder", "parentId": 0 }, "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\" style=\"height:150px; overflow:hidden;\"><p class=\"textblock\" style=\"margin:0; padding:0; overflow:hidden;\"><span style=\"float:left; margin: 0 6px 6px 0; width:50%; height: 75px; overflow:hidden; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2sAAABLCAMAAADZL+8JAAAAS1BMVEUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGt0wPNAAAAGHRSTlMw51fNi5ilsr9K83HZPWR+N/rhxmq4rESzSUQKAAAGxElEQVR4XuzYW46DMAxAUUMDacK7pcX7X+lMNX+IoUgF5Kj3rMBSdKPE8j0AAAAAAACAIGcAcDEwA6bsLscDrSFoLfaB1npaOwVorem/uDW03aKW1g4Qmi9uDVdd5OUAtBZoLWm0Zh+toYuDLhriSGu7y3NJmys0c6Osw9Ixh0L/5SZam6G1LW8eVHGhHa8rSnOtNcWUeGutvZH2bg1Npo/EW+td1CBJa0dzqRWynXP6Uq++IvFU1WreX7jqCm9qQ93cMtXkW6tkL+F5Kbu8lw+5u2wXZ5sza7pysnDI+iubteP1jUKsmMqoukNrIS7I5Sxjt1tpg74MtXftJ1fiI24f3g/6R2++t7lTN/Af/mHfbpeUBQEwDL8iaAACfvac/5G+W02xlqVtqGjcv9cZRa4R2MlWONVtz5qbWX6s4bEFXxD1NKJd6Wu1n0x/egoXivCkHZVAtf6UzXBJb9EaaQHswprxNaTe/hnKAboXazyI1S3BJVR2c9b0AdiJNQoArQ3JmgHaiX+ZK7jQ5jxaG8i6Uco2Zq1JAX/WWJpiIJV2i1ED0iIgax2QvLU0cpG9W7PFqXenGFxkU9Y6wKe1A56k/s2eewsVD8eaejqm0ZrBqTfvoYRL2etOUusaI+Var7suP+zHWoZbQn92BkCIL2sFAJgpd58I3JUkzTdYY9cmXZMOfqsoJiWjNS8xuFASD2tRH9Yadzr9uhwDyf1ZoweXQq8/vJqSfKm1QsoUT0qk9PgBH5+sMhBrDABUtDZlW0V/si8vbqhAP0X5V1ojeJneiDVCMn/W0qnn99rUuIsZ/uZJQ79FrNGkn/m7tfGRygTuE812rUVrAvBmzZY41SxxNpICr9dkTqFHawz96AzWXNkTPtFatKZxjoVgjeBWXaxtLVqL1ojWPq1RnEtnt0a0VrhL/1QMv56Ke7HGCen8WkOynLVoTdLf6YWtJRgs/2x4Szu3tWR8dpH+NseHtQOA7VqL1lL8Ltu2NeGePSxrAJ3HmsofI0Fao8x1DMyaZj/JXVuzhVdrbkToWtYSdatCv9x6sjZeprUmoVkTcJWsCMoacyMdorX+k5gP9nz+rEl3/eLWxuMLWHOlIVsDBLXBWKO0DtmabdGrpNHaSNFav8SEYg1AwNa4Aj5ZIkVr0RpQyWhttEbgMcVXt2ZwCa0Nx1q0ps2pEo8pHa29jmIwQVa2ZnFLhmAtWhu/h5rswprl3M5iLcVwbO3vmsK14zzWorWWnaq9WQNavgNrGqjzc1mxC2vT+VQb2a8Zda7m27Dm8mgN6I47sHaLbdBal7vMm2cj7UfWJBtIz2GNvfqxLTdnM3L31lCyYk1r0ZqAC8z/OeR/du5tWUEQCsBwIihCCNGu4f2fdI9UYi5T09Z44r/FaQrWd5HOCK31jjT7qTXJfRY+M4EQd2pt8HGbKmEE3Vq05nKzsLW8rPqVNQZW7wa+HtIv6J1aG3zcJqe8byBa07SOTLPm6ALWQGKutZt4dOnAobr3udynNZiVX1gjHJRt19o1eXWfbS0BFx3R2oCWhBzbmku/sFZ2rQ1bg8j4ktbgDXSOYC1agwk51lq0ZsBXE8UYazpr5D+RYFgr5Ft/460ZpdCtRWvwBsys/2vKd1vSWpr7LIK1E4VnM8YaHDmKYY2BXR5pzVqXaG3QrUVr7mbArzlPsRaabw0/aI1xzjvHTAhR7tVaqMC3Fq25HM4KOaC11H1uhdY4bw44A+vRWitJnqULWuPhln84k5VZi9Zg/daE9lkEayVvxDCtEVZleq0Z8kzNnyPxzKFbCycmTLTWTJOqbEPWYPOtmfzR2wUppjXt11SvtaI+JIQ5QrJmKA17dqckWgMd3JpyIGDtSilVC1vLqs5rttbaSYZoTdGQ2rC1S9bKbtdaUneZZi1UTLRWnNslH61J/upaM88enf7bt8NWB0EoAMN0bctjpy4VF/z/v/QyNqYDCcbBlex9vwqU4oMgGFNnPdeGfPpurGhNYkoatVauWWt5x1grz7hsbfc5YwPW0pLlB7L/7O9izemtX6xhrWZYe+7B/i1rW781ZS2oavyANaxhbXWZtb/upZisGTqttVR9a1jDWmoofLd9a1jDGtaCPluwlsIa1upntzZNU1VrWMMa1lLNWcPaqqrhIGtjwBrWDI3zPLt61trPZW/TTmoNa+HRYrB2fFiTe0Os0+a97/bvKkJMYW03rJkjrKn33n2JtUlEcmu9iNisEdYq1XmvDVu7FAYya4S1JRisVQlr9ugico2nC2tYo3asYe26lgZ+3rdG5B51sRDWNJYaDdaIsGaNCGtE9A9/OsOIx1k7gwAAAABJRU5ErkJggg==) repeat-x 0 0\"></span>In viverra et dui id fermentum. Nulla tortor libero, aliquam in dictum id, vestibulum nec lacus. Curabitur sit amet accumsan magna. Mauris mollis eu lorem sodales mattis. Mauris et iaculis odio. Suspendisse et metus maximus, dapibus lectus in, placerat est. Praesent sit amet lacinia ligula. Donec non magna dictum, feugiat arcu vel, volutpat augue. In hac habitasse platea dictumst. Nunc eleifend nulla elit, vel condimentum lectus dictum sit amet. Aliquam ante nulla, dapibus ut nisi vitae, convallis malesuada mauris. Duis mattis, ex a hendrerit ullamcorper, eros massa consectetur elit, vel lobortis justo arcu ac mi magna, blandit sit amet eros id, dapibus cursus justo. Suspendisse mauris odio, aliquet ut ligula in, porta mollis risus. Ut ultrices lectus dolor, sed euismod nulla ultrices ac. Phasellus laoreet ultricies facilisis. Fusce imperdiet maximus ipsum vitae rutrum. Maecenas faucibus vestibulum lorem sit amet varius. Vivamus et ultricies ligula. Mauris semper scelerisque ante id fermentum. Curabitur non odio pellentesque, consectetur odio eu, commodo risus. Mauris egestas elit vel ipsum sagittis fermentum. Cras varius quam ac enim eleifend, eu porttitor odio finibus. Aenean quis finibus dolor. Nunc bibendum aliquam auctor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vestibulum nunc feugiat porta consectetur. Sed vehicula vel ante suscipit sagittis. Ut metus metus, feugiat ut laoreet blandit, viverra non mi. Phasellus convallis, mauris ac vehicula posuere, ligula magna mattis ipsum, in sollicitudin nibh lacus eget sapien.</p></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "x0ecuu93q1k": { "assetType": { "id": 223, "name": "referenceblock" }, "design": "<div class=\"default-design\"><div style=\"width:100%;height:150px;background-size:cover;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADawAAAEtCAIAAADRXFFBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAALyhJREFUeNrs3ftvI+l+J2aOSF27JbWu7Z72nPEJdrOws5ss9hcj58R/vWEDQYLAhjdeZHfhcbeGYosiRfFWrHuFPZpty30btcRLFfk8IASKIt+q+r6UVMX61Pt+13r3rgYAAAAAAAAAAABQNY2rd1eqAAAAAAAAAAAAAFTOhhIAAAAAAAAAAAAAVSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUkhAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAAADg4drt9ngSTe88290+Pz9XEAAAAIAlMhIkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFRSo7Rr1mxexmn26eO///EH3QYAAAAAAAAAAAAYCRIAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvSicKAIAMG9CkAAAAAAAAADA7MVxoggAwLwJQQIAAAAAAAAAs5fnmSIAAPMmBAkAAAAAAAAAzF5kJEgAYP6EIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYiyicKAIAMFdCkAAAAAAAAADAXMRxoggAwFwJQQIAAAAAAAAAAACV1FACAAAAmLlm8zJOM3X4yOnR4f7BgToAAAAAAACzYiRIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvaIo8jxTBwBgrhpKAAAAAAAAAADMXJpm0XeJOgAAc2UkSAAAAAAAAAAAAKCShCABAAAAAAAAAACAShKCBAAAAAAAAAAAACqpoQQAAADwFMF4lGX5Rw9meaEyn4qiqDYYfPTg3t5uvbGpOAAAAAAAwCMIQQIAAMCT9G4HcZqpw0MMg3B6++jB01pt/0AIEgAAAAAAeAzTYQMAAAAAAAAAAACVJAQJAAAAAAAAAMxFkqSKAADMlRAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAADwVFmaKAIAAAAAH8nyQhEAgHlrlGElfnpz8cQnP9vdPj8/150AAACLNxwMbm77P/7uB6UAAAAA4L4sz+sbdXUAAOaqoQQAAAA8WpYmN7f9vKi12+31uTit2byM00zvz0qn15/ePnx7enS4f3CgLAAAAAAAwEOYDhsAAIDH63Rv7iY1Gk+iYDxSEACAr+jf9qJwog4AAABQUcPBQBFKSAgSAACAxx/qB2H84dvOTV9NAAC+tOPUbF7e9EdxnKgGALBWksx8GgCsjsHQeBBlZDpsAAAAHqnXH97/NsvztZoUGwDgIYaDwWA4ilPn/gGANVUUagDAiojCyfQAf/p1e2dXNUpFCBIAAIDHaLfbWZ5/9GAQRg7+AQDuTPeLbnq3YZwqBQAAAKyAMAynX8fjwHmQshGCBAAA4JsF49F4En36eFHUOt3e69cO/gGAtSb+CAAAAKsnjOLp1yR1vF86QpAAAAB8s85N/0s/itOsc319enamSgDAGsrSpHvT++zlIgAAAEClRb9c7hi56LF8hCABAAD4Np3r608nwr5vNAn3TYoNAKyZu/hjEEZFoRgAAACwggf+dydHpl+n9+uNTTUpjw0lAAAA4OGicDKahF9/zt2k2GoFAKyPzvX1xeW78UQCEgAAAFZTEEw+3B+NRgpSKkaCBAAA4Bt0ur2HnNqP06x/2zt8caRiAMBqu+l2h+Mgl30EAPhEliZ3dyJzhsCyTX8Nb3q3Gxsb9Y2N7e3t/YMDNYFvNQn/ZYSIKE4UpFQWGoIcDgbz2nnKss82vre3a+hRAACAWelcX8dp9sAn9waj58+fOygDAFbYeBIpAgDAl3wYMSuOEyFIWJa7+GMYpx8eGQZhp9ff+K622Ziq7+7sbG1t+iWF35Qk6WfvUwYLDUFO/4bOqeXpH+sw/kzjp7Xa/oHzbQAAADOQpclvToR9X1HUrtqd779/pXQAwCoZDgZhZLwHAACg7D6NP96XF7UoSae3u4u7vvuutlmvb242GvX6zs723rPnCggfuT9IxMMHjGAxTIcNAADAg1y1O8U3zvMYJWmlJ8Vut9uGd1q8Tq//2asof//jD4oDwHLddLujIMzyXCngiaJwEq/Z5HH1+oYkAQCwyN2tr8QfP6so3oe67nJd/VFQ6/TqGxubjemtsb29bSJW+HSO4ukjZpYvDyFIAAAAflv/thc9anKHW5NiAwDVd9PtDsdBXqgEzOj4YjBct8uNthp1IUgAYAEeEX/8kizPszifNjUMwtq96bO3tzZ3dnZMn83a/XJF0aeP7KtLaQhBAsDqa7fbn9kJqNePT04UB4CHyNKkNxg97rV5Uet0b16+fKmMAEAV94L677Na4o8AAEDZzTD++Fn/avrs/vuPi7ca9UajvtlobG5uGg+PlRd/Mk5EnKTKUh5CkACw+j57Yf30sERlAHigR0yEfV8QxmaFAACqJUuT7k0vCKNC/BEAACi3eccfv+R/TJ8dT+93ev36xkajvtFo1Hd3dkyfzeqJ0/Q3H2GJhCABAAD4muFgED35csab276PvQCAShB/BAAAqmJZ8cfPH0zl+fT261CRvf5339U26/XNzcb21ubU3rPn+otK/659+inB9JFgPPLeLgkhSAAAAL4oS5Ob2/7T2zEpNgBQfnenD6MkFX8EAJitSRiaJATmcfxSkvjjZ00PrO6Givx1zrpO7/D53vHJib6jisbj4LOPh2EkBFkScwxBNpuXS9+8Xn84GI7uP3L04sCbDwAA4IE63Zt8RiGAIIxdEwkAlFP5Tx8CAFRRnmd3dwpXmYDjl1otzTLdR1V/7+L4mx5n8eYYgozT5f/x+mWs3X/9yEffAwAA8AXDwSAIZ3kA37np/04IEgAo2Q7PaDwWfwQAmLlgPOoNfh2xKAjjm27XCHAwE5dXHUWABYuT9JseZ/FMhw0AAMDnzWQi7PuyPG+32+fn52oLACzdcDAYDEdluJgfAGD19G97vcHo/viP/VGQpOnLly8VB4BqydLkS1NmTR+Pwsn2zq4qLZ0QJACsmptu9yGDyU+f02637z+yu7Ozf3CggADcmf6byOcwT9F4EpkUGwBYLvFHAIC5uul2+6Pg08eDMG61Wudnp/XGpioBUBWj0egrPw3DUAiyDIQgAWDVTMLoISdy8uJ9DOWjB4UgAbgTjEef/puYld7tQAgSAFiKm253OA7mcaUHAAAf9rg+m4C8E8Zps9V+/epcDhKAqgij+Os/PVSjEthQAgAAAD7SuenPr/E4zTrX14oMACzSTbf75u1FfyQBCQAw352uryQg72R5/vPlu2A8Ui4AKiGK00f/lIUxEiQAAAD/SrvdzvJ8rosYTcL9cGKGCABg3rI06d70JmEk+wgAMG8PSUDeme6btbu981rNbCEAlN/Xz5jM+3wKD2QkSAAAAP5FFE7mNxH2B0VR63R7qg0AzE+WJu12++Ly3XTfRgISAGDerq6uHpiAvFMUtatO76bbVToAymw4GMzkOcybECQAAAD/YmHZRJNiAwBzEoWTD/HHQvwRAGD+Wq1WEMaPeGF/FEz33BQQgNKahOFMnsO8mQ4bAACAX3Wur+M0W9jiRpPwKE3qjU2VBwBmIgonN73bME6VAgBgYVqt1lN2wMaTaNrCq1evVBKAEkqSdCbPYd6MBAkAAMB7UTgZTRZ6teL7aY/aHZUHAGayJ9NqtS6vOhKQAACL9MQE5J1pC28vmlmaqCcAZZNkvz1yxCJHl+BLjAQJAADAe51ub/HzRUZJ2r/tHb44Un8A4HGGg8FgOHK+Acrm63ObruFAKWmWfb0m5+fn3jZAtWRp0r6e2SUoWZ43W+3T48O9Z8/VFoCSCMajB543mT7Tv7DlemoIcjgYdHr9Cm3wdG0/u8Jbjfrr1997QwAAAOupf9tbVnSgNxg9f/7cpNgAwLcSf4QyG08iRbgvL9QEWClZmjRb7SzPZ9lmnre7vfNaTYgEgJIIgsnDn+n/13IZCRIAAGDdZWnSG4yWtfSiqLWvO69evdIRAMAD3XS7kzASfwQAWIp5JCDvvP+YqNs7CKPjkxN1BmDp4gePYR+v32j3ZSMECQAAsO6u2p3FT4R9Xxinw8Fg/+BAXwAAX3fT7Q7HQV6oBADAcswvAXmnKGr9UZDn+enZmWoDsFxJms78mczJhhIAAACss/5tLyrBFYo3t/0sTXQHAPCVnZY3by/enxGXgAQAWJJ5JyA/GAZhq9VScACWKAonD/8IYvrM6fMVbYmEIAEAANZXlia3y5sI+768qHW6N3oEAPiS0Xgi/ggAsETBePTz5bsFJCDvhHHabF66aBaAZRmPg7k+n9kSggQAAFhfne5NecIEQRgPBwOdAgAAAFA2wXjU7vYW/DlSnGbNVtvAWgAsxbfOcB3FsaItUUMJAACgDK6urtI0e0oLr19/r4x8k+FgEITlOia/ue3vHxzoGgAAAIDyuEtAFsu4kjbL81a7c35ytPfsuY4AYJGi+NtCkEmaK9oSCUECAEAppGkWPy0ECd8kS5Ob237Z1iovau12+/z8XAcBAAAAlMESE5B3pouersBRkhy+ONIdACxGliZZ/m2hxunzp6+qNzZVbylMhw0AALCOSjUR9n3jSRSMRzoIAAAAYOmGg8FyE5B3pitw0x/ddLt6BIDFGI1GC3sVM2EkSAAAgLUTjEdlmwj7vs5N/3cLmeFoWocs+9qlnFlmfNYSGQ4GX3/C3t6uq2wBAABgVm663f4oKM/6TFcmiuNXr17pGgDmLYqTR7wqjOJDtVsSIUgAAIC107npl3n1sjxfzKTYvduBaeir9L7t/cb79rRW2z8QggQAAIAZKFsC8k4Yp5eXrZfnpy6DZLX99OZCEWC5kiR9xKtSZxyW56EhyGbzcrXPDE237kv/RX7/4w/eKAAAwMpot9tZnpd8JceTKAon2zu7+gsAAABgwcqZgLwTJWmz1X796lwOEoD5eVxMzrALS2QkSAAAWBHtdntBRxH1+vHJiYJXVDAejSdRJVa10+29fi0ECQAAALBQ/dteaROQd7I8v7h89+r81AW0AMzDcDB4ymv3Dw7UcPGEIAEAYEUsLNm21airdnX1bgdVWdU4zTrX16dnZ3oNAAAAYGGiOCn/ShZFLY4TIUgA5mEShk95rRDkUmwoAQAAwJroXF9Xay6G0SSMwomOAwAAAAAAFiN9wpmU1IzYS2IkSAAA1lEwHmVZXqpVyvJCvzBXUTgZTcJqrXNRmBQbAAAAAABYnDhNl/JankIIEgCAddS7HcSuxGLNdLq9ooJR2+mvav+2d/jiSA8CAAAAAABzFYxHTzmZMn3ttIW9Z89VcsGEIAEAAFZf5SbCvq83GD1//rze2NSPAABQHldXVyZ6m6Fm8/IrP339+nslAgCABQjD6IktBMFECHLxhCABAABWXJYmlZsI+76iqF21O99//0pXAgBAeaRpZo6FGVJMAAAogyiOn9hCYkbsZdhQAgAAgNV21e5UcSLs+6Ik7d/2dCUAAAAAADA/cZIuvQUeQQgSAABglfVve9FKHG/3BqMsTXQoAAAAAAAwD1E4yZ88qMS0hWk7irlgpsMGAAC+TZxmP725+KaXnB4d7h8cKN0CtNvt8SRayU0ritrb5jtvLQAAAACg6oLxKMtydYCyCcNwJu2Mx8H2zq56LpIQJAAAAAAAAAAALEjvdhCnmTpA2YRRPJN2ktSM2IsmBAkAVFizeVndld/d2T4+OdGJAAAAAAAAAEsXxWmp2uHhHhqCfP36+88+vjJTrW016l/aRgCgtCp9kdxm5go/AAAAAAAAgOXL0iTLZzNP/bSdaWv1xqaqLsyGEgAAAAAAAAAAALC2gmBS2tb4TabDhser9Bys9xkGFQBgZRwe7O/u7NzdH43H4SpOuHB6dPjh/t7erk4HAAAAAACeaBKGs21t/+BAVRdGCBIer9JzsAIAsJK2d3ant3uH6ysYgvSpAQAAAAAAMFtJkpa2NX6T6bABAAAAAAAAAABYX7MdCs3AagsmBAkAAAAAAAAAAMCaCsajmbc5HAwUdmFMhw1UW7vdXtait7c2D18c6QIAAAAAAAAAgOoKgsnM24yiaF9lF0UIEqi28SRa4qKDSfjq1Su9AAAAAAAAAABQUXGSVqJNvsR02ACPF8Zps3mZpYlSAAAAAAAAAABUUZymlWiTLzESJMAT/2llP1++Ozs52nv2XDUAAAAAAAAA1tlNt5tm2def85tPABYpCidFMftmp21OW97e2VXhBRCCBHiqvKi1u72jJDl8caQaAPD5o8coqg0GHz24tbXpwA8AAAAAgFUyCaM4lXGEKhmPg/m17FzYYghBAsxAUdRu+qMoTs7Pz1UDAD41DMLp7aMHn+1unzvwAwAAAAAAYHmiOK5cy3xkQwkAZmU8iVqtVpYmSgEAAAAAAAAAUH5xklauZT5iJEj4jCicxPEa5diGn8xN+Zv29nbrjU1vlU+FcdpstV+eHRvQGAAAAAAA+Kyf3lxUZVV//+MP+gsAWGFZmuTFvBqftjxtX8BmAYQg4TP6g+F4Eq3P9nZ6/W99yWmttn/gb/QX/kHmeavdOT852nv2XDXg0Sr0ISAAAAAAAAAAVTQajebd/uGLI3WeN9NhA8xeUdSuOr2bblcpAAAAAAAAAADKKYziSrfPHSFIgHnpj4Krqyt1AAAAAAAAAAAooTTN5tp+FKeKvABCkABzFIRxs3mZpYlSAAAAAAAAAACUSjznEGSW54q8AEKQAHP/f9lstYPxSCkAAAAAAAAAAEpiOBiszFLWnBAkwNxled7u9vq3PaUAAAAAAAAAACiDSRiuzFLWXEMJABagKGo3/VGSpKdnZ6oB/I+d3ajZvFyHLd3Y+O787LTe2NTpAKynUl3mu39woEcAqKgonPQHw0e//PBgf3tnVxkBAAD4IEnSlVnKmhOCBFicYRAmrZYkEHAnL2pxmq3Jxl5cvnu+uyMIDsB66vT65VmZm9v+/rO945MT/QJA5cRxMp5Ej3757s6OECQAAAD3JVm2MktZc0KQAAsVxmmz1X796lwOElgrRfE+CB41L09PjpxzAoAlyotafxRMwuhg/7lRIQEAAACeYjgYfDrLbSrtBBURjEdFsYgFTZcyXdbes+dqPj9CkMBjjMbjT3fmeKAszy8u352fHPkPB6ybOM1a7c7ezvb5+blqAMBy/yl3ev3BcCQKCQAAAPBokzB8ymjlwHIFwWSRyxIRmSshSOAxwjit1VJ1eLSiqLW7vYMwMgkdsIZ/AMeT6O1F8/T40I4+ACzXXRRyNB4fH70wVDMAAAAAsFbyxYwDufBlrSchSIDlKH6ZhC5J05cvX6oGsG6yPL/q9PZG4+++++6hu631uuA4AMxDGKeXV52drYYoJAAAAMF4FEZJJVZ1NB6b3AAAuLOgEOTm5uYf//CXLw4Pn9hOkqR//Td/OxgM9RywIkeSYdy5vj49O1MKYD3/Bj78yVuNuooBwPyEcdpqd/Z2tk+Oj+qNTQUBAABYQ/3bXm8wqspIVdMj2bcXzdevzh3GAgAbi1nMTBKQtfdhysZf/fEPe3uGJQBWh0GPAQCAMpgemown0cXlu3a7naWJggAAAKyV6cHgTX9UrdNWWZ5PD2OD8Uj3AcCaW9BIkDNJQN7Z3Gzs7e4GweT+g7/709d/+sOfTu/8fPHz25+b+hUAAADgEe6ikJPLd/vP9o5PThQEAABg5WVpctXuREla0cPYq07vMIwcwwLAOmuswDb87k9f/6f/9B/v7nc6XZ0KAAAA8BR5UeuPguE4EIUEYMF+enOhCACwSMF4dN3t5RWft2x6DBvF8fnZqamxAWA9bVR9A+4nIKdSszUBAAAAzMJdFLLZvBwOBqoBAACwem663Xb1E5B3wjhtttpRONGtALCGqh2C/CgB+c9v3v7TT290KgAAAMCsxGnW6fVFIQEAAFbM1dVVfxQUxepsUZbnrXbH0SsArKEKT4f9UQIySdIgmPzP//bf3H2bpsm7q/b0EX0MAAAA8ER3UcjReHx89GJ7Z1dBAAAAqit7fzL9enqgt3qbVhS16dFrFEWnZ2c6GgDWR4VDkPcTkFObm42/+PN/d/+R//U/1P7xv/x///W//XfdDAAAAPB0YZxeXnV2thqikAAAABUVjEfXqzIF9pcMgzBptc7PTuuNTT0OAOtgY7U37y/+/N/9L3/x57oZAAAAYFbCOG21O+12O0sT1QAAAKiQm263veoJyA+Hrs1WOwpNHQkAa6HCIcgkSR/ytH/7b/6nvT0jEwAAAADMTFHUxpPo4vKdKCQAAEBVXF1d9UdBUazL9mZ53mp3hoOBrgeAlVfh6bD/+m/+9q/++IfNzV83IUnS6SODwXB6/+Bg//6P/uTl+T/99EZnAwAAAMzQXRRycvlu/9ne8cmJggAAAJRTlibvrq7jNFvD49ZOrx9F0enZmbcBAKywCo8EORgM//pv/vbDeJCbm42/+uMfDg72P/zowzMbjU09DQAAADAPeVHrj4I3by9uul3VAAAAKJtgPPr58t0aJiA/GAZhq9UyjwEArLCNSq/9pznIP3n58sOP9C4AAADAYtxFIZvNSxONAQAAlMdNt9vu9vJi3esQxmmz1Y7CibcEAO12u9m8nN4mYbSwhU6XdbfQ6dJ1wTxsVH0DPspBAgAAALAscZp1en1RSAAAgDK4urrqj4KiUIn3sjxvtTsOVwGo/fIx5vS2yIsEpsu6W6jiz0ljBbbhLgd5Nwbkzc2NTgUAAABYorso5HA0Pjl+sb2zqyAAAAALlqXJu6trSYuPFEVtergaRdHp2ZlqAKyt3Z2d8SRa4tJ1wTwsKAT5z2/e/tmPv5tVU53ux0nHwWBo/msAAABgtq6urlJnjB4rStLLq87OVuP4SBQSAABggYdj4eRdu2MK7C8ZBmF2dfXyl1GWAFhD+wcHnV5/iUvXBfOwoBDk3/39PwwGg0Zj84ntpGnyTz+90W0AAADAAqQmKHmyMH4fhXy2u31yfFR/8kdDAAAA/KY4TiQgf/N4XxEA1tlWo76UD36ny1X8OVncdNjCiwAAAADraTyJgst3ezuikAAAAADAkm1uNpYSgpwuV/HnZEMJAAAAAJi3ongfhby4fHfT7aoGAAAAALAsuzs7a7XcdSAECQAAAMCCFEWtPwrevL0QhQQAAAAAlmJvb3etlrsOjLEJAAAAwELlv0QhR0F4dLi/f3CgIAAA3yQYj3q3g6884fXr71UJAAC+pN7YrG9sZHm+0IVubEyXq/hzsqAQ5Obm5n/83/7D9OsT20mS5O/+/h+mX/UcAAAAQKVled7p9QfD0cH+c1FIAIBv2I/K8jjN1AEAAB5te6sRhPGCl6js87Og4v7xD3/54vBwJk09e7b3N3/7f8pBAgAArKd2uz2rptLMWUNYvjjNOr3+cDQ+OX6xvWM6GACAGWg2L+fR7OZm4/z8XHkBAFgBO9tbCw5BTpeo7POzoBDkrBKQd00dHux3ujc6DwAAYA2NJ5EiwOqJkvTyqrOz1Tg+EoUEAHiqOY0TOW327UXz9Phw79lzRQYAoNKeP39+0x8teInKPj+LHmYzCILROHjEC7e2NmeYpAQAAACgbML4fRTy2e72yfFRvbGpIAAAZZPl+VWntzcav3z5UjUAAKiuemNz47taXixocdNl+cBzrhYdgvznNxf/9b/990e88PTk+P/44/+uwwAqKgon/cFw5s1ub20evjhSXgAAWCXjSRRcvtvbEYUEACipBc8bCAAA87C12QjjdGHLUvC5Ul8AFiGOk3nMXDltM4xi1xwDAMCKKYpfo5AHz/aOT04UBAAAAGB9/PTmolTr8913tfOTo71n5jJeNfV6vVZLF7gs5mhjVTdsc9M4AQBrIQjjy8tWliZKAQAAK6Yoav1R8ObtxU23qxoAAAAALEVR1K46PZ9QQZmtZghyc3Pzj3/4S70LsCaiJG222sF4pBQAALB68l+ikG8vmsPBQDUAAAAAWIr+KOhcX6sDlFMlp8P+9//+L+L4ayN+PX+2N/Xh23dXV3oaYLVled7u9k6yfP/gQDUAAGAl9/k7vf5gODrYf263HwAAAIDFGwZh0mq9evVKKaBsKhmCfHF4+PAnt687g8GwbJsQjEdZlq/ne65e39h79tzvHjBzRVHr9PpRFJ2enakGAACspDjNprv9w9H45PjF9s6uggAAAACwSGGctlqt87PTemNTNaA8Gqu9ebf9/v/1f/8/JVyx3u0gTrP1fM9tNepCkMD8rOfFN+12+/63afbIfzFJkt5vqlGvH5+ceFMBAFA2UZJeXnV2thrHR6KQAAAAACxUGKfNVvv1q3M5SCiPSoYgb/v9r0+Hfefdu3cXP18mSaKbAdZtp/PtRXOtdjrHk2gm7cRpdj+jv9WoezsBAFDmPf/Lq86z3e2T4yOfOAMAAACwMFmeN1vtl2fHLtCFkqhkCPI//+d/7HRvdB4AX9npvLh8d35yZOhZAABYbeNJFFy+29sRhQQAAABgcbI8b7U7TklDSSw6BPlnP/5wevqYiTW3tnyKDbAgw8Gg0+tXfSuKotbu9g7CyITOAACw2qY7/3dRyINne/b/AQAAAFiMu1PSR0ly+OJINWC5Fh2C3PuFugOwmJ3O/ihIs+z8/Fw1AABgHfb/h+Ngf9WjkFmaBMFkrTp3/+DAOxwAAAAooaKo3fRHWZa7NBeWa0EhyH9+8/bPfvzdTJq67ff7g6GeA+CBxpPo8rL18vzU1HgAALDy8l+ikKMgPDrcX9XkXBBMVmDw/m8iBAkAAACUmaF5YOkWFIL8u7//hyRJDw+f+nllkiS/NJXoOQAeLkrSZqv98ux4e2d3JTfw2e723Z3xJHp6axvf1XZ33jfYqNe9eQAAqKIszzu9/mA4Oth/Lj8HAAAAwLyNJ1Hn+vr07EwpYCkWNx32//uP/0W5AViWLM9b7c7Ji8OVPAP64aKin95czGDnoF53lRIAACsgTrNOrz8cjU+OX6zqBVEAAAAAlEReFIoAy9JQAhYszbJ2u/2kd229fnxyopLAt5ruc3Z6/SRJ/A0BAID1ESXp5VVnZ6txfCQKCQAAAI/UbF7Gabb01dhq1F+//l53APARIUgWLS+eOlvrdLdGGYFH64+CKI5fvXqlFAAAsD7C+H0U8tnu9snxUb2xqSAAAAAAACtDCBKgekpyoVV1hXH69qL5+tW5c58AALBWxpMouHy3tyMKCQAA1XDT7U7CaFlLbzTqL1++1AsAAOUnBAnAOsry/OfLd2cnR3vPnqsGAACsj6L4NQr5fHfn9OxMQfjIT28uVn4bf//jDzoaAKiKNMuMCgEAwG/aUAIA1lNe1NrdXv+2pxQAALBuiqI2DMI3by9uul3VAAAAAACoNCNBArC+iqJ20x9FcXJ+fq4aAACwbvKi1h8FxycnSgHwCFE46Q+Gj3hho173txcAAACYISFIANbdeBK1Wq3zs9N6Y1M1AAAAAB4ijpPxJHrEC7caddUDAAAAZsh02ABQC+O02WpH4UQpAAAAAAAAAAAqRAgSAN7L8rzV7gTjkVIAAAAAAAAAAFSFECQA/Kooaled3k23qxQAAAAAAAAAAJXQUAIAuK8/CqI4fvXqlVIAAACsm9Ojw7s7vf4wy/OV2a76xsbR4b7+BQAAAGAlCUECwMfCOG02L//k5Vm9sakaAAAA62P/4ODuzmA4ylYnA1mrb3z3YdOooqurqzTNyrZWWV48+oXDweD9O7O+sffsuf4FAAAAnkgIEgA+I06zZqt9enzos3gAAABgudI0i8sXgny0LM87vf70zlaj7oMXWENROOkPhlVc892dHRcVAABAOQlBAsDnZXne7vaOkuTwxZFqAAAAAAA8XRwn40lU0ZUXglxbw8FgEoZf+unhwf72zq4qAQAskRAkAHxRUdRu+qMkSU/Pzsq/tnczST1dnGZZmpgKHAAAAAAApiZh+JXw7u7OjhAkAMByCUECwG8YBmHSap2fnZY8Fzgaj2fVVK93W4ncJwDAv9qH6Q8Hw9Fs20yyTGEBAADWU5pl7Xb7/bFhkqoGAECZCUECwG8L47TZar9+dV7aHGSWJtOVnFVrQRjrdACgcrI8z3JlAAAAYDbyovaQ2ds7vf709tkfnR4dmkUdAGABhCAB4EGyPL+4fHd+crT37HkJV6/Xu53txgbjUTm3lLWVZFmzeTnbBlUVAKAShoPBQ55Wr284igEAAACANSQECQAPVRS1q07vMIyOT07Ktm7jSTjbBvuDodOHlO0XME7FFgGAVfPAeN99URStW5W+NKzOR7YadUcxAAAAALCGhCAB4Nv0R0GSpi9fvizPKg0Hg7yYcZtRkmZpUtrpvwEAYDU8MN4HAAAAAMCXbCgBAHyrIIwvL1tZmpRkfUbj8czbLIpavz/Q1wAAAAAAAABAmRkJEgAeI0rSZqt9eny49NnWsjQJ43QeLY+C8PhEVwMAAAAAD5KlSRBMvv6cKIoUCgAAmC0hSAB4pCzP293eea223Bzk/MZrnG5gMB4tPeUJAAAAAFRCEEw6vb46AAAACyYECQCPVxS10ThYbkxwFITza7w/GApBAgAAAMByNZuX97/N8kJNAAAAPhCCBIAKC8ajLM/n136UpIoMAAAAAMsVp5kiAAAAfMmGEgBAdfUHw7m2XxS1m25XnQEAAAAAAACAchKCBICqytJkASM1TsJIqQEAAAAAAACAcjIdNgBUVb8/KIq5LyVOsyicbO/sKjgAAAAAAMC3ajYv4zQr7er9/scf9BEwWzfdbpo96e/e4cG+M9R8EyHIX2V5MRwMFrk4NQfgiUZBuJgF3fYHL+1iAgAAAABrbBJGzealOgAAPGTH6Ynh792dHSFIvokQ5K+yPO/0+upQkc6ae2I1yzJ1BkouGI+m/7wWtJMaxQoOAAAAAKyzvKiVeSA3AAB4tHa7PZ5E817K6dHh/sHBnBoXgqR6JFYBpoaj8cKWVRTvRyw/PjlRdgAAAAAAAACgVIQgAaCSFjw64ySM1BwAAAAAAFhJN93u/E6FJOYhBIA5E4IEgEoeihfFQpcYp1kUTrZ3dhUfAAAAAABYMWmWmfIeAKpLCBIAqmcp4zL2B8NzIUgAAKCs4jT76c2FOgAAAADAutlQAgColiicLOViRDNiAwAAAAAAAABlYyRIACijLE2CYPLZH43G46WsUl7UOtfX29vbn/3p/sGBXgMAAAAAAGB+srwYDgYPfPLW1ua2Wc4A1oMQJACUURBMOr1+2dZqGITT22d/JAQJAAAAAADAXGV5/vAzaM92t8+FIAHWg+mwAQAAAAAAAAAAgEoyEiQAAAAAAAAAzFin1y/hpE8AlEq73V69jUqzTM+yYI1m89K7FgAAKI9gPMqyfOmrsbW1uW2qFABgJSRZ9sTPgUuyFboSAACAFTOeRIrAnZ/eXKz2Bvb6w8FwNKfGG3HqkyMAAKBMh0C3gzIcpzzb3T4XggQAVkJR1HwODAAAAMASZXk+v1FQNtQXAAAAAAAAAAAAqCIhSAAAAAAAAAAAAKCShCABAAAAAAAAAACASmooAQCU0N7e7um9b0fjcRinpVrDna3G82fP9BQAAAAAAAAAsERCkABQRvXG5v7B5odvJ2FYq5UrBFmv1/cPDvQU8BRZlg0Hg888nhdlXr1l2dvbnf538LYBAAAAAACA+4QgAQCA5QjjNIz7Vu+BTmu1+/l4AACAD66urtI0m0lTuzvbxycnSgoAAECFCEECAAAAAABUWJpm8YxCkJtZpp4AAABUy4YSAAAAAAAAAAAAAFUkBAkAAAAAAAAAAABUkumwAQAAAAAAAACAOZqEUbN5qQ7APAhBAgAAAAAAAAAAc5QXtTjN1AGYByFIAAAAAAAA4Bv89OZCEQAAgJLYUAIAAAAAAAAAAACgiowECQAAAAAALFqWF8PBoIQrFoxHvdtBtYqZZGYVBAAAYH0JQQIAAAAAAIuW5Xmn1y/jimV5nMoUAgAAQGWYDhsAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkhpKAAAAAAAAAMCn2u32EpeeJKkuAADgNwlBAgAAAAAAAPAZ40mkCAAAlJzpsAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkoQgAQAAAAAAAAAAgEpqKAEAAAAAAAAAwBpqt9sPeVqaZWoFQGkJQQIAAAAAAAAArKPxJFIEAKrOdNgAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAym80Hk/C8JtekiSpugGUVpYm7euOOgAAAAAAPJEQJAAAQAWEcVqrCTUCrIgsTZqtdpbnSgEAAAAA8ERCkAAAAACwOMF41O72ikIlAAAAAABmQAgSAAAAABbkptvtjwJ1AAAAAACYFSFIAAAAAFiEq6urIIzVAQAAAAC+otPrT2/qwMMJQQIAAADAfGVpctXuREmqFAAAAAAAsyUECbBkSZK22+1vekmaZeoGAABQFVE4ubq+yfJcKQAAAAAAZk4IEmDJ4jSb3tQBAABgJQXjUbvbKwqVAAAAAACYCyFIAAAAAJiLm263PwrUAaAMRuPxJAwf8szMNCwAAABQKUKQAAAAADB7rVYrjFN1AD7S6fWnN3VYvF/+JvuzDAAAACtICBIAAAAAZilLk3dX13FqIDEAAAAAgLkTggQAAABgfTWblzNvM82yvFBaAAAAAIBFEIIEAAAA4P9n745a2gbDMAwXKbgdqAg7HcP//6NERMEg25quNE2+N7XiiQiyupA1r70uelJaaPu0J4WbfMfL9RoBAAAAGC4ilnVtBzgIESQAAAAAAAAAAMC/a9rStAs7wEGcmAAAAAAAAAAAAADISAQJAAAAAAAAAAAApOQ4bAAAAAAAAAAAABhFRCzr2g7jEUECAAAAAAAAAADAKJq2NO3CDuNxHDYAAAAAAAAAAACQkitBAsDBXN/c5n3zq/Vm//d/9eO7rxsAAAAAAJiC6LdvziSNCLMAQF4iSAAAAAAAAADgWETfP/5yJikAfB6OwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAHxAlC76rR0AAACYgrkJAAAAAAAA2NOyrn/+XmggAQAAmAgRJAAAAAAAAH8XpXuoHjddMQUAAADTIYIEAAAAAADg2brZ3N3dv/doF7F1AUgAAAAmRgQJAAAAAADAs347a0vYAQAAgEROTAAAAAAAAAAAAABkJIIEAAAAAAAAAAAAUhJBAgAAAAAAAAAAACnNTQAAAAAAAAAAwGfSdaWqqrFfws4AUyCCBID/ZPcva7XeHOdnv765fX332+XF2fm5nwQAAAAAAAAjaUvsbnYAOAaOwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgpbkJAGCIritVVe35THO9+LNarZvGDgAAAAAAAADAQCJIABikLbG72eFDmrbMZpJQAAAAAAAAAGAox2EDAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgJREkAAAAAAAAAAAAkJIIEgAAAAAAAAAAAEhp/vXLqRUAAAAAAAAAAACAdJ4EGAD0UiXBHYVPBAAAAABJRU5ErkJggg==)\"></div></div>", "meta": { "options": { "id": 760, "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 }, "8uflrc8ao4r": { "assetType": { "id": 223, "name": "referenceblock" }, "design": "<div class=\"default-design\"><div style=\"width:100%;height:150px;background-size:cover;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADawAAAEtCAIAAADRXFFBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAALyhJREFUeNrs3ftvI+l+J2aOSF27JbWu7Z72nPEJdrOws5ss9hcj58R/vWEDQYLAhjdeZHfhcbeGYosiRfFWrHuFPZpty30btcRLFfk8IASKIt+q+r6UVMX61Pt+13r3rgYAAAAAAAAAAABQNY2rd1eqAAAAAAAAAAAAAFTOhhIAAAAAAAAAAAAAVSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUkhAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFSSECQAAAAAAAAAAABQSUKQAAAAAAAAAAAAQCUJQQIAAAAAAAAAAACVJAQJAAAAAAAAAAAAVJIQJAAAAAAAAAAAAFBJQpAAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAAADg4drt9ngSTe88290+Pz9XEAAAAIAlMhIkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAAAAAAAAAAAAlSQECQAAAAAAAAAAAFRSo7Rr1mxexmn26eO///EH3QYAAAAAAAAAAAAYCRIAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvSicKAIAMG9CkAAAAAAAAADA7MVxoggAwLwJQQIAAAAAAAAAs5fnmSIAAPMmBAkAAAAAAAAAzF5kJEgAYP6EIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYiyicKAIAMFdCkAAAAAAAAADAXMRxoggAwFwJQQIAAAAAAAAAAACV1FACAAAAmLlm8zJOM3X4yOnR4f7BgToAAAAAAACzYiRIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAACYvaIo8jxTBwBgrhpKAAAAAAAAAADMXJpm0XeJOgAAc2UkSAAAAAAAAAAAAKCShCABAAAAAAAAAACAShKCBAAAAAAAAAAAACqpoQQAAADwFMF4lGX5Rw9meaEyn4qiqDYYfPTg3t5uvbGpOAAAAAAAwCMIQQIAAMCT9G4HcZqpw0MMg3B6++jB01pt/0AIEgAAAAAAeAzTYQMAAAAAAAAAAACVJAQJAAAAAAAAAMxFkqSKAADMlRAkAAAAAAAAAAAAUElCkAAAAAAAAAAAAEAlCUECAADwVFmaKAIAAAAAH8nyQhEAgHlrlGElfnpz8cQnP9vdPj8/150AAACLNxwMbm77P/7uB6UAAAAA4L4sz+sbdXUAAOaqoQQAAAA8WpYmN7f9vKi12+31uTit2byM00zvz0qn15/ePnx7enS4f3CgLAAAAAAAwEOYDhsAAIDH63Rv7iY1Gk+iYDxSEACAr+jf9qJwog4AAABQUcPBQBFKSAgSAACAxx/qB2H84dvOTV9NAAC+tOPUbF7e9EdxnKgGALBWksx8GgCsjsHQeBBlZDpsAAAAHqnXH97/NsvztZoUGwDgIYaDwWA4ilPn/gGANVUUagDAiojCyfQAf/p1e2dXNUpFCBIAAIDHaLfbWZ5/9GAQRg7+AQDuTPeLbnq3YZwqBQAAAKyAMAynX8fjwHmQshGCBAAA4JsF49F4En36eFHUOt3e69cO/gGAtSb+CAAAAKsnjOLp1yR1vF86QpAAAAB8s85N/0s/itOsc319enamSgDAGsrSpHvT++zlIgAAAEClRb9c7hi56LF8hCABAAD4Np3r608nwr5vNAn3TYoNAKyZu/hjEEZFoRgAAACwggf+dydHpl+n9+uNTTUpjw0lAAAA4OGicDKahF9/zt2k2GoFAKyPzvX1xeW78UQCEgAAAFZTEEw+3B+NRgpSKkaCBAAA4Bt0ur2HnNqP06x/2zt8caRiAMBqu+l2h+Mgl30EAPhEliZ3dyJzhsCyTX8Nb3q3Gxsb9Y2N7e3t/YMDNYFvNQn/ZYSIKE4UpFQWGoIcDgbz2nnKss82vre3a+hRAACAWelcX8dp9sAn9waj58+fOygDAFbYeBIpAgDAl3wYMSuOEyFIWJa7+GMYpx8eGQZhp9ff+K622Ziq7+7sbG1t+iWF35Qk6WfvUwYLDUFO/4bOqeXpH+sw/kzjp7Xa/oHzbQAAADOQpclvToR9X1HUrtqd779/pXQAwCoZDgZhZLwHAACg7D6NP96XF7UoSae3u4u7vvuutlmvb242GvX6zs723rPnCggfuT9IxMMHjGAxTIcNAADAg1y1O8U3zvMYJWmlJ8Vut9uGd1q8Tq//2asof//jD4oDwHLddLujIMzyXCngiaJwEq/Z5HH1+oYkAQCwyN2tr8QfP6so3oe67nJd/VFQ6/TqGxubjemtsb29bSJW+HSO4ukjZpYvDyFIAAAAflv/thc9anKHW5NiAwDVd9PtDsdBXqgEzOj4YjBct8uNthp1IUgAYAEeEX/8kizPszifNjUMwtq96bO3tzZ3dnZMn83a/XJF0aeP7KtLaQhBAsDqa7fbn9kJqNePT04UB4CHyNKkNxg97rV5Uet0b16+fKmMAEAV94L677Na4o8AAEDZzTD++Fn/avrs/vuPi7ca9UajvtlobG5uGg+PlRd/Mk5EnKTKUh5CkACw+j57Yf30sERlAHigR0yEfV8QxmaFAACqJUuT7k0vCKNC/BEAACi3eccfv+R/TJ8dT+93ev36xkajvtFo1Hd3dkyfzeqJ0/Q3H2GJhCABAAD4muFgED35csab276PvQCAShB/BAAAqmJZ8cfPH0zl+fT261CRvf5339U26/XNzcb21ubU3rPn+otK/659+inB9JFgPPLeLgkhSAAAAL4oS5Ob2/7T2zEpNgBQfnenD6MkFX8EAJitSRiaJATmcfxSkvjjZ00PrO6Givx1zrpO7/D53vHJib6jisbj4LOPh2EkBFkScwxBNpuXS9+8Xn84GI7uP3L04sCbDwAA4IE63Zt8RiGAIIxdEwkAlFP5Tx8CAFRRnmd3dwpXmYDjl1otzTLdR1V/7+L4mx5n8eYYgozT5f/x+mWs3X/9yEffAwAA8AXDwSAIZ3kA37np/04IEgAo2Q7PaDwWfwQAmLlgPOoNfh2xKAjjm27XCHAwE5dXHUWABYuT9JseZ/FMhw0AAMDnzWQi7PuyPG+32+fn52oLACzdcDAYDEdluJgfAGD19G97vcHo/viP/VGQpOnLly8VB4BqydLkS1NmTR+Pwsn2zq4qLZ0QJACsmptu9yGDyU+f02637z+yu7Ozf3CggADcmf6byOcwT9F4EpkUGwBYLvFHAIC5uul2+6Pg08eDMG61Wudnp/XGpioBUBWj0egrPw3DUAiyDIQgAWDVTMLoISdy8uJ9DOWjB4UgAbgTjEef/puYld7tQAgSAFiKm253OA7mcaUHAAAf9rg+m4C8E8Zps9V+/epcDhKAqgij+Os/PVSjEthQAgAAAD7SuenPr/E4zTrX14oMACzSTbf75u1FfyQBCQAw352uryQg72R5/vPlu2A8Ui4AKiGK00f/lIUxEiQAAAD/SrvdzvJ8rosYTcL9cGKGCABg3rI06d70JmEk+wgAMG8PSUDeme6btbu981rNbCEAlN/Xz5jM+3wKD2QkSAAAAP5FFE7mNxH2B0VR63R7qg0AzE+WJu12++Ly3XTfRgISAGDerq6uHpiAvFMUtatO76bbVToAymw4GMzkOcybECQAAAD/YmHZRJNiAwBzEoWTD/HHQvwRAGD+Wq1WEMaPeGF/FEz33BQQgNKahOFMnsO8mQ4bAACAX3Wur+M0W9jiRpPwKE3qjU2VBwBmIgonN73bME6VAgBgYVqt1lN2wMaTaNrCq1evVBKAEkqSdCbPYd6MBAkAAMB7UTgZTRZ6teL7aY/aHZUHAGayJ9NqtS6vOhKQAACL9MQE5J1pC28vmlmaqCcAZZNkvz1yxCJHl+BLjAQJAADAe51ub/HzRUZJ2r/tHb44Un8A4HGGg8FgOHK+Acrm63ObruFAKWmWfb0m5+fn3jZAtWRp0r6e2SUoWZ43W+3T48O9Z8/VFoCSCMajB543mT7Tv7DlemoIcjgYdHr9Cm3wdG0/u8Jbjfrr1997QwAAAOupf9tbVnSgNxg9f/7cpNgAwLcSf4QyG08iRbgvL9QEWClZmjRb7SzPZ9lmnre7vfNaTYgEgJIIgsnDn+n/13IZCRIAAGDdZWnSG4yWtfSiqLWvO69evdIRAMAD3XS7kzASfwQAWIp5JCDvvP+YqNs7CKPjkxN1BmDp4gePYR+v32j3ZSMECQAAsO6u2p3FT4R9Xxinw8Fg/+BAXwAAX3fT7Q7HQV6oBADAcswvAXmnKGr9UZDn+enZmWoDsFxJms78mczJhhIAAACss/5tLyrBFYo3t/0sTXQHAPCVnZY3by/enxGXgAQAWJJ5JyA/GAZhq9VScACWKAonD/8IYvrM6fMVbYmEIAEAANZXlia3y5sI+768qHW6N3oEAPiS0Xgi/ggAsETBePTz5bsFJCDvhHHabF66aBaAZRmPg7k+n9kSggQAAFhfne5NecIEQRgPBwOdAgAAAFA2wXjU7vYW/DlSnGbNVtvAWgAsxbfOcB3FsaItUUMJAACgDK6urtI0e0oLr19/r4x8k+FgEITlOia/ue3vHxzoGgAAAIDyuEtAFsu4kjbL81a7c35ytPfsuY4AYJGi+NtCkEmaK9oSCUECAEAppGkWPy0ECd8kS5Ob237Z1iovau12+/z8XAcBAAAAlMESE5B3pouersBRkhy+ONIdACxGliZZ/m2hxunzp6+qNzZVbylMhw0AALCOSjUR9n3jSRSMRzoIAAAAYOmGg8FyE5B3pitw0x/ddLt6BIDFGI1GC3sVM2EkSAAAgLUTjEdlmwj7vs5N/3cLmeFoWocs+9qlnFlmfNYSGQ4GX3/C3t6uq2wBAABgVm663f4oKM/6TFcmiuNXr17pGgDmLYqTR7wqjOJDtVsSIUgAAIC107npl3n1sjxfzKTYvduBaeir9L7t/cb79rRW2z8QggQAAIAZKFsC8k4Yp5eXrZfnpy6DZLX99OZCEWC5kiR9xKtSZxyW56EhyGbzcrXPDE237kv/RX7/4w/eKAAAwMpot9tZnpd8JceTKAon2zu7+gsAAABgwcqZgLwTJWmz1X796lwOEoD5eVxMzrALS2QkSAAAWBHtdntBRxH1+vHJiYJXVDAejSdRJVa10+29fi0ECQAAALBQ/dteaROQd7I8v7h89+r81AW0AMzDcDB4ymv3Dw7UcPGEIAEAYEUsLNm21airdnX1bgdVWdU4zTrX16dnZ3oNAAAAYGGiOCn/ShZFLY4TIUgA5mEShk95rRDkUmwoAQAAwJroXF9Xay6G0SSMwomOAwAAAAAAFiN9wpmU1IzYS2IkSAAA1lEwHmVZXqpVyvJCvzBXUTgZTcJqrXNRmBQbAAAAAABYnDhNl/JankIIEgCAddS7HcSuxGLNdLq9ooJR2+mvav+2d/jiSA8CAAAAAABzFYxHTzmZMn3ttIW9Z89VcsGEIAEAAFZf5SbCvq83GD1//rze2NSPAABQHldXVyZ6m6Fm8/IrP339+nslAgCABQjD6IktBMFECHLxhCABAABWXJYmlZsI+76iqF21O99//0pXAgBAeaRpZo6FGVJMAAAogyiOn9hCYkbsZdhQAgAAgNV21e5UcSLs+6Ik7d/2dCUAAAAAADA/cZIuvQUeQQgSAABglfVve9FKHG/3BqMsTXQoAAAAAAAwD1E4yZ88qMS0hWk7irlgpsMGAAC+TZxmP725+KaXnB4d7h8cKN0CtNvt8SRayU0ritrb5jtvLQAAAACg6oLxKMtydYCyCcNwJu2Mx8H2zq56LpIQJAAAAAAAAAAALEjvdhCnmTpA2YRRPJN2ktSM2IsmBAkAVFizeVndld/d2T4+OdGJAAAAAAAAAEsXxWmp2uHhHhqCfP36+88+vjJTrW016l/aRgCgtCp9kdxm5go/AAAAAAAAgOXL0iTLZzNP/bSdaWv1xqaqLsyGEgAAAAAAAAAAALC2gmBS2tb4TabDhser9Bys9xkGFQBgZRwe7O/u7NzdH43H4SpOuHB6dPjh/t7erk4HAAAAAACeaBKGs21t/+BAVRdGCBIer9JzsAIAsJK2d3ant3uH6ysYgvSpAQAAAAAAMFtJkpa2NX6T6bABAAAAAAAAAABYX7MdCs3AagsmBAkAAAAAAAAAAMCaCsajmbc5HAwUdmFMhw1UW7vdXtait7c2D18c6QIAAAAAAAAAgOoKgsnM24yiaF9lF0UIEqi28SRa4qKDSfjq1Su9AAAAAAAAAABQUXGSVqJNvsR02ACPF8Zps3mZpYlSAAAAAAAAAABUUZymlWiTLzESJMAT/2llP1++Ozs52nv2XDUAAAAAAAAA1tlNt5tm2def85tPABYpCidFMftmp21OW97e2VXhBRCCBHiqvKi1u72jJDl8caQaAPD5o8coqg0GHz24tbXpwA8AAAAAgFUyCaM4lXGEKhmPg/m17FzYYghBAsxAUdRu+qMoTs7Pz1UDAD41DMLp7aMHn+1unzvwAwAAAAAAYHmiOK5cy3xkQwkAZmU8iVqtVpYmSgEAAAAAAAAAUH5xklauZT5iJEj4jCicxPEa5diGn8xN+Zv29nbrjU1vlU+FcdpstV+eHRvQGAAAAAAA+Kyf3lxUZVV//+MP+gsAWGFZmuTFvBqftjxtX8BmAYQg4TP6g+F4Eq3P9nZ6/W99yWmttn/gb/QX/kHmeavdOT852nv2XDXg0Sr0ISAAAAAAAAAAVTQajebd/uGLI3WeN9NhA8xeUdSuOr2bblcpAAAAAAAAAADKKYziSrfPHSFIgHnpj4Krqyt1AAAAAAAAAAAooTTN5tp+FKeKvABCkABzFIRxs3mZpYlSAAAAAAAAAACUSjznEGSW54q8AEKQAHP/f9lstYPxSCkAAAAAAAAAAEpiOBiszFLWnBAkwNxled7u9vq3PaUAAAAAAAAAACiDSRiuzFLWXEMJABagKGo3/VGSpKdnZ6oB/I+d3ajZvFyHLd3Y+O787LTe2NTpAKynUl3mu39woEcAqKgonPQHw0e//PBgf3tnVxkBAAD4IEnSlVnKmhOCBFicYRAmrZYkEHAnL2pxmq3Jxl5cvnu+uyMIDsB66vT65VmZm9v+/rO945MT/QJA5cRxMp5Ej3757s6OECQAAAD3JVm2MktZc0KQAAsVxmmz1X796lwOElgrRfE+CB41L09PjpxzAoAlyotafxRMwuhg/7lRIQEAAACeYjgYfDrLbSrtBBURjEdFsYgFTZcyXdbes+dqPj9CkMBjjMbjT3fmeKAszy8u352fHPkPB6ybOM1a7c7ezvb5+blqAMBy/yl3ev3BcCQKCQAAAPBokzB8ymjlwHIFwWSRyxIRmSshSOAxwjit1VJ1eLSiqLW7vYMwMgkdsIZ/AMeT6O1F8/T40I4+ACzXXRRyNB4fH70wVDMAAAAAsFbyxYwDufBlrSchSIDlKH6ZhC5J05cvX6oGsG6yPL/q9PZG4+++++6hu631uuA4AMxDGKeXV52drYYoJAAAAMF4FEZJJVZ1NB6b3AAAuLOgEOTm5uYf//CXLw4Pn9hOkqR//Td/OxgM9RywIkeSYdy5vj49O1MKYD3/Bj78yVuNuooBwPyEcdpqd/Z2tk+Oj+qNTQUBAABYQ/3bXm8wqspIVdMj2bcXzdevzh3GAgAbi1nMTBKQtfdhysZf/fEPe3uGJQBWh0GPAQCAMpgemown0cXlu3a7naWJggAAAKyV6cHgTX9UrdNWWZ5PD2OD8Uj3AcCaW9BIkDNJQN7Z3Gzs7e4GweT+g7/709d/+sOfTu/8fPHz25+b+hUAAADgEe6ikJPLd/vP9o5PThQEAABg5WVpctXuREla0cPYq07vMIwcwwLAOmuswDb87k9f/6f/9B/v7nc6XZ0KAAAA8BR5UeuPguE4EIUEYMF+enOhCACwSMF4dN3t5RWft2x6DBvF8fnZqamxAWA9bVR9A+4nIKdSszUBAAAAzMJdFLLZvBwOBqoBAACwem663Xb1E5B3wjhtttpRONGtALCGqh2C/CgB+c9v3v7TT290KgAAAMCsxGnW6fVFIQEAAFbM1dVVfxQUxepsUZbnrXbH0SsArKEKT4f9UQIySdIgmPzP//bf3H2bpsm7q/b0EX0MAAAA8ER3UcjReHx89GJ7Z1dBAAAAqit7fzL9enqgt3qbVhS16dFrFEWnZ2c6GgDWR4VDkPcTkFObm42/+PN/d/+R//U/1P7xv/x///W//XfdDAAAAPB0YZxeXnV2thqikAAAABUVjEfXqzIF9pcMgzBptc7PTuuNTT0OAOtgY7U37y/+/N/9L3/x57oZAAAAYFbCOG21O+12O0sT1QAAAKiQm263veoJyA+Hrs1WOwpNHQkAa6HCIcgkSR/ytH/7b/6nvT0jEwAAAADMTFHUxpPo4vKdKCQAAEBVXF1d9UdBUazL9mZ53mp3hoOBrgeAlVfh6bD/+m/+9q/++IfNzV83IUnS6SODwXB6/+Bg//6P/uTl+T/99EZnAwAAAMzQXRRycvlu/9ne8cmJggAAAJRTlibvrq7jNFvD49ZOrx9F0enZmbcBAKywCo8EORgM//pv/vbDeJCbm42/+uMfDg72P/zowzMbjU09DQAAADAPeVHrj4I3by9uul3VAAAAKJtgPPr58t0aJiA/GAZhq9UyjwEArLCNSq/9pznIP3n58sOP9C4AAADAYtxFIZvNSxONAQAAlMdNt9vu9vJi3esQxmmz1Y7CibcEAO12u9m8nN4mYbSwhU6XdbfQ6dJ1wTxsVH0DPspBAgAAALAscZp1en1RSAAAgDK4urrqj4KiUIn3sjxvtTsOVwGo/fIx5vS2yIsEpsu6W6jiz0ljBbbhLgd5Nwbkzc2NTgUAAABYorso5HA0Pjl+sb2zqyAAAAALlqXJu6trSYuPFEVtergaRdHp2ZlqAKyt3Z2d8SRa4tJ1wTwsKAT5z2/e/tmPv5tVU53ux0nHwWBo/msAAABgtq6urlJnjB4rStLLq87OVuP4SBQSAABggYdj4eRdu2MK7C8ZBmF2dfXyl1GWAFhD+wcHnV5/iUvXBfOwoBDk3/39PwwGg0Zj84ntpGnyTz+90W0AAADAAqQmKHmyMH4fhXy2u31yfFR/8kdDAAAA/KY4TiQgf/N4XxEA1tlWo76UD36ny1X8OVncdNjCiwAAAADraTyJgst3ezuikAAAAADAkm1uNpYSgpwuV/HnZEMJAAAAAJi3ongfhby4fHfT7aoGAAAAALAsuzs7a7XcdSAECQAAAMCCFEWtPwrevL0QhQQAAAAAlmJvb3etlrsOjLEJAAAAwELlv0QhR0F4dLi/f3CgIAAA3yQYj3q3g6884fXr71UJAAC+pN7YrG9sZHm+0IVubEyXq/hzsqAQ5Obm5n/83/7D9OsT20mS5O/+/h+mX/UcAAAAQKVled7p9QfD0cH+c1FIAIBv2I/K8jjN1AEAAB5te6sRhPGCl6js87Og4v7xD3/54vBwJk09e7b3N3/7f8pBAgAArKd2uz2rptLMWUNYvjjNOr3+cDQ+OX6xvWM6GACAGWg2L+fR7OZm4/z8XHkBAFgBO9tbCw5BTpeo7POzoBDkrBKQd00dHux3ujc6DwAAYA2NJ5EiwOqJkvTyqrOz1Tg+EoUEAHiqOY0TOW327UXz9Phw79lzRQYAoNKeP39+0x8teInKPj+LHmYzCILROHjEC7e2NmeYpAQAAACgbML4fRTy2e72yfFRvbGpIAAAZZPl+VWntzcav3z5UjUAAKiuemNz47taXixocdNl+cBzrhYdgvznNxf/9b/990e88PTk+P/44/+uwwAqKgon/cFw5s1ub20evjhSXgAAWCXjSRRcvtvbEYUEACipBc8bCAAA87C12QjjdGHLUvC5Ul8AFiGOk3nMXDltM4xi1xwDAMCKKYpfo5AHz/aOT04UBAAAAGB9/PTmolTr8913tfOTo71n5jJeNfV6vVZLF7gs5mhjVTdsc9M4AQBrIQjjy8tWliZKAQAAK6Yoav1R8ObtxU23qxoAAAAALEVR1K46PZ9QQZmtZghyc3Pzj3/4S70LsCaiJG222sF4pBQAALB68l+ikG8vmsPBQDUAAAAAWIr+KOhcX6sDlFMlp8P+9//+L+L4ayN+PX+2N/Xh23dXV3oaYLVled7u9k6yfP/gQDUAAGAl9/k7vf5gODrYf263HwAAAIDFGwZh0mq9evVKKaBsKhmCfHF4+PAnt687g8GwbJsQjEdZlq/ne65e39h79tzvHjBzRVHr9PpRFJ2enakGAACspDjNprv9w9H45PjF9s6uggAAAACwSGGctlqt87PTemNTNaA8Gqu9ebf9/v/1f/8/JVyx3u0gTrP1fM9tNepCkMD8rOfFN+12+/63afbIfzFJkt5vqlGvH5+ceFMBAFA2UZJeXnV2thrHR6KQAAAAACxUGKfNVvv1q3M5SCiPSoYgb/v9r0+Hfefdu3cXP18mSaKbAdZtp/PtRXOtdjrHk2gm7cRpdj+jv9WoezsBAFDmPf/Lq86z3e2T4yOfOAMAAACwMFmeN1vtl2fHLtCFkqhkCPI//+d/7HRvdB4AX9npvLh8d35yZOhZAABYbeNJFFy+29sRhQQAAABgcbI8b7U7TklDSSw6BPlnP/5wevqYiTW3tnyKDbAgw8Gg0+tXfSuKotbu9g7CyITOAACw2qY7/3dRyINne/b/AQAAAFiMu1PSR0ly+OJINWC5Fh2C3PuFugOwmJ3O/ihIs+z8/Fw1AABgHfb/h+Ngf9WjkFmaBMFkrTp3/+DAOxwAAAAooaKo3fRHWZa7NBeWa0EhyH9+8/bPfvzdTJq67ff7g6GeA+CBxpPo8rL18vzU1HgAALDy8l+ikKMgPDrcX9XkXBBMVmDw/m8iBAkAAACUmaF5YOkWFIL8u7//hyRJDw+f+nllkiS/NJXoOQAeLkrSZqv98ux4e2d3JTfw2e723Z3xJHp6axvf1XZ33jfYqNe9eQAAqKIszzu9/mA4Oth/Lj8HAAAAwLyNJ1Hn+vr07EwpYCkWNx32//uP/0W5AViWLM9b7c7Ji8OVPAP64aKin95czGDnoF53lRIAACsgTrNOrz8cjU+OX6zqBVEAAAAAlEReFIoAy9JQAhYszbJ2u/2kd229fnxyopLAt5ruc3Z6/SRJ/A0BAID1ESXp5VVnZ6txfCQKCQAAAI/UbF7Gabb01dhq1F+//l53APARIUgWLS+eOlvrdLdGGYFH64+CKI5fvXqlFAAAsD7C+H0U8tnu9snxUb2xqSAAAAAAACtDCBKgekpyoVV1hXH69qL5+tW5c58AALBWxpMouHy3tyMKCQAA1XDT7U7CaFlLbzTqL1++1AsAAOUnBAnAOsry/OfLd2cnR3vPnqsGAACsj6L4NQr5fHfn9OxMQfjIT28uVn4bf//jDzoaAKiKNMuMCgEAwG/aUAIA1lNe1NrdXv+2pxQAALBuiqI2DMI3by9uul3VAAAAAACoNCNBArC+iqJ20x9FcXJ+fq4aAACwbvKi1h8FxycnSgHwCFE46Q+Gj3hho173txcAAACYISFIANbdeBK1Wq3zs9N6Y1M1AAAAAB4ijpPxJHrEC7caddUDAAAAZsh02ABQC+O02WpH4UQpAAAAAAAAAAAqRAgSAN7L8rzV7gTjkVIAAAAAAAAAAFSFECQA/Kooaled3k23qxQAAAAAAAAAAJXQUAIAuK8/CqI4fvXqlVIAAACsm9Ojw7s7vf4wy/OV2a76xsbR4b7+BQAAAGAlCUECwMfCOG02L//k5Vm9sakaAAAA62P/4ODuzmA4ylYnA1mrb3z3YdOooqurqzTNyrZWWV48+oXDweD9O7O+sffsuf4FAAAAnkgIEgA+I06zZqt9enzos3gAAABgudI0i8sXgny0LM87vf70zlaj7oMXWENROOkPhlVc892dHRcVAABAOQlBAsDnZXne7vaOkuTwxZFqAAAAAAA8XRwn40lU0ZUXglxbw8FgEoZf+unhwf72zq4qAQAskRAkAHxRUdRu+qMkSU/Pzsq/tnczST1dnGZZmpgKHAAAAAAApiZh+JXw7u7OjhAkAMByCUECwG8YBmHSap2fnZY8Fzgaj2fVVK93W4ncJwDAv9qH6Q8Hw9Fs20yyTGEBAADWU5pl7Xb7/bFhkqoGAECZCUECwG8L47TZar9+dV7aHGSWJtOVnFVrQRjrdACgcrI8z3JlAAAAYDbyovaQ2ds7vf709tkfnR4dmkUdAGABhCAB4EGyPL+4fHd+crT37HkJV6/Xu53txgbjUTm3lLWVZFmzeTnbBlUVAKAShoPBQ55Wr284igEAAACANSQECQAPVRS1q07vMIyOT07Ktm7jSTjbBvuDodOHlO0XME7FFgGAVfPAeN99URStW5W+NKzOR7YadUcxAAAAALCGhCAB4Nv0R0GSpi9fvizPKg0Hg7yYcZtRkmZpUtrpvwEAYDU8MN4HAAAAAMCXbCgBAHyrIIwvL1tZmpRkfUbj8czbLIpavz/Q1wAAAAAAAABAmRkJEgAeI0rSZqt9eny49NnWsjQJ43QeLY+C8PhEVwMAAAAAD5KlSRBMvv6cKIoUCgAAmC0hSAB4pCzP293eea223Bzk/MZrnG5gMB4tPeUJAAAAAFRCEEw6vb46AAAACyYECQCPVxS10ThYbkxwFITza7w/GApBAgAAAMByNZuX97/N8kJNAAAAPhCCBIAKC8ajLM/n136UpIoMAAAAAMsVp5kiAAAAfMmGEgBAdfUHw7m2XxS1m25XnQEAAAAAAACAchKCBICqytJkASM1TsJIqQEAAAAAAACAcjIdNgBUVb8/KIq5LyVOsyicbO/sKjgAAAAAAMC3ajYv4zQr7er9/scf9BEwWzfdbpo96e/e4cG+M9R8EyHIX2V5MRwMFrk4NQfgiUZBuJgF3fYHL+1iAgAAAABrbBJGzealOgAAPGTH6Ynh792dHSFIvokQ5K+yPO/0+upQkc6ae2I1yzJ1BkouGI+m/7wWtJMaxQoOAAAAAKyzvKiVeSA3AAB4tHa7PZ5E817K6dHh/sHBnBoXgqR6JFYBpoaj8cKWVRTvRyw/PjlRdgAAAAAAAACgVIQgAaCSFjw64ySM1BwAAAAAAFhJN93u/E6FJOYhBIA5E4IEgEoeihfFQpcYp1kUTrZ3dhUfAAAAAABYMWmWmfIeAKpLCBIAqmcp4zL2B8NzIUgAAKCs4jT76c2FOgAAAADAutlQAgColiicLOViRDNiAwAAAAAAAABlYyRIACijLE2CYPLZH43G46WsUl7UOtfX29vbn/3p/sGBXgMAAAAAAGB+srwYDgYPfPLW1ua2Wc4A1oMQJACUURBMOr1+2dZqGITT22d/JAQJAAAAAADAXGV5/vAzaM92t8+FIAHWg+mwAQAAAAAAAAAAgEoyEiQAAAAAAAAAzFin1y/hpE8AlEq73V69jUqzTM+yYI1m89K7FgAAKI9gPMqyfOmrsbW1uW2qFABgJSRZ9sTPgUuyFboSAACAFTOeRIrAnZ/eXKz2Bvb6w8FwNKfGG3HqkyMAAKBMh0C3gzIcpzzb3T4XggQAVkJR1HwODAAAAMASZXk+v1FQNtQXAAAAAAAAAAAAqCIhSAAAAAAAAAAAAKCShCABAAAAAAAAAACASmooAQCU0N7e7um9b0fjcRinpVrDna3G82fP9BQAAAAAAAAAsERCkABQRvXG5v7B5odvJ2FYq5UrBFmv1/cPDvQU8BRZlg0Hg888nhdlXr1l2dvbnf538LYBAAAAAACA+4QgAQCA5QjjNIz7Vu+BTmu1+/l4AACAD66urtI0m0lTuzvbxycnSgoAAECFCEECAAAAAABUWJpm8YxCkJtZpp4AAABUy4YSAAAAAAAAAAAAAFUkBAkAAAAAAAAAAABUkumwAQAAAAAAAACAOZqEUbN5qQ7APAhBAgAAAAAAAAAAc5QXtTjN1AGYByFIAAAAAAAA4Bv89OZCEQAAgJLYUAIAAAAAAAAAAACgiowECQAAAAAALFqWF8PBoIQrFoxHvdtBtYqZZGYVBAAAYH0JQQIAAAAAAIuW5Xmn1y/jimV5nMoUAgAAQGWYDhsAAAAAAAAAAACoJCFIAAAAAAAAAAAAoJKEIAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkhpKAAAAAAAAAMCn2u32EpeeJKkuAADgNwlBAgAAAAAAAPAZ40mkCAAAlJzpsAEAAAAAAAAAAIBKEoIEAAAAAAAAAAAAKkkIEgAAAAAAAAAAAKgkIUgAAAAAAAAAAACgkoQgAQAAAAAAAAAAgEpqKAEAAAAAAAAAwBpqt9sPeVqaZWoFQGkJQQIAAAAAAAAArKPxJFIEAKrOdNgAAAAAAAAAAABAJQlBAgAAAAAAAAAAAJUkBAkAAAAAAAAAAABUUkMJAAAAym80Hk/C8JtekiSpugGUVpYm7euOOgAAAAAAPJEQJAAAQAWEcVqrCTUCrIgsTZqtdpbnSgEAAAAA8ERCkAAAAACwOMF41O72ikIlAAAAAABmQAgSAAAAABbkptvtjwJ1AAAAAACYFSFIAAAAAFiEq6urIIzVAQAAAAC+otPrT2/qwMMJQQIAAADAfGVpctXuREmqFAAAAAAAsyUECbBkSZK22+1vekmaZeoGAABQFVE4ubq+yfJcKQAAAAAAZk4IEmDJ4jSb3tQBAABgJQXjUbvbKwqVAAAAAACYCyFIAAAAAJiLm263PwrUAaAMRuPxJAwf8szMNCwAAABQKUKQAAAAADB7rVYrjFN1AD7S6fWnN3VYvF/+JvuzDAAAACtICBIAAAAAZilLk3dX13FqIDEAAAAAgLkTggQAAABgfTWblzNvM82yvFBaAAAAAIBFEIIEAAAA4P9n745a2gbDMAwXKbgdqAg7HcP//6NERMEg25quNE2+N7XiiQiyupA1r70uelJaaPu0J4WbfMfL9RoBAAAAGC4ilnVtBzgIESQAAAAAAAAAAMC/a9rStAs7wEGcmAAAAAAAAAAAAADISAQJAAAAAAAAAAAApOQ4bAAAAAAAAAAAABhFRCzr2g7jEUECAAAAAAAAAADAKJq2NO3CDuNxHDYAAAAAAAAAAACQkitBAsDBXN/c5n3zq/Vm//d/9eO7rxsAAAAAAJiC6LdvziSNCLMAQF4iSAAAAAAAAADgWETfP/5yJikAfB6OwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAHxAlC76rR0AAACYgrkJAAAAAAAA2NOyrn/+XmggAQAAmAgRJAAAAAAAAH8XpXuoHjddMQUAAADTIYIEAAAAAADg2brZ3N3dv/doF7F1AUgAAAAmRgQJAAAAAADAs347a0vYAQAAgEROTAAAAAAAAAAAAABkJIIEAAAAAAAAAAAAUhJBAgAAAAAAAAAAACnNTQAAAAAAAAAAwGfSdaWqqrFfws4AUyCCBID/ZPcva7XeHOdnv765fX332+XF2fm5nwQAAAAAAAAjaUvsbnYAOAaOwwYAAAAAAAAAAABSEkECAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgpbkJAGCIritVVe35THO9+LNarZvGDgAAAAAAAADAQCJIABikLbG72eFDmrbMZpJQAAAAAAAAAGAox2EDAAAAAAAAAAAAKYkgAQAAAAAAAAAAgJREkAAAAAAAAAAAAEBKIkgAAAAAAAAAAAAgJREkAAAAAAAAAAAAkJIIEgAAAAAAAAAAAEhp/vXLqRUAAAAAAAAAAACAdJ4EGAD0UiXBHYVPBAAAAABJRU5ErkJggg==)\"></div></div>", "meta": { "options": { "id": 761, "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" } } }, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "template": { "id": 0, "assetType": { "id": 214, "name": "defaulttemplate" }, "name": "CONTENTTEMPLATES_BLANK_PAGE", "meta": { "contentHash": -765177524 }, "availableViews": [], "slots": { "banner": { "locked": false, "availableViews": [], "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "data": { "email": { "options": {} } }, "modelVersion": 2 }, "data": { "email": { "options": {} } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" } } }, "modelVersion": 2, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 } } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_htmlblock.json ================================================ { "id": 1322777, "customerKey": "testNew_asset_htmlblock", "objectID": "26fdf503-eeed-49eb-b428-cb3ghbc2ba49", "assetType": { "id": 196, "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_htmlblock" }, "name": "testNew_asset_htmlblock", "description": "bla bla", "owner": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "createdDate": "2024-05-07T05:08:46.927-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2024-05-07T05:08:46.927-06:00", "modifiedBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1324776/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<html></html>\n", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_template.json ================================================ { "id": 8973, "customerKey": "testNew_asset_template", "objectID": "a6aad42d-df00-4b5d-9780-b7adc2a3cfa4", "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "fileProperties": { "fileName": "testNew_asset_template" }, "name": "testNew_asset_template", "owner": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "createdDate": "2025-02-12T11:06:57.24-06:00", "createdBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "modifiedDate": "2025-02-12T11:06:57.24-06:00", "modifiedBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/8973/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style type=\"text/css\">\n ReadMsgBody{ width: 100%;}\n .ExternalClass {width: 100%;}\n .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}\n body {-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;margin:0 !important;}\n p { margin: 1em 0;}\n table td { border-collapse: collapse;}\n img {outline:0;}\n a img {border:none;}\n @-ms-viewport{ width: device-width;}\n </style>\n <style type=\"text/css\">\n @media only screen and (max-width: 480px) {\n .container {width: 100% !important;}\n .footer { width:auto !important; margin-left:0; }\n .mobile-hidden { display:none !important; }\n .logo { display:block !important; padding:0 !important; }\n img { max-width:100% !important; height:auto !important; max-height:auto !important;}\n .header img{max-width:100% !important;height:auto !important; max-height:auto !important;}\n .photo img { width:100% !important; max-width:100% !important; height:auto !important;}\n .drop { display:block !important; width: 100% !important; float:left; clear:both;}\n .footerlogo { display:block !important; width: 100% !important; padding-top:15px; float:left; clear:both;}\n .nav4, .nav5, .nav6 { display: none !important; }\n .tableBlock {width:100% !important;}\n .responsive-td {width:100% !important; display:block !important; padding:0 !important; }\n .fluid, .fluid-centered {\n width: 100% !important;\n max-width: 100% !important;\n height: auto !important;\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .fluid-centered {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n /* MOBILE GLOBAL STYLES - DO NOT CHANGE */\n body { padding: 0px !important; font-size: 16px !important; line-height: 150% !important;}\n h1 { font-size: 22px !important; line-height: normal !important;}\n h2 { font-size: 20px !important; line-height: normal !important;}\n h3 { font-size: 18px !important; line-height: normal !important;}\n .buttonstyles {\n font-family:arial,helvetica,sans-serif !important;\n font-size: 16px !important;\n color: #FFFFFF !important;\n padding: 10px !important;\n }\n /* END OF MOBILE GLOBAL STYLES - DO NOT CHANGE */\n }\n @media only screen and (max-width: 640px) {\n .container { width:100% !important; }\n .mobile-hidden { display:none !important; }\n .logo { display:block !important; padding:0 !important; }\n .photo img { width:100% !important; height:auto !important;}\n .nav5, .nav6 { display: none !important;}\n .fluid, .fluid-centered {\n width: 100% !important;\n max-width: 100% !important;\n height: auto !important;\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .fluid-centered {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n }\n </style>\n <!--[if mso]>\n <style type=\"text/css\">\n /* Begin Outlook Font Fix */\n body, table, td {\n font-family: Arial, Helvetica, sans-serif ;\n font-size:16px;\n color:#000000;\n line-height:1;\n }\n /* End Outlook Font Fix */\n </style>\n <![endif]-->\n </head>\n <body bgcolor=\"#ffffff\" text=\"#000000\" style=\"background-color: #ffffff; color: #000000; padding: 0px; -webkit-text-size-adjust:none; font-size: 16px; font-family:arial,helvetica,sans-serif;\">\n <div style=\"font-size:0; line-height:0;\"><custom name=\"opencounter\" type=\"tracking\"><custom name=\"usermatch\" type=\"tracking\" /></div>\n <table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" align=\"center\">\n <tr>\n <td align=\"center\" valign=\"top\">\n <custom type=\"header\"/>\n </td>\n </tr>\n <tr>\n <td align=\"center\">\n <table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"600\" class=\"container\" align=\"center\">\n <tr>\n <td>\n <table class=\"tb_properties border_style\" style=\"background-color:#FFFFFF;\" cellspacing=\"0\" cellpadding=\"0\" bgcolor=\"#ffffff\" width=\"100%\">\n <tr>\n <td align=\"center\" valign=\"top\">\n <table align=\"left\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr>\n <!-- added padding here -->\n <td class=\"content_padding\" style=\"\">\n <!-- end of comment -->\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr> <!-- top slot -->\n <td align=\"center\" class=\"header\" valign=\"top\">\n <table align=\"left\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tbody>\n <tr>\n <td align=\"left\" valign=\"top\">\n <table cellspacing=\"0\" cellpadding=\"0\" style=\"width:100%\">\n <tbody>\n <tr>\n <td class=\"responsive-td\" valign=\"top\" style=\"width: 100%;\">\n <div data-type=\"slot\" data-key=\"banner\">\n\t\t\t\t\t\t\t\t\t\t\t\t </div>\n </td>\n </tr>\n </tbody>\n </table>\n </td>\n </tr>\n </tbody>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td valign=\"top\">\n <custom type=\"footer\" />\n </td>\n </tr>\n </table>\n </body>\n</html>\n", "meta": { "globalStyles": { "isLocked": false, "template": { "background-color": "#FFFFFF", "border-color": "", "border-width": "0px", "border-style": "solid" }, "body": { "background-color": "#FFFFFF", "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#000000", "line-height": 1, "margin": "0px", "padding": "0px", "content-padding-top": "0px", "content-padding-right": "0px", "content-padding-bottom": "0px", "content-padding-left": "0px" }, "h1": { "font-family": "Arial,helvetica,sans-serif", "font-size": "28px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h2": { "font-family": "Arial,helvetica,sans-serif", "font-size": "22px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h3": { "font-family": "Arial,helvetica,sans-serif", "font-size": "20px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "links": { "font-weight": "normal", "color": "#0176d3", "text-decoration": "none" }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "background-color": "#5D5D5D", "border-radius": "3px", "padding": "10px", "border-color": "#5D5D5D", "border-width": "1px", "border-style": "solid" }, "mobile": { "body": { "padding": "0px", "font-size": "16px", "line-height": 1.5 }, "h1": { "font-size": "22px", "line-height": 1 }, "h2": { "font-size": "20px", "line-height": 1 }, "h3": { "font-size": "18px", "line-height": 1 }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "padding": "10px" } } } }, "availableViews": [], "slots": { "banner": { "thumbnail": {}, "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "modelVersion": 2 } }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_templatebasedemail.json ================================================ { "id": 8974, "customerKey": "testNew_asset_templatebasedemail", "objectID": "184d3a14-b983-429d-a723-36604d24022b", "contentType": "application/vnd.etmc.email.Message; kind=template", "assetType": { "id": 207, "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": "testNew_asset_templatebasedemail", "description": "", "owner": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "createdDate": "2025-02-12T11:06:57.63-06:00", "createdBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "modifiedDate": "2025-02-12T11:06:57.63-06:00", "modifiedBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/8974/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "meta": { "globalStyles": { "isLocked": false, "template": { "background-color": "#FFFFFF", "border-color": "", "border-width": "0px", "border-style": "solid" }, "body": { "background-color": "#FFFFFF", "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#000000", "line-height": 1, "margin": "0px", "padding": "0px", "content-padding-top": "0px", "content-padding-right": "0px", "content-padding-bottom": "0px", "content-padding-left": "0px" }, "h1": { "font-family": "Arial,helvetica,sans-serif", "font-size": "28px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h2": { "font-family": "Arial,helvetica,sans-serif", "font-size": "22px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "h3": { "font-family": "Arial,helvetica,sans-serif", "font-size": "20px", "color": "#181818", "line-height": 1, "font-weight": "bold", "font-style": "normal" }, "links": { "font-weight": "normal", "color": "#0176d3", "text-decoration": "none" }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "background-color": "#5D5D5D", "border-radius": "3px", "padding": "10px", "border-color": "#5D5D5D", "border-width": "1px", "border-style": "solid" }, "mobile": { "body": { "padding": "0px", "font-size": "16px", "line-height": 1.5 }, "h1": { "font-size": "22px", "line-height": 1 }, "h2": { "font-size": "20px", "line-height": 1 }, "h3": { "font-size": "18px", "line-height": 1 }, "buttons": { "font-family": "Arial,helvetica,sans-serif", "font-size": "16px", "color": "#FFFFFF", "padding": "10px" } } } }, "views": { "subjectline": { "contentType": "application/vnd.etmc.email.View; kind=subjectline", "thumbnail": {}, "content": "my subject", "meta": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "preheader": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "html": { "thumbnail": {}, "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style type=\"text/css\">\n ReadMsgBody{ width: 100%;}\n .ExternalClass {width: 100%;}\n .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}\n body {-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;margin:0 !important;}\n p { margin: 1em 0;}\n table td { border-collapse: collapse;}\n img {outline:0;}\n a img {border:none;}\n @-ms-viewport{ width: device-width;}\n </style>\n <style type=\"text/css\">\n @media only screen and (max-width: 480px) {\n .container {width: 100% !important;}\n .footer { width:auto !important; margin-left:0; }\n .mobile-hidden { display:none !important; }\n .logo { display:block !important; padding:0 !important; }\n img { max-width:100% !important; height:auto !important; max-height:auto !important;}\n .header img{max-width:100% !important;height:auto !important; max-height:auto !important;}\n .photo img { width:100% !important; max-width:100% !important; height:auto !important;}\n .drop { display:block !important; width: 100% !important; float:left; clear:both;}\n .footerlogo { display:block !important; width: 100% !important; padding-top:15px; float:left; clear:both;}\n .nav4, .nav5, .nav6 { display: none !important; }\n .tableBlock {width:100% !important;}\n .responsive-td {width:100% !important; display:block !important; padding:0 !important; }\n .fluid, .fluid-centered {\n width: 100% !important;\n max-width: 100% !important;\n height: auto !important;\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .fluid-centered {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n /* MOBILE GLOBAL STYLES - DO NOT CHANGE */\n body { padding: 0px !important; font-size: 16px !important; line-height: 150% !important;}\n h1 { font-size: 22px !important; line-height: normal !important;}\n h2 { font-size: 20px !important; line-height: normal !important;}\n h3 { font-size: 18px !important; line-height: normal !important;}\n .buttonstyles {\n font-family:arial,helvetica,sans-serif !important;\n font-size: 16px !important;\n color: #FFFFFF !important;\n padding: 10px !important;\n }\n /* END OF MOBILE GLOBAL STYLES - DO NOT CHANGE */\n }\n @media only screen and (max-width: 640px) {\n .container { width:100% !important; }\n .mobile-hidden { display:none !important; }\n .logo { display:block !important; padding:0 !important; }\n .photo img { width:100% !important; height:auto !important;}\n .nav5, .nav6 { display: none !important;}\n .fluid, .fluid-centered {\n width: 100% !important;\n max-width: 100% !important;\n height: auto !important;\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .fluid-centered {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n }\n </style>\n <!--[if mso]>\n <style type=\"text/css\">\n /* Begin Outlook Font Fix */\n body, table, td {\n font-family: Arial, Helvetica, sans-serif ;\n font-size:16px;\n color:#000000;\n line-height:1;\n }\n /* End Outlook Font Fix */\n </style>\n <![endif]-->\n </head>\n <body bgcolor=\"#ffffff\" text=\"#000000\" style=\"background-color: #ffffff; color: #000000; padding: 0px; -webkit-text-size-adjust:none; font-size: 16px; font-family:arial,helvetica,sans-serif;\">\n <div style=\"font-size:0; line-height:0;\"><custom name=\"opencounter\" type=\"tracking\"><custom name=\"usermatch\" type=\"tracking\" /></div>\n <table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" align=\"center\">\n <tr>\n <td align=\"center\" valign=\"top\">\n <custom type=\"header\"/>\n </td>\n </tr>\n <tr>\n <td align=\"center\">\n <table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"600\" class=\"container\" align=\"center\">\n <tr>\n <td>\n <table class=\"tb_properties border_style\" style=\"background-color:#FFFFFF;\" cellspacing=\"0\" cellpadding=\"0\" bgcolor=\"#ffffff\" width=\"100%\">\n <tr>\n <td align=\"center\" valign=\"top\">\n <table align=\"left\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr>\n <!-- added padding here -->\n <td class=\"content_padding\" style=\"\">\n <!-- end of comment -->\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr> <!-- top slot -->\n <td align=\"center\" class=\"header\" valign=\"top\">\n <table align=\"left\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tbody>\n <tr>\n <td align=\"left\" valign=\"top\">\n <table cellspacing=\"0\" cellpadding=\"0\" style=\"width:100%\">\n <tbody>\n <tr>\n <td class=\"responsive-td\" valign=\"top\" style=\"width: 100%;\">\n <div data-type=\"slot\" data-key=\"banner\">\n\t\t\t\t\t\t\t\t\t\t\t\t </div>\n </td>\n </tr>\n </tbody>\n </table>\n </td>\n </tr>\n </tbody>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td valign=\"top\">\n <custom type=\"footer\" />\n </td>\n </tr>\n </table>\n </body>\n</html>\n", "availableViews": [], "slots": { "banner": { "design": "<p style=\"font-family:Arial;color:#ccc;font-size:12px;text-align:center;vertical-align:middle;font-weight:bold;height:150px;display:flex;flex-direction:column;justify-content:center;padding:10px;margin:0;border: #cccccc dashed 1px;\">Drop blocks or content here</p>", "availableViews": [], "blocks": {}, "slots": {}, "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 } }, "template": { "id": 8973, "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "name": "testNew_asset_template", "content": "", "meta": { "contentHash": 1850388723 }, "availableViews": [], "slots": { "banner": { "locked": false, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 } }, "data": { "email": { "options": { "generateFrom": null } } }, "modelVersion": 2 }, "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "text": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "html" } } }, "generateFrom": "html", "modelVersion": 2 }, "viewAsAWebPage": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "subscriptioncenter": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "forwardHTML": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 }, "forwardText": { "thumbnail": {}, "availableViews": [], "data": { "email": { "options": { "generateFrom": "" } } }, "modelVersion": 2 } }, "availableViews": [ "subjectline", "preheader", "html", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "attributes": [], "legacy": { "legacyId": 2614, "legacyKey": "testNew_asset_templatebasedemail", "legacyType": "email", "legacyCategoryId": 5330 } } }, "legacyData": { "legacyId": 2614, "legacyKey": "testNew_asset_templatebasedemail", "legacyType": "email", "legacyCategoryId": 5330 }, "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_withCBBK_notexisting.json ================================================ { "id": 1322777, "customerKey": "testNew_asset_withCBBK_notexisting", "objectID": "26fdf503-eeed-49eb-b428-cb3b4bc2ba49", "assetType": { "id": 196, "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_withCBBK_notexisting" }, "name": "testNew_asset_withCBBK_notexisting", "description": "bla bla", "owner": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "createdDate": "2024-05-07T05:08:46.927-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2024-05-07T05:08:46.927-06:00", "modifiedBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1324776/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "%%[\n ContentBlockByKey(\"testNew_asset_htmlblock\")\n]%%\n\n", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_withCBBK_preexisting.json ================================================ { "id": 1322777, "customerKey": "testNew_asset_withCBBK_preexisting", "objectID": "26fdf503-eeed-49eb-b428-cb3b4bc2ba49", "assetType": { "id": 196, "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_withCBBK_preexisting" }, "name": "testNew_asset_withCBBK_preexisting", "description": "bla bla", "owner": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "createdDate": "2024-05-07T05:08:46.927-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2024-05-07T05:08:46.927-06:00", "modifiedBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1324776/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "%%[\n ContentBlockByKey(\"testExisting_asset_htmlblock\")\n]%%\n\n", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response-key=test_slash.json ================================================ { "id": 16992, "customerKey": "test_slash", "objectID": "13f34d9c-f555-4fce-b862-26ff7f9fef7a", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "test_slash" }, "name": "test_slash", "owner": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "createdDate": "2026-03-06T07:47:11.04-06:00", "createdBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "modifiedDate": "2026-03-06T07:47:11.04-06:00", "modifiedBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/16992/thumbnail" }, "category": { "id": 38491, "name": "bla/blub", "parentId": 89397 }, "content": "<table\n cellpadding=\"0\"\n cellspacing=\"0\"\n width=\"100%\"\n role=\"presentation\"\n style=\"min-width: 100%\"\n class=\"stylingblock-content-wrapper\"\n>\n <tr>\n <td class=\"stylingblock-content-wrapper camarker-inner\">test</td>\n </tr>\n</table>\n", "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/post-response.json ================================================ { "id": 1324776, "customerKey": "testNew_asset-9999999", "objectID": "26fdf503-eeed-49eb-b428-cb3b4bc2ba48", "assetType": { "id": 196, "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset" }, "name": "testNew_asset", "description": "bla bla", "owner": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "createdDate": "2024-05-07T05:08:46.927-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2024-05-07T05:08:46.927-06:00", "modifiedBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 1111111, "memberId": 9999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/1324776/thumbnail" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "content": "<table\n cellpadding=\"0\"\n cellspacing=\"0\"\n width=\"100%\"\n role=\"presentation\"\n style=\"min-width: 100%\"\n class=\"stylingblock-content-wrapper\"\n>\n <tr>\n <td class=\"stylingblock-content-wrapper camarker-inner\">foobar</td>\n </tr>\n</table>\n", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2 } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/+post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213-slashfolder.json ================================================ { "count": 5, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 16992, "customerKey": "test_slash", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "test_slash" }, "name": "test_slash", "createdDate": "2026-03-06T07:47:11.04-06:00", "createdBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "modifiedDate": "2026-03-06T07:47:11.04-06:00", "modifiedBy": { "id": 710420432, "email": "", "name": "IDE - joern.berkefeld app user", "userId": "710420432" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 38491, "name": "bla/blub", "parentId": 89397 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295065, "customerKey": "testExisting_htmlblock1", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock1" }, "name": "testExisting_htmlblock1", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295066, "customerKey": "testExisting_htmlblock2", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock2" }, "name": "testExisting_htmlblock2", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295067, "customerKey": "testExisting_htmlblock 3 spaces", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock 3 spaces" }, "name": "testExisting_htmlblock 3 spaces", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J\u00f6rn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN1,205,206,230,232.json ================================================ { "count": 2, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1209971, "customerKey": "mobileMessage_test", "assetType": { "id": 230, "name": "jsonmessage", "displayName": "JSON Message" }, "name": "mobileMessage_test", "createdDate": "2022-12-07T02:49:36.857-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2022-12-07T02:49:57.44-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["push"], "modelVersion": 2 }, { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN1,3,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,210,211,212,213,215,216,217,218,219,220,221,222,223,224.json ================================================ { "count": 5, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295065, "customerKey": "testExisting_htmlblock1", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock1" }, "name": "testExisting_htmlblock1", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295066, "customerKey": "testExisting_htmlblock2", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock2" }, "name": "testExisting_htmlblock2", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295067, "customerKey": "testExisting_htmlblock 3 spaces", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock 3 spaces" }, "name": "testExisting_htmlblock 3 spaces", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN1,3,4,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,210,211,212,213,214,215,216,217,218,219,220,221,222.json ================================================ { "count": 9, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 5286, "customerKey": "testExisting_asset_template", "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "name": " testExisting_asset_template", "createdDate": "2024-04-22T03:33:08.253-06:00", "createdBy": { "id": 710411605, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710411605" }, "modifiedDate": "2024-05-13T07:12:13.117-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "category": { "id": 89397 }, "modelVersion": 2 }, { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295065, "customerKey": "testExisting_htmlblock1", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock1" }, "name": "testExisting_htmlblock1", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295066, "customerKey": "testExisting_htmlblock2", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock2" }, "name": "testExisting_htmlblock2", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295067, "customerKey": "testExisting_htmlblock 3 spaces", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock 3 spaces" }, "name": "testExisting_htmlblock 3 spaces", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 }, { "id": 9459, "customerKey": "test_interactivecontent_content", "objectID": "283dc273-84c0-44b6-979c-b9f2534b28a1", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "name": "test_interactivecontent", "createdDate": "2025-03-25T03:02:47.323-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:02:47.323-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "category": { "id": 5328, "name": "Content Builder", "parentId": 0 }, "modelVersion": 2 }, { "id": 9461, "customerKey": "test_microsite_content", "objectID": "8f32dff3-026b-4cd6-9096-d3ecb319f386", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "name": "test_microsite_content", "createdDate": "2025-03-25T03:10:56.733-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:10:56.733-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "category": { "id": 5328, "name": "Content Builder", "parentId": 0 }, "modelVersion": 2 }, { "id": 9466, "customerKey": "test_landingpage_content", "objectID": "95aa069b-5d48-41b9-a206-a623832cfc6d", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "name": "test_landingpage_content", "createdDate": "2025-03-25T03:17:52.317-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:17:52.317-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "category": { "id": 5328, "name": "Content Builder", "parentId": 0 }, "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN1,3,4,5,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,207,208,209,210,211,212,213,214,215,216,217,218.json ================================================ { "count": 8, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295065, "customerKey": "testExisting_htmlblock1", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock1" }, "name": "testExisting_htmlblock1", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295066, "customerKey": "testExisting_htmlblock2", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock2" }, "name": "testExisting_htmlblock2", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295067, "customerKey": "testExisting_htmlblock 3 spaces", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock 3 spaces" }, "name": "testExisting_htmlblock 3 spaces", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 5286, "customerKey": "testExisting_asset_template", "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "name": " testExisting_asset_template", "createdDate": "2024-04-22T03:33:08.253-06:00", "createdBy": { "id": 710411605, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710411605" }, "modifiedDate": "2024-05-13T07:12:13.117-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "category": { "id": 89397 }, "modelVersion": 2 }, { "id": 5289, "customerKey": "testExisting_asset_templatebasedemail", "assetType": { "id": 207, "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " testExisting_asset_templatebasedemail", "createdDate": "2024-04-22T06:36:03.117-06:00", "createdBy": { "id": 710369861, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710369861" }, "modifiedDate": "2024-05-13T07:15:29.77-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397 }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "legacy": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 } } }, "legacyData": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 }, "modelVersion": 2 }, { "id": 808714, "customerKey": "testExisting_asset_message", "assetType": { "id": 208, "name": "htmlemail", "displayName": "HTML Email" }, "name": "testExisting_asset_message", "createdDate": "2021-01-31T14:11:01.423-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2021-01-31T14:13:30-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["html", "text", "subjectline", "preheader"], "data": { "email": { "options": { "characterEncoding": "us-ascii" }, "legacy": { "legacyId": 531213, "legacyKey": "testExisting_asset_message", "legacyType": "email", "legacyCategoryId": 290835 } } }, "legacyData": { "legacyId": 531213, "legacyKey": "testExisting_asset_message", "legacyType": "email", "legacyCategoryId": 290835 }, "modelVersion": 2 }, { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 }, { "id": 1295075, "customerKey": "testExisting_htmlblock_matchName1", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock_matchName" }, "name": "testExisting_htmlblock_matchName", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295076, "customerKey": "testExisting_htmlblock_matchName2", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock_matchName" }, "name": "testExisting_htmlblock_matchName", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 90888, "name": "Test Folder", "parentId": 89397 }, "availableViews": [], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN1,5,205,206,207,208,209,230,232.json ================================================ { "count": 4, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1209971, "customerKey": "mobileMessage_test", "assetType": { "id": 230, "name": "jsonmessage", "displayName": "JSON Message" }, "name": "mobileMessage_test", "createdDate": "2022-12-07T02:49:36.857-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2022-12-07T02:49:57.44-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["push"], "modelVersion": 2 }, { "id": 808714, "customerKey": "testExisting_asset_message", "assetType": { "id": 208, "name": "htmlemail", "displayName": "HTML Email" }, "name": "testExisting_asset_message", "createdDate": "2021-01-31T14:11:01.423-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2021-01-31T14:13:30-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["html", "text", "subjectline", "preheader"], "data": { "email": { "options": { "characterEncoding": "us-ascii" }, "legacy": { "legacyId": 531213, "legacyKey": "testExisting_asset_message", "legacyType": "email", "legacyCategoryId": 290835 } } }, "legacyData": { "legacyId": 531213, "legacyKey": "testExisting_asset_message", "legacyType": "email", "legacyCategoryId": 290835 }, "modelVersion": 2 }, { "id": 5289, "customerKey": "testExisting_asset_templatebasedemail", "assetType": { "id": 207, "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " testExisting_asset_templatebasedemail", "createdDate": "2024-04-22T06:36:03.117-06:00", "createdBy": { "id": 710369861, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710369861" }, "modifiedDate": "2024-05-13T07:15:29.77-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397 }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "legacy": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 } } }, "legacyData": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 }, "modelVersion": 2 }, { "id": 950143, "customerKey": "testExisting_asset", "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", "contentType": "text/html", "assetType": { "id": 205, "name": "webpage", "displayName": "Web Page" }, "version": 1, "name": "testExisting_asset", "owner": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "createdDate": "2021-09-13T12:14:02.32-06:00", "createdBy": { "id": 717319337, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "717319337" }, "modifiedDate": "2023-08-02T07:10:29.553-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "enterpriseId": 111111, "memberId": 999999, "status": { "id": 1, "name": "Draft" }, "thumbnail": { "thumbnailUrl": "/v1/assets/950143/thumbnail" }, "category": { "id": 89397 }, "meta": { "globalStyles": { "isLocked": false, "body": { "max-width": "1280px", "color": "#000000", "font-family": "Arial", "font-size": "12px", "margin": "0px auto" }, "template": { "background-color": "#FFFFFF", "border": "none", "box-sizing": "border-box", "padding": "0px", "width": "100%" } } }, "views": { "html": { "thumbnail": {}, "content": "<!DOCTYPE html>\n<html>\n <head>\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"\n />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <style class=\"main_style\">\n .layout-canvas-g {\n background-color: #ffffff;\n border: none;\n box-sizing: border-box;\n padding: 0px;\n width: 100%;\n }\n .layout-canvas-g > .header,\n .layout-canvas-g > .section,\n .layout-canvas-g > .footer {\n position: relative;\n overflow: hidden;\n width: 100%;\n overflow-wrap: break-word;\n }\n .layout-canvas-g > .section {\n margin: 10px 0px;\n }\n .layout-canvas-g > .section > .columns {\n box-sizing: border-box;\n overflow-wrap: break-word;\n }\n body {\n color: #000000;\n font-family: Arial;\n font-size: 12px;\n margin: 0px auto;\n max-width: 1280px;\n }\n @media only screen and (max-width: 480px) {\n .mobile-hidden {\n display: none !important;\n }\n .responsive-td {\n width: 100% !important;\n display: block !important;\n padding: 0px !important;\n }\n }\n .layout-canvas-g > .section > .columns {\n width: 100%;\n }\n </style>\n </head>\n <body>\n <div class=\"layout layout-canvas-g\">\n <div class=\"section\">\n <div class=\"columns col1\">\n <div data-type=\"slot\" data-key=\"col1\"></div>\n </div>\n </div>\n </div>\n </body>\n</html>\n", "slots": { "col1": { "content": "<div data-type=\"block\" data-key=\"bgbqbbx4we9\"></div>", "design": "<p style=\"font-family:arial;color:#ccc;font-size:11px;text-align:center;vertical-align:middle;font-weight:bold;padding:10px;margin:0;border:#ccc dashed 1px;\">Drop blocks or content here</p>", "blocks": { "bgbqbbx4we9": { "assetType": { "id": 197, "name": "htmlblock" }, "content": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\">\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"<br>\"))NEXT @i\n]%%\n</td></tr></table>", "design": "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" role=\"presentation\" style=\"min-width: 100%; \" class=\"stylingblock-content-wrapper\"><tr><td class=\"stylingblock-content-wrapper camarker-inner\"><div class=\"default-design\"></div></td></tr></table>", "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "modelVersion": 2 } }, "availableViews": ["html"], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN14,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192.json ================================================ { "count": 0, "page": 1, "pageSize": 50, "links": {}, "items": [] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN15,193,194.json ================================================ { "count": 0, "page": 1, "pageSize": 50, "links": {}, "items": [] } ================================================ FILE: 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 ================================================ { "count": 0, "page": 1, "pageSize": 50, "links": {}, "items": [] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN219,220,221,222,223,224,225,226,227,228,230,232,240,241,242,243,244,245.json ================================================ { "count": 4, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1209971, "customerKey": "mobileMessage_test", "assetType": { "id": 230, "name": "jsonmessage", "displayName": "JSON Message" }, "name": "mobileMessage_test", "createdDate": "2022-12-07T02:49:36.857-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2022-12-07T02:49:57.44-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["push"], "modelVersion": 2 }, { "id": 9463, "customerKey": "test_coderesource_json", "assetType": { "id": 242, "name": "jsoncoderesource", "displayName": "JSON Code Resource" }, "name": "test_coderesource_json", "createdDate": "2025-03-25T03:15:22.72-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:16:40.913-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "{\n\"test\": true\n}", "meta": { "cloudPages": { "publishDate": "2025-03-25 03:16:40.913" } }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource_json\"}" } }, "modelVersion": 2 }, { "id": 9460, "customerKey": "test_coderesource_xml", "assetType": { "id": 245, "name": "xmlcoderesource", "displayName": "XML Code Resource" }, "name": "test_coderesource_xml", "createdDate": "2025-03-25T03:03:45.713-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:04:06.48-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "<xml>test</xml>", "meta": { "cloudPages": {} }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource_xml\"}" } }, "modelVersion": 2 }, { "id": 9451, "customerKey": "test_coderesource_js", "assetType": { "id": 240, "name": "jscoderesource", "displayName": "Javascript Code Resource" }, "name": "test_coderesource_js", "createdDate": "2025-03-24T05:20:40.82-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:03:20.603-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "/* insert code here */\n", "meta": { "cloudPages": { "publishDate": "2025-03-24 06:05:23.203" } }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource\"}" } }, "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN223,224,225,226,227,228,230,232.json ================================================ { "count": 1, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1209971, "customerKey": "mobileMessage_test", "assetType": { "id": 230, "name": "jsonmessage", "displayName": "JSON Message" }, "name": "mobileMessage_test", "createdDate": "2022-12-07T02:49:36.857-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2022-12-07T02:49:57.44-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "J├Ârn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["push"], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN225,226,227,228,230,232.json ================================================ { "count": 0, "page": 1, "pageSize": 50, "links": {}, "items": [] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN240,241,242,243,244,245.json ================================================ { "count": 3, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 9463, "customerKey": "test_coderesource_json", "assetType": { "id": 242, "name": "jsoncoderesource", "displayName": "JSON Code Resource" }, "name": "test_coderesource_json", "createdDate": "2025-03-25T03:15:22.72-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:16:40.913-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "{\n\"test\": true\n}", "meta": { "cloudPages": { "publishDate": "2025-03-25 03:16:40.913" } }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource_json\"}" } }, "modelVersion": 2 }, { "id": 9460, "customerKey": "test_coderesource_xml", "assetType": { "id": 245, "name": "xmlcoderesource", "displayName": "XML Code Resource" }, "name": "test_coderesource_xml", "createdDate": "2025-03-25T03:03:45.713-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:04:06.48-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "<xml>test</xml>", "meta": { "cloudPages": {} }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource_xml\"}" } }, "modelVersion": 2 }, { "id": 9451, "customerKey": "test_coderesource_js", "assetType": { "id": 240, "name": "jscoderesource", "displayName": "Javascript Code Resource" }, "name": "test_coderesource_js", "createdDate": "2025-03-24T05:20:40.82-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:03:20.603-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "/* insert code here */\n", "meta": { "cloudPages": { "publishDate": "2025-03-24 06:05:23.203" } }, "availableViews": [], "data": { "site": { "content": "{\"url\":\"https://oss-test.accenture.com/test_coderesource\"}" } }, "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN246,247,248,249.json ================================================ { "count": 4, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 9465, "customerKey": "test_landingpage", "assetType": { "id": 247, "name": "landingpage", "displayName": "Landing Page" }, "name": "test_landingpage", "createdDate": "2025-03-25T03:17:51.88-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:17:52.187-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "{\"url\":\"https://oss-test.accenture.com/test_landingpage\"}", "meta": { "thumbnailRefAssetId": 9466, "cloudPages": {} }, "availableViews": [], "modelVersion": 2 }, { "id": 9456, "customerKey": "test_microsite", "assetType": { "id": 248, "name": "microsite", "displayName": "Microsite" }, "name": "test_microsite", "createdDate": "2025-03-25T03:01:05.467-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:12:51.85-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "{\"url\":\"https://oss-test.accenture.com/test_microsite\"}", "meta": { "thumbnailRefAssetId": 9461, "cloudPages": { "publishDate": "2025-03-25 03:12:51.850" } }, "availableViews": [], "modelVersion": 2 }, { "id": 9458, "customerKey": "test_interactivecontent", "assetType": { "id": 249, "name": "interactivecontent", "displayName": "Interactive Email Page" }, "name": "test_interactivecontent", "createdDate": "2025-03-25T03:02:46.823-06:00", "createdBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "modifiedDate": "2025-03-25T03:02:55.307-06:00", "modifiedBy": { "id": 710420418, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710420418" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 27675, "name": "mcdev", "parentId": 23009 }, "content": "{\"url\":\"https://oss-test.accenture.com/test_interactivecontent\"}", "meta": { "thumbnailRefAssetId": 9459, "cloudPages": { "publishDate": "2025-03-25 03:02:55.307" } }, "availableViews": [], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213.json ================================================ { "count": 4, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295065, "customerKey": "testExisting_htmlblock1", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock1" }, "name": "testExisting_htmlblock1", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295066, "customerKey": "testExisting_htmlblock2", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock2" }, "name": "testExisting_htmlblock2", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 }, { "id": 1295067, "customerKey": "testExisting_htmlblock 3 spaces", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "testExisting_htmlblock 3 spaces" }, "name": "testExisting_htmlblock 3 spaces", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN4,214.json ================================================ { "count": 1, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 5286, "customerKey": "testExisting_asset_template", "assetType": { "id": 4, "name": "template", "displayName": "Template" }, "name": " testExisting_asset_template", "createdDate": "2024-04-22T03:33:08.253-06:00", "createdBy": { "id": 710411605, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710411605" }, "modifiedDate": "2024-05-13T07:12:13.117-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "category": { "id": 89397 }, "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN5,207,208,209.json ================================================ { "count": 3, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 808714, "customerKey": "testExisting_asset_message", "assetType": { "id": 208, "name": "htmlemail", "displayName": "HTML Email" }, "name": "testExisting_asset_message", "createdDate": "2021-01-31T14:11:01.423-06:00", "createdBy": { "id": 700304523, "email": "", "name": "SFMC DEVOPS app user", "userId": "700304523" }, "modifiedDate": "2021-01-31T14:13:30-06:00", "modifiedBy": { "id": 700304523, "name": "SFMC DEVOPS app user", "userId": "700304523" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": ["html", "text", "subjectline", "preheader"], "data": { "email": { "options": { "characterEncoding": "us-ascii" }, "legacy": { "legacyId": 531213, "legacyKey": "testExisting_asset_message", "legacyType": "email", "legacyCategoryId": 290835 } } }, "legacyData": { "legacyId": 531213, "legacyKey": "testExisting_asset_message", "legacyType": "email", "legacyCategoryId": 290835 }, "modelVersion": 2 }, { "id": 5289, "customerKey": "testExisting_asset_templatebasedemail", "assetType": { "id": 207, "name": "templatebasedemail", "displayName": "Template-Based Email" }, "name": " testExisting_asset_templatebasedemail", "createdDate": "2024-04-22T06:36:03.117-06:00", "createdBy": { "id": 710369861, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld", "userId": "710369861" }, "modifiedDate": "2024-05-13T07:15:29.77-06:00", "modifiedBy": { "id": 710420432, "name": "joern.berkefeld app user", "userId": "710420432" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397 }, "availableViews": [ "subjectline", "preheader", "text", "viewAsAWebPage", "subscriptioncenter", "forwardHTML", "forwardText", "html" ], "data": { "email": { "options": { "characterEncoding": "utf-8" }, "legacy": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 } } }, "legacyData": { "legacyId": 1643, "legacyKey": "9b6edc22-d19a-429a-a705-da88c3a16543", "legacyType": "email", "legacyCategoryId": 10251 }, "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/assets/query/post-response-customerKey=testExisting_asset_htmlblock.json ================================================ { "count": 3, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": 1295064, "customerKey": "testExisting_asset_htmlblock", "assetType": { "id": 197, "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "dont strip non ssjs content" }, "name": "dont strip non ssjs content", "createdDate": "2024-01-08T08:26:58.277-06:00", "createdBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "modifiedDate": "2024-01-08T08:28:01.6-06:00", "modifiedBy": { "id": 700301950, "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld (ASGR)", "userId": "700301950" }, "status": { "id": 1, "name": "Draft" }, "category": { "id": 89397, "name": "Content Builder", "parentId": 0 }, "availableViews": [], "modelVersion": 2 } ] } ================================================ FILE: test/resources/9999999/asset/v1/content/categories/post-response.json ================================================ { "id": 38491, "description": "", "enterpriseId": 1111111, "memberId": 9999999, "name": "bla/blub", "parentId": 89397, "categoryType": "asset" } ================================================ FILE: test/resources/9999999/asset-deploy/block/testNew_asset_badExtension.bad-type-extension.json ================================================ { "customerKey": "testNew_asset_badExtension", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_badExtension" }, "name": "testNew_asset_badExtension", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 1111111, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset-deploy/block/testNew_asset_badName_bad.asset-block-meta.json ================================================ { "customerKey": "testNew_asset_badName", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testNew_asset_badName" }, "name": "testNew_asset_badName", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 1111111, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset-deploy2/block/testBlacklist_asset_htmlblock.asset-block-meta.html ================================================ <html></html> ================================================ FILE: test/resources/9999999/asset-deploy2/block/testBlacklist_asset_htmlblock.asset-block-meta.json ================================================ { "customerKey": "testBlacklist_asset_htmlblock", "assetType": { "name": "textblock", "displayName": "Text Block" }, "fileProperties": { "fileName": "testBlacklist_asset_htmlblock" }, "name": "testBlacklist_asset_htmlblock", "description": "bla bla", "owner": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "createdDate": "2022-10-14T08:54:26.643-06:00", "createdBy": { "email": "joern.berkefeld@accenture.com", "name": "Jörn Berkefeld" }, "modifiedDate": "2024-05-06T07:18:33.787-06:00", "modifiedBy": { "name": "SFMC DEVOPS app user" }, "memberId": 9999999, "status": { "name": "Draft" }, "meta": { "wrapperStyles": { "mobile": { "visible": true } } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder" } ================================================ FILE: test/resources/9999999/asset-slashfolder-deploy/block/test_slash.asset-block-meta.html ================================================ <table cellpadding="0" cellspacing="0" width="100%" role="presentation" style="min-width: 100%" class="stylingblock-content-wrapper" > <tr> <td class="stylingblock-content-wrapper camarker-inner">test</td> </tr> </table> ================================================ FILE: test/resources/9999999/asset-slashfolder-deploy/block/test_slash.asset-block-meta.json ================================================ { "customerKey": "test_slash", "assetType": { "name": "htmlblock", "displayName": "HTML Block" }, "fileProperties": { "fileName": "test_slash" }, "name": "test_slash", "createdBy": {}, "modifiedBy": {}, "memberId": "9999999", "status": { "name": "Draft" }, "design": "", "meta": { "wrapperStyles": { "mobile": { "visible": true }, "styling": {} } }, "availableViews": [], "modelVersion": 2, "r__folder_Path": "Content Builder/bla∕blub" } ================================================ FILE: test/resources/9999999/attributeGroup/retrieve-expected.json ================================================ { "applicationKey": "com.exacttarget.mobileconnect", "attributeCount": 37, "attributeGroupIconKey": "Mobile", "attributeGroupType": "Standard", "r__attributeSet_key": ["MobileDemographics", "MobileSubscriptions"], "canAddProperties": false, "canAddRelationships": true, "canChangeProperties": false, "canModify": false, "canRemove": false, "definitionKey": "ETMobileConnect", "definitionName": { "value": "MobileConnect Data" }, "description": "", "displayOrder": 4, "isHidden": false, "isOwner": true, "isSystemDefined": true, "requiredRelationships": [ "4651de3f-31e2-e611-80cc-1402ec7222b4", "4352de3f-31e2-e611-80cc-1402ec7222b4" ] } ================================================ FILE: test/resources/9999999/attributeSet/retrieve-expected.json ================================================ { "attributeCount": 0, "canAddValues": true, "canChangeValues": true, "canModify": true, "canRemove": true, "createDate": "2023-08-11T08:22:00", "createdBy": 700301950, "dataRetentionProperties": { "isDeleteAtEndOfRetentionPeriod": false, "isResetRetentionPeriodOnImport": false, "isRowBasedRetention": true, "periodLength": 6, "periodUnitOfMeasure": 5 }, "definitionKey": "testExisting_dataExtensionShared", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": true, "isShared": true, "isSystemDefined": false, "isTestaable": true, "localizedDescription": { "value": "Container for my test emails" }, "name": "testExisting_dataExtensionShared", "parentID": "00000000-0000-0000-0000-000000000000", "r__dataExtension_key": "testExisting_dataExtensionShared", "r__folder_Path": "Shared Items/Shared Data Extensions", "relationshipCount": 1, "relationships": [ { "canModify": true, "canRemove": true, "isGroupToSetRelationship": true, "isHidden": false, "isSystemDefined": false, "leftItem": { "cardinality": "One", "r__attributeGroup_key": "testExisting_attributeGroup", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "3" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "c__leftFullyQualifiedName": "Contact.Contact Key", "c__rightFullyQualifiedName": "testExisting_dataExtensionShared.ContactKey" } ], "relationshipID": "598b787a-5238-ee11-b85a-48df37d1de8a", "rightItem": { "cardinality": "One", "r__attributeSet_key": "testExisting_dataExtensionShared", "relationshipType": "AttributeSet" } } ], "sendAttributeStorageName": "ContactKey", "sendContactKeyStorageName": "_SubscriberKey", "setDefinitionKey": "testExisting_dataExtensionShared", "storageLogicalType": "DataExtension", "storageObjectIDs": ["5b8b787a-5238-ee11-b85a-48df37d1de8a"], "valueDefinitions": [ { "dataType": "LongNumber", "definitionKey": "CustomObjectKey", "description": "", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": true, "name": "Custom Object Key" }, { "dataType": "Text", "definitionKey": "FirstName", "description": "", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "name": "FirstName" }, { "dataType": "Text", "definitionKey": "LastName", "description": "", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 55, "name": "LastName" }, { "dataType": "EmailAddress", "definitionKey": "EmailAddress", "description": "", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 254, "name": "EmailAddress" }, { "dataType": "Text", "definitionKey": "ContactKey", "description": "", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "name": "ContactKey" } ] } ================================================ FILE: test/resources/9999999/automation/build-expected.json ================================================ { "description": "foobar", "key": "testTemplated_automation", "name": "testTemplated_automation", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "testTemplated_dataExtract", "r__type": "dataExtract" }, { "r__key": "testTemplated_emailSend", "r__type": "emailSend" }, { "r__key": "testTemplated_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testTemplated_importFile", "r__type": "importFile" }, { "r__key": "testTemplated_query", "r__type": "query" }, { "r__key": "testTemplated_script", "r__type": "script" }, { "r__key": "testTemplated_automation__s1.7", "r__type": "verification" } ], "name": "" } ], "type": "scheduled", "notifications": [ { "email": ["complete@test.accenture.com"], "message": "", "type": "Complete" }, { "email": ["error@test.accenture.com"], "message": "test", "type": "Error" } ] } ================================================ FILE: test/resources/9999999/automation/clone-expected.json ================================================ { "description": "bla bla", "key": "testExisting_automation", "name": "testExisting_automation", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" }, { "r__key": "testExisting_automation__s1.7", "r__type": "verification" } ], "name": "" } ], "type": "scheduled", "notifications": [ { "email": ["complete@test.accenture.com"], "message": "", "type": "Complete" }, { "email": ["error@test.accenture.com"], "message": "test", "type": "Error" } ] } ================================================ FILE: test/resources/9999999/automation/create-callout-expected.json ================================================ { "description": "created on deploy", "key": "testNew_automation", "name": "testNew_automation", "status": "Scheduled", "steps": [ { "activities": [ { "displayOrder": 1, "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "name": "testExisting_dataExtract", "objectTypeId": 73 }, { "displayOrder": 2, "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "name": "testExisting_emailSend", "objectTypeId": 42 }, { "displayOrder": 3, "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "name": "testExisting_fileTransfer", "objectTypeId": 53 }, { "displayOrder": 4, "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "name": "testExisting_importFile", "objectTypeId": 43 }, { "displayOrder": 5, "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "name": "testExisting_query", "objectTypeId": 300 }, { "displayOrder": 6, "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "name": "testExisting_script", "objectTypeId": 423 }, { "displayOrder": 7, "activityObjectId": "testNew_RANDOM_NEW_GUID", "name": "testNew_automation__s1.7", "objectTypeId": 1000 } ], "annotation": "", "stepNumber": 0 } ], "categoryId": 290937, "startSource": { "schedule": { "startDate": "2020-05-14T02:30:32.11", "endDate": "2079-06-06T21:00:00", "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", "timezoneId": 5 }, "typeId": 1 } } ================================================ FILE: test/resources/9999999/automation/create-expected.json ================================================ { "description": "created on deploy", "key": "testNew_automation", "name": "testNew_automation", "r__folder_Path": "my automations", "type": "scheduled", "status": "PausedSchedule", "schedule": { "endDate": "2079-06-06T21:00:00-06:00", "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", "startDate": "2020-05-13T18:30:32.11-06:00", "timezoneName": "W. Europe Standard Time" }, "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" }, { "r__key": "testNew_automation__s1.7", "r__type": "verification" } ], "name": "" } ], "createdDate": "2023-07-04T07:49:08.297" } ================================================ FILE: test/resources/9999999/automation/create-testNew_automation-expected.md ================================================ ## testNew_automation **Description:** created on deploy **Folder:** my automations/ **Started by:** Schedule **Status:** PausedSchedule **Schedule:** * Start: 2020-05-13 18:30:32.11-06:00 +01:00 * End: 2079-06-06 21:00:00-06:00 +01:00 * Timezone: W. Europe Standard Time * Recurrence: every 5 minutes until end date **Notifications:** _none_ | Step 1<br>_<small>-</small>_ | | --- | | _1.1: dataExtract_<br>testExisting_dataExtract | | _1.2: emailSend_<br>testExisting_emailSend | | _1.3: fileTransfer_<br>testExisting_fileTransfer | | _1.4: importFile_<br>testExisting_importFile | | _1.5: query_<br>testExisting_query | | _1.6: script_<br>testExisting_script | | _1.7: verification_<br>testNew_automation__s1.7 | ================================================ FILE: test/resources/9999999/automation/delete-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>DeleteResponse</wsa:Action> <wsa:MessageID>urn:uuid:cc45bb83-15a3-4a82-ba48-47ac4fb13000</wsa:MessageID> <wsa:RelatesTo>urn:uuid:29986848-a0c3-4f3b-bf5a-91151f784449</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-4e8dad58-7a68-4653-8406-a172d1960c8a"> <wsu:Created>2023-06-02T13:41:30Z</wsu:Created> <wsu:Expires>2023-06-02T13:46:30Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <DeleteResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Program deleted</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="Automation"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> <CustomerKey>testExisting_automation</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name /> <Description /> <IsActive>true</IsActive> </Object> </Results> <RequestID>898702fc-a432-4176-8130-5d6dd5ad9ca6</RequestID> <OverallStatus>OK</OverallStatus> </DeleteResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/automation/patch_fixKeys-pause-expected.json ================================================ { "description": "testing fixKey on an a paused automation", "key": "testExisting_automation_fixedKey_paused", "name": "testExisting_automation_fixedKey_paused", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" } ] } ], "type": "scheduled" } ================================================ FILE: test/resources/9999999/automation/patch_fixKeys-schedule-expected.json ================================================ { "description": "testing fixKey on an a scheduled automation", "key": "testExisting_automation_fixedKey_scheduled", "name": "testExisting_automation_fixedKey_scheduled", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "Scheduled", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" } ] } ], "type": "scheduled" } ================================================ FILE: test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>PerformResponse</wsa:Action> <wsa:MessageID>urn:uuid:cc45bb83-15a3-4a82-ba48-47ac4fb13000</wsa:MessageID> <wsa:RelatesTo>urn:uuid:29986848-a0c3-4f3b-bf5a-91151f784449</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-4e8dad58-7a68-4653-8406-a172d1960c8a"> <wsu:Created>2023-06-02T13:41:30Z</wsu:Created> <wsu:Expires>2023-06-02T13:46:30Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <PerformResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <Result> <StatusCode>OK</StatusCode> <StatusMessage>Performed Activity</StatusMessage> <Object xsi:type="Automation"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> <CustomerKey>testExisting_automation</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name /> <Description /> <IsActive>true</IsActive> </Object> </Result> </Results> <OverallStatus>OK</OverallStatus> <OverallStatusMessage /> <RequestID>898702fc-a432-4176-8130-5d6dd5ad9ca6</RequestID> </PerformResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_pause-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>PerformResponse</wsa:Action> <wsa:MessageID>urn:uuid:cc45bb83-15a3-4a82-ba48-47ac4fb13000</wsa:MessageID> <wsa:RelatesTo>urn:uuid:29986848-a0c3-4f3b-bf5a-91151f784449</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-4e8dad58-7a68-4653-8406-a172d1960c8a"> <wsu:Created>2023-06-02T13:41:30Z</wsu:Created> <wsu:Expires>2023-06-02T13:46:30Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <PerformResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <Result> <StatusCode>OK</StatusCode> <StatusMessage>Performed Activity</StatusMessage> <Object xsi:type="Automation"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_pause</ObjectID> <CustomerKey>testExisting_automation_fixedKey_paused</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name /> <Description /> <IsActive>true</IsActive> </Object> </Result> </Results> <OverallStatus>OK</OverallStatus> <OverallStatusMessage /> <RequestID>898702fc-a432-4176-8130-5d6dd5ad9ca6</RequestID> </PerformResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_schedule-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>PerformResponse</wsa:Action> <wsa:MessageID>urn:uuid:cc45bb83-15a3-4a82-ba48-47ac4fb13000</wsa:MessageID> <wsa:RelatesTo>urn:uuid:29986848-a0c3-4f3b-bf5a-91151f784449</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-4e8dad58-7a68-4653-8406-a172d1960c8a"> <wsu:Created>2023-06-02T13:41:30Z</wsu:Created> <wsu:Expires>2023-06-02T13:46:30Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <PerformResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <Result> <StatusCode>OK</StatusCode> <StatusMessage>Performed Activity</StatusMessage> <Object xsi:type="Automation"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_schedule</ObjectID> <CustomerKey>testExisting_automation_fixedKey_scheduled</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name /> <Description /> <IsActive>true</IsActive> </Object> </Result> </Results> <OverallStatus>OK</OverallStatus> <OverallStatusMessage /> <RequestID>898702fc-a432-4176-8130-5d6dd5ad9ca6</RequestID> </PerformResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/automation/perform-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>PerformResponse</wsa:Action> <wsa:MessageID>urn:uuid:cc45bb83-15a3-4a82-ba48-47ac4fb13000</wsa:MessageID> <wsa:RelatesTo>urn:uuid:29986848-a0c3-4f3b-bf5a-91151f784449</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-4e8dad58-7a68-4653-8406-a172d1960c8a"> <wsu:Created>2023-06-02T13:41:30Z</wsu:Created> <wsu:Expires>2023-06-02T13:46:30Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <PerformResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <Result> <StatusCode>OK</StatusCode> <StatusMessage>Performed Activity</StatusMessage> <Object xsi:type="Automation"> <PartnerKey xsi:nil="true" /> <ObjectID>a8afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> <CustomerKey>testNew_automation</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name /> <Description /> <IsActive>true</IsActive> </Object> </Result> </Results> <OverallStatus>OK</OverallStatus> <OverallStatusMessage /> <RequestID>898702fc-a432-4176-8130-5d6dd5ad9ca6</RequestID> </PerformResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/automation/retrieve-expected.json ================================================ { "description": "bla bla", "key": "testExisting_automation", "name": "testExisting_automation", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" }, { "r__key": "testExisting_automation__s1.7", "r__type": "verification" } ], "name": "" } ], "type": "scheduled", "notifications": [ { "email": ["complete@test.accenture.com"], "message": "", "type": "Complete" }, { "email": ["error@test.accenture.com"], "message": "test", "type": "Error" } ], "createdDate": "2022-01-12T08:41:35.773Z", "createdName": "Tom Tester", "modifiedDate": "2024-11-04T17:42:13.143Z", "modifiedName": "Jörn Berkefeld", "pausedDate": "2025-03-14T15:21:57.62Z", "pausedName": "Jörn Berkefeld" } ================================================ FILE: test/resources/9999999/automation/retrieve-testExisting_automation-expected.md ================================================ ## testExisting_automation **Description:** bla bla **Folder:** my automations/ **Started by:** Schedule **Status:** PausedSchedule **Schedule:** * Start: 2022-07-30 00:00:00 +01:00 * End: 2022-07-30 00:00:00 +01:00 * Timezone: W. Europe Standard Time * Recurrence: run only once **Notifications:** * Complete: complete@test.accenture.com * Error: error@test.accenture.com ("test") | Step 1<br>_<small>-</small>_ | | --- | | _1.1: dataExtract_<br>testExisting_dataExtract | | _1.2: emailSend_<br>testExisting_emailSend | | _1.3: fileTransfer_<br>testExisting_fileTransfer | | _1.4: importFile_<br>testExisting_importFile | | _1.5: query_<br>testExisting_query | | _1.6: script_<br>testExisting_script | | _1.7: verification_<br>testExisting_automation__s1.7 | ================================================ FILE: test/resources/9999999/automation/retrieve-wait-expected.json ================================================ { "name": "testExisting_automation_wait", "description": "", "key": "testExisting_automation_wait", "type": "unspecified", "status": "Ready", "schedule": {}, "steps": [ { "name": "", "activities": [ { "name": "1 Years", "r__type": "wait" } ] }, { "name": "", "activities": [ { "name": "1 Months", "r__type": "wait" } ] }, { "name": "", "activities": [ { "name": "1 Weeks", "r__type": "wait" } ] }, { "name": "", "activities": [ { "name": "1 Days", "r__type": "wait" } ] }, { "name": "", "activities": [ { "name": "1 Hours", "r__type": "wait" } ] }, { "name": "", "activities": [ { "name": "1 Minutes", "r__type": "wait" } ] }, { "name": "", "activities": [ { "name": "15:00", "timeZone": "GMT Standard Time", "r__type": "wait" } ] } ], "r__folder_Path": "my automations", "createdDate": "2024-11-04T17:30:12.973Z", "createdName": "Jörn Berkefeld", "modifiedDate": "2024-11-04T17:42:13.143Z", "modifiedName": "Jörn Berkefeld", "pausedDate": "2025-03-14T15:21:57.62Z", "pausedName": "Jörn Berkefeld" } ================================================ FILE: test/resources/9999999/automation/retrieve-wait-expected.md ================================================ ## testExisting_automation_wait **Description:** n/a **Folder:** my automations/ **Started by:** Not defined **Status:** Ready **Schedule:** Not defined **Notifications:** _none_ | Step 1<br>_<small>-</small>_ | Step 2<br>_<small>-</small>_ | Step 3<br>_<small>-</small>_ | Step 4<br>_<small>-</small>_ | Step 5<br>_<small>-</small>_ | Step 6<br>_<small>-</small>_ | Step 7<br>_<small>-</small>_ | | --- | --- | --- | --- | --- | --- | --- | | _1.1: wait_<br>1 Years | _2.1: wait_<br>1 Months | _3.1: wait_<br>1 Weeks | _4.1: wait_<br>1 Days | _5.1: wait_<br>1 Hours | _6.1: wait_<br>1 Minutes | _7.1: wait_<br>15:00<br>GMT Standard Time | ================================================ FILE: test/resources/9999999/automation/template-expected.json ================================================ { "description": "{{{description}}}", "key": "{{{prefix}}}automation", "name": "{{{prefix}}}automation", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "{{{prefix}}}dataExtract", "r__type": "dataExtract" }, { "r__key": "{{{prefix}}}emailSend", "r__type": "emailSend" }, { "r__key": "{{{prefix}}}fileTransfer", "r__type": "fileTransfer" }, { "r__key": "{{{prefix}}}importFile", "r__type": "importFile" }, { "r__key": "{{{prefix}}}query", "r__type": "query" }, { "r__key": "{{{prefix}}}script", "r__type": "script" }, { "r__key": "{{{prefix}}}automation__s1.7", "r__type": "verification" } ], "name": "" } ], "type": "scheduled", "notifications": [ { "email": ["complete@test.accenture.com"], "message": "", "type": "Complete" }, { "email": ["error@test.accenture.com"], "message": "test", "type": "Error" } ] } ================================================ FILE: test/resources/9999999/automation/update-callout-expected.json ================================================ { "description": "updated on deploy", "key": "testExisting_automation", "name": "testExisting_automation", "status": "PausedSchedule", "steps": [ { "activities": [ { "displayOrder": 1, "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "name": "testExisting_dataExtract", "objectTypeId": 73 }, { "displayOrder": 2, "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "name": "testExisting_emailSend", "objectTypeId": 42 }, { "displayOrder": 3, "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "name": "testExisting_fileTransfer", "objectTypeId": 53 }, { "displayOrder": 4, "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "name": "testExisting_importFile", "objectTypeId": 43 }, { "displayOrder": 5, "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "name": "testExisting_query", "objectTypeId": 300 }, { "displayOrder": 6, "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "name": "testExisting_script", "objectTypeId": 423 } ], "annotation": "", "stepNumber": 0 } ], "notifications": [ { "email": ["error-updated@test.accenture.com"], "message": "test updated", "type": "Error" } ], "categoryId": 290937, "startSource": { "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneId": 5 }, "typeId": 1 }, "id": "08afb0e2-b00a-4c88-ad2e-1f7f8788c560" } ================================================ FILE: test/resources/9999999/automation/update-expected.json ================================================ { "description": "bla bla", "key": "testExisting_automation", "name": "testExisting_automation", "r__folder_Path": "my automations", "schedule": { "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ { "activities": [ { "r__key": "testExisting_dataExtract", "r__type": "dataExtract" }, { "r__key": "testExisting_emailSend", "r__type": "emailSend" }, { "r__key": "testExisting_fileTransfer", "r__type": "fileTransfer" }, { "r__key": "testExisting_importFile", "r__type": "importFile" }, { "r__key": "testExisting_query", "r__type": "query" }, { "r__key": "testExisting_script", "r__type": "script" }, { "r__key": "testExisting_automation__s1.7", "r__type": "verification" } ], "name": "" } ], "type": "scheduled", "notifications": [ { "email": ["complete@test.accenture.com"], "message": "", "type": "Complete" }, { "email": ["error@test.accenture.com"], "message": "test", "type": "Error" } ], "createdDate": "2022-01-12T08:41:35.773Z", "createdName": "Tom Tester", "modifiedDate": "2024-11-04T17:42:13.143Z", "modifiedName": "Jörn Berkefeld", "pausedDate": "2025-03-14T15:21:57.62Z", "pausedName": "Jörn Berkefeld" } ================================================ FILE: test/resources/9999999/automation/update-testExisting_automation-expected.md ================================================ ## testExisting_automation **Description:** bla bla **Folder:** my automations/ **Started by:** Schedule **Status:** PausedSchedule **Schedule:** * Start: 2022-07-30 00:00:00 +01:00 * End: 2022-07-30 00:00:00 +01:00 * Timezone: W. Europe Standard Time * Recurrence: run only once **Notifications:** * Complete: complete@test.accenture.com * Error: error@test.accenture.com ("test") | Step 1<br>_<small>-</small>_ | | --- | | _1.1: dataExtract_<br>testExisting_dataExtract | | _1.2: emailSend_<br>testExisting_emailSend | | _1.3: fileTransfer_<br>testExisting_fileTransfer | | _1.4: importFile_<br>testExisting_importFile | | _1.5: query_<br>testExisting_query | | _1.6: script_<br>testExisting_script | | _1.7: verification_<br>testExisting_automation__s1.7 | ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json ================================================ { "id": "08afb0e2-b00a-4c88-ad2e-1f7f8788c560", "name": "testExisting_automation", "description": "bla bla", "key": "testExisting_automation", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "PausedSchedule", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 }, { "id": "f3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_dataExtension", "activityObjectId": "testExisting_39f6a488-20eb-4ba0-b0b9", "objectTypeId": 1000, "displayOrder": 7 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/patch-response.json ================================================ { "legacyId": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "name": "testExisting_automation", "description": "updated on deploy", "key": "testExisting_automation", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "PausedSchedule", "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ], "annotation": "", "stepNumber": 0 } ], "categoryId": 290937, "id": "08afb0e2-b00a-4c88-ad2e-1f7f8788c560" } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json ================================================ { "id": "08afb0e2-b00a-4c88-ad2e-pause", "name": "testExisting_automation_pause", "description": "bla bla", "key": "testExisting_automation_pause", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "Scheduled", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "scheduled", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json ================================================ { "legacyId": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED", "name": "testExisting_automation_pause", "description": "updated on deploy", "key": "testExisting_automation_pause", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "Scheduled", "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "scheduled", "timezoneId": 5 }, "steps": [ { "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ], "annotation": "", "stepNumber": 0 } ], "categoryId": 290937, "id": "08afb0e2-b00a-4c88-ad2e-1f7f8788c560" } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/get-response.json ================================================ { "id": "08afb0e2-b00a-4c88-fixKey_pause", "name": "testExisting_automation_fixedKey_paused", "description": "testing fixKey on an a paused automation", "key": "testExisting_automation_fixKey_pause", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "PausedSchedule", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/patch-response.json ================================================ { "id": "08afb0e2-b00a-4c88-fixKey_pause", "legacyId": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "name": "testExisting_automation_fixedKey_paused", "description": "testing fixKey on an a paused automation", "key": "testExisting_automation_fixedKey_paused", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "PausedSchedule", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/get-response.json ================================================ { "id": "08afb0e2-b00a-4c88-fixKey_schedule", "name": "testExisting_automation_fixedKey_scheduled", "description": "testing fixKey on an a scheduled automation", "key": "testExisting_automation_fixKey_schedule", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "Scheduled", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/patch-response.json ================================================ { "id": "08afb0e2-b00a-4c88-fixKey_schedule", "legacyId": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "name": "testExisting_automation_fixedKey_scheduled", "description": "testing fixKey on an a scheduled automation", "key": "testExisting_automation_fixedKey_scheduled", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "Scheduled", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/0fc2ac96-14ba-495a-8db9-3ddd4f8ac444-wait/get-response.json ================================================ { "id": "0fc2ac96-14ba-495a-8db9-3ddd4f8ac444-wait", "name": "testExisting_automation_wait", "description": "", "key": "testExisting_automation_wait", "typeId": 0, "type": "unspecified", "statusId": 2, "status": "Ready", "categoryId": 290937, "schedule": { "scheduleStatus": "none" }, "steps": [ { "id": "73acb9f6-3dd2-4a7e-a25b-7c3a03170957", "name": "", "step": 1, "activities": [ { "id": "f8c0e577-278c-479f-b381-610569b0b52e", "name": "1 Years", "activityObjectId": "1bd41a92-2c57-463c-a1e6-6e1549e481a1", "objectTypeId": 467, "displayOrder": 1 } ] }, { "id": "83fd8f6d-54bb-4b04-bc0d-dd62e16f452a", "name": "", "step": 2, "activities": [ { "id": "d364faa9-06e3-4d38-9fbe-93986b1d541e", "name": "1 Months", "activityObjectId": "76f255e3-1603-4d8b-be59-32ac6fe61e15", "objectTypeId": 467, "displayOrder": 1 } ] }, { "id": "935d4ac1-c65e-4ba6-adb4-a3c8e8dcb241", "name": "", "step": 3, "activities": [ { "id": "5aaeb136-9b1b-4d1f-95f2-bdd8d522f018", "name": "1 Weeks", "activityObjectId": "85a405e4-e77b-4a2e-8d1b-9ad34244ac10", "objectTypeId": 467, "displayOrder": 1 } ] }, { "id": "eb5871a6-1399-446c-a067-3a03d1a4367f", "name": "", "step": 4, "activities": [ { "id": "002fbe34-10b0-4121-b19a-e9c073cbd700", "name": "1 Days", "activityObjectId": "562cf01a-6cca-4fd9-9d3c-f2649379a282", "objectTypeId": 467, "displayOrder": 1 } ] }, { "id": "26c45a57-8761-4dac-91b4-c1c64d1a6741", "name": "", "step": 5, "activities": [ { "id": "283a0acf-d5ed-4535-a2a7-383e2c8c51db", "name": "1 Hours", "activityObjectId": "2722bb7c-2ea2-4cf5-8891-96c5a4362a72", "objectTypeId": 467, "displayOrder": 1 } ] }, { "id": "93065127-adcc-43cb-b040-ef63be2285ec", "name": "", "step": 6, "activities": [ { "id": "167b101a-af09-4002-a14f-f537de266ce0", "name": "1 Minutes", "activityObjectId": "5d5f816b-b024-45a9-8ce9-726c6dd61bf4", "objectTypeId": 467, "displayOrder": 1 } ] }, { "id": "0d8d1390-75be-427d-900b-0af5c906a01b", "name": "", "step": 7, "activities": [ { "id": "6752906a-ce99-4bfe-b1d5-4db8eb4a24b0", "name": "03:00 PM", "activityObjectId": "1c9836b8-0242-4620-9421-21d36a0df751", "objectTypeId": 467, "displayOrder": 1 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/8f82c2a7-0bae-45a9-bdee-e631ab25c0d5/get-response.json ================================================ { "id": "8f82c2a7-0bae-45a9-bdee-e631ab25c0d5", "name": "testExisting_automation_event", "description": "", "key": "testExisting_automation_event", "typeId": 1, "type": "scheduled", "statusId": 6, "status": "Scheduled", "categoryId": 290937, "lastRunTime": "2024-11-08T03:15:20.27", "lastRunInstanceId": "b2bc1d03-04ba-4a01-9e33-0c246f07dd36", "schedule": { "id": "064cf4ba-a5d0-420a-8a4f-26055a3550ba", "typeId": 2, "startDate": "2024-11-07T12:15:00", "endDate": "2079-06-06T00:00:00", "scheduledTime": "2024-11-08T11:15:00", "rangeTypeId": 1, "occurrences": 478403, "pattern": "<Pattern><PatternType>0</PatternType><HourInterval>1</HourInterval></Pattern>", "icalRecur": "FREQ=HOURLY;UNTIL=20790606T080000;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "active", "timezoneId": 5 }, "steps": [ { "id": "83755b3f-5012-49b4-8112-0291c879b9d5", "name": "", "description": "", "step": 1, "activities": [ { "id": "39d74fe0-ced2-4e91-b23e-11218adc304c", "name": "testExisting_event_automation", "activityObjectId": "161b64a1-1867-4272-8c5c-4d7abe880702", "objectTypeId": 952, "displayOrder": 1 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json ================================================ { "id": "a8afb0e2-b00a-4c88-ad2e-1f7f8788c560", "name": "testNew_automation", "description": "created on deploy", "key": "testNew_automation", "typeId": 1, "type": "scheduled", "statusId": 4, "status": "Scheduled", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", "typeId": 3, "startDate": "2022-07-30T00:00:00", "endDate": "2022-07-30T00:00:00", "scheduledTime": "0001-01-01T07:00:00", "rangeTypeId": 0, "occurrences": 1, "pattern": "<Pattern><PatternType>0</PatternType><DayInterval>1</DayInterval></Pattern>", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "timezoneName": "W. Europe Standard Time", "scheduleStatus": "paused", "timezoneId": 5 }, "steps": [ { "id": "13fda077-0e82-4936-b936-a36b0997fc44", "name": "", "step": 1, "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 } ] } ] } ================================================ FILE: test/resources/9999999/automation/v1/automations/post-response.json ================================================ { "id": "a8afb0e2-b00a-4c88-ad2e-1f7f8788c560", "legacyId": "NewRkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "name": "testNew_automation", "description": "created on deploy", "key": "testNew_automation", "categoryId": 290937, "statusId": 4, "lastSavedDate": "2023-07-04T07:49:08.577", "lastSavedByName": "SFMC DevTools app user", "createdDate": "2023-07-04T07:49:08.297", "createdByName": "SFMC DevTools app user", "updateInProgress": false, "startSource": { "typeId": 1, "schedule": { "scheduleTypeId": 1, "startDate": "2020-05-13T18:30:32.11-06:00", "endDate": "2079-06-06T21:00:00-06:00", "rangeTypeId": 1, "occurrences": 6213054, "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", "timezoneId": 5, "statusId": 0 } }, "steps": [ { "activities": [ { "id": "8081a992-a27d-4a43-984a-d60114ea1025", "name": "testExisting_dataExtract", "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "objectTypeId": 73, "displayOrder": 1 }, { "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_emailSend", "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", "objectTypeId": 42, "displayOrder": 2 }, { "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", "name": "testExisting_fileTransfer", "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "objectTypeId": 53, "displayOrder": 3 }, { "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", "name": "testExisting_importFile", "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "objectTypeId": 43, "displayOrder": 4, "targetDataExtensions": [ { "id": "21711373-72c1-ec11-b83b-48df37d1deb7", "name": "testExisting_dataExtension", "key": "testExisting_dataExtension", "description": "bla bla", "rowCount": 0 } ] }, { "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_query_WRONG_NAME", "activityObjectId": "549f0568-607c-4940-afef-437965094dat", "objectTypeId": 300, "displayOrder": 5 }, { "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_script", "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "objectTypeId": 423, "displayOrder": 6 }, { "id": "f3774dc2-a271-4a44-8cbe-f630a6d6545e", "name": "testExisting_dataExtension", "activityObjectId": "testNew_RANDOM_NEW_GUID", "objectTypeId": 1000, "displayOrder": 7 } ], "annotation": "", "stepNumber": 0 } ] } ================================================ FILE: test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/delete-response.txt ================================================ OK ================================================ FILE: test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/get-response.json ================================================ { "dataExtractDefinitionId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "name": "testExisting_dataExtract", "key": "testExisting_dataExtract", "description": "blabla", "dataExtractTypeId": "bb94a04d-9632-4623-be47-daabc3f588a6", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "createdBy": 700301950, "modifiedBy": 700301950, "intervalType": 0, "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string", "value": "testExisting_dataExtension" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ] } ================================================ FILE: test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/patch-response.json ================================================ { "dataExtractDefinitionId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "name": "testExisting_dataExtract", "key": "testExisting_dataExtract", "description": "created via deploy", "dataExtractTypeId": "bb94a04d-9632-4623-be47-daabc3f588a6", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "createdBy": 700301950, "modifiedBy": 700301950, "intervalType": 0, "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string", "value": "testExisting_dataExtension" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ] } ================================================ FILE: test/resources/9999999/automation/v1/dataextracts/get-response.json ================================================ { "count": 1, "page": 1, "pageSize": 500, "items": [ { "dataExtractDefinitionId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "name": "testExisting_dataExtract", "key": "testExisting_dataExtract", "description": "bla bla", "dataExtractTypeId": "bb94a04d-9632-4623-be47-daabc3f588a6", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "createdDate": "2022-11-09T05:31:21.667", "modifiedDate": "2022-11-17T07:13:36.9", "createdBy": 700301950, "modifiedBy": 700301950, "intervalType": 0 } ] } ================================================ FILE: test/resources/9999999/automation/v1/dataextracts/post-response.json ================================================ { "dataExtractDefinitionId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", "name": "testNew_dataExtract", "key": "testNew_dataExtract", "description": "blabla", "dataExtractTypeId": "bb94a04d-9632-4623-be47-daabc3f588a6", "fileSpec": "testNew-%%Year%%-%%Month%%-%%Day%%", "createdBy": 700301950, "modifiedBy": 700301950, "intervalType": 0, "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string", "value": "testExisting_dataExtension" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ] } ================================================ FILE: test/resources/9999999/automation/v1/dataextracttypes/get-response.json ================================================ [ { "name": "Audit Trail Activity Log", "extractId": "d804ddf9-feda-4495-8e7e-069a14f5d248" }, { "name": "Zip", "extractId": "9a487c7d-96bd-484c-ad80-0f0bcbb91ca7" }, { "name": "Tracking Extract", "extractId": "c7219016-a7f0-4c72-8657-1ec12c28a0db" }, { "name": "Mobile Push Detail Extract Report", "extractId": "e6647310-ac95-4f32-a639-2a6b145c83f1" }, { "name": "UTF16 to ASCII Converter", "extractId": "e7e14f95-b925-462d-b6b4-4a6b1dca7ca1" }, { "name": "Contacts Without Channel Addresses", "extractId": "f2500d28-b3cb-42b9-ad31-361123ec1222" }, { "name": "Convert XML", "extractId": "805dfb29-82cb-43dc-989b-53ef5d181920" }, { "name": "GZip", "extractId": "7e7d322a-88ca-499a-9fb3-90e72fcf00af" }, { "name": "XmlToTextMapper", "extractId": "cf2cd221-fc3c-4d9f-90b4-a4e879a51ab6" }, { "name": "Enhanced FTP File Move and Copy", "extractId": "90d90e0a-fd9a-4d35-b471-cde0d17c91d4" }, { "name": "Data Extension Extract", "extractId": "bb94a04d-9632-4623-be47-daabc3f588a6" }, { "name": "Audit Trail Access Log", "extractId": "382b94bd-bd1b-45e1-864f-eb824841885a" } ] ================================================ FILE: test/resources/9999999/automation/v1/dataverifications/post-response.json ================================================ { "dataVerificationDefinitionId": "testNew_RANDOM_NEW_GUID", "targetObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "verificationType": "IsEqualTo", "value1": 2, "value2": 0, "shouldStopOnFailure": false, "shouldEmailOnFailure": false, "notificationEmailAddress": "", "notificationEmailMessage": "", "createdBy": 700301950 } ================================================ FILE: test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/delete-response.json ================================================ ================================================ FILE: test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/get-response.json ================================================ { "dataVerificationDefinitionId": "testExisting_39f6a488-20eb-4ba0-b0b9", "targetObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "verificationType": "IsEqualTo", "value1": 1, "value2": 0, "shouldStopOnFailure": true, "shouldEmailOnFailure": false, "notificationEmailAddress": "", "notificationEmailMessage": "", "createdBy": 700301950 } ================================================ FILE: test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/patch-response.json ================================================ { "dataVerificationDefinitionId": "testExisting_39f6a488-20eb-4ba0-b0b9", "targetObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "verificationType": "IsEqualTo", "value1": 1, "value2": 0, "shouldStopOnFailure": true, "shouldEmailOnFailure": true, "notificationEmailAddress": "test@accenture.com", "notificationEmailMessage": "", "createdBy": 700301950 } ================================================ FILE: test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/delete-response.json ================================================ {} ================================================ FILE: test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/get-response.json ================================================ { "id": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "name": "testExisting_fileTransfer", "description": "17.11.2022", "customerKey": "testExisting_fileTransfer", "fileSpec": "%%Year%%", "isEncrypted": false, "isCompressed": false, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "isUpload": true, "isPgp": false, "isFileSpecLocalized": false, "createdDate": "2022-11-09T05:31:56.477", "modifiedDate": "2022-11-17T07:13:20.05" } ================================================ FILE: test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/patch-response.json ================================================ { "id": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "name": "testExisting_fileTransfer", "description": "17.11.2022", "customerKey": "testExisting_fileTransfer", "fileSpec": "%%Year%% updated via deploy", "isEncrypted": false, "isCompressed": false, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "isUpload": true, "isPgp": false, "isFileSpecLocalized": false, "createdDate": "2022-11-09T05:31:56.477", "modifiedDate": "2022-11-17T07:13:20.05" } ================================================ FILE: test/resources/9999999/automation/v1/filetransfers/get-response.json ================================================ { "page": 1, "pageSize": 500, "count": 1, "items": [ { "id": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "name": "testExisting_fileTransfer", "description": "17.11.2022", "customerKey": "testExisting_fileTransfer", "createdDate": "2022-11-09T05:31:56.477", "modifiedDate": "2022-11-17T07:13:20.05" } ] } ================================================ FILE: test/resources/9999999/automation/v1/filetransfers/post-response.json ================================================ { "id": "72c328ac-f5b0-4e37-91d3-a775666f15a6", "name": "testNew_fileTransfer", "description": "17.11.2022", "customerKey": "testNew_fileTransfer", "fileSpec": "%%Year%% created on deploy", "isEncrypted": false, "isCompressed": false, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "isUpload": true, "isPgp": false, "isFileSpecLocalized": false, "createdDate": "2022-11-09T05:31:56.477", "modifiedDate": "2022-11-17T07:13:20.05" } ================================================ FILE: test/resources/9999999/automation/v1/filters/a0f1a1bc-4ea1-44b3-8fe1-ce40ef35c1c0/patch-response.json ================================================ { "categoryId": 37139, "customerKey": "testNew_filter", "description": "created via deploy", "destinationObjectId": "21711373-72c1-ec11-b83b-exclusion", "destinationTypeId": 2, "filterActivityId": "a0f1a1bc-4ea1-44b3-8fe1-ce40ef35c1c0", "filterDefinitionId": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "name": "testNew_filter", "sourceObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "sourceTypeId": 2, "statusId": 1, "resultDEName": "testExisting_dataExtension_exclusion", "resultDEKey": "testExisting_dataExtension_exclusion", "resultDEDescription": "", "createdDate": "2026-02-02T07:34:49.203", "modifiedDate": "2026-02-02T07:34:49.277" } ================================================ FILE: test/resources/9999999/automation/v1/filters/f018f237-f7ef-40b0-afc8-39ea2e5dcca4/delete-response.txt ================================================ ================================================ FILE: test/resources/9999999/automation/v1/filters/f018f237-f7ef-40b0-afc8-39ea2e5dcca4/get-response.json ================================================ { "categoryId": 37139, "customerKey": "testExisting_filter", "description": "blabla", "destinationObjectId": "21711373-72c1-ec11-b83b-exclusion", "destinationTypeId": 2, "filterActivityId": "f018f237-f7ef-40b0-afc8-39ea2e5dcca4", "filterDefinitionId": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "name": "testExisting_filter", "sourceObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "sourceTypeId": 2, "statusId": 1, "createdDate": "2025-12-01T17:53:39.163", "modifiedDate": "2026-01-28T10:14:46.717" } ================================================ FILE: test/resources/9999999/automation/v1/filters/f018f237-f7ef-40b0-afc8-39ea2e5dcca4/patch-response.json ================================================ { "categoryId": 5319, "customerKey": "testExisting_filter", "description": "updated on deploy", "destinationObjectId": "21711373-72c1-ec11-b83b-exclusion", "destinationTypeId": 2, "filterActivityId": "f018f237-f7ef-40b0-afc8-39ea2e5dcca4", "filterDefinitionId": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "name": "testExisting_filter", "sourceObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "sourceTypeId": 2, "statusId": 1, "createdDate": "2025-12-01T17:53:39.163", "modifiedDate": "2026-01-28T10:14:46.717" } ================================================ FILE: test/resources/9999999/automation/v1/filters/get-response.json ================================================ { "count": 54, "page": 1, "pageSize": 500, "items": [ { "categoryId": 37139, "customerKey": "testExisting_filter", "description": "blabla", "destinationObjectId": "21711373-72c1-ec11-b83b-exclusion", "destinationTypeId": 2, "filterActivityId": "f018f237-f7ef-40b0-afc8-39ea2e5dcca4", "filterDefinitionId": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "name": "testExisting_filter", "sourceObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "sourceTypeId": 2, "statusId": 1, "createdDate": "2025-12-01T17:53:39.163", "modifiedDate": "2026-01-28T10:14:46.717" } ] } ================================================ FILE: test/resources/9999999/automation/v1/ftplocations/get-response.json ================================================ { "page": 1, "pageSize": 2, "count": 5, "items": [ { "name": "Salesforce Objects & Reports", "id": "a4a0aff9-ddc5-4608-b0e1-40d0a5133d8f", "locationTypeId": 4 }, { "name": "ExactTarget Enhanced FTP", "id": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "locationTypeId": 0, "relPath": "ExactTarget Enhanced FTP" }, { "name": "testExisting_fileLocation_gcp_name", "id": "5fc2cc79-b4fb-465d-bc09-7dacf8afebae", "locationTypeId": 16, "locationUrl": "GCP://some-bucket/Task/Activity" }, { "name": "testExisting_fileLocation_azure_name", "id": "fff73b41-dced-4a2a-a6cf-430a46a18df6", "locationTypeId": 15, "locationUrl": "Azure://container-name/my/path" }, { "name": "testExisting_fileLocation_aws_name", "id": "62bb39b1-c84f-47b5-98a0-61e5d79b7f31", "locationTypeId": 13, "locationUrl": "S3://bucket-name/my/path" }, { "name": "testExisting_fileLocation_exsftp_name", "id": "335802a4-479d-4834-a491-fc5d2d068132", "locationTypeId": 2, "locationUrl": "sftp://test.com" } ] } ================================================ FILE: test/resources/9999999/automation/v1/imports/1ebf557b-372e-eb11-b81b-48df37d1dbd7/get-response.json ================================================ { "allowErrors": true, "customerKey": "testExisting_importFileSMS", "createdDate": "2022-11-24T03:29:01.05", "modifiedDate": "2023-07-19T23:06:33.577", "dateFormatLocale": "en-US", "deleteFile": false, "description": "Unsub for Keyword", "destinationObjectId": "00000000-0000-0000-0000-000000000000", "destinationId": 0, "destinationObjectTypeId": 584, "fieldMappings": [ { "sourceFieldName": "Locale", "destinationFieldName": "_CountryCode" }, { "sourceFieldName": "FirstName", "destinationFieldName": "_FirstName" }, { "sourceFieldName": "IsHonorDST", "destinationFieldName": "_IsHonorDST" }, { "sourceFieldName": "LastName", "destinationFieldName": "_LastName" }, { "sourceFieldName": "MobileNumber", "destinationFieldName": "_MobileNumber" }, { "sourceFieldName": "Status", "destinationFieldName": "_Status" }, { "sourceFieldName": "ContactKey", "destinationFieldName": "_SubscriberKey" }, { "sourceFieldName": "UTCoffset", "destinationFieldName": "_UTCOffset" }, { "sourceFieldName": "Action", "destinationFieldName": "Action" }, { "sourceFieldName": "ModifiedDate", "destinationFieldName": "SalesforceModified" }, { "sourceFieldName": "SFContactID", "destinationFieldName": "SFContactID" } ], "fieldMappingType": "ManualMap", "fileNamingPattern": "_CustomObject", "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "fileTransferLocationName": "ExactTarget Enhanced FTP", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "1ebf557b-372e-eb11-b81b-48df37d1dbd7", "isOrderedImport": false, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFileSMS", "notificationEmailAddress": "joern.berkefeld@accenture.com", "sendEmailNotification": true, "standardQuotedStrings": false, "subscriberImportTypeId": 255, "updateTypeId": 0, "fileTransferLocationTypeId": 0 } ================================================ FILE: test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/delete-response.txt ================================================ ================================================ FILE: test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/get-response.json ================================================ { "allowErrors": true, "customerKey": "testExisting_importFile", "createdDate": "2022-11-09T05:32:30.533", "modifiedDate": "2022-11-17T07:13:03.95", "dateFormatLocale": "en-US", "deleteFile": false, "description": "17.11.2022", "destinationObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "destinationId": 0, "destinationObjectTypeId": 310, "destinationName": "testExisting_dataExtension", "encodingName": "utf-8", "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "blabla", "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "fileTransferLocationName": "ExactTarget Enhanced FTP", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "subscriberImportTypeId": 255, "updateTypeId": 0, "fileTransferLocationTypeId": 0, "blankFileProcessingType": 2 } ================================================ FILE: test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/patch-response.json ================================================ { "allowErrors": true, "customerKey": "testExisting_importFile", "createdDate": "2022-11-09T05:32:30.533", "modifiedDate": "2023-07-18T09:11:26.19", "dateFormatLocale": "en-US", "deleteFile": false, "description": "updated on deploy", "destinationObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "destinationId": 0, "destinationObjectTypeId": 310, "destinationName": "testExisting_dataExtension", "encodingName": "utf-8", "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "blabla", "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "fileTransferLocationName": "ExactTarget Enhanced FTP", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "subscriberImportTypeId": 255, "updateTypeId": 0, "fileTransferLocationTypeId": 0, "blankFileProcessingType": 1 } ================================================ FILE: test/resources/9999999/automation/v1/imports/d2474efb-a449-ef11-b876-f40343c95928/get-response.json ================================================ { "allowErrors": true, "customerKey": "testExisting_importFileDataImport", "createdDate": "2024-07-24T04:10:42.15", "modifiedDate": "2024-07-24T04:10:42.15", "dateFormatLocale": "en-US", "deleteFile": false, "destinationObjectId": "1c8064d5-6502-ef11-a5c8-5cba2c702db8", "destinationId": 0, "destinationObjectTypeId": 310, "destinationName": "importFileTestB", "encodingName": "utf-8", "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "_CustomObject", "fileSpec": "_CustomObject", "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "fileTransferLocationName": "ExactTarget Enhanced FTP", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "d2474efb-a449-ef11-b876-f40343c95928", "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFileDataImport", "sendEmailNotification": false, "sourceCustomObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "sourceDataExtensionName": "testExisting_dataExtension", "standardQuotedStrings": true, "subscriberImportTypeId": 255, "updateTypeId": 4, "fileTransferLocationTypeId": 0, "blankFileProcessingType": 0 } ================================================ FILE: test/resources/9999999/automation/v1/imports/get-response.json ================================================ { "page": 1, "pageSize": 500, "count": 3, "items": [ { "allowErrors": true, "customerKey": "testExisting_importFile", "createdDate": "2022-11-09T05:32:30.533", "modifiedDate": "2022-11-17T07:13:03.95", "dateFormatLocale": "en-US", "deleteFile": false, "description": "17.11.2022", "destinationObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "destinationId": 0, "destinationObjectTypeId": 310, "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "blabla", "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "9d16f42c-2260-ed11-b849-48df37d1de8b", "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "subscriberImportTypeId": 255, "updateTypeId": 0, "fileTransferLocationTypeId": 0 }, { "allowErrors": true, "customerKey": "testExisting_importFileSMS", "createdDate": "2022-11-24T03:29:01.05", "modifiedDate": "2023-07-19T23:06:33.577", "dateFormatLocale": "en-US", "deleteFile": false, "description": "Unsub for Keyword", "destinationObjectId": "00000000-0000-0000-0000-000000000000", "destinationId": 0, "destinationObjectTypeId": 584, "fieldMappings": [ { "sourceFieldName": "Locale", "destinationFieldName": "_CountryCode" }, { "sourceFieldName": "FirstName", "destinationFieldName": "_FirstName" }, { "sourceFieldName": "IsHonorDST", "destinationFieldName": "_IsHonorDST" }, { "sourceFieldName": "LastName", "destinationFieldName": "_LastName" }, { "sourceFieldName": "MobileNumber", "destinationFieldName": "_MobileNumber" }, { "sourceFieldName": "Status", "destinationFieldName": "_Status" }, { "sourceFieldName": "ContactKey", "destinationFieldName": "_SubscriberKey" }, { "sourceFieldName": "UTCoffset", "destinationFieldName": "_UTCOffset" }, { "sourceFieldName": "Action", "destinationFieldName": "Action" }, { "sourceFieldName": "ModifiedDate", "destinationFieldName": "SalesforceModified" }, { "sourceFieldName": "SFContactID", "destinationFieldName": "SFContactID" } ], "fieldMappingType": "ManualMap", "fileNamingPattern": "_CustomObject", "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "1ebf557b-372e-eb11-b81b-48df37d1dbd7", "isOrderedImport": false, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFileSMS", "notificationEmailAddress": "joern.berkefeld@accenture.com", "sendEmailNotification": true, "standardQuotedStrings": false, "subscriberImportTypeId": 255, "updateTypeId": 0, "fileTransferLocationTypeId": 0 }, { "allowErrors": true, "customerKey": "testExisting_importFileDataImport", "createdDate": "2024-07-24T04:10:42.15", "modifiedDate": "2024-07-24T04:10:42.15", "dateFormatLocale": "en-US", "deleteFile": false, "destinationObjectId": "bf4f1d9b-a349-ef11-b876-f40343c95928", "destinationId": 0, "destinationObjectTypeId": 310, "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "_CustomObject", "fileSpec": "_CustomObject", "fileTransferLocationId": "527eeab5-fd9e-4a2d-ad38-f3c856ea2031", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "importDefinitionId": "d2474efb-a449-ef11-b876-f40343c95928", "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFileDataImport", "sendEmailNotification": false, "standardQuotedStrings": true, "subscriberImportTypeId": 255, "updateTypeId": 4, "fileTransferLocationTypeId": 0 } ] } ================================================ FILE: test/resources/9999999/automation/v1/imports/post-response.json ================================================ { "allowErrors": true, "customerKey": "testNew_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "created via deploy", "fieldMappingType": "InferFromColumnHeadings", "fieldMappings": [], "fileNamingPattern": "blabla", "fileTransferLocationTypeId": 0, "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "name": "testNew_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "fileTransferLocationId": "41a5ded7-0d98-4910-a15f-d09e7ab0af24", "destinationObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "destinationObjectTypeId": 310, "subscriberImportTypeId": 255, "updateTypeId": 0, "createdDate": "2022-11-09T05:53:03.243", "destinationId": 0, "modifiedDate": "2023-07-18T09:11:26.19" } ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt ================================================ OK ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/actions/start/post-response.txt ================================================ OK ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/delete-response.json ================================================ "OK" ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nFrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", "name": "testExisting_query", "key": "testExisting_query", "description": "updated on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixKeys", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixedKeys", "description": "updated on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeysSuffix/get-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeysSuffix", "name": "testExisting_query_fixedKeysSuffix", "key": "testExisting_query_fixKeysSuffix", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nfrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeysSuffix/patch-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", "name": "testExisting_query_fixedKeysSuffix", "key": "testExisting_query_fixedKeysSuff_DEV", "description": "updated on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/abcde-607c-4940-afef-437965094dat/get-response.json ================================================ { "queryDefinitionId": "abcde-607c-4940-afef-437965094dat", "name": "testExisting_query2", "key": "testExisting_query2", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nfrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension-WRONG", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/queries/get-response-Name=testExisting_query.json ================================================ { "count": 1, "page": 1, "pageSize": 50, "items": [ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nFrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false } ] } ================================================ FILE: test/resources/9999999/automation/v1/queries/get-response.json ================================================ { "count": 3, "page": 1, "pageSize": 50, "items": [ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nFrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false }, { "queryDefinitionId": "abcde-607c-4940-afef-437965094dat", "name": "testExisting_query2", "key": "testExisting_query2", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nfrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension-WRONG", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false }, { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixKeys", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nfrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false }, { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeysSuffix", "name": "testExisting_query_fixedKeysSuffix", "key": "testExisting_query_fixKeysSuffix", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nfrom\n _Subscribers\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false }, { "queryDefinitionId": "shared-607c-4940-afef-437965094dat", "name": "testExisting_query_SharedDE", "key": "testExisting_query_SharedDE", "description": "bla bla", "queryText": "Select\n SubscriberKey as testField, Trim(last_name) AS name\nFrom\n testExisting_dataExtensionShared\nwhere\n country in ('test')\n", "targetName": "testExisting_dataExtensionShared", "targetKey": "testExisting_dataExtensionShared", "targetId": "21711373-72c1-ec11-b83b-shared", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false } ] } ================================================ FILE: test/resources/9999999/automation/v1/queries/post-response.json ================================================ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dae", "name": "testNew_query", "key": "testNew_query", "description": "created on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\n", "targetName": "testExisting_dataExtension", "targetKey": "testExisting_dataExtension", "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", "targetDescription": "", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeId": 0, "targetUpdateTypeName": "Overwrite", "validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n", "categoryId": 999, "isFrozen": false } ================================================ FILE: test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/delete-response.txt ================================================ OK ================================================ FILE: test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/get-response.json ================================================ { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "name": "testExisting_script", "key": "testExisting_script", "description": "updated on deploy", "script": "<script runat=\"server\">\n// dummy updated\n</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" } ================================================ FILE: test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json ================================================ { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "name": "testExisting_script", "key": "testExisting_script", "description": "updated on deploy", "script": "<script runat=\"server\">\n// dummy updated\n</script>", "categoryId": 304, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "0001-01-01T00:00:00" } ================================================ FILE: test/resources/9999999/automation/v1/scripts/get-response-name=testExisting_script.json ================================================ { "count": 1, "page": 1, "pageSize": 500, "items": [ { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "name": "testExisting_script", "key": "testExisting_script", "description": "", "script": " <script runat=\"server\">\n//dummy\n</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" } ] } ================================================ FILE: test/resources/9999999/automation/v1/scripts/get-response.json ================================================ { "count": 5, "page": 1, "pageSize": 500, "items": [ { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", "name": "testExisting_script", "key": "testExisting_script", "description": "", "script": " <script runat=\"server\">\n//dummy\n</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" }, { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-noScriptTag", "name": "testExisting_script_noScriptTag", "key": "testExisting_script_noScriptTag", "description": "", "script": "// no script tag\n", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" }, { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-ampscript", "name": "testExisting_script_ampscript", "key": "testExisting_script_ampscript", "description": "", "script": "line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%% still line2\nline3\n<script runat=\"server\">\nPlatform.Function.ContentBlockByName(\"Content Builder\\\\dont strip non ssjs content\"); Platform.Function.ContentBlockByKey(\"testExisting_htmlblock1\");</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" }, { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-ampincluded", "name": "testExisting_script_ampincluded", "key": "testExisting_script_ampincluded", "description": "", "script": " <script runat=\"server\">line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockById(1295064) =%% still line2\nline3\n</script>\n<script runat=\"server\">\nPlatform.Function.ContentBlockById(1295064);</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" }, { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-mixed", "name": "testExisting_script_mixed", "key": "testExisting_script_mixed", "description": "", "script": " <script runat=\"server\">//dummy\n</script>line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%% still line2;\n collapsed to line2 because it's assumed HTML\n<script runat=\"server\">\nPlatform.Function.ContentBlockByKey(\"testExisting_asset_htmlblock\");</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" } ] } ================================================ FILE: test/resources/9999999/automation/v1/scripts/post-response.json ================================================ { "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-new", "name": "testNew_script", "key": "testNew_script", "description": "created on deploy", "script": "<script runat=\"server\">\n// dummy created\n</script>", "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" } ================================================ FILE: test/resources/9999999/data/v1/customobjectdata/key/testExisting_dataExtension/rowset/get-response.json ================================================ { "links": { "self": "/v1/customobjectdata/token/ea0a44dc-b679-4d7d-8b77-e5d3f106e854/rowset?$page=1" }, "requestToken": "ea0a44dc-b679-4d7d-8b77-e5d3f106e854", "tokenExpireDateUtc": "2023-01-26T13:54:59.883", "customObjectId": "30400c03-0ec4-ec11-b83c-48df37d1de8b", "customObjectKey": "testExisting_dataExtension", "pageSize": 1, "page": 1, "count": 0, "top": 0 } ================================================ FILE: test/resources/9999999/data/v1/filetransferlocation/Salesforce%20Objects%20%26%20Reports/get-response.json ================================================ { "requestId": "bfc409fb-2fd5-459a-81d6-525b20f6eed4", "resultMessages": [] } ================================================ FILE: test/resources/9999999/data/v1/filetransferlocation/testExisting_fileLocation_aws/patch-response.json ================================================ { "fileTransferLocation": { "customerKey": "testExisting_fileLocation_aws", "name": "testExisting_fileLocation_aws_name", "description": "updated via deploy", "locationType": "AmazonSimpleStorage", "awsFileTransferLocation": { "regionName": "eucentral1", "transferAccelerationEnabled": false, "accessKeyId": "key-id", "relativePath": "my/path", "bucketName": "bucket-name", "authType": "AccessKey" } }, "requestId": "ae8149ee-819e-40b7-b08f-cb59fdf88ddb", "resultMessages": [] } ================================================ FILE: test/resources/9999999/data/v1/filetransferlocation/testExisting_fileLocation_azure/delete-response.json ================================================ { "requestId": "dba273e4-6036-4c1d-99de-e08626e102d5", "resultMessages": [] } ================================================ FILE: test/resources/9999999/data/v1/filetransferlocation/testExisting_fileLocation_azure/get-response.json ================================================ { "fileTransferLocation": { "customerKey": "testExisting_fileLocation_azure", "name": "testExisting_fileLocation_azure_name", "description": "blabla", "locationType": "AzureBlobStorage", "azureFileTransferLocation": { "storageAccountName": "accountname", "tenantId": "my-id", "accessKeyId": "client-id", "relativePath": "my/path", "bucketName": "container-name", "authType": "AccessKey" } }, "requestId": "d49c372e-9939-4b81-91d2-69a37a8bb036", "resultMessages": [] } ================================================ FILE: test/resources/9999999/data/v1/filetransferlocation/testExisting_fileLocation_exsftp/patch-response.json ================================================ { "fileTransferLocation": { "customerKey": "testExisting_fileLocation_exsftp", "name": "testExisting_fileLocation_exsftp_name", "description": "updated via deploy", "locationType": "ExternalSftp", "sFtpFileTransferLocation": { "portNumber": 22, "userName": "abc", "url": "sftp://test.com", "authType": "Password" } }, "requestId": "05ef7257-72e6-4774-87c7-1f99aa892534", "resultMessages": [] } ================================================ FILE: test/resources/9999999/data/v1/filetransferlocations/get-response.json ================================================ { "page": 1, "pageSize": 50, "count": 4, "items": [ { "customerKey": "testExisting_fileLocation_gcp", "name": "testExisting_fileLocation_gcp_name", "description": "", "locationType": "GcpBlobStorage", "gcpFileTransferLocation": { "relativePath": "Task/Activity", "bucketName": "some-bucket" } }, { "customerKey": "testExisting_fileLocation_aws", "name": "testExisting_fileLocation_aws_name", "description": "", "locationType": "AmazonSimpleStorage", "awsFileTransferLocation": { "regionName": "eucentral1", "transferAccelerationEnabled": false, "accessKeyId": "key-id", "relativePath": "my/path", "bucketName": "bucket-name", "authType": "AccessKey" } }, { "customerKey": "testExisting_fileLocation_azure", "name": "testExisting_fileLocation_azure_name", "description": "blabla", "locationType": "AzureBlobStorage", "azureFileTransferLocation": { "storageAccountName": "accountname", "tenantId": "my-id", "accessKeyId": "client-id", "relativePath": "my/path", "bucketName": "container-name", "authType": "AccessKey" } }, { "customerKey": "testExisting_fileLocation_exsftp", "name": "testExisting_fileLocation_exsftp_name", "description": "blabla", "locationType": "ExternalSftp", "sFtpFileTransferLocation": { "portNumber": 22, "userName": "abc", "url": "sftp://test.com", "authType": "Password" } } ], "requestId": "3870c0e1-943c-4ae4-9cff-26736372dbe7", "resultMessages": [] } ================================================ FILE: test/resources/9999999/dataExtension/build-expected.json ================================================ { "CustomerKey": "testTemplated_dataExtension", "Name": "testTemplated_dataExtension", "Description": "foobar", "IsSendable": true, "IsTestable": true, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "Name": "FirstName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "EmailAddress", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "ContactKey", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "decimalField", "DefaultValue": "", "MaxLength": 6, "Scale": 3, "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Decimal" }, { "Name": "numberField", "DefaultValue": "", "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Number" } ], "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retainUntil": "2024-5-9", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/resources/9999999/dataExtension/create-expected.json ================================================ { "CustomerKey": "testNew_dataExtension", "Name": "testNew_dataExtension", "Description": "", "IsSendable": false, "IsTestable": false, "Fields": [ { "Name": "testField", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "Text" } ], "c__retentionPolicy": "none", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/resources/9999999/dataExtension/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:3a5f1edf-dacb-4d19-a0d3-4e0dcc9f507d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:fb395987-bf45-42d6-af73-f51816c7b73f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-b5d88471-97ad-4070-a18f-4c148a52da96"> <wsu:Created>2022-04-24T20:35:10Z</wsu:Created> <wsu:Expires>2022-04-24T20:40:10Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Data Extension created.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>30400c03-0ec4-ec11-b83c-48df37d1de8a</NewObjectID> <Object xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <ObjectID>30400c03-0ec4-ec11-b83c-48df37d1de8a</ObjectID> <CustomerKey>testNew_dataExtension</CustomerKey> <Name>testNew_dataExtension</Name> <Description /> <IsSendable>false</IsSendable> <IsTestable>false</IsTestable> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <Fields> <Field> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>testField</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> </Field> </Fields> <CategoryID>2</CategoryID> </Object> </Results> <RequestID>c41aa55a-90e3-4021-9f82-103796aae6da</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/delete-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>DeleteResponse</wsa:Action> <wsa:MessageID>urn:uuid:cbcad7ed-d768-4dbd-b2b9-230cc05dca1b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:545315fb-1e5b-4b6b-a17a-da1fcac3524f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-cd8b5c6b-0bc1-45e1-8df0-4c61bf120d0e"> <wsu:Created>2023-08-11T12:34:31Z</wsu:Created> <wsu:Expires>2023-08-11T12:39:31Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <DeleteResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Data Extension deleted. / Data Extension Fields deleted</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <ObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</ObjectID> <CustomerKey>testExisting_dataExtension</CustomerKey> <!-- <Fields> <Field> <PartnerKey xsi:nil="true" /> <ObjectID>d26f1b9c-fb30-4a91-9fe8-e2495cffbd74</ObjectID> </Field> </Fields> --> </Object> </Results> <RequestID>5c0faaa8-81db-4530-8b47-c56432f68543</RequestID> <OverallStatus>OK</OverallStatus> </DeleteResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/retrieve-CustomerKey=testExisting_dataExtension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-52fe9187-6f22-4701-bd57-d0eaa4aef215"> <wsu:Created>2022-04-21T19:21:50Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:50Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7</RequestID> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-04-21T06:56:27.927</CreatedDate> <ModifiedDate>2022-04-21T06:56:27.927</ModifiedDate> <ObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</ObjectID> <CustomerKey>testExisting_dataExtension</CustomerKey> <Name>testExisting_dataExtension</Name> <Description>bla bla</Description> <IsSendable>true</IsSendable> <IsTestable>true</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactKey</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>true</DeleteAtEndOfRetentionPeriod> <RetainUntil>5/9/2024 12:00:00 AM</RetainUntil> <CategoryID>2</CategoryID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/retrieve-CustomerKey=testNew_event_withSchema-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-52fe9187-6f22-4701-bd57-d0eaa4aef215"> <wsu:Created>2022-04-21T19:21:50Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:50Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7</RequestID> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-07-05T08:01:54.803</CreatedDate> <ModifiedDate>2024-07-05T08:01:58.923</ModifiedDate> <ObjectID>4342972c-a43c-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testNew_event_withSchema</CustomerKey> <Name>testNew_event_withSchema</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-52fe9187-6f22-4701-bd57-d0eaa4aef215"> <wsu:Created>2022-04-21T19:21:50Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:50Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7</RequestID> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-04-21T06:56:27.927</CreatedDate> <ModifiedDate>2022-04-21T06:56:27.927</ModifiedDate> <ObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</ObjectID> <CustomerKey>testExisting_dataExtension</CustomerKey> <Name>testExisting_dataExtension</Name> <Description>bla bla</Description> <IsSendable>true</IsSendable> <IsTestable>true</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactKey</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>true</DeleteAtEndOfRetentionPeriod> <RetainUntil>5/9/2024 12:00:00 AM</RetainUntil> <CategoryID>2</CategoryID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/retrieve-createdViaEvent-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-52fe9187-6f22-4701-bd57-d0eaa4aef215"> <wsu:Created>2022-04-21T19:21:50Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:50Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7</RequestID> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-07-05T08:01:54.803</CreatedDate> <ModifiedDate>2024-07-05T08:01:58.923</ModifiedDate> <ObjectID>4342972c-a43c-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>0A1730F7-D7E3-4F30-8279-575BDB38D24D</CustomerKey> <Name>testNew_event_withSchema - 2024-07-08T014814443</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/retrieve-expected.json ================================================ { "CustomerKey": "testExisting_dataExtension", "Name": "testExisting_dataExtension", "Description": "bla bla", "IsSendable": true, "IsTestable": true, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "Name": "FirstName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "EmailAddress", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "ContactKey", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "decimalField", "DefaultValue": "", "MaxLength": 6, "Scale": 3, "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Decimal" }, { "Name": "numberField", "DefaultValue": "", "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Number" } ], "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retainUntil": "2024-5-9", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/resources/9999999/dataExtension/retrieve-expected.md ================================================ ## testExisting_dataExtension **Description:** bla bla **Folder:** Data Extensions/ **Fields in table:** 6 **Sendable:** Yes (`ContactKey` to `Subscriber Key`) **Testable:** Yes **Retention Policy:** allRecords - **Retention Period:** 6 Months - **Reset Retention Period on import:** no | Name | FieldType | MaxLength | IsPrimaryKey | IsNullable | DefaultValue | | --- | --- | --- | --- | --- | --- | | FirstName | Text | 50 | - | + | | | LastName | Text | 50 | - | + | | | EmailAddress | EmailAddress | 254 | - | - | | | ContactKey | Text | 50 | + | - | | | decimalField | Decimal | 6,3 | - | - | | | numberField | Number | | - | - | | ================================================ FILE: test/resources/9999999/dataExtension/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-52fe9187-6f22-4701-bd57-d0eaa4aef215"> <wsu:Created>2022-04-21T19:21:50Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:50Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7</RequestID> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-04-21T06:56:27.927</CreatedDate> <ModifiedDate>2022-04-21T06:56:27.927</ModifiedDate> <ObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</ObjectID> <CustomerKey>testExisting_dataExtension</CustomerKey> <Name>testExisting_dataExtension</Name> <Description>bla bla</Description> <IsSendable>true</IsSendable> <IsTestable>true</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactKey</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>true</DeleteAtEndOfRetentionPeriod> <RetainUntil>5/9/2024 12:00:00 AM</RetainUntil> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-04-21T06:56:27.927</CreatedDate> <ModifiedDate>2022-04-21T06:56:27.927</ModifiedDate> <ObjectID>21711373-72c1-ec11-b83b-exclusion</ObjectID> <CustomerKey>testExisting_dataExtension_exclusion</CustomerKey> <Name>testExisting_dataExtension_exclusion</Name> <Description>bla bla</Description> <IsSendable>true</IsSendable> <IsTestable>true</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactKey</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>true</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-04-24T12:15:55.853</CreatedDate> <ModifiedDate>2024-04-24T12:15:55.853</ModifiedDate> <ObjectID>5a7194ad-6602-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testExisting_DomainExclusion</CustomerKey> <Name>testExisting_DomainExclusion</Name> <Description>Domain Exclusion Data Extension Template</Description> <IsSendable>false</IsSendable> <IsTestable>false</IsTestable> <Template> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>086D14D3-5057-462B-AF33-01CA8D1FE87A</CustomerKey> </Template> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-04-24T12:09:53.527</CreatedDate> <ModifiedDate>2024-04-24T12:09:53.527</ModifiedDate> <ObjectID>1c8064d5-6502-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testExisting_journey_Quicksend</CustomerKey> <Name>testExisting_journey_Quicksend</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-04-24T12:10:46.457</CreatedDate> <ModifiedDate>2024-04-24T12:10:46.457</ModifiedDate> <ObjectID>ed305df3-6502-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testExisting_journey_Multistep</CustomerKey> <Name>testExisting_journey_Multistep</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-07-05T08:01:54.803</CreatedDate> <ModifiedDate>2024-07-05T08:01:58.923</ModifiedDate> <ObjectID>f2cc2b21-d73a-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> <Name>testExisting_event - 2024-07-05T080154625</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-07-05T08:01:54.803</CreatedDate> <ModifiedDate>2024-07-05T08:01:58.923</ModifiedDate> <ObjectID>4342972c-a43c-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> <Name>testNew_event_withSchema - 2024-07-08T014814443</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <Results xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-08-21T09:54:28.807</CreatedDate> <ModifiedDate>2024-08-21T09:54:28.807</ModifiedDate> <ObjectID>3c3a54a5-d55f-ef11-b876-f40343c95928</ObjectID> <CustomerKey>testExisting_temail_notPublished</CustomerKey> <Name>testExisting_temail_notPublished</Name> <Description>Triggered Send Source Data Extension Template</Description> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>SubscriberKey</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <Template> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>B6E8AE4C-3D93-49B1-B299-E0AE734213DD</CustomerKey> </Template> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/retrieve_event_withSchema-expected.json ================================================ { "CustomerKey": "testNew_event_withSchema", "Name": "testNew_event_withSchema", "Description": "", "IsSendable": true, "IsTestable": false, "SendableDataExtensionField": { "Name": "ContactId" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "Fields": [ { "Name": "ContactId", "DefaultValue": "", "MaxLength": 18, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "Type", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Status", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "Respondent", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "FirstName", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "PreferredLanguage", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "TouchPoint", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Datestamp", "DefaultValue": "GetDate()", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Date" }, { "Name": "StartDate", "DefaultValue": "", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Date" }, { "Name": "EndDate", "DefaultValue": "", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Date" }, { "Name": "BroadcastedNotificationDate", "DefaultValue": "", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Date" }, { "Name": "FirstReminderDate", "DefaultValue": "", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Date" }, { "Name": "SecondReminderDate", "DefaultValue": "", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Date" }, { "Name": "Title", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "DisplayName", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Text", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Description", "DefaultValue": "", "MaxLength": 4000, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Channel", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "FirstReminderChannel", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "SecondReminderChannel", "DefaultValue": "", "MaxLength": 256, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Email", "DefaultValue": "", "MaxLength": 254, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "ArticleOrTaskID", "DefaultValue": "", "MaxLength": 18, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "Points", "DefaultValue": "", "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Number" }, { "Name": "TaskType", "DefaultValue": "", "MaxLength": 255, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "TaskArea", "DefaultValue": "", "MaxLength": 255, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" } ], "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions", "c__retentionPolicy": "none" } ================================================ FILE: test/resources/9999999/dataExtension/template-expected.json ================================================ { "CustomerKey": "{{{prefix}}}dataExtension", "Name": "{{{prefix}}}dataExtension", "Description": "{{{description}}}", "IsSendable": true, "IsTestable": true, "SendableDataExtensionField": { "Name": "ContactKey" }, "SendableSubscriberField": { "Name": "Subscriber Key" }, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "Name": "FirstName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "EmailAddress", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "ContactKey", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "decimalField", "DefaultValue": "", "MaxLength": 6, "Scale": 3, "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Decimal" }, { "Name": "numberField", "DefaultValue": "", "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Number" } ], "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retainUntil": "2024-5-9", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/resources/9999999/dataExtension/update-afterCreatedViaEvent-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:994e213d-1125-450d-b187-32e3870147d1</wsa:MessageID> <wsa:RelatesTo>urn:uuid:f1fc86ef-c0c8-4c17-a901-a15fc2631f76</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-88cf0bce-bf0f-4d5f-90a6-2897708181b5"> <wsu:Created>2022-04-26T20:49:03Z</wsu:Created> <wsu:Expires>2022-04-26T20:54:03Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Data Extension updated.</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-07-05T08:01:54.803</CreatedDate> <ModifiedDate>2024-07-05T08:01:58.923</ModifiedDate> <ObjectID>4342972c-a43c-ef11-a5c8-5cba2c702db8</ObjectID> <CustomerKey>testNew_event_withSchema</CustomerKey> <Name>testNew_event_withSchema</Name> <Description /> <IsSendable>true</IsSendable> <IsTestable>false</IsTestable> <SendableDataExtensionField> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>ContactId</Name> </SendableDataExtensionField> <SendableSubscriberField> <Name>_SubscriberKey</Name> </SendableSubscriberField> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod> <RetainUntil /> <CategoryID>2</CategoryID> </Results> <RequestID>dbfedcb6-a809-4101-b314-a7b920c9fb1e</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension/update-callout-afterCreatedViaEvent-expected.xml ================================================ <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><UpdateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI"><Objects xsi:type="DataExtension"><CreatedDate>2024-07-05T08:01:54.803</CreatedDate><ModifiedDate>2024-07-05T08:01:58.923</ModifiedDate><ObjectID>4342972c-a43c-ef11-a5c8-5cba2c702db8</ObjectID><CustomerKey>testNew_event_withSchema</CustomerKey><Name>testNew_event_withSchema</Name><Description></Description><IsSendable>true</IsSendable><IsTestable>false</IsTestable><SendableDataExtensionField><ObjectID></ObjectID><Name>ContactId</Name></SendableDataExtensionField><SendableSubscriberField><Name>_SubscriberKey</Name></SendableSubscriberField><RowBasedRetention>false</RowBasedRetention><ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport><DeleteAtEndOfRetentionPeriod>false</DeleteAtEndOfRetentionPeriod><RetainUntil></RetainUntil><CategoryID>2</CategoryID></Objects></UpdateRequest></Body><Header><fueloauth xmlns="http://exacttarget.com">9999999</fueloauth></Header></Envelope> ================================================ FILE: test/resources/9999999/dataExtension/update-expected.json ================================================ { "CustomerKey": "testExisting_dataExtension", "Name": "testExisting_dataExtension", "Description": "Container for my test emails", "IsSendable": false, "IsTestable": false, "DataRetentionPeriodLength": 6, "ResetRetentionPeriodOnImport": false, "Fields": [ { "Name": "FirstName", "DefaultValue": "", "MaxLength": 50, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "LastName", "DefaultValue": "", "MaxLength": 55, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" }, { "Name": "Email", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "EmailAddress" }, { "Name": "ContactKey", "DefaultValue": "", "MaxLength": 50, "IsRequired": true, "IsPrimaryKey": true, "FieldType": "Text" }, { "Name": "decimalField", "DefaultValue": "", "MaxLength": 6, "Scale": 3, "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Decimal" }, { "Name": "numberField", "DefaultValue": "", "IsPrimaryKey": false, "IsRequired": true, "FieldType": "Number" }, { "Name": "testField", "DefaultValue": "", "MaxLength": 254, "IsRequired": false, "IsPrimaryKey": false, "FieldType": "Text" } ], "c__dataRetentionPeriodUnitOfMeasure": "Months", "c__retainUntil": "2024-5-9", "c__retentionPolicy": "allRecords", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/resources/9999999/dataExtension/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:994e213d-1125-450d-b187-32e3870147d1</wsa:MessageID> <wsa:RelatesTo>urn:uuid:f1fc86ef-c0c8-4c17-a901-a15fc2631f76</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-88cf0bce-bf0f-4d5f-90a6-2897708181b5"> <wsu:Created>2022-04-26T20:49:03Z</wsu:Created> <wsu:Expires>2022-04-26T20:54:03Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Data Extension updated.</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="DataExtension"> <PartnerKey xsi:nil="true" /> <ObjectID>30400c03-0ec4-ec11-b83c-48df37d1de8b</ObjectID> <CustomerKey>testExisting_dataExtension</CustomerKey> <Name>testExisting_dataExtension</Name> <Description>Container for my test emails</Description> <IsSendable>false</IsSendable> <IsTestable>false</IsTestable> <DataRetentionPeriodLength>6</DataRetentionPeriodLength> <DataRetentionPeriodUnitOfMeasure>5</DataRetentionPeriodUnitOfMeasure> <RowBasedRetention>false</RowBasedRetention> <ResetRetentionPeriodOnImport>false</ResetRetentionPeriodOnImport> <DeleteAtEndOfRetentionPeriod>true</DeleteAtEndOfRetentionPeriod> <RetainUntil>5/9/2024 12:00:00 AM</RetainUntil> <Fields> <Field> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <Name>testField</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> </Field> </Fields> <CategoryID>2</CategoryID> </Object> </Results> <RequestID>dbfedcb6-a809-4101-b314-a7b920c9fb1e</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtension-deploy/testBlacklist_dataExtension.dataExtension-meta.json ================================================ { "CustomerKey": "testBlacklist_dataExtension", "Name": "testBlacklist_dataExtension", "Description": "", "IsSendable": false, "IsTestable": false, "Fields": [ { "Name": "testField", "DefaultValue": "", "MaxLength": 254, "IsRequired": true, "IsPrimaryKey": false, "FieldType": "Text" } ], "c__retentionPolicy": "none", "r__folder_ContentType": "dataextension", "r__folder_Path": "Data Extensions" } ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtension].[LastName]-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtension].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtension].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtension].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtension].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtension].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>7b7ef009-4b85-455b-9bdf-b7bef93791d7</ObjectID> <CustomerKey>[testExisting_dataExtension].[numberField]</CustomerKey> <Name>numberField</Name> <Scale>0</Scale> <DefaultValue /> <IsRequired>true</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Number</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c5d553cc-2c2a-464d-953d-6901be040f20</ObjectID> <CustomerKey>[testExisting_dataExtension].[decimalField]</CustomerKey> <Name>decimalField</Name> <Scale>3</Scale> <DefaultValue /> <MaxLength>6</MaxLength> <IsRequired>true</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Decimal</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml ================================================ <!-- used by deploy to get existing fields for existing and new dataExtension --> <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtension].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtension].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtension].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtension].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_event_withSchema-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>eb18160e-ec0f-46ca-b59a-1287dbeb7172</ObjectID> <CustomerKey>[testNew_event_withSchema].[DisplayName]</CustomerKey> <Name>DisplayName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>15</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ae0a3a3e-e81a-4b13-9a70-12ff6903c901</ObjectID> <CustomerKey>[testNew_event_withSchema].[PreferredLanguage]</CustomerKey> <Name>PreferredLanguage</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>6</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>3d39db8b-b561-4227-9051-1c201c79033e</ObjectID> <CustomerKey>[testNew_event_withSchema].[FirstReminderDate]</CustomerKey> <Name>FirstReminderDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>12</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>4eadce50-f552-41e5-8318-2fd367f043b9</ObjectID> <CustomerKey>[testNew_event_withSchema].[Description]</CustomerKey> <Name>Description</Name> <DefaultValue /> <MaxLength>4000</MaxLength> <IsRequired>false</IsRequired> <Ordinal>17</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d2826773-6965-4e78-9a05-3008ea45a104</ObjectID> <CustomerKey>[testNew_event_withSchema].[EndDate]</CustomerKey> <Name>EndDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>10</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>3bb8fa91-5881-4ca1-ac09-30604ba0b9be</ObjectID> <CustomerKey>[testNew_event_withSchema].[TaskArea]</CustomerKey> <Name>TaskArea</Name> <DefaultValue /> <MaxLength>255</MaxLength> <IsRequired>false</IsRequired> <Ordinal>25</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>721b938f-67ab-4d82-bb1c-33add4ec1533</ObjectID> <CustomerKey>[testNew_event_withSchema].[ContactId]</CustomerKey> <Name>ContactId</Name> <DefaultValue /> <MaxLength>18</MaxLength> <IsRequired>true</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>5ccee5f6-f282-4741-899d-400b05c57425</ObjectID> <CustomerKey>[testNew_event_withSchema].[FirstName]</CustomerKey> <Name>FirstName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d0ec626c-7cba-492b-abd0-48484e0c18bb</ObjectID> <CustomerKey>[testNew_event_withSchema].[Type]</CustomerKey> <Name>Type</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>0d49e8cf-cce9-4323-9b17-52f2366f9fc2</ObjectID> <CustomerKey>[testNew_event_withSchema].[Datestamp]</CustomerKey> <Name>Datestamp</Name> <DefaultValue>GetDate()</DefaultValue> <IsRequired>false</IsRequired> <Ordinal>8</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c44861f7-bac3-4b32-a5f8-744f67a66aaa</ObjectID> <CustomerKey>[testNew_event_withSchema].[Email]</CustomerKey> <Name>Email</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>false</IsRequired> <Ordinal>21</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c78d6054-5ce0-4438-a7ad-76b375224033</ObjectID> <CustomerKey>[testNew_event_withSchema].[Status]</CustomerKey> <Name>Status</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>541b063f-7c25-45b2-af53-7fdafbe0ee12</ObjectID> <CustomerKey>[testNew_event_withSchema].[BroadcastedNotificationDate]</CustomerKey> <Name>BroadcastedNotificationDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>11</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ff54519e-931b-432f-9083-861213fa9460</ObjectID> <CustomerKey>[testNew_event_withSchema].[TouchPoint]</CustomerKey> <Name>TouchPoint</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>7</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>f0a58625-0b62-496f-bea9-9d2722e50864</ObjectID> <CustomerKey>[testNew_event_withSchema].[Points]</CustomerKey> <Name>Points</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>23</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Number</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>43f69e09-9f47-477f-95b6-a9b9b8111f5e</ObjectID> <CustomerKey>[testNew_event_withSchema].[Title]</CustomerKey> <Name>Title</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>14</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>e9cd8c9f-39b0-4c93-8fce-aa3f0ca0d310</ObjectID> <CustomerKey>[testNew_event_withSchema].[SecondReminderDate]</CustomerKey> <Name>SecondReminderDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>13</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>403e68ee-f203-42e1-ac48-af18def0cccd</ObjectID> <CustomerKey>[testNew_event_withSchema].[TaskType]</CustomerKey> <Name>TaskType</Name> <DefaultValue /> <MaxLength>255</MaxLength> <IsRequired>false</IsRequired> <Ordinal>24</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>555ad728-f99a-4e13-a992-b70b1ffe36a2</ObjectID> <CustomerKey>[testNew_event_withSchema].[Respondent]</CustomerKey> <Name>Respondent</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>95948e52-e8d0-4908-98a9-cc34cd84233e</ObjectID> <CustomerKey>[testNew_event_withSchema].[LastName]</CustomerKey> <Name>LastName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>7976b904-1ed5-46f0-a524-cd1a787bfb5e</ObjectID> <CustomerKey>[testNew_event_withSchema].[FirstReminderChannel]</CustomerKey> <Name>FirstReminderChannel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>19</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ed225fdd-1aff-401d-906e-cd59b4d86fe2</ObjectID> <CustomerKey>[testNew_event_withSchema].[SecondReminderChannel]</CustomerKey> <Name>SecondReminderChannel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>20</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>30222d00-35c5-46e8-ab41-d3febd909eed</ObjectID> <CustomerKey>[testNew_event_withSchema].[ArticleOrTaskID]</CustomerKey> <Name>ArticleOrTaskID</Name> <DefaultValue /> <MaxLength>18</MaxLength> <IsRequired>true</IsRequired> <Ordinal>22</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8c79306f-4f3a-4925-bd48-e6c6905c157c</ObjectID> <CustomerKey>[testNew_event_withSchema].[StartDate]</CustomerKey> <Name>StartDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>9</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>1892b0ee-26ea-4280-8bca-e8cc5d3f9658</ObjectID> <CustomerKey>[testNew_event_withSchema].[Channel]</CustomerKey> <Name>Channel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>18</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bf50095e-54ba-42c7-9baf-f91618738d85</ObjectID> <CustomerKey>[testNew_event_withSchema].[Text]</CustomerKey> <Name>Text</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>16</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKeyINtestExisting_dataExtension,testNew_dataExtension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtension].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtension].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtension].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtension].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>7b7ef009-4b85-455b-9bdf-b7bef93791d7</ObjectID> <CustomerKey>[testExisting_dataExtension].[numberField]</CustomerKey> <Name>numberField</Name> <Scale>0</Scale> <DefaultValue /> <IsRequired>true</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Number</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c5d553cc-2c2a-464d-953d-6901be040f20</ObjectID> <CustomerKey>[testExisting_dataExtension].[decimalField]</CustomerKey> <Name>decimalField</Name> <Scale>3</Scale> <DefaultValue /> <MaxLength>6</MaxLength> <IsRequired>true</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Decimal</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-Name=FirstName-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtension].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>5ccee5f6-f282-4741-899d-400b05c57425</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[FirstName]</CustomerKey> <Name>FirstName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>5ccee5f6-f282-4741-899d-400b05c57425</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[FirstName]</CustomerKey> <Name>FirstName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-Name=LastName-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtension].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>95948e52-e8d0-4908-98a9-cc34cd84233e</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[LastName]</CustomerKey> <Name>LastName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>95948e52-e8d0-4908-98a9-cc34cd84233e</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[LastName]</CustomerKey> <Name>LastName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionField/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-468a08b7-c8fd-44bf-a2c8-fd6063127ca6"> <wsu:Created>2022-04-21T19:21:52Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:52Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>cfe51e71-6a2b-4cb4-aecd-3777076d63bc</RequestID> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8018397d-880d-4f88-940e-3b4eca098a0c</ObjectID> <CustomerKey>[testExisting_dataExtension].[ContactKey]</CustomerKey> <Name>ContactKey</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bea0e308-5d45-4181-a673-da9972a7c674</ObjectID> <CustomerKey>[testExisting_dataExtension].[LastName]</CustomerKey> <Name>LastName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>2557b461-a699-4744-950d-e80a19afc2dc</ObjectID> <CustomerKey>[testExisting_dataExtension].[EmailAddress]</CustomerKey> <Name>EmailAddress</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>42760528-a8c5-44dd-8c1d-ff34e5daee54</ObjectID> <CustomerKey>[testExisting_dataExtension].[FirstName]</CustomerKey> <Name>FirstName</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>7b7ef009-4b85-455b-9bdf-b7bef93791d7</ObjectID> <CustomerKey>[testExisting_dataExtension].[numberField]</CustomerKey> <Name>numberField</Name> <Scale>0</Scale> <DefaultValue /> <IsRequired>true</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Number</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c5d553cc-2c2a-464d-953d-6901be040f20</ObjectID> <CustomerKey>[testExisting_dataExtension].[decimalField]</CustomerKey> <Name>decimalField</Name> <Scale>3</Scale> <DefaultValue /> <MaxLength>6</MaxLength> <IsRequired>true</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Decimal</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_dataExtension</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>78b6d411-a5a3-42ac-b9ef-4b5b31db861d</ObjectID> <CustomerKey>[testExisting_journey_Multistep].[Email]</CustomerKey> <Name>Email</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_journey_Multistep</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d38a445a-34b4-499d-9764-ce46cfc675a2</ObjectID> <CustomerKey>[testExisting_journey_Multistep].[ContactId]</CustomerKey> <Name>ContactId</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_journey_Multistep</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>f8c11314-49fc-4e9b-8971-5d6a50705195</ObjectID> <CustomerKey>[testExisting_journey_Quicksend].[ContactId]</CustomerKey> <Name>ContactId</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_journey_Quicksend</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>633ca953-b614-4715-8310-91cdadd085c6</ObjectID> <CustomerKey>[testExisting_journey_Quicksend].[Email]</CustomerKey> <Name>Email</Name> <Scale>0</Scale> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>true</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_journey_Quicksend</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>eb18160e-ec0f-46ca-b59a-1287dbeb7172</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[DisplayName]</CustomerKey> <Name>DisplayName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>15</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ae0a3a3e-e81a-4b13-9a70-12ff6903c901</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[PreferredLanguage]</CustomerKey> <Name>PreferredLanguage</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>6</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>3d39db8b-b561-4227-9051-1c201c79033e</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[FirstReminderDate]</CustomerKey> <Name>FirstReminderDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>12</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>4eadce50-f552-41e5-8318-2fd367f043b9</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Description]</CustomerKey> <Name>Description</Name> <DefaultValue /> <MaxLength>4000</MaxLength> <IsRequired>false</IsRequired> <Ordinal>17</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d2826773-6965-4e78-9a05-3008ea45a104</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[EndDate]</CustomerKey> <Name>EndDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>10</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>3bb8fa91-5881-4ca1-ac09-30604ba0b9be</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[TaskArea]</CustomerKey> <Name>TaskArea</Name> <DefaultValue /> <MaxLength>255</MaxLength> <IsRequired>false</IsRequired> <Ordinal>25</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>721b938f-67ab-4d82-bb1c-33add4ec1533</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[ContactId]</CustomerKey> <Name>ContactId</Name> <DefaultValue /> <MaxLength>18</MaxLength> <IsRequired>true</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>5ccee5f6-f282-4741-899d-400b05c57425</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[FirstName]</CustomerKey> <Name>FirstName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d0ec626c-7cba-492b-abd0-48484e0c18bb</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Type]</CustomerKey> <Name>Type</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>0d49e8cf-cce9-4323-9b17-52f2366f9fc2</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Datestamp]</CustomerKey> <Name>Datestamp</Name> <DefaultValue>GetDate()</DefaultValue> <IsRequired>false</IsRequired> <Ordinal>8</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c44861f7-bac3-4b32-a5f8-744f67a66aaa</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Email]</CustomerKey> <Name>Email</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>false</IsRequired> <Ordinal>21</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c78d6054-5ce0-4438-a7ad-76b375224033</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Status]</CustomerKey> <Name>Status</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>541b063f-7c25-45b2-af53-7fdafbe0ee12</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[BroadcastedNotificationDate]</CustomerKey> <Name>BroadcastedNotificationDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>11</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ff54519e-931b-432f-9083-861213fa9460</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[TouchPoint]</CustomerKey> <Name>TouchPoint</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>7</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>f0a58625-0b62-496f-bea9-9d2722e50864</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Points]</CustomerKey> <Name>Points</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>23</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Number</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>43f69e09-9f47-477f-95b6-a9b9b8111f5e</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Title]</CustomerKey> <Name>Title</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>14</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>e9cd8c9f-39b0-4c93-8fce-aa3f0ca0d310</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[SecondReminderDate]</CustomerKey> <Name>SecondReminderDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>13</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>403e68ee-f203-42e1-ac48-af18def0cccd</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[TaskType]</CustomerKey> <Name>TaskType</Name> <DefaultValue /> <MaxLength>255</MaxLength> <IsRequired>false</IsRequired> <Ordinal>24</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>555ad728-f99a-4e13-a992-b70b1ffe36a2</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Respondent]</CustomerKey> <Name>Respondent</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>95948e52-e8d0-4908-98a9-cc34cd84233e</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[LastName]</CustomerKey> <Name>LastName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>7976b904-1ed5-46f0-a524-cd1a787bfb5e</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[FirstReminderChannel]</CustomerKey> <Name>FirstReminderChannel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>19</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ed225fdd-1aff-401d-906e-cd59b4d86fe2</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[SecondReminderChannel]</CustomerKey> <Name>SecondReminderChannel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>20</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>30222d00-35c5-46e8-ab41-d3febd909eed</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[ArticleOrTaskID]</CustomerKey> <Name>ArticleOrTaskID</Name> <DefaultValue /> <MaxLength>18</MaxLength> <IsRequired>true</IsRequired> <Ordinal>22</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8c79306f-4f3a-4925-bd48-e6c6905c157c</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[StartDate]</CustomerKey> <Name>StartDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>9</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>1892b0ee-26ea-4280-8bca-e8cc5d3f9658</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Channel]</CustomerKey> <Name>Channel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>18</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bf50095e-54ba-42c7-9baf-f91618738d85</ObjectID> <CustomerKey>[testExisting_event - 2024-07-05T080154625].[Text]</CustomerKey> <Name>Text</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>16</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_event - 2024-07-05T080154625</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>eb18160e-ec0f-46ca-b59a-1287dbeb7172</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[DisplayName]</CustomerKey> <Name>DisplayName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>15</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ae0a3a3e-e81a-4b13-9a70-12ff6903c901</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[PreferredLanguage]</CustomerKey> <Name>PreferredLanguage</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>false</IsRequired> <Ordinal>6</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>3d39db8b-b561-4227-9051-1c201c79033e</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[FirstReminderDate]</CustomerKey> <Name>FirstReminderDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>12</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>4eadce50-f552-41e5-8318-2fd367f043b9</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Description]</CustomerKey> <Name>Description</Name> <DefaultValue /> <MaxLength>4000</MaxLength> <IsRequired>false</IsRequired> <Ordinal>17</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d2826773-6965-4e78-9a05-3008ea45a104</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[EndDate]</CustomerKey> <Name>EndDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>10</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>3bb8fa91-5881-4ca1-ac09-30604ba0b9be</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[TaskArea]</CustomerKey> <Name>TaskArea</Name> <DefaultValue /> <MaxLength>255</MaxLength> <IsRequired>false</IsRequired> <Ordinal>25</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>721b938f-67ab-4d82-bb1c-33add4ec1533</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[ContactId]</CustomerKey> <Name>ContactId</Name> <DefaultValue /> <MaxLength>18</MaxLength> <IsRequired>true</IsRequired> <Ordinal>0</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>5ccee5f6-f282-4741-899d-400b05c57425</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[FirstName]</CustomerKey> <Name>FirstName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>4</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>d0ec626c-7cba-492b-abd0-48484e0c18bb</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Type]</CustomerKey> <Name>Type</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>1</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>0d49e8cf-cce9-4323-9b17-52f2366f9fc2</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Datestamp]</CustomerKey> <Name>Datestamp</Name> <DefaultValue>GetDate()</DefaultValue> <IsRequired>false</IsRequired> <Ordinal>8</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c44861f7-bac3-4b32-a5f8-744f67a66aaa</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Email]</CustomerKey> <Name>Email</Name> <DefaultValue /> <MaxLength>254</MaxLength> <IsRequired>false</IsRequired> <Ordinal>21</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>EmailAddress</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>c78d6054-5ce0-4438-a7ad-76b375224033</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Status]</CustomerKey> <Name>Status</Name> <DefaultValue /> <MaxLength>50</MaxLength> <IsRequired>true</IsRequired> <Ordinal>2</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>541b063f-7c25-45b2-af53-7fdafbe0ee12</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[BroadcastedNotificationDate]</CustomerKey> <Name>BroadcastedNotificationDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>11</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ff54519e-931b-432f-9083-861213fa9460</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[TouchPoint]</CustomerKey> <Name>TouchPoint</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>7</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>f0a58625-0b62-496f-bea9-9d2722e50864</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Points]</CustomerKey> <Name>Points</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>23</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Number</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>43f69e09-9f47-477f-95b6-a9b9b8111f5e</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Title]</CustomerKey> <Name>Title</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>14</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>e9cd8c9f-39b0-4c93-8fce-aa3f0ca0d310</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[SecondReminderDate]</CustomerKey> <Name>SecondReminderDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>13</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>403e68ee-f203-42e1-ac48-af18def0cccd</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[TaskType]</CustomerKey> <Name>TaskType</Name> <DefaultValue /> <MaxLength>255</MaxLength> <IsRequired>false</IsRequired> <Ordinal>24</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>555ad728-f99a-4e13-a992-b70b1ffe36a2</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Respondent]</CustomerKey> <Name>Respondent</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>3</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>95948e52-e8d0-4908-98a9-cc34cd84233e</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[LastName]</CustomerKey> <Name>LastName</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>5</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>7976b904-1ed5-46f0-a524-cd1a787bfb5e</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[FirstReminderChannel]</CustomerKey> <Name>FirstReminderChannel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>19</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>ed225fdd-1aff-401d-906e-cd59b4d86fe2</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[SecondReminderChannel]</CustomerKey> <Name>SecondReminderChannel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>20</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>30222d00-35c5-46e8-ab41-d3febd909eed</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[ArticleOrTaskID]</CustomerKey> <Name>ArticleOrTaskID</Name> <DefaultValue /> <MaxLength>18</MaxLength> <IsRequired>true</IsRequired> <Ordinal>22</Ordinal> <IsPrimaryKey>true</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>8c79306f-4f3a-4925-bd48-e6c6905c157c</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[StartDate]</CustomerKey> <Name>StartDate</Name> <DefaultValue /> <IsRequired>false</IsRequired> <Ordinal>9</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Date</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>1892b0ee-26ea-4280-8bca-e8cc5d3f9658</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Channel]</CustomerKey> <Name>Channel</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>18</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> <Results xsi:type="DataExtensionField"> <PartnerKey xsi:nil="true" /> <ObjectID>bf50095e-54ba-42c7-9baf-f91618738d85</ObjectID> <CustomerKey>[testNew_event_withSchema - 2024-07-08T014814443].[Text]</CustomerKey> <Name>Text</Name> <DefaultValue /> <MaxLength>256</MaxLength> <IsRequired>false</IsRequired> <Ordinal>16</Ordinal> <IsPrimaryKey>false</IsPrimaryKey> <FieldType>Text</FieldType> <DataExtension> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_event_withSchema - 2024-07-08T014814443</CustomerKey> </DataExtension> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtensionTemplate/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:110bbc72-d639-4e67-ab93-68e081bcf3a0</wsa:MessageID> <wsa:RelatesTo>urn:uuid:753eed05-f925-4113-8a98-e81ca69c96fd</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-a81724ab-b6f6-4825-82e8-ec523642075e"> <wsu:Created>2022-04-21T19:21:49Z</wsu:Created> <wsu:Expires>2022-04-21T19:26:49Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>82fd5f74-ad8c-49ad-958f-867d4a4b53b0</RequestID> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>cfd6fc95-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>086D14D3-5057-462B-AF33-01CA8D1FE87A</CustomerKey> <Name>DomainExclusion</Name> <Description>Domain Exclusion Data Extension Template</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>1fd7fc95-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>B6E8AE4C-3D93-49B1-B299-E0AE734213DD</CustomerKey> <Name>TriggeredSendDataExtension</Name> <Description>Triggered Send Source Data Extension Template</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>Email Address</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_EmailAddress</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>bb1df59b-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>23471ECA-8710-4512-9296-040CA86FBD9E</CustomerKey> <Name>CONTEXTUAL_SUPPRESSION_LISTS</Name> <Description>Used to create new auto-suppression lists</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>EmailAddress</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>e61df59b-d594-ea11-a2e6-1402ec938a35</ObjectID> <CustomerKey>00A4369E-0B57-4EF2-BFFA-E3F23B4D1098</CustomerKey> <Name>SocialPages Default Template Extension</Name> <Description>Required for contacts. Used by Smart Capture for Social Pages.</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value>6</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value>5</Value> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>37d8c7f2-ad19-4084-8d18-4dda1dc36772</ObjectID> <CustomerKey>DAE95D91-762C-4124-B082-0433165ADD30</CustomerKey> <Name>AudienceBuilderResult</Name> <Description>Used for creating audience builder result destinations.</Description> </Results> <Results xsi:type="DataExtensionTemplate"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>IsSendable</Name> <Value>True</Value> </PartnerProperties> <PartnerProperties> <Name>IsTestable</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>SendableCustomObjectField</Name> <Value>ContactKey</Value> </PartnerProperties> <PartnerProperties> <Name>SendableSubscriberField</Name> <Value>_SubscriberKey</Value> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodLength</Name> <Value /> </PartnerProperties> <PartnerProperties> <Name>DataRetentionPeriodUnitOfMeasure</Name> <Value>0</Value> </PartnerProperties> <PartnerProperties> <Name>RowBasedRetention</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>ResetRetentionPeriodOnImport</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>DeleteAtEndOfRetentionPeriod</Name> <Value>False</Value> </PartnerProperties> <PartnerProperties> <Name>RetainUntil</Name> <Value /> </PartnerProperties> <ObjectID>941cf36b-f927-4674-8468-c9a3bed7cae4</ObjectID> <CustomerKey>BE1B7591-BFA6-473F-A6CE-0E458204865B</CustomerKey> <Name>Event DE Template</Name> <Description>Event Data Extension Template</Description> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataExtract/build-expected.json ================================================ { "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ], "description": "blabla", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "key": "testTemplated_dataExtract", "name": "testTemplated_dataExtract", "r__dataExtension_key": "testTemplated_dataExtension", "r__dataExtractType_name": "Data Extension Extract" } ================================================ FILE: test/resources/9999999/dataExtract/get-expected.json ================================================ { "createdBy": "Jörn Berkefeld", "createdDate": "2022-11-09T05:31:21.667", "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ], "description": "blabla", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "key": "testExisting_dataExtract", "modifiedBy": "Jörn Berkefeld", "modifiedDate": "2022-11-17T07:13:36.9", "name": "testExisting_dataExtract", "r__dataExtension_key": "testExisting_dataExtension", "r__dataExtractType_name": "Data Extension Extract" } ================================================ FILE: test/resources/9999999/dataExtract/patch-expected.json ================================================ { "createdBy": "Jörn Berkefeld", "createdDate": "2022-11-09T05:31:21.667", "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ], "description": "blabla", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "key": "testExisting_dataExtract", "modifiedBy": "Jörn Berkefeld", "modifiedDate": "2022-11-17T07:13:36.9", "name": "testExisting_dataExtract", "r__dataExtension_key": "testExisting_dataExtension", "r__dataExtractType_name": "Data Extension Extract" } ================================================ FILE: test/resources/9999999/dataExtract/post-expected.json ================================================ { "createdBy": "Jörn Berkefeld", "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ], "description": "blabla", "fileSpec": "testNew-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "key": "testNew_dataExtract", "modifiedBy": "Jörn Berkefeld", "name": "testNew_dataExtract", "r__dataExtension_key": "testExisting_dataExtension", "r__dataExtractType_name": "Data Extension Extract" } ================================================ FILE: test/resources/9999999/dataExtract/template-expected.json ================================================ { "dataFields": [ { "name": "ColumnDelimiter", "type": "string", "value": "," }, { "name": "DECustomerKey", "type": "string" }, { "name": "HasColumnHeaders", "type": "bool", "value": "False" }, { "name": "TextQualified", "type": "bool", "value": "False" }, { "name": "UsesLineFeed", "type": "bool", "value": "False" } ], "description": "blabla", "fileSpec": "testExisting-%%Year%%-%%Month%%-%%Day%%", "intervalType": 0, "key": "{{{prefix}}}dataExtract", "name": "{{{prefix}}}dataExtract", "r__dataExtension_key": "{{{prefix}}}dataExtension", "r__dataExtractType_name": "Data Extension Extract" } ================================================ FILE: test/resources/9999999/dataFilter/build-expected.json ================================================ { "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Ends", "Value": "_testTarget", "r__dataExtensionField_name": "LastName" } } }, "description": "test", "isSendable": true, "key": "testTemplated_dataFilter", "name": "testTemplated_dataFilter", "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "testTemplated_dataExtension" } ================================================ FILE: test/resources/9999999/dataFilter/get-expected.json ================================================ { "createdByName": "Jörn Berkefeld", "createdDate": "2025-12-01T16:54:09.813", "lastUpdated": "2025-12-01T17:17:31.827", "lastUpdatedByName": "Jörn Berkefeld", "description": "test", "key": "testExisting_dataFilter", "name": "testExisting_dataFilter", "isSendable": true, "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Ends", "Value": "_test", "r__dataExtensionField_name": "LastName" } } }, "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "testExisting_dataExtension" } ================================================ FILE: test/resources/9999999/dataFilter/patch-expected.json ================================================ { "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Begins", "Value": "testExisting_", "r__dataExtensionField_name": "LastName" } } }, "createdDate": "2026-01-27T06:24:40.527", "isSendable": true, "key": "testExisting_dataFilter", "lastUpdated": "2026-01-30T10:46:59.777", "name": "testExisting_dataFilter", "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "testExisting_dataExtension" } ================================================ FILE: test/resources/9999999/dataFilter/post-expected.json ================================================ { "createdDate": "2026-01-30T11:04:06.883", "lastUpdated": "2026-01-30T11:04:06.883", "isSendable": false, "key": "testNew_dataFilter", "name": "testNew_dataFilter", "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Ends", "Value": "_test", "r__dataExtensionField_name": "LastName" } } }, "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "testExisting_dataExtension" } ================================================ FILE: test/resources/9999999/dataFilter/template-expected.json ================================================ { "c__filterDefinition": { "ConditionSet": { "@_ConditionSetName": "Outer Grouping", "@_Operator": "AND", "Condition": { "@_Operator": "Ends", "Value": "{{{suffix}}}", "r__dataExtensionField_name": "LastName" } } }, "description": "test", "isSendable": true, "key": "{{{prefix}}}dataFilter", "name": "{{{prefix}}}dataFilter", "r__folder_Path": "Data Filters", "r__source_dataExtension_key": "{{{prefix}}}dataExtension" } ================================================ FILE: test/resources/9999999/dataFolder/+retrieve-ContentTypeINasset,asset-shared,cloudpages-slashfolder-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:00106553-ac00-4e72-b387-42325fe6f93d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a1dd2a9d-b696-480e-9a1b-265f262a8997</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-d82724f8-afc2-4461-8e3e-190aeb6d9625"> <wsu:Created>2024-01-08T14:30:39Z</wsu:Created> <wsu:Expires>2024-01-08T14:35:39Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>6596087d-d12f-4c9d-9353-783fe01775a3</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2026-03-06T07:47:11.04</CreatedDate> <ModifiedDate>2026-03-06T07:47:11.04</ModifiedDate> <ID>38491</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>bla/blub</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/create-ContentType=asset,Name=testFolder_samePath,ParentFolderID=89397-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:50c68314-30a5-45d4-93aa-6dd1191190e3</wsa:MessageID> <wsa:RelatesTo>urn:uuid:00b40ac8-d7e8-4e55-8b88-fcf3569684a9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-26435e8f-90d6-4552-aabb-d5eefa3a4bed"> <wsu:Created>2024-08-08T09:56:20Z</wsu:Created> <wsu:Expires>2024-08-08T10:01:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder created successfully.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>88888</NewID> <NewObjectID>a890243b-a4e1-4010-85e4-db6d6ae84502</NewObjectID> </Results> <RequestID>6b408e0b-ecbe-4b8e-9019-6376f6eeb0e2</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/create-ContentType=dataextension,Name=my,ParentFolderID=2-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:50c68314-30a5-45d4-93aa-6dd1191190e2</wsa:MessageID> <wsa:RelatesTo>urn:uuid:00b40ac8-d7e8-4e55-8b88-fcf3569684a8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-26435e8f-90d6-4552-aabb-d5eefa3a4bec"> <wsu:Created>2024-08-08T09:56:20Z</wsu:Created> <wsu:Expires>2024-08-08T10:01:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder created successfully.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>862001</NewID> <NewObjectID>d890243b-a4e1-4010-85e4-db6d6ae84501</NewObjectID> </Results> <RequestID>5b408e0b-ecbe-4b8e-9019-6376f6eeb0e1</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/create-ContentType=dataextension,Name=path,ParentFolderID=862002-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:50c68314-30a5-45d4-93aa-6dd1191190e2</wsa:MessageID> <wsa:RelatesTo>urn:uuid:00b40ac8-d7e8-4e55-8b88-fcf3569684a8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-26435e8f-90d6-4552-aabb-d5eefa3a4bec"> <wsu:Created>2024-08-08T09:56:20Z</wsu:Created> <wsu:Expires>2024-08-08T10:01:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder created successfully.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>862003</NewID> <NewObjectID>d890243b-a4e1-4010-85e4-db6d6ae84503</NewObjectID> </Results> <RequestID>5b408e0b-ecbe-4b8e-9019-6376f6eeb0e1</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/create-ContentType=dataextension,Name=sub,ParentFolderID=862001-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:50c68314-30a5-45d4-93aa-6dd1191190e2</wsa:MessageID> <wsa:RelatesTo>urn:uuid:00b40ac8-d7e8-4e55-8b88-fcf3569684a8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-26435e8f-90d6-4552-aabb-d5eefa3a4bec"> <wsu:Created>2024-08-08T09:56:20Z</wsu:Created> <wsu:Expires>2024-08-08T10:01:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder created successfully.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>862002</NewID> <NewObjectID>d890243b-a4e1-4010-85e4-db6d6ae84502</NewObjectID> </Results> <RequestID>5b408e0b-ecbe-4b8e-9019-6376f6eeb0e1</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/create-ContentType=dataextension,Name=subpath,ParentFolderID=862003-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:50c68314-30a5-45d4-93aa-6dd1191190e2</wsa:MessageID> <wsa:RelatesTo>urn:uuid:00b40ac8-d7e8-4e55-8b88-fcf3569684a8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-26435e8f-90d6-4552-aabb-d5eefa3a4bec"> <wsu:Created>2024-08-08T09:56:20Z</wsu:Created> <wsu:Expires>2024-08-08T10:01:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder created successfully.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>862004</NewID> <NewObjectID>d890243b-a4e1-4010-85e4-db6d6ae84504</NewObjectID> </Results> <RequestID>5b408e0b-ecbe-4b8e-9019-6376f6eeb0e1</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:50c68314-30a5-45d4-93aa-6dd1191190e3</wsa:MessageID> <wsa:RelatesTo>urn:uuid:00b40ac8-d7e8-4e55-8b88-fcf3569684a9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-26435e8f-90d6-4552-aabb-d5eefa3a4bed"> <wsu:Created>2024-08-08T09:56:20Z</wsu:Created> <wsu:Expires>2024-08-08T10:01:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder created successfully.</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>862099</NewID> <NewObjectID>d890243b-a4e1-4010-85e4-db6d6ae84502</NewObjectID> </Results> <RequestID>5b408e0b-ecbe-4b8e-9019-6376f6eeb0e2</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=asset-shared-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:ece12788-5617-4bf7-97b6-d2ee6fefa7c5</wsa:MessageID> <wsa:RelatesTo>urn:uuid:260afb64-4686-421e-bc94-46386dd6e28d</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c6787260-1486-411c-b1e4-1a561aa1efd8"> <wsu:Created>2024-07-22T09:14:36Z</wsu:Created> <wsu:Expires>2024-07-22T09:19:36Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>0df23b67-2645-4b4f-87e1-f3eb6b818dde</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:12.743</CreatedDate> <ModifiedDate>2021-06-21T11:55:12.743</ModifiedDate> <ID>4707</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:13.34</CreatedDate> <ModifiedDate>2021-06-21T11:55:13.34</ModifiedDate> <ID>4710</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Content</Name> <Description>The root shared folder for assets</Description> <ContentType>asset-shared</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=asset-shared-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:ece12788-5617-4bf7-97b6-d2ee6fefa7c5</wsa:MessageID> <wsa:RelatesTo>urn:uuid:260afb64-4686-421e-bc94-46386dd6e28d</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c6787260-1486-411c-b1e4-1a561aa1efd8"> <wsu:Created>2024-07-22T09:14:36Z</wsu:Created> <wsu:Expires>2024-07-22T09:19:36Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>0df23b67-2645-4b4f-87e1-f3eb6b818dde</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:12.743</CreatedDate> <ModifiedDate>2021-06-21T11:55:12.743</ModifiedDate> <ID>4707</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:13.34</CreatedDate> <ModifiedDate>2021-06-21T11:55:13.34</ModifiedDate> <ID>4710</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Content</Name> <Description>The root shared folder for assets</Description> <ContentType>asset-shared</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=automations-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=journey-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:dc2be79b-a2b9-4775-90f9-92f7298129e4</wsa:MessageID> <wsa:RelatesTo>urn:uuid:e6015b6f-c9d3-4649-aed8-ea66f1a1dbe8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-89a3ca99-8f71-4361-959c-6fd89384ed9e"> <wsu:Created>2024-07-22T11:05:21Z</wsu:Created> <wsu:Expires>2024-07-22T11:10:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>37bbe40c-a525-4f43-b907-0cc83fe7a020</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=queryactivity-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-01-24T06:32:42.353</CreatedDate> <ModifiedDate>2017-01-24T06:32:42.353</ModifiedDate> <ID>304</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SSJSActivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Scripts</Name> <Description /> <ContentType>SSJSActivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentType=userinitiatedsends-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:1512750f-32c9-4e70-adfe-6863acb037b4</wsa:MessageID> <wsa:RelatesTo>urn:uuid:58a10fa7-12d7-4221-9d70-028add22d7be</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-fb923341-9f26-4ee2-8893-28bbf44ef6bb"> <wsu:Created>2024-04-16T16:38:36Z</wsu:Created> <wsu:Expires>2024-04-16T16:43:36Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>f0fec0a3-586b-4da9-95d3-ed47245d395c</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:54:58.023</CreatedDate> <ModifiedDate>2021-06-21T11:54:58.023</ModifiedDate> <ID>4691</ID> <ObjectID xsi:nil="true" /> <CustomerKey>userinitiatedsends_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>User-Initiated</Name> <Description /> <ContentType>userinitiatedsends</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-sha,automatio,cloudpage,dataexten,filteract,filterdef,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,useriniti-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:31.84</CreatedDate> <ModifiedDate>2022-06-21T09:34:31.84</ModifiedDate> <ID>5319</ID> <ObjectID xsi:nil="true" /> <CustomerKey>filteractivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Filter</Name> <Description /> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:39.98</CreatedDate> <ModifiedDate>2022-06-21T09:34:39.98</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8504</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenFilterActivities_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>SystemHiddenFilterActivities</Name> <Description>filteractivity folder to store filteractivity items</Description> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8505</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenFilterActivitiesForGE_de</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>8504</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenFilterActivities_default</CustomerKey> </ParentFolder> <Name>SystemHiddenFilterActivitiesForGE</Name> <Description>filteractivity folder to store filteractivity items</Description> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2026-01-27T06:57:18.513</CreatedDate> <ModifiedDate>2026-01-27T06:57:18.513</ModifiedDate> <ID>37139</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>5319</ID> <ObjectID xsi:nil="true" /> <CustomerKey>filteractivity_default</CustomerKey> </ParentFolder> <Name>filterSubfolder</Name> <Description>doesnt have a CustomerKey for some reason</Description> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:31.823</CreatedDate> <ModifiedDate>2022-06-21T09:34:31.823</ModifiedDate> <ID>5318</ID> <ObjectID xsi:nil="true" /> <CustomerKey>filterdefinition_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Filters</Name> <Description /> <ContentType>filterdefinition</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:39.98</CreatedDate> <ModifiedDate>2022-06-21T09:34:39.98</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8502</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenDataFilters_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>SystemHiddenDataFilters</Name> <Description>filterdefinition folder to store filterdefinition items</Description> <ContentType>filterdefinition</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8503</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenDataFiltersForGE_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>8502</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenDataFilters_default</CustomerKey> </ParentFolder> <Name>SystemHiddenDataFiltersForGE</Name> <Description>filterdefinition folder to store filterdefinition items</Description> <ContentType>filterdefinition</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-sha,automatio,cloudpage,dataexten,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,triggered,triggered,useriniti-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-sha,automatio,cloudpage,dataexten,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,useriniti-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-sha,dataexten,salesforc,shared_da,shared_da,shared_sa,synchroni,automatio,useriniti,journey,mysubs,list,publicati,queryacti,ssjsactiv,triggered,triggered-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,cloudpages,dataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,cloudpages,journey-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:dc2be79b-a2b9-4775-90f9-92f7298129e4</wsa:MessageID> <wsa:RelatesTo>urn:uuid:e6015b6f-c9d3-4649-aed8-ea66f1a1dbe8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-89a3ca99-8f71-4361-959c-6fd89384ed9e"> <wsu:Created>2024-07-22T11:05:21Z</wsu:Created> <wsu:Expires>2024-07-22T11:10:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>37bbe40c-a525-4f43-b907-0cc83fe7a020</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:12.743</CreatedDate> <ModifiedDate>2021-06-21T11:55:12.743</ModifiedDate> <ID>4707</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:13.34</CreatedDate> <ModifiedDate>2021-06-21T11:55:13.34</ModifiedDate> <ID>4710</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Content</Name> <Description>The root shared folder for assets</Description> <ContentType>asset-shared</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,cloudpages,ssjsactivity-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:00106553-ac00-4e72-b387-42325fe6f93d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a1dd2a9d-b696-480e-9a1b-265f262a8997</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-d82724f8-afc2-4461-8e3e-190aeb6d9625"> <wsu:Created>2024-01-08T14:30:39Z</wsu:Created> <wsu:Expires>2024-01-08T14:35:39Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>6596087d-d12f-4c9d-9353-783fe01775a3</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-01-24T06:32:42.353</CreatedDate> <ModifiedDate>2017-01-24T06:32:42.353</ModifiedDate> <ID>304</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SSJSActivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Scripts</Name> <Description /> <ContentType>SSJSActivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,cloudpages-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:00106553-ac00-4e72-b387-42325fe6f93d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a1dd2a9d-b696-480e-9a1b-265f262a8997</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-d82724f8-afc2-4461-8e3e-190aeb6d9625"> <wsu:Created>2024-01-08T14:30:39Z</wsu:Created> <wsu:Expires>2024-01-08T14:35:39Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>6596087d-d12f-4c9d-9353-783fe01775a3</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-02-16T10:12:15.9</CreatedDate> <ModifiedDate>2024-02-16T10:12:15.9</ModifiedDate> <ID>14914</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>CloudPages</Name> <Description>The root folder for CloudPages</Description> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>510007949</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2025-03-25T03:00:33.163</CreatedDate> <ModifiedDate>2025-03-26T03:33:00.893</ModifiedDate> <ID>27675</ID> <ObjectID xsi:nil="true" /> <CustomerKey>958bac7c-972b-4cac-aa8a-22a2b77b0fbc</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>14914</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>mcdev</Name> <Description /> <ContentType>cloudpages</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:ece12788-5617-4bf7-97b6-d2ee6fefa7c5</wsa:MessageID> <wsa:RelatesTo>urn:uuid:260afb64-4686-421e-bc94-46386dd6e28d</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c6787260-1486-411c-b1e4-1a561aa1efd8"> <wsu:Created>2024-07-22T09:14:36Z</wsu:Created> <wsu:Expires>2024-07-22T09:19:36Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>0df23b67-2645-4b4f-87e1-f3eb6b818dde</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:12.743</CreatedDate> <ModifiedDate>2021-06-21T11:55:12.743</ModifiedDate> <ID>4707</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:13.34</CreatedDate> <ModifiedDate>2021-06-21T11:55:13.34</ModifiedDate> <ID>4710</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Content</Name> <Description>The root shared folder for assets</Description> <ContentType>asset-shared</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:ece12788-5617-4bf7-97b6-d2ee6fefa7c5</wsa:MessageID> <wsa:RelatesTo>urn:uuid:260afb64-4686-421e-bc94-46386dd6e28d</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c6787260-1486-411c-b1e4-1a561aa1efd8"> <wsu:Created>2024-07-22T09:14:36Z</wsu:Created> <wsu:Expires>2024-07-22T09:19:36Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>0df23b67-2645-4b4f-87e1-f3eb6b818dde</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:12.743</CreatedDate> <ModifiedDate>2021-06-21T11:55:12.743</ModifiedDate> <ID>4707</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:13.34</CreatedDate> <ModifiedDate>2021-06-21T11:55:13.34</ModifiedDate> <ID>4710</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Content</Name> <Description>The root shared folder for assets</Description> <ContentType>asset-shared</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:00106553-ac00-4e72-b387-42325fe6f93d</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a1dd2a9d-b696-480e-9a1b-265f262a8997</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-d82724f8-afc2-4461-8e3e-190aeb6d9625"> <wsu:Created>2024-01-08T14:30:39Z</wsu:Created> <wsu:Expires>2024-01-08T14:35:39Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>6596087d-d12f-4c9d-9353-783fe01775a3</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINasset-shared,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:4d209b2f-d7ce-4e6e-916c-c8642d368866</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a850f043-1422-4d16-8443-702dd2f9f13a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-5da63531-caa7-4ead-9f10-a33d9bf66745"> <wsu:Created>2023-08-11T13:15:46Z</wsu:Created> <wsu:Expires>2023-08-11T13:20:46Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ba1b0c59-78c4-4608-8423-35dda2248d4d</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.54</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.54</ModifiedDate> <ID>93698</ID> <ObjectID xsi:nil="true" /> <CustomerKey>salesforcedataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Salesforce Data Extensions</Name> <Description /> <ContentType>salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.55</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.55</ModifiedDate> <ID>93699</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_salesforcedataextension_defau</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Salesforce Data Extensions</Name> <Description /> <ContentType>shared_salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-01-27T10:50:46.573</CreatedDate> <ModifiedDate>2020-01-27T10:50:46.573</ModifiedDate> <ID>309082</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>QueryStudioResults</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-04-17T08:14:19.763</CreatedDate> <ModifiedDate>2020-04-17T08:14:19.763</ModifiedDate> <ID>587750</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>catalyst target 1</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-07-09T02:30:12.38</CreatedDate> <ModifiedDate>2021-12-16T03:43:30.753</ModifiedDate> <ID>605618</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Audiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-12-25T06:11:40.107</CreatedDate> <ModifiedDate>2021-12-23T10:51:24.393</ModifiedDate> <ID>633441</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>System DEs</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:54:36.11</CreatedDate> <ModifiedDate>2021-01-30T11:54:36.11</ModifiedDate> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>Customer 360 Segments</Name> <Description>All Customer 360 segments will be grouped here. Each sub-folder relates to an activation profile name.</Description> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:56:38.77</CreatedDate> <ModifiedDate>2021-01-30T11:56:38.77</ModifiedDate> <ID>638815</ID> <ObjectID xsi:nil="true" /> <CustomerKey>cedd206d-178e-41cb-8965-ce255975b046</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> </ParentFolder> <Name>FirstAudience360 Segment</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-02-07T10:44:01.413</CreatedDate> <ModifiedDate>2021-12-16T03:43:33.38</ModifiedDate> <ID>639967</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>TestAudiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-04T15:17:18.533</CreatedDate> <ModifiedDate>2021-08-04T15:17:18.567</ModifiedDate> <ID>675203</ID> <ObjectID xsi:nil="true" /> <CustomerKey>A19F7E38-7369-497E-826F-D551F17FB0B4</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-10-03T05:01:37.23</CreatedDate> <ModifiedDate>2021-10-03T05:01:37.37</ModifiedDate> <ID>688352</ID> <ObjectID xsi:nil="true" /> <CustomerKey>B80AE306-55BC-4C2E-A79F-8CCA486F0BA0</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-10-26T09:48:38.293</CreatedDate> <ModifiedDate>2022-10-26T09:48:38.31</ModifiedDate> <ID>757145</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0ACB800B-AA8B-4F0F-9642-4907592C919C</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:12.743</CreatedDate> <ModifiedDate>2021-06-21T11:55:12.743</ModifiedDate> <ID>4707</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-21T11:55:13.34</CreatedDate> <ModifiedDate>2021-06-21T11:55:13.34</ModifiedDate> <ID>4710</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Content</Name> <Description>The root shared folder for assets</Description> <ContentType>asset-shared</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINautomations,queryactivity-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINcontextual_suppression_list,hidden,list,mysubs,publication,suppression_list,triggered_send,triggered_send_journeybuilder-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINcontextual_suppression_list,list,mysubs,publication,suppression_list-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:016c1c21-3227-4e9c-9497-33b0c15d971b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:f559d162-26ae-4a2c-8bfe-0abaa0be36aa</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-9215e989-d752-4c92-914c-5d254c377f41"> <wsu:Created>2023-08-08T12:49:25Z</wsu:Created> <wsu:Expires>2023-08-08T12:54:25Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>01c5259b-174e-4c70-9fa7-f5cd984b28c6</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:17.55</CreatedDate> <ModifiedDate>2016-07-22T11:52:17.55</ModifiedDate> <ID>89332</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:24.417</CreatedDate> <ModifiedDate>2016-07-22T11:52:24.417</ModifiedDate> <ID>89373</ID> <ObjectID xsi:nil="true" /> <CustomerKey>contextual_suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Auto-Suppression Configuration</Name> <Description /> <ContentType>contextual_suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINdataextension,hidden,queryactivity,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINdataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINdataextension,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINfilteractivity,hidden-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:75cc7360-d424-486e-b122-b5b491b697bc</wsa:MessageID> <wsa:RelatesTo>urn:uuid:5f907880-a5dd-431e-8fe3-65cd04806e06</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-4c68bf94-5cbc-4cb7-a7bb-12cde6ec88e6"> <wsu:Created>2026-02-02T08:57:49Z</wsu:Created> <wsu:Expires>2026-02-02T09:02:49Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>0af64064-a1f2-4247-87d1-cd838f224360</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:31.84</CreatedDate> <ModifiedDate>2022-06-21T09:34:31.84</ModifiedDate> <ID>5319</ID> <ObjectID xsi:nil="true" /> <CustomerKey>filteractivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Filter</Name> <Description /> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:39.98</CreatedDate> <ModifiedDate>2022-06-21T09:34:39.98</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8504</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenFilterActivities_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>SystemHiddenFilterActivities</Name> <Description>filteractivity folder to store filteractivity items</Description> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8505</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenFilterActivitiesForGE_de</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>8504</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenFilterActivities_default</CustomerKey> </ParentFolder> <Name>SystemHiddenFilterActivitiesForGE</Name> <Description>filteractivity folder to store filteractivity items</Description> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2026-01-27T06:57:18.513</CreatedDate> <ModifiedDate>2026-01-27T06:57:18.513</ModifiedDate> <ID>37139</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>5319</ID> <ObjectID xsi:nil="true" /> <CustomerKey>filteractivity_default</CustomerKey> </ParentFolder> <Name>filterSubfolder</Name> <Description>doesnt have a CustomerKey for some reason</Description> <ContentType>filteractivity</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINfilterdefinition,hidden-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:08aa605a-0837-4c4a-9725-028e93720e77</wsa:MessageID> <wsa:RelatesTo>urn:uuid:2da02491-3144-43ab-8ac4-349824d29db2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-48ea9660-d7b7-4709-acff-f868467729bb"> <wsu:Created>2026-01-30T11:58:58Z</wsu:Created> <wsu:Expires>2026-01-30T12:03:58Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>8da38b8d-30d2-4c4a-a81e-e564915e7312</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:31.823</CreatedDate> <ModifiedDate>2022-06-21T09:34:31.823</ModifiedDate> <ID>5318</ID> <ObjectID xsi:nil="true" /> <CustomerKey>filterdefinition_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Filters</Name> <Description /> <ContentType>filterdefinition</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-06-21T09:34:39.98</CreatedDate> <ModifiedDate>2022-06-21T09:34:39.98</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8502</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenDataFilters_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>SystemHiddenDataFilters</Name> <Description>filterdefinition folder to store filterdefinition items</Description> <ContentType>filterdefinition</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-02-03T07:22:55.39</CreatedDate> <ModifiedDate>2023-02-03T07:22:55.39</ModifiedDate> <ID>8503</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenDataFiltersForGE_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>8502</ID> <ObjectID xsi:nil="true" /> <CustomerKey>SystemHiddenDataFilters_default</CustomerKey> </ParentFolder> <Name>SystemHiddenDataFiltersForGE</Name> <Description>filterdefinition folder to store filterdefinition items</Description> <ContentType>filterdefinition</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINhidden,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINhidden,triggered_send,triggered_send_journeybuilder-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:d626d883-8ca4-4cd1-b4ea-cb399015e275</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b1d23385-97c0-4bc8-b0fe-b54e3310ae6b</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-a9582e47-b23f-4956-85b1-fe0b7fa73cf2"> <wsu:Created>2023-08-08T12:49:16Z</wsu:Created> <wsu:Expires>2023-08-08T12:54:16Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>6e8873dd-03e2-47b6-823a-fb8681d93d78</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-ContentTypeINshared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:4d209b2f-d7ce-4e6e-916c-c8642d368866</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a850f043-1422-4d16-8443-702dd2f9f13a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-5da63531-caa7-4ead-9f10-a33d9bf66745"> <wsu:Created>2023-08-11T13:15:46Z</wsu:Created> <wsu:Expires>2023-08-11T13:20:46Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ba1b0c59-78c4-4608-8423-35dda2248d4d</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.55</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.55</ModifiedDate> <ID>93699</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_salesforcedataextension_defau</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Salesforce Data Extensions</Name> <Description /> <ContentType>shared_salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-04-17T08:14:19.763</CreatedDate> <ModifiedDate>2020-04-17T08:14:19.763</ModifiedDate> <ID>587750</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>catalyst target 1</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:54:36.11</CreatedDate> <ModifiedDate>2021-01-30T11:54:36.11</ModifiedDate> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>Customer 360 Segments</Name> <Description>All Customer 360 segments will be grouped here. Each sub-folder relates to an activation profile name.</Description> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:56:38.77</CreatedDate> <ModifiedDate>2021-01-30T11:56:38.77</ModifiedDate> <ID>638815</ID> <ObjectID xsi:nil="true" /> <CustomerKey>cedd206d-178e-41cb-8965-ce255975b046</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> </ParentFolder> <Name>FirstAudience360 Segment</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-04T15:17:18.533</CreatedDate> <ModifiedDate>2021-08-04T15:17:18.567</ModifiedDate> <ID>675203</ID> <ObjectID xsi:nil="true" /> <CustomerKey>A19F7E38-7369-497E-826F-D551F17FB0B4</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-10-03T05:01:37.23</CreatedDate> <ModifiedDate>2021-10-03T05:01:37.37</ModifiedDate> <ID>688352</ID> <ObjectID xsi:nil="true" /> <CustomerKey>B80AE306-55BC-4C2E-A79F-8CCA486F0BA0</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-10-26T09:48:38.293</CreatedDate> <ModifiedDate>2022-10-26T09:48:38.31</ModifiedDate> <ID>757145</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0ACB800B-AA8B-4F0F-9642-4907592C919C</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-QAA-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:4d209b2f-d7ce-4e6e-916c-c8642d368866</wsa:MessageID> <wsa:RelatesTo>urn:uuid:a850f043-1422-4d16-8443-702dd2f9f13a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-5da63531-caa7-4ead-9f10-a33d9bf66745"> <wsu:Created>2023-08-11T13:15:46Z</wsu:Created> <wsu:Expires>2023-08-11T13:20:46Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>ba1b0c59-78c4-4608-8423-35dda2248d4d</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:18.73</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Shared Items</Name> <Description /> <ContentType>shared_data</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.603</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.603</ModifiedDate> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Data Extensions</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.54</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.54</ModifiedDate> <ID>93698</ID> <ObjectID xsi:nil="true" /> <CustomerKey>salesforcedataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Salesforce Data Extensions</Name> <Description /> <ContentType>salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-23T09:22:27.55</CreatedDate> <ModifiedDate>2016-08-23T09:22:27.55</ModifiedDate> <ID>93699</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_salesforcedataextension_defau</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89344</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_data_default</CustomerKey> </ParentFolder> <Name>Shared Salesforce Data Extensions</Name> <Description /> <ContentType>shared_salesforcedataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-01-27T10:50:46.573</CreatedDate> <ModifiedDate>2020-01-27T10:50:46.573</ModifiedDate> <ID>309082</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>QueryStudioResults</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-04-17T08:14:19.763</CreatedDate> <ModifiedDate>2020-04-17T08:14:19.763</ModifiedDate> <ID>587750</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>catalyst target 1</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-07-09T02:30:12.38</CreatedDate> <ModifiedDate>2021-12-16T03:43:30.753</ModifiedDate> <ID>605618</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Audiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-12-25T06:11:40.107</CreatedDate> <ModifiedDate>2021-12-23T10:51:24.393</ModifiedDate> <ID>633441</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>System DEs</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:54:36.11</CreatedDate> <ModifiedDate>2021-01-30T11:54:36.11</ModifiedDate> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89356</ID> <ObjectID xsi:nil="true" /> <CustomerKey>shared_dataextension_default</CustomerKey> </ParentFolder> <Name>Customer 360 Segments</Name> <Description>All Customer 360 segments will be grouped here. Each sub-folder relates to an activation profile name.</Description> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-01-30T11:56:38.77</CreatedDate> <ModifiedDate>2021-01-30T11:56:38.77</ModifiedDate> <ID>638815</ID> <ObjectID xsi:nil="true" /> <CustomerKey>cedd206d-178e-41cb-8965-ce255975b046</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>638814</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0b72bf27-0678-484d-ac0b-a8762b9bec33</CustomerKey> </ParentFolder> <Name>FirstAudience360 Segment</Name> <Description /> <ContentType>shared_dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>false</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-02-07T10:44:01.413</CreatedDate> <ModifiedDate>2021-12-16T03:43:33.38</ModifiedDate> <ID>639967</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89355</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>TestAudiences</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-04T15:17:18.533</CreatedDate> <ModifiedDate>2021-08-04T15:17:18.567</ModifiedDate> <ID>675203</ID> <ObjectID xsi:nil="true" /> <CustomerKey>A19F7E38-7369-497E-826F-D551F17FB0B4</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-10-03T05:01:37.23</CreatedDate> <ModifiedDate>2021-10-03T05:01:37.37</ModifiedDate> <ID>688352</ID> <ObjectID xsi:nil="true" /> <CustomerKey>B80AE306-55BC-4C2E-A79F-8CCA486F0BA0</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-10-26T09:48:38.293</CreatedDate> <ModifiedDate>2022-10-26T09:48:38.31</ModifiedDate> <ID>757145</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0ACB800B-AA8B-4F0F-9642-4907592C919C</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Synchronized Data Extensions</Name> <Description /> <ContentType>synchronizeddataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>66666</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>testExisting_FOLDER</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/retrieve-samePathOtherBU-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.6</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.6</ModifiedDate> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Data Extensions</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:20.407</CreatedDate> <ModifiedDate>2016-07-22T11:52:20.407</ModifiedDate> <ID>999</ID> <ObjectID xsi:nil="true" /> <CustomerKey>queryactivity_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Query</Name> <Description /> <ContentType>queryactivity</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.18</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.18</ModifiedDate> <ID>412</ID> <ObjectID xsi:nil="true" /> <CustomerKey>mysubs_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my subscribers</Name> <Description /> <ContentType>mysubs</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.177</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.177</ModifiedDate> <ID>404</ID> <ObjectID xsi:nil="true" /> <CustomerKey>list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my lists</Name> <Description /> <ContentType>list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:34.023</CreatedDate> <ModifiedDate>2017-02-16T01:59:34.023</ModifiedDate> <ID>424</ID> <ObjectID xsi:nil="true" /> <CustomerKey>publication_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Publication Lists</Name> <Description /> <ContentType>publication</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>419</ID> <ObjectID xsi:nil="true" /> <CustomerKey>suppression_list_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Suppression Lists</Name> <Description /> <ContentType>suppression_list</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:32.323</CreatedDate> <ModifiedDate>2017-02-16T01:59:32.323</ModifiedDate> <ID>6298</ID> <ObjectID xsi:nil="true" /> <CustomerKey>journey_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my journeys</Name> <Description>The root folder for Journeys</Description> <ContentType>journey</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2019-10-25T05:35:17.337</CreatedDate> <ModifiedDate>2019-10-25T05:35:17.337</ModifiedDate> <ID>290937</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>my automations</Name> <Description /> <ContentType>automations</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>386</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>Einstein</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-08T10:19:37.123</CreatedDate> <ModifiedDate>2017-02-08T10:19:37.123</ModifiedDate> <ID>66666</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>2</ID> <ObjectID xsi:nil="true" /> <CustomerKey>dataextension_default</CustomerKey> </ParentFolder> <Name>testExisting_FOLDER</Name> <Description /> <ContentType>dataextension</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:35.687</CreatedDate> <ModifiedDate>2016-07-22T11:52:35.687</ModifiedDate> <ID>89397</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Content Builder</Name> <Description>The root folder for assets</Description> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:07.7</CreatedDate> <ModifiedDate>2021-12-16T02:56:14.68</ModifiedDate> <ID>90888</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Test Folder</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:19.28</CreatedDate> <ModifiedDate>2016-07-22T11:52:19.28</ModifiedDate> <ID>89348</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Triggered Sends</Name> <Description /> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:52:34.983</CreatedDate> <ModifiedDate>2016-07-22T11:52:34.983</ModifiedDate> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Journey Builder Sends</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-29T12:13:27.28</CreatedDate> <ModifiedDate>2016-07-29T12:13:27.28</ModifiedDate> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>0</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>HiddenCategory</Name> <Description>Hidden folder to store Hidden items</Description> <ContentType>Hidden</ContentType> <IsActive>true</IsActive> <IsEditable>false</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.12</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.12</ModifiedDate> <ID>94030</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89396</ID> <ObjectID xsi:nil="true" /> <CustomerKey>triggered_send_journeybuilder</CustomerKey> </ParentFolder> <Name>Satisfaction Score Survey</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-25T10:04:09.133</CreatedDate> <ModifiedDate>2016-08-25T10:04:09.133</ModifiedDate> <ID>94031</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>94030</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>Version 1</Name> <Description /> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-06-09T10:17:06.27</CreatedDate> <ModifiedDate>2021-06-09T10:17:06.27</ModifiedDate> <ID>664654</ID> <ObjectID xsi:nil="true" /> <CustomerKey>6aa28490-6577-4cb2-8eac-fd5e4f983cae</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>6aa28490-6577-4cb2-8eac-fd5e4f983cae_V9</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:55:31.657</CreatedDate> <ModifiedDate>2022-07-31T19:55:31.657</ModifiedDate> <ID>742869</ID> <ObjectID xsi:nil="true" /> <CustomerKey>77211381-9967-4472-bd12-f58d4d5952a1</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>77211381-9967-4472-bd12-f58d4d5952a1_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-07-31T19:56:51.297</CreatedDate> <ModifiedDate>2022-07-31T19:56:51.297</ModifiedDate> <ID>742871</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderSimulationTrigge</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderSimulationTriggeredSends</Name> <Description>triggered_send_journeybuilder folder to store triggered_send_journeybuilder items</Description> <ContentType>triggered_send_journeybuilder</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-03-08T10:26:55.787</CreatedDate> <ModifiedDate>2023-03-08T10:26:55.787</ModifiedDate> <ID>771879</ID> <ObjectID xsi:nil="true" /> <CustomerKey>8c24f428-4da8-4df6-97a7-beba5166c3c7</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>8c24f428-4da8-4df6-97a7-beba5166c3c7_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2023-04-10T15:46:09.947</CreatedDate> <ModifiedDate>2023-04-10T15:46:09.947</ModifiedDate> <ID>776623</ID> <ObjectID xsi:nil="true" /> <CustomerKey>0a85b483-4208-4377-87fb-25794f5df244</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> </ParentFolder> <Name>0a85b483-4208-4377-87fb-25794f5df244_V1</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>9999999</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2020-03-06T07:57:37.633</CreatedDate> <ModifiedDate>2020-03-06T07:57:37.633</ModifiedDate> <ID>317169</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenJourneyBuilderTriggeredSends_d</CustomerKey> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>90889</ID> <ObjectID xsi:nil="true" /> <CustomerKey>HiddenCategory_default</CustomerKey> </ParentFolder> <Name>HiddenJourneyBuilderTriggeredSends</Name> <Description>triggered_send folder to store triggered_send items</Description> <ContentType>triggered_send</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> <Results xsi:type="DataFolder"> <Client> <ID>1111111</ID> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-01-01T00:00:00.0</CreatedDate> <ModifiedDate>2022-01-01T00:00:00.0</ModifiedDate> <ID>77777</ID> <ObjectID xsi:nil="true" /> <CustomerKey /> <ParentFolder> <PartnerKey xsi:nil="true" /> <ID>89397</ID> <ObjectID xsi:nil="true" /> </ParentFolder> <Name>testFolder_samePath</Name> <Description /> <ContentType>asset</ContentType> <IsActive>true</IsActive> <IsEditable>true</IsEditable> <AllowChildren>true</AllowChildren> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/dataFolder/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:be177208-5317-4cf6-ac91-ca6ee3cf2e9c</wsa:MessageID> <wsa:RelatesTo>urn:uuid:860092b1-f5d0-4e26-bac6-e6176e1a24e3</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-31f5e02a-c01e-4460-9652-c34da0c5eaa4"> <wsu:Created>2025-04-23T11:22:29Z</wsu:Created> <wsu:Expires>2025-04-23T11:27:29Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>Folder updated successfully.</StatusMessage> <OrdinalID>0</OrdinalID> </Results> <RequestID>b7ffdc43-dd86-41ef-979d-ab3d4badcb07</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/deliveryProfile/get-expected.json ================================================ { "key": "Default", "createdDate": "2021-06-21T17:55:00Z", "lastUpdated": "2021-06-21T17:55:00Z", "name": "Default", "description": "Account defaults" } ================================================ FILE: test/resources/9999999/domainVerification/create-expected.json ================================================ { "domain": "joern.berkefeld.New@accenture.com" } ================================================ FILE: test/resources/9999999/domainVerification/get-sap-expected.json ================================================ { "domain": "mcdev.accenture.com", "domainType": "SAP", "isSendable": true, "status": "Verified" } ================================================ FILE: test/resources/9999999/domainVerification/update-expected.json ================================================ { "domain": "joern.berkefeld@accenture.com", "domainType": "UserDomain", "isSendable": true, "status": "Verified" } ================================================ FILE: test/resources/9999999/email/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:bda830a5-f8a8-4555-a0f0-9b3cdae02f9f</wsa:MessageID> <wsa:RelatesTo>urn:uuid:afa5fcc9-c276-4f3d-9796-6b31a2b55721</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-1332843c-2deb-4570-822f-502889ddd5c9"> <wsu:Created>2023-08-08T12:49:19Z</wsu:Created> <wsu:Expires>2023-08-08T12:54:19Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e25a4055-f1b6-4fcd-a771-76bcb1cff6a9</RequestID> <Results xsi:type="Email"> <PartnerKey /> <CreatedDate>2020-08-13T10:16:59</CreatedDate> <ModifiedDate>2020-11-09T13:33:30.15</ModifiedDate> <ID>483943</ID> <ObjectID xsi:nil="true" /> <CustomerKey>255f0e7c-cd37-452b-ba59-cd802359f199</CustomerKey> <Name>Sporting Goods for September</Name> <Folder>my emails</Folder> <CategoryID>283575</CategoryID> <HTMLBody><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> ReadMsgBody{ width: 100%;} .ExternalClass {width: 100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} body {-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;margin:0 !important; padding:0 !important;} p { margin: 1em 0;} table td { border-collapse: collapse;} img {outline:0;} a img {border:none;} p {margin: 1em 0;} @-ms-viewport{ width: device-width;} @media only screen and (max-width: 480px) { body[yahoo] .container { width:100% !important; } body[yahoo] .footer { width:auto !important; margin-left:0; } body[yahoo] .content-padding{ padding:4px !important; } body[yahoo] .mobile-hidden { display:none !important; } body[yahoo] .logo { display:block !important; padding:0 !important; } body[yahoo] img { width:auto !important; max-width:308px !important; height:auto !important; max-height:auto !important;} body[yahoo] .header img { width:auto !important; max-width:316px !important; height:auto !important; max-height:auto !important;} body[yahoo] .photo img { width:100% !important; max-width:100% !important; height:auto !important;} body[yahoo] .drop { display:block !important; width: 100% !important; float:left; clear:both;} body[yahoo] .footerlogo { display:block !important; width: 100% !important; padding-top:15px; float:left; clear:both;} body[yahoo] .nav4, body[yahoo] .nav5, body[yahoo] .nav6 { display: none !important; } } @media only screen and (max-width: 640px) { body[yahoo] .container { width:100% !important; } body[yahoo] .mobile-hidden { display:none !important; } body[yahoo] .logo { display:block !important; padding:0 !important; } body[yahoo] .photo img { width:100% !important; height:auto !important;} body[yahoo] .nav5, body[yahoo] .nav6 { display: none !important;} } </style> </head> <body bgcolor="#ffffff" text="#000000" style="background-color: #FFFFFF; color: #000000; margin: 0px; padding:0px; -webkit-text-size-adjust:none;" yahoo="fix"> <table width="100%" border="0" cellpadding="0" cellspacing="0" align="center"> <tr> <td align="center" valign="top"><custom type="header" name="header"></td> </tr> <tr> <td align="center"> <table cellspacing="0" cellpadding="0" border="0" width="600" class="container" align="center"> <tr> <td> <table cellspacing="0" cellpadding="0" border="1" bordercolor="#000000" bgcolor="#ffffff" width="100%"> <tr> <td align="center" class="header" valign="top"></td> </tr> <tr> <td align="center" valign="top"><table cellspacing="0" cellpadding="0" border="0" width="100%" align="left"> <tr> <td class="content-padding" style="padding:10px;"> <table cellspacing="0" cellpadding="0" border="0" width="100%"> <tr> <td class="drop" valign="top" width="33%" align="left"> <custom type="content" name="left"> </td> <td class="drop" valign="top" width="2%" height="10"><img alt="" src="https://image.s7.sfmc-content.com/lib/ffcf14/m/1/spacer.gif" height="10" width="10" style="display: block;"/></td> <td class="drop" valign="top" width="65%"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td align="left" valign="top"> <custom type="content" name="right1"> </td> </tr> <tr> <td align="left" valign="top" style="padding-top: 10px;"> <custom type="content" name="right2"> </td> </tr> </table> </td> </tr> <tr> <td align="left" colspan="3" valign="top" class="drop" style="padding-top:10px;"> <custom type="content" name="bottom"> </td> </tr> </table> </td> </tr> </table></td> </tr> </table> </td> </tr> </table> </td> </tr> <tr> <td valign="top"><custom type="footer" name="footer"></td> </tr> </table> <custom name="opencounter" type="tracking"> </body> </html></HTMLBody> <TextBody /> <ContentAreas> <PartnerKey xsi:nil="true" /> <ID>934961</ID> <ObjectID>5E999EA7-97D8-4910-91B3-ED29B16567DA</ObjectID> <CustomerKey>36D85559-5345-41CB-9E8E-A6B7675E4A6F</CustomerKey> <Key>left</Key> <Content><table width="100%" bgcolor="" border="0" bordercolor="" cellpadding="0" cellspacing="0"><tr><td style="font-family:Arial;font-size:13px;">%%First Name%%</td></tr></table></Content> <IsBlank>false</IsBlank> <CategoryID>0</CategoryID> <Name /> <IsDynamicContent>false</IsDynamicContent> <IsSurvey>false</IsSurvey> <IsLocked>false</IsLocked> </ContentAreas> <ContentAreas> <PartnerKey xsi:nil="true" /> <ID>934962</ID> <ObjectID>9FA2FEE0-8439-4475-B990-BBC95CB30E31</ObjectID> <CustomerKey>68DC9A04-6662-4A23-912A-4A349A1EF040</CustomerKey> <Key>right1</Key> <Content><table width="100%" bgcolor="" border="0" bordercolor="" cellpadding="0" cellspacing="0"><tr><td style="font-family:Arial;font-size:13px;">%%Last Name%%</td></tr></table></Content> <IsBlank>false</IsBlank> <CategoryID>0</CategoryID> <Name /> <IsDynamicContent>false</IsDynamicContent> <IsSurvey>false</IsSurvey> <IsLocked>false</IsLocked> </ContentAreas> <ContentAreas> <PartnerKey xsi:nil="true" /> <ID>934963</ID> <ObjectID>5CE10FC0-CE06-40CC-8BE4-14583E2D02B3</ObjectID> <CustomerKey>AB7920D1-AE37-4137-9BB9-77B746D4A66C</CustomerKey> <Key>right2</Key> <Content><table width="100%" bgcolor="" border="0" bordercolor="" cellpadding="0" cellspacing="0"><tr><td style="font-family:Arial;font-size:13px;">%%emailname_%%</td></tr></table></Content> <IsBlank>false</IsBlank> <CategoryID>0</CategoryID> <Name /> <IsDynamicContent>false</IsDynamicContent> <IsSurvey>false</IsSurvey> <IsLocked>false</IsLocked> </ContentAreas> <ContentAreas> <PartnerKey xsi:nil="true" /> <ID>934964</ID> <ObjectID>AF6501E0-8367-4121-9142-ADAFD632FBE7</ObjectID> <CustomerKey>84B63EB0-E248-42D4-B6A6-716C18D2718D</CustomerKey> <Key>bottom</Key> <Content><table width="100%" bgcolor="" border="0" bordercolor="" cellpadding="0" cellspacing="0"><tr><td style="font-family:Arial;font-size:13px;">%%emailaddr%%</td></tr></table></Content> <IsBlank>false</IsBlank> <CategoryID>0</CategoryID> <Name /> <IsDynamicContent>false</IsDynamicContent> <IsSurvey>false</IsSurvey> <IsLocked>false</IsLocked> </ContentAreas> <Subject>Sporting Goods for September</Subject> <IsActive>true</IsActive> <IsHTMLPaste>false</IsHTMLPaste> <Status>New</Status> <EmailType>Normal</EmailType> <CharacterSet>utf-8</CharacterSet> <HasDynamicSubjectLine>false</HasDynamicSubjectLine> <ContentCheckStatus>Not Checked</ContentCheckStatus> <PreHeader /> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/email/v1/category/post-response-parentCatId=290937,name=my,catType=automations.json ================================================ { "categoryId": 862100, "parentCatId": 290937, "objectId": "07d346ff-c0b2-4f1b-9ca0-bddd156d3950", "catType": "automations", "name": "my" } ================================================ FILE: test/resources/9999999/email/v1/category/post-response-parentCatId=862100,name=sub,catType=automations.json ================================================ { "categoryId": 862101, "parentCatId": 862100, "objectId": "07d346ff-c0b2-4f1b-9ca0-bddd156d3951", "catType": "automations", "name": "sub" } ================================================ FILE: test/resources/9999999/email/v1/category/post-response-parentCatId=862101,name=path,catType=automations.json ================================================ { "categoryId": 862102, "parentCatId": 862101, "objectId": "07d346ff-c0b2-4f1b-9ca0-bddd156d3952", "catType": "automations", "name": "path" } ================================================ FILE: test/resources/9999999/email/v1/category/post-response-parentCatId=862102,name=subpath,catType=automations.json ================================================ { "categoryId": 862103, "parentCatId": 862102, "objectId": "07d346ff-c0b2-4f1b-9ca0-bddd156d3953", "catType": "automations", "name": "subpath" } ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/10ef27dd-4be8-4bf6-970a-8acf8e281e55/delete-response.txt ================================================ 10ef27dd-4be8-4bf6-970a-8acf8e281e55 ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/10ef27dd-4be8-4bf6-970a-8acf8e281e55/get-response.json ================================================ { "id": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "key": "testExisting_dataFilter", "createdDate": "2025-12-01T16:54:09.813", "createdBy": 700301950, "createdByName": "Jörn Berkefeld", "lastUpdated": "2025-12-01T17:17:31.827", "lastUpdatedBy": 700301950, "lastUpdatedByName": "Jörn Berkefeld", "name": "testExisting_dataFilter", "description": "test", "categoryId": 5318, "filterDefinitionXml": "<FilterDefinition Source=\"DataExtension\" SourceID=\"21711373-72c1-ec11-b83b-48df37d1deb7\"><ConditionSet Operator=\"AND\" ConditionSetName=\"Outer Grouping\"><Condition ID=\"bea0e308-5d45-4181-a673-da9972a7c674\" Operator=\"Ends\"><Value><![CDATA[_test]]></Value></Condition></ConditionSet></FilterDefinition>", "derivedFromObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "derivedFromType": 2, "isSendable": true, "derivedFromObjectTypeName": "DataExtension", "derivedFromObjectName": "testExisting_dataExtension" } ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/10ef27dd-4be8-4bf6-970a-8acf8e281e55/patch-response.json ================================================ { "id": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "key": "testExisting_dataFilter", "owner": 700301950, "createdDate": "2026-01-27T06:24:40.527", "createdBy": 700301950, "lastUpdated": "2026-01-30T10:46:59.777", "lastUpdatedBy": 700301950, "name": "testExisting_dataFilter", "categoryId": 5318, "filterDefinitionXml": "<FilterDefinition Source=\"DataExtension\" SourceID=\"21711373-72c1-ec11-b83b-48df37d1deb7\"><ConditionSet Operator=\"AND\" ConditionSetName=\"Outer Grouping\"><Condition ID=\"bea0e308-5d45-4181-a673-da9972a7c674\" Operator=\"Begins\"><Value><![CDATA[testExisting_]]></Value></Condition></ConditionSet></FilterDefinition>", "derivedFromObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "derivedFromType": 2, "isSendable": true } ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/category/5318/get-response.json ================================================ { "count": 1, "page": 1, "pageSize": 100, "links": {}, "items": [ { "id": "10ef27dd-4be8-4bf6-970a-8acf8e281e55", "key": "testExisting_dataFilter", "createdDate": "2025-12-01T16:54:09.813", "createdBy": 700301950, "createdByName": "Jörn Berkefeld", "lastUpdated": "2025-12-01T17:17:31.827", "lastUpdatedBy": 700301950, "lastUpdatedByName": "Jörn Berkefeld", "name": "testExisting_dataFilter", "description": "test", "categoryId": 5318, "filterDefinitionXml": "<FilterDefinition Source=\"DataExtension\" SourceID=\"21711373-72c1-ec11-b83b-48df37d1deb7\"><ConditionSet Operator=\"AND\" ConditionSetName=\"Outer Grouping\"><Condition ID=\"bea0e308-5d45-4181-a673-da9972a7c674\" Operator=\"Ends\"><Value><![CDATA[_test]]></Value></Condition></ConditionSet></FilterDefinition>", "derivedFromObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "derivedFromType": 2, "isSendable": true, "derivedFromObjectTypeName": "DataExtension", "derivedFromObjectName": "MCV_Talent_flat" } ] } ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/category/8502/get-response.json ================================================ { "count": 0, "page": 1, "pageSize": 100, "links": {}, "items": [] } ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/category/8503/get-response.json ================================================ { "count": 0, "page": 1, "pageSize": 100, "links": {}, "items": [] } ================================================ FILE: test/resources/9999999/email/v1/filters/filterdefinition/post-response.json ================================================ { "id": "4c92630e-e3e8-4940-a93d-99da02123e93", "key": "testNew_dataFilter", "owner": 700301950, "createdDate": "2026-01-30T11:04:06.883", "createdBy": 700301950, "lastUpdated": "2026-01-30T11:04:06.883", "lastUpdatedBy": 700301950, "name": "testNew_dataFilter", "categoryId": 5318, "filterDefinitionXml": "<FilterDefinition Source=\"DataExtension\" SourceID=\"21711373-72c1-ec11-b83b-48df37d1deb7\"><ConditionSet Operator=\"AND\" ConditionSetName=\"Outer Grouping\"><Condition ID=\"bea0e308-5d45-4181-a673-da9972a7c674\" Operator=\"Ends\"><Value><![CDATA[_test]]></Value></Condition></ConditionSet></FilterDefinition>", "derivedFromObjectId": "21711373-72c1-ec11-b83b-48df37d1deb7", "derivedFromType": 2, "isSendable": false } ================================================ FILE: test/resources/9999999/emailSend/build-expected.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CreatedDate": "2022-11-14T12:27:29.963", "CustomerKey": "testTemplated_emailSend", "DeduplicateByEmail": false, "Description": "some description", "DynamicEmailSubject": "someSubject", "EmailSubject": "someSubject", "ExclusionFilter": "Domain(emailaddr) != \"accenture.com\"", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "ModifiedDate": "2022-11-14T12:27:29.963", "Name": "testTemplated_emailSend", "SendDefinitionList": [ { "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "SendDefinitionListType": "ExclusionList", "r__dataExtension_key": "testTemplated_dataExtension_exclusion" }, { "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "SendDefinitionListType": "SourceList", "r__dataExtension_key": "testTemplated_dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "testTemplated_asset_message", "r__asset_name_readOnly": "testTemplated_asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "testTemplated_sendClassification", "r__senderProfile_key": "testTemplated_senderProfile" } ================================================ FILE: test/resources/9999999/emailSend/get-expected.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CreatedDate": "2022-11-14T12:27:29.963", "CustomerKey": "testExisting_emailSend", "DeduplicateByEmail": false, "Description": "some description", "DynamicEmailSubject": "someSubject", "EmailSubject": "someSubject", "ExclusionFilter": "Domain(emailaddr) != \"accenture.com\"", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "ModifiedDate": "2022-11-14T12:27:29.963", "Name": "testExisting_emailSend", "SendDefinitionList": [ { "SendDefinitionListType": "ExclusionList", "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "r__dataExtension_key": "testExisting_dataExtension_exclusion" }, { "SendDefinitionListType": "SourceList", "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "r__dataExtension_key": "testExisting_dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/resources/9999999/emailSend/patch-expected.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CustomerKey": "testExisting_emailSend", "DeduplicateByEmail": false, "Description": "updated on deploy", "DynamicEmailSubject": "someSubject", "EmailSubject": "someSubject", "ExclusionFilter": "", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "Name": "testExisting_emailSend", "SendDefinitionList": [ { "SendDefinitionListType": "ExclusionList", "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "r__dataExtension_key": "testExisting_dataExtension_exclusion" }, { "SendDefinitionListType": "SourceList", "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "r__dataExtension_key": "testExisting_dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/resources/9999999/emailSend/post-expected.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CustomerKey": "testNew_emailSend", "DeduplicateByEmail": false, "Description": "created on deploy", "DynamicEmailSubject": "testExisting_asset_email", "EmailSubject": "testExisting_asset_email", "ExclusionFilter": "", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "Name": "testNew_emailSend", "SendDefinitionList": [ { "SendDefinitionListType": "ExclusionList", "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "r__dataExtension_key": "testExisting_dataExtension_exclusion" }, { "SendDefinitionListType": "SourceList", "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "r__dataExtension_key": "testExisting_dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/resources/9999999/emailSend/template-expected.json ================================================ { "Additional": "", "AutoBccEmail": "", "BccEmail": "", "CCEmail": "", "CreatedDate": "2022-11-14T12:27:29.963", "CustomerKey": "{{{prefix}}}emailSend", "DeduplicateByEmail": false, "Description": "some description", "DynamicEmailSubject": "someSubject", "EmailSubject": "someSubject", "ExclusionFilter": "Domain(emailaddr) != \"accenture.com\"", "IsMultipart": true, "IsSendLogging": false, "IsWrapped": true, "ModifiedDate": "2022-11-14T12:27:29.963", "Name": "{{{prefix}}}emailSend", "SendDefinitionList": [ { "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "SendDefinitionListType": "ExclusionList", "r__dataExtension_key": "{{{prefix}}}dataExtension_exclusion" }, { "DataSourceTypeID": "CustomObject", "IsTestObject": false, "Name": "", "SendDefinitionListType": "SourceList", "r__dataExtension_key": "{{{prefix}}}dataExtension", "r__list_PathName": "Publication Lists/Demo Publication List" } ], "SuppressTracking": false, "TestEmailAddr": "", "r__asset_key": "{{{prefix}}}asset_message", "r__asset_name_readOnly": "{{{prefix}}}asset_message", "r__deliveryProfile_key": "Default", "r__folder_Path": "User-Initiated", "r__sendClassification_key": "{{{prefix}}}sendClassification", "r__senderProfile_key": "{{{prefix}}}senderProfile" } ================================================ FILE: test/resources/9999999/emailSendDefinition/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:a717abcf-ef43-42a9-af53-69d95f93cf4a</wsa:MessageID> <wsa:RelatesTo>urn:uuid:38efc94c-5fea-43e3-8689-fd26ec03d091</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-2552d265-3c7a-4593-ba69-15566a731880"> <wsu:Created>2024-04-17T12:57:44Z</wsu:Created> <wsu:Expires>2024-04-17T13:02:44Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>EmailSendDefinition created</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>ce281713-bafc-ee11-a5c8-5cba2c6fc270</NewObjectID> <Object xsi:type="EmailSendDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>ce281713-bafc-ee11-a5c8-5cba2c6fc270</ObjectID> <CustomerKey>testNew_emailSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testNew_emailSend</Name> <Description>created on deploy</Description> <CategoryID>4691</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>Default</CustomerKey> </DeliveryProfile> <SuppressTracking>false</SuppressTracking> <IsSendLogging>false</IsSendLogging> <SendDefinitionList> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <SendDefinitionListType>ExclusionList</SendDefinitionListType> <CustomObjectID>21711373-72c1-ec11-b83b-exclusion</CustomObjectID> <DataSourceTypeID>CustomObject</DataSourceTypeID> <IsTestObject>false</IsTestObject> <Name /> </SendDefinitionList> <SendDefinitionList> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <List> <PartnerKey xsi:nil="true" /> <ID>114</ID> <ObjectID xsi:nil="true" /> </List> <SendDefinitionListType>SourceList</SendDefinitionListType> <CustomObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</CustomObjectID> <DataSourceTypeID>CustomObject</DataSourceTypeID> <IsTestObject>false</IsTestObject> <Name /> </SendDefinitionList> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <BccEmail /> <AutoBccEmail /> <TestEmailAddr /> <EmailSubject>testExisting_asset_email</EmailSubject> <DynamicEmailSubject>testExisting_asset_email</DynamicEmailSubject> <IsMultipart>true</IsMultipart> <IsWrapped>true</IsWrapped> <DeduplicateByEmail>false</DeduplicateByEmail> <ExclusionFilter /> <Additional /> <CCEmail /> </Object> </Results> <RequestID>8a548392-c00a-4909-97d3-85b5a9305d35</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/emailSendDefinition/delete-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>DeleteResponse</wsa:Action> <wsa:MessageID>urn:uuid:b9803c4e-4d42-44c3-87fe-3b216ee29eb4</wsa:MessageID> <wsa:RelatesTo>urn:uuid:7b32fd02-7791-4e57-9a18-50936e575c9a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-b119a5cf-5dcd-440a-8ed5-c96a134727b1"> <wsu:Created>2024-04-17T13:26:48Z</wsu:Created> <wsu:Expires>2024-04-17T13:31:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <DeleteResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>EmailSendDefinition deleted</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="EmailSendDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>748400fc-b3fc-ee11-a5c8-5cba2c6fc270</ObjectID> <CustomerKey>testExisting_emailSend</CustomerKey> </Object> </Results> <RequestID>02ef6a83-36cc-402e-901e-c24d49cc0e3c</RequestID> <OverallStatus>OK</OverallStatus> </DeleteResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/emailSendDefinition/retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:e0ba7da7-7e82-42db-a166-42a488ac375b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:17a3f405-6bd8-4b30-9230-44fea1749b96</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-96902d78-e86f-4361-855e-c37e2e3b4b58"> <wsu:Created>2023-06-01T12:04:17Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:17Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>687d0584-acbe-4bac-bfc2-4c41b73b5a32</RequestID> <Results xsi:type="EmailSendDefinition"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-11-14T12:27:29.963</CreatedDate> <ModifiedDate>2022-11-14T12:27:29.963</ModifiedDate> <ObjectID>9b1c7bf9-4964-ed11-b849-48df37d1de8b</ObjectID> <CustomerKey>testExisting_emailSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_emailSend</Name> <Description>some description</Description> <CategoryID>4691</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>Default</CustomerKey> </DeliveryProfile> <SuppressTracking>false</SuppressTracking> <IsSendLogging>false</IsSendLogging> <SendDefinitionList> <PartnerKey xsi:nil="true" /> <ObjectID>9d1c7bf9-4964-ed11-b849-48df37d1de8c</ObjectID> <SendDefinitionListType>ExclusionList</SendDefinitionListType> <CustomObjectID>21711373-72c1-ec11-b83b-exclusion</CustomObjectID> <DataSourceTypeID>CustomObject</DataSourceTypeID> <IsTestObject>false</IsTestObject> <SalesForceObjectID /> <Name /> </SendDefinitionList> <SendDefinitionList> <PartnerKey xsi:nil="true" /> <ObjectID>9d1c7bf9-4964-ed11-b849-48df37d1de8b</ObjectID> <List> <PartnerKey xsi:nil="true" /> <ID>114</ID> <ObjectID xsi:nil="true" /> </List> <SendDefinitionListType>SourceList</SendDefinitionListType> <CustomObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</CustomObjectID> <DataSourceTypeID>CustomObject</DataSourceTypeID> <IsTestObject>false</IsTestObject> <SalesForceObjectID /> <Name /> </SendDefinitionList> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <BccEmail /> <AutoBccEmail /> <TestEmailAddr /> <EmailSubject>someSubject</EmailSubject> <DynamicEmailSubject>someSubject</DynamicEmailSubject> <IsMultipart>true</IsMultipart> <IsWrapped>true</IsWrapped> <DeduplicateByEmail>false</DeduplicateByEmail> <ExclusionFilter>Domain(emailaddr) != "accenture.com"</ExclusionFilter> <Additional /> <CCEmail /> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/emailSendDefinition/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:166b4a28-09e8-444b-ac08-91a7fb32af13</wsa:MessageID> <wsa:RelatesTo>urn:uuid:95dd02cf-53a5-4bd7-acaf-4c0609f81912</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-0706d339-c346-4fa4-940d-565ca79a3f3f"> <wsu:Created>2024-04-17T12:55:18Z</wsu:Created> <wsu:Expires>2024-04-17T13:00:18Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>EmailSendDefinition updated</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="EmailSendDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>748400fc-b3fc-ee11-a5c8-5cba2c6fc270</ObjectID> <CustomerKey>testExisting_emailSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_emailSend</Name> <Description>updated on deploy</Description> <CategoryID>4691</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>Default</CustomerKey> </DeliveryProfile> <SuppressTracking>false</SuppressTracking> <IsSendLogging>false</IsSendLogging> <SendDefinitionList> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <SendDefinitionListType>ExclusionList</SendDefinitionListType> <CustomObjectID>21711373-72c1-ec11-b83b-exclusion</CustomObjectID> <DataSourceTypeID>CustomObject</DataSourceTypeID> <IsTestObject>false</IsTestObject> <Name /> </SendDefinitionList> <SendDefinitionList> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <List> <PartnerKey xsi:nil="true" /> <ID>114</ID> <ObjectID xsi:nil="true" /> </List> <SendDefinitionListType>SourceList</SendDefinitionListType> <CustomObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</CustomObjectID> <DataSourceTypeID>CustomObject</DataSourceTypeID> <IsTestObject>false</IsTestObject> <Name /> </SendDefinitionList> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> <Subject>testExisting_asset_email</Subject> </Email> <BccEmail /> <AutoBccEmail /> <TestEmailAddr /> <EmailSubject>someSubject</EmailSubject> <DynamicEmailSubject>someSubject</DynamicEmailSubject> <IsMultipart>true</IsMultipart> <IsWrapped>true</IsWrapped> <DeduplicateByEmail>false</DeduplicateByEmail> <ExclusionFilter /> <Additional /> <CCEmail /> </Object> </Results> <RequestID>d961a829-bcbc-4f74-bbf3-66c3f391d471</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/event/build-expected.json ================================================ { "type": "APIEvent", "name": "testTemplated_event", "description": "", "eventDefinitionKey": "testTemplated_event", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "sourceApplicationExtensionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "", "arguments": { "serializedObjectType": 11, "criteria": "" }, "metaData": { "scheduleState": "No Schedule" }, "isVisibleInPicker": true, "category": "Event", "disableDEDataLogging": false, "r__dataExtension_key": "testTemplated_event - 2024-07-05T080154625" } ================================================ FILE: test/resources/9999999/event/get-automation-expected.json ================================================ { "type": "AutomationAudience", "name": "testExisting_event_automation", "description": "", "createdDate": "2024-11-07T04:58:46.51", "createdBy": "Jörn Berkefeld", "modifiedDate": "2024-11-07T04:58:46.51", "modifiedBy": "Jörn Berkefeld", "eventDefinitionKey": "testExisting_event_automation", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "arguments": { "serializedObjectType": 9, "useHighWatermark": true, "resetHighWatermark": false, "criteria": "" }, "configurationArguments": {}, "metaData": { "criteriaDescription": "", "scheduleFlowMode": "automation" }, "schedule": { "startDateTime": "2024-11-07T12:15:00", "endDateTime": "2079-06-06T00:00:00", "timeZone": "W. Europe Standard Time", "occurrences": 478403, "endType": "EndDate", "frequency": "Hourly", "recurrencePattern": "Interval", "interval": 1 }, "interactionCount": 1, "isVisibleInPicker": false, "category": "Audience", "publishedInteractionCount": 1, "disableDEDataLogging": false, "r__automation_key": "testExisting_automation_event", "r__dataExtension_key": "testExisting_dataExtension" } ================================================ FILE: test/resources/9999999/event/get-expected.json ================================================ { "type": "APIEvent", "name": "testExisting_event", "description": "", "createdDate": "2024-07-05T06:12:24.227", "createdBy": "Jörn Berkefeld", "modifiedDate": "2024-07-05T08:01:55.4", "modifiedBy": "Jörn Berkefeld", "eventDefinitionKey": "testExisting_event", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "sourceApplicationExtensionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "", "arguments": { "serializedObjectType": 11, "criteria": "" }, "metaData": { "scheduleState": "No Schedule" }, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "disableDEDataLogging": false, "r__dataExtension_key": "testExisting_event - 2024-07-05T080154625" } ================================================ FILE: test/resources/9999999/event/get-published-expected.json ================================================ { "type": "EmailAudience", "name": "testExisting_journey_Multistep", "description": "", "createdDate": "2024-05-04T05:54:44.95", "createdBy": "Jörn Berkefeld", "modifiedDate": "2024-05-04T05:54:44.95", "modifiedBy": "Jörn Berkefeld", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "configurationArguments": {}, "arguments": { "serializedObjectType": 3, "criteria": "" }, "metaData": { "criteriaDescription": "", "scheduleState": "No Schedule" }, "interactionCount": 1, "isVisibleInPicker": false, "category": "Audience", "publishedInteractionCount": 0, "disableDEDataLogging": false, "r__dataExtension_key": "testExisting_journey_Multistep" } ================================================ FILE: test/resources/9999999/event/post_withExistingDE-callout-expected.json ================================================ { "type": "APIEvent", "name": "testNew_event_withExistingDE", "description": "created on deploy", "eventDefinitionKey": "testNew_event_withExistingDE", "schema": { "fields": [ { "dataType": "Text", "isDevicePreference": false, "isNullable": false, "isPrimaryKey": true, "maxLength": "18", "name": "ContactId" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": false, "isPrimaryKey": false, "maxLength": "50", "name": "Type" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": false, "isPrimaryKey": true, "maxLength": "50", "name": "Status" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "Respondent" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "FirstName" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "LastName" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "50", "name": "PreferredLanguage" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "TouchPoint" }, { "dataType": "Date", "defaultValue": "GetDate()", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "name": "Datestamp" }, { "dataType": "Date", "defaultValue": "", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "name": "StartDate" }, { "dataType": "Date", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "name": "EndDate" }, { "dataType": "Date", "defaultValue": "", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "name": "BroadcastedNotificationDate" }, { "dataType": "Date", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "name": "FirstReminderDate" }, { "dataType": "Date", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "name": "SecondReminderDate" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "Title" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "DisplayName" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "Text" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "4000", "name": "Description" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "Channel" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "FirstReminderChannel" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "256", "name": "SecondReminderChannel" }, { "dataType": "Email", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "", "name": "Email" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": false, "isPrimaryKey": true, "maxLength": "18", "name": "ArticleOrTaskID" }, { "dataType": "Number", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "", "name": "Points" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "255", "name": "TaskType" }, { "dataType": "Text", "isDevicePreference": false, "isNullable": true, "isPrimaryKey": false, "maxLength": "255", "name": "TaskArea" } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "entrySourceGroupConfigUrl": "jb:///data/entry/api-event/entrysourcegroupconfig.json", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "testNew_event_withExistingDE" }, "metaData": {}, "isVisibleInPicker": true, "category": "Event", "automationId": "00000000-0000-0000-0000-000000000000", "mode": "Production", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8" } ================================================ FILE: test/resources/9999999/event/post_withExistingDE-expected.json ================================================ { "type": "APIEvent", "name": "testNew_event_withExistingDE", "description": "created on deploy", "createdDate": "0001-01-01T00:00:00", "createdBy": 0, "modifiedDate": "0001-01-01T00:00:00", "modifiedBy": 0, "eventDefinitionKey": "testNew_event_withExistingDE", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "arguments": { "serializedObjectType": 11 }, "metaData": {}, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "r__dataExtension_key": "testExisting_event - 2024-07-05T080154625" } ================================================ FILE: test/resources/9999999/event/post_withSchema-callout-expected.json ================================================ { "type": "APIEvent", "name": "testNew_event_withSchema", "description": "created on deploy", "mode": "Production", "automationId": "00000000-0000-0000-0000-000000000000", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "eventDefinitionKey": "testNew_event_withSchema", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "entrySourceGroupConfigUrl": "jb:///data/entry/api-event/entrysourcegroupconfig.json", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": 18, "isNullable": false, "isPrimaryKey": true }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Datestamp", "dataType": "Date", "defaultValue": "GetDate()", "isNullable": true, "isPrimaryKey": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "isVisibleInPicker": true, "arguments": { "automationId": "00000000-0000-0000-0000-000000000000", "eventDefinitionKey": "testNew_event_withSchema" } } ================================================ FILE: test/resources/9999999/event/post_withSchema-expected.json ================================================ { "type": "APIEvent", "name": "testNew_event_withSchema", "description": "created on deploy", "createdDate": "0001-01-01T00:00:00", "createdBy": 0, "modifiedDate": "0001-01-01T00:00:00", "modifiedBy": 0, "eventDefinitionKey": "testNew_event_withSchema", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "arguments": { "serializedObjectType": 11 }, "metaData": {}, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "r__dataExtension_key": "testNew_event_withSchema" } ================================================ FILE: test/resources/9999999/event/put-callout-expected.json ================================================ { "type": "APIEvent", "name": "testExisting_event", "description": "updated on deploy", "mode": "Production", "eventDefinitionKey": "testExisting_event", "entrySourceGroupConfigUrl": "jb:///data/entry/api-event/entrysourcegroupconfig.json", "automationId": "00000000-0000-0000-0000-000000000000", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Datestamp", "dataType": "Date", "defaultValue": "GetDate()", "isNullable": true, "isPrimaryKey": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey", "id": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "name": "testExisting_event - 2024-07-05T080154625" }, "isVisibleInPicker": false, "arguments": { "automationId": "00000000-0000-0000-0000-000000000000", "eventDefinitionKey": "testExisting_event", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8" }, "isPlatformObject": false, "id": "d8d57832-ce9c-4bf6-8c24-3044ece5dffd", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8" } ================================================ FILE: test/resources/9999999/event/put-expected.json ================================================ { "type": "APIEvent", "name": "testExisting_event", "description": "", "createdDate": "2024-07-05T06:12:24.227", "createdBy": "Jörn Berkefeld", "modifiedDate": "2024-07-05T08:01:55.4", "modifiedBy": "Jörn Berkefeld", "eventDefinitionKey": "testExisting_event", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "sourceApplicationExtensionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "", "arguments": { "serializedObjectType": 11, "criteria": "" }, "metaData": { "scheduleState": "No Schedule" }, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "disableDEDataLogging": false, "r__dataExtension_key": "testExisting_event - 2024-07-05T080154625" } ================================================ FILE: test/resources/9999999/event/template-expected.json ================================================ { "type": "APIEvent", "name": "{{{prefix}}}event", "description": "", "eventDefinitionKey": "{{{prefix}}}event", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "sourceApplicationExtensionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "", "arguments": { "serializedObjectType": 11, "criteria": "" }, "metaData": { "scheduleState": "No Schedule" }, "isVisibleInPicker": true, "category": "Event", "disableDEDataLogging": false, "r__dataExtension_key": "{{{prefix}}}event - 2024-07-05T080154625" } ================================================ FILE: test/resources/9999999/event-deploy/testNew_event_badExtension.bad-type-extension.json ================================================ { "type": "APIEvent", "name": "testNew_event_badExtension", "description": "updated on deploy", "mode": "Production", "eventDefinitionKey": "testNew_event_badExtension", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": 18, "isNullable": false, "isPrimaryKey": true }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Datestamp", "dataType": "Date", "defaultValue": "GetDate()", "isNullable": true, "isPrimaryKey": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "AddedField", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "isVisibleInPicker": true } ================================================ FILE: test/resources/9999999/event-deploy/testNew_event_badName_bad.event-meta.json ================================================ { "type": "APIEvent", "name": "testNew_event_badName", "description": "updated on deploy", "mode": "Production", "eventDefinitionKey": "testNew_event_badName", "schema": { "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": 18, "isNullable": false, "isPrimaryKey": true }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Datestamp", "dataType": "Date", "defaultValue": "GetDate()", "isNullable": true, "isPrimaryKey": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false }, { "name": "AddedField", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey" }, "isVisibleInPicker": true } ================================================ FILE: test/resources/9999999/eventDefinition/get-expected.json ================================================ { "type": "APIEvent", "name": "TestContact_Event", "description": "", "createdDate": "2018-08-03T07:55:27.38", "createdBy": 7586085, "modifiedDate": "2018-08-03T08:22:03.76", "modifiedBy": 7586085, "mode": "Production", "eventDefinitionKey": "APIEvent-60130566-e2fe-eb29-4140-15c27093a80b", "dataExtensionName": "Contact_Data", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "filterDefinitionTemplate": "", "iconUrl": "/events/images/icon_journeyBuilder-event-api-blue.svg", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "APIEvent-60130566-e2fe-eb29-4140-15c27093a80b", "dataExtensionId": "C25D5A59-5EBC-40C9-8D27-149831881D89", "automationId": "00000000-0000-0000-0000-000000000000", "criteria": "", "useHighWatermark": false }, "metaData": { "scheduleState": "No Schedule", "criteriaDescription": "" }, "interactionCount": 1, "isVisibleInPicker": true, "isPlatformObject": false, "category": "Event", "publishedInteractionCount": 1, "automationId": "00000000-0000-0000-0000-000000000000", "disableDEDataLogging": false } ================================================ FILE: test/resources/9999999/fileLocation/build-expected.json ================================================ { "customerKey": "testTemplated_fileLocation_azure", "description": "blabla", "name": "testTemplated_fileLocation_azure_name", "azureFileTransferLocation": { "accessKeyId": "client-id", "authType": "AccessKey", "bucketName": "container-name", "relativePath": "my/path", "storageAccountName": "accountname", "tenantId": "my-id" }, "c__locationType": "Azure Blob Storage" } ================================================ FILE: test/resources/9999999/fileLocation/get-aws-expected.json ================================================ { "customerKey": "testExisting_fileLocation_aws", "name": "testExisting_fileLocation_aws_name", "description": "", "awsFileTransferLocation": { "accessKeyId": "key-id", "authType": "AccessKey", "bucketName": "bucket-name", "regionName": "eucentral1", "relativePath": "my/path", "transferAccelerationEnabled": false }, "c__locationType": "Amazon Simple Storage Service" } ================================================ FILE: test/resources/9999999/fileLocation/get-azure-expected.json ================================================ { "customerKey": "testExisting_fileLocation_azure", "name": "testExisting_fileLocation_azure_name", "description": "blabla", "azureFileTransferLocation": { "accessKeyId": "client-id", "authType": "AccessKey", "bucketName": "container-name", "relativePath": "my/path", "storageAccountName": "accountname", "tenantId": "my-id" }, "c__locationType": "Azure Blob Storage" } ================================================ FILE: test/resources/9999999/fileLocation/get-eftp-expected.json ================================================ { "customerKey": "ExactTarget Enhanced FTP", "name": "ExactTarget Enhanced FTP", "c__locationType": "Enhanced FTP Site Import Directory" } ================================================ FILE: test/resources/9999999/fileLocation/get-exsftp-expected.json ================================================ { "customerKey": "testExisting_fileLocation_exsftp", "name": "testExisting_fileLocation_exsftp_name", "description": "blabla", "sFtpFileTransferLocation": { "authType": "Password", "portNumber": 22, "url": "sftp://test.com", "userName": "abc" }, "c__locationType": "External SFTP Site" } ================================================ FILE: test/resources/9999999/fileLocation/get-gcp-expected.json ================================================ { "customerKey": "testExisting_fileLocation_gcp", "name": "testExisting_fileLocation_gcp_name", "description": "", "gcpFileTransferLocation": { "bucketName": "some-bucket", "relativePath": "Task/Activity" }, "c__locationType": "Google Cloud Storage" } ================================================ FILE: test/resources/9999999/fileLocation/get-sor-expected.json ================================================ { "customerKey": "Salesforce Objects & Reports", "name": "Salesforce Objects & Reports", "c__locationType": "Salesforce Objects and Reports" } ================================================ FILE: test/resources/9999999/fileLocation/patch-aws-expected.json ================================================ { "customerKey": "testExisting_fileLocation_aws", "description": "updated via deploy", "name": "testExisting_fileLocation_aws_name", "awsFileTransferLocation": { "accessKeyId": "key-id", "authType": "AccessKey", "bucketName": "bucket-name", "regionName": "eucentral1", "relativePath": "my/path", "transferAccelerationEnabled": false }, "c__locationType": "Amazon Simple Storage Service" } ================================================ FILE: test/resources/9999999/fileLocation/patch-exsftp-expected.json ================================================ { "customerKey": "testExisting_fileLocation_exsftp", "name": "testExisting_fileLocation_exsftp_name", "description": "updated via deploy", "sFtpFileTransferLocation": { "authType": "Password", "portNumber": 22, "url": "sftp://test.com", "userName": "abc" }, "c__locationType": "External SFTP Site" } ================================================ FILE: test/resources/9999999/fileLocation/template-expected.json ================================================ { "customerKey": "{{{prefix}}}fileLocation_azure", "description": "blabla", "name": "{{{prefix}}}fileLocation_azure_name", "azureFileTransferLocation": { "accessKeyId": "client-id", "authType": "AccessKey", "bucketName": "container-name", "relativePath": "my/path", "storageAccountName": "accountname", "tenantId": "my-id" }, "c__locationType": "Azure Blob Storage" } ================================================ FILE: test/resources/9999999/fileTransfer/build-expected.json ================================================ { "customerKey": "testTemplated_fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%%", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "name": "testTemplated_fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/resources/9999999/fileTransfer/get-expected.json ================================================ { "createdDate": "2022-11-09T05:31:56.477", "customerKey": "testExisting_fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%%", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "modifiedDate": "2022-11-17T07:13:20.05", "name": "testExisting_fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/resources/9999999/fileTransfer/patch-expected.json ================================================ { "createdDate": "2022-11-09T05:31:56.477", "customerKey": "testExisting_fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%% updated via deploy", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "modifiedDate": "2022-11-17T07:13:20.05", "name": "testExisting_fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/resources/9999999/fileTransfer/post-expected.json ================================================ { "createdDate": "2022-11-09T05:31:56.477", "customerKey": "testNew_fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%% created on deploy", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "modifiedDate": "2022-11-17T07:13:20.05", "name": "testNew_fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/resources/9999999/fileTransfer/template-expected.json ================================================ { "customerKey": "{{{prefix}}}fileTransfer", "description": "17.11.2022", "fileSpec": "%%Year%%", "isCompressed": false, "isEncrypted": false, "isFileSpecLocalized": false, "isPgp": false, "isUpload": true, "maxFileAge": 0, "maxFileAgeScheduleOffset": 0, "maxImportFrequency": 0, "name": "{{{prefix}}}fileTransfer", "r__fileLocation_name": "ExactTarget Enhanced FTP" } ================================================ FILE: test/resources/9999999/filter/build-expected.json ================================================ { "customerKey": "testTemplated_filter", "name": "testTemplated_filter", "description": "blabla", "statusId": 1, "r__dataFilter_key": "testTemplated_dataFilter", "r__destination_dataExtension_key": "testTemplated_dataExtension_exclusion", "r__source_dataExtension_key": "testTemplated_dataExtension", "r__folder_Path": "Filter/filterSubfolder" } ================================================ FILE: test/resources/9999999/filter/get-expected.json ================================================ { "customerKey": "testExisting_filter", "name": "testExisting_filter", "description": "blabla", "modifiedDate": "2026-01-28T10:14:46.717", "statusId": 1, "r__dataFilter_key": "testExisting_dataFilter", "r__destination_dataExtension_key": "testExisting_dataExtension_exclusion", "r__source_dataExtension_key": "testExisting_dataExtension", "r__folder_Path": "Filter/filterSubfolder" } ================================================ FILE: test/resources/9999999/filter/patch-expected.json ================================================ { "customerKey": "testExisting_filter", "name": "testExisting_filter", "description": "updated on deploy", "modifiedDate": "2026-01-28T10:14:46.717", "statusId": 1, "r__dataFilter_key": "testExisting_dataFilter", "r__destination_dataExtension_key": "testExisting_dataExtension_exclusion", "r__source_dataExtension_key": "testExisting_dataExtension", "r__folder_Path": "Filter" } ================================================ FILE: test/resources/9999999/filter/post-expected.json ================================================ { "customerKey": "testNew_filter", "name": "testNew_filter", "description": "created via deploy", "modifiedDate": "2026-02-02T07:34:49.277", "statusId": 1, "r__dataFilter_key": "testExisting_dataFilter", "r__destination_dataExtension_key": "testExisting_dataExtension_exclusion", "r__source_dataExtension_key": "testExisting_dataExtension", "r__folder_Path": "Filter/filterSubfolder" } ================================================ FILE: test/resources/9999999/filter/template-expected.json ================================================ { "customerKey": "{{{prefix}}}filter", "name": "{{{prefix}}}filter", "description": "blabla", "statusId": 1, "r__dataFilter_key": "{{{prefix}}}dataFilter", "r__destination_dataExtension_key": "{{{prefix}}}dataExtension_exclusion", "r__source_dataExtension_key": "{{{prefix}}}dataExtension", "r__folder_Path": "Filter/filterSubfolder" } ================================================ FILE: test/resources/9999999/filterActivity/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:d5e6c2a7-842c-49c4-9486-5f62c19a3bb3</wsa:MessageID> <wsa:RelatesTo>urn:uuid:25aedc29-eff1-40d2-bb67-c0e12af440c1</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-2b9eda1c-baa1-4ee7-b79f-8ce8d79f7f8a"> <wsu:Created>2026-02-02T13:15:41Z</wsu:Created> <wsu:Expires>2026-02-02T13:20:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>FilterActivity Created</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>a0f1a1bc-4ea1-44b3-8fe1-ce40ef35c1c0</NewObjectID> <Object xsi:type="FilterActivity"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testNew_filter</CustomerKey> <Name>testNew_filter</Name> <Description /> <FilterActivityID>a0f1a1bc-4ea1-44b3-8fe1-ce40ef35c1c0</FilterActivityID> <FilterDefinitionID>10ef27dd-4be8-4bf6-970a-8acf8e281e55</FilterDefinitionID> <DestinationObjectID>21711373-72c1-ec11-b83b-exclusion</DestinationObjectID> <DestinationTypeID>2</DestinationTypeID> <SourceObjectID>21711373-72c1-ec11-b83b-48df37d1deb7</SourceObjectID> <SourceTypeID>2</SourceTypeID> </Object> </Results> <RequestID>1391248a-ec47-4941-9e84-8272d4d23f8a</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/filterActivity/retrieve-CustomerKey=testExisting_filter-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:37985d19-539c-4205-bb97-26d8fb24f474</wsa:MessageID> <wsa:RelatesTo>urn:uuid:2ccf52c3-4f84-4e4f-93e0-0b657d8eabe0</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-acf74abc-5790-458b-9632-c1f74a7aa0c3"> <wsu:Created>2026-02-02T10:48:38Z</wsu:Created> <wsu:Expires>2026-02-02T10:53:38Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>a60e3780-8b90-40ae-ade4-68b8732e756a</RequestID> <Results xsi:type="FilterActivity"> <PartnerKey xsi:nil="true" /> <ObjectID>f018f237-f7ef-40b0-afc8-39ea2e5dcca4</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/filterDefinition/retrieve-CustomerKey=testExisting_dataFilter-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:ab5dec96-be6e-4900-b0a8-4cd958182307</wsa:MessageID> <wsa:RelatesTo>urn:uuid:4ddb474a-4449-43da-b7f4-a7c2e34b66d9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-6d8a8fea-bf2a-4be2-8265-63f395ddf550"> <wsu:Created>2026-01-30T15:50:29Z</wsu:Created> <wsu:Expires>2026-01-30T15:55:29Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>5b3f20f1-e615-445f-9bd3-ece1d239aa0f</RequestID> <Results xsi:type="FilterDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>10ef27dd-4be8-4bf6-970a-8acf8e281e55</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/folder-deploy/Data Extensions/my/sub/path/subpath.folder-meta.json ================================================ { "Name": "subpath", "Description": "", "ContentType": "dataextension", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/Data Extensions/my/sub/path.folder-meta.json ================================================ { "Name": "path", "Description": "", "ContentType": "dataextension", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/Data Extensions/my/sub.folder-meta.json ================================================ { "Name": "sub", "Description": "", "ContentType": "dataextension", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/Data Extensions/my.folder-meta.json ================================================ { "Name": "my", "Description": "", "ContentType": "dataextension", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/Data Extensions/testExisting_folder.folder-meta.json ================================================ { "Name": "testExisting_folder", "Description": "", "ContentType": "dataextension", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/my automations/my/sub/path/subpath.folder-meta.json ================================================ { "Name": "subpath", "Description": "", "ContentType": "automations", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/my automations/my/sub/path.folder-meta.json ================================================ { "Name": "path", "Description": "", "ContentType": "automations", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/my automations/my/sub.folder-meta.json ================================================ { "Name": "sub", "Description": "", "ContentType": "automations", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy/my automations/my.folder-meta.json ================================================ { "Name": "my", "Description": "", "ContentType": "automations", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy-samepath/Content Builder/testFolder_samePath.folder-meta.json ================================================ { "Name": "testFolder_samePath", "Description": "", "ContentType": "asset", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/folder-deploy-slash/Content Builder/Headers%2FFolders.folder-meta.json ================================================ { "Name": "Headers/Folders", "Description": "", "ContentType": "asset", "IsActive": true, "IsEditable": true, "AllowChildren": true, "_generated": true } ================================================ FILE: test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json ================================================ { "attributeGroupDefinitions": [ { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Email Addresses" }, "definitionKey": "EmailAddresses", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Contact" }, "definitionKey": "Contact", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": false, "canAddRelationships": false, "containsSchemaAttributes": true, "canRemove": false, "canChangeProperties": false, "displayOrder": 0, "requiredRelationships": [ "0e51de3f-31e2-e611-80cc-1402ec7222b4", "1451de3f-31e2-e611-80cc-1402ec7222b4", "9893dc39-31e2-e611-80cc-1402ec7222b4" ], "applicationID": "ce703ed3-e01f-4f5f-900d-76a95b363e29", "canModify": false, "applicationKey": "com.exacttarget.contacts", "attributeGroupIconKey": "People", "fullyQualifiedName": "System Data", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 7, "definitionID": "8f93dc39-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "System Data" }, "definitionKey": "ETSystem", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionName": { "value": "Chat Message Demographics" }, "definitionKey": "ChatMessageDemographics", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionName": { "value": "Chat Message Subscriptions" }, "definitionKey": "ChatMessageSubscriptions", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": true, "canAddRelationships": true, "containsSchemaAttributes": false, "canRemove": false, "canChangeProperties": true, "displayOrder": 1, "requiredRelationships": [ "9a42dcad-ae72-4cde-9937-193e17485ad6", "04ea847d-696d-eb11-b81e-48df37d1df5a" ], "canModify": true, "fullyQualifiedName": "Chat Message Data", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 37, "definitionID": "cae9847d-696d-eb11-b81e-48df37d1df5a", "definitionName": { "value": "Chat Message Data" }, "definitionKey": "ETChatMessage", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Email Demographics" }, "definitionKey": "EmailDemographics", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": false, "canAddRelationships": true, "containsSchemaAttributes": false, "canRemove": false, "canChangeProperties": false, "displayOrder": 2, "requiredRelationships": ["b751de3f-31e2-e611-80cc-1402ec7222b4"], "applicationID": "b2ca1f50-3cc4-4fd7-a3a3-88bf09fb59fa", "canModify": false, "applicationKey": "com.exacttarget.email", "attributeGroupIconKey": "Email", "fullyQualifiedName": "Email Data", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 16, "definitionID": "b451de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Email Data" }, "definitionKey": "ETEmail", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionName": { "value": "GroupConnect LINE Addresses" }, "definitionKey": "GroupConnectLineAddress", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "GroupConnect LINE Demographics" }, "definitionKey": "GroupConnectLineDemographics", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "definitionKey": "GroupConnectLineSubscriptions", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": false, "canAddRelationships": true, "containsSchemaAttributes": false, "canRemove": false, "canChangeProperties": false, "displayOrder": 3, "requiredRelationships": [ "8686d247-3045-ea11-a2e0-1402ec94ec41", "a686d247-3045-ea11-a2e0-1402ec94ec41", "9386d247-3045-ea11-a2e0-1402ec94ec41" ], "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", "canModify": false, "applicationKey": "com.exacttarget.GroupConnect", "attributeGroupIconKey": "Mobile", "fullyQualifiedName": "GroupConnect LINE Data", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 23, "definitionID": "ab51de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "GroupConnect LINE Data" }, "definitionKey": "ETGroupConnectLine", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobileConnect Demographics" }, "definitionKey": "MobileDemographics", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobileConnect Subscriptions" }, "definitionKey": "MobileSubscriptions", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": false, "canAddRelationships": true, "containsSchemaAttributes": false, "canRemove": false, "canChangeProperties": false, "displayOrder": 4, "requiredRelationships": [ "4651de3f-31e2-e611-80cc-1402ec7222b4", "4352de3f-31e2-e611-80cc-1402ec7222b4" ], "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", "canModify": false, "applicationKey": "com.exacttarget.mobileconnect", "attributeGroupIconKey": "Mobile", "fullyQualifiedName": "MobileConnect Data", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 37, "definitionID": "4351de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobileConnect Data" }, "definitionKey": "ETMobileConnect", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobilePush Demographics" }, "definitionKey": "PushDemographics", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobilePush Subscriptions" }, "definitionKey": "PushSubscriptions", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobilePush Tags" }, "definitionKey": "PushTags", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": false, "canAddRelationships": true, "containsSchemaAttributes": false, "canRemove": false, "canChangeProperties": false, "displayOrder": 5, "requiredRelationships": [ "9651de3f-31e2-e611-80cc-1402ec7222b4", "d052de3f-31e2-e611-80cc-1402ec7222b4", "bc52de3f-31e2-e611-80cc-1402ec7222b4" ], "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", "canModify": false, "applicationKey": "com.exacttarget.mobilepush", "attributeGroupIconKey": "Mobile", "fullyQualifiedName": "MobilePush Data", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 65, "definitionID": "9351de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "MobilePush Data" }, "definitionKey": "ETMobilePush", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 1111111, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "definitionKey": "PredictiveIntelProductSessions", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Content Views" }, "definitionKey": "PredictiveIntelContentViews", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Content" }, "definitionKey": "PredictiveIntelContent", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "definitionKey": "PredictiveIntelContentAttribs", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "definitionKey": "PredictiveIntelAbandonedCartEvents", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "definitionKey": "PredictiveIntelAbandonedCartItems", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "definitionKey": "PredictiveIntelSessionEnds", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionName": { "value": "Einstein MC Predictive Scores" }, "definitionKey": "EinsteinMCPredictiveScores", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Scores" }, "definitionKey": "PredictiveIntelScores", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Product Views" }, "definitionKey": "PredictiveIntelProductViews", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Products" }, "definitionKey": "PredictiveIntelProducts", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "definitionKey": "PredictiveIntelProductAttribs", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "definitionKey": "PredictiveIntelProductPurchases", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Profiles" }, "definitionKey": "PredictiveIntelProfiles", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": true, "isHidden": false, "canAddProperties": true, "canAddRelationships": false, "containsSchemaAttributes": false, "canRemove": false, "canChangeProperties": true, "displayOrder": 7, "requiredRelationships": [ "1586d645-31e2-e611-80cc-1402ec7222b4", "2686d645-31e2-e611-80cc-1402ec7222b4", "3586d645-31e2-e611-80cc-1402ec7222b4", "4686d645-31e2-e611-80cc-1402ec7222b4", "5d86d645-31e2-e611-80cc-1402ec7222b4", "6c86d645-31e2-e611-80cc-1402ec7222b4", "7887d645-31e2-e611-80cc-1402ec7222b4", "7d86d645-31e2-e611-80cc-1402ec7222b4", "c80f6472-c416-ec11-b839-48df37d1dc79", "a985d645-31e2-e611-80cc-1402ec7222b4", "ba85d645-31e2-e611-80cc-1402ec7222b4", "cd85d645-31e2-e611-80cc-1402ec7222b4", "0086d645-31e2-e611-80cc-1402ec7222b4", "de85d645-31e2-e611-80cc-1402ec7222b4", "fd85d645-31e2-e611-80cc-1402ec7222b4", "9885d645-31e2-e611-80cc-1402ec7222b4" ], "applicationID": "aed181bc-d7b7-465e-a3dd-9cdfb13943e2", "canModify": false, "applicationKey": "com.sfmc-einstein.Einstein Engagement Scoring", "attributeGroupIconKey": "PredictiveIntel", "fullyQualifiedName": "Predictive Intelligence Data", "attributeGroupType": "Standard", "description": "Attribute Group for Einstein Engagement Scoring", "localizedDescription": { "resourceSetKey": "ContactsMeta.SystemAttributeGroupDescriptions", "resourceValueKey": "ATTR_GROUP_DESC_ETPredictiveIntel", "value": "Attribute Group for Einstein Engagement Scoring" }, "attributeCount": 112, "definitionID": "e152de3f-31e2-e611-80cc-1402ec7222b4", "definitionName": { "value": "Predictive Intelligence Data" }, "definitionKey": "ETPredictiveIntel", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" }, { "mID": 7330928, "objectState": "Created", "attributeSetIdentifiers": [ { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionName": { "value": "testExisting_dataExtensionShared" }, "definitionKey": "testExisting_dataExtensionShared", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "isOwner": true, "isPrimary": false, "isSystemDefined": false, "isHidden": false, "canAddProperties": true, "canAddRelationships": true, "containsSchemaAttributes": false, "canRemove": true, "canChangeProperties": true, "displayOrder": 8, "requiredRelationships": [], "canModify": true, "attributeGroupIconKey": "et-icon-databas", "fullyQualifiedName": "testExisting_attributeGroup", "attributeGroupType": "Standard", "localizedDescription": {}, "attributeCount": 6, "definitionID": "79846c6e-5238-ee11-b85a-48df37d1de8a", "definitionName": { "value": "testExisting_attributeGroup" }, "definitionKey": "testExisting_attributeGroup", "connectingID": { "identifierType": "FullyQualifiedName" }, "namespace": "" } ], "responseContext": { "operationStatus": "OK", "schemaType": "Contacts", "populateInternalProperties": false }, "requestServiceMessageID": "9dac2279-40db-4e67-a862-d6ecbadf109a", "responseDateTime": "2023-07-12T09:17:31.8837381-06:00", "resultMessages": [], "serviceMessageID": "92930c00-cacf-41e1-ba8d-04ad4d903f65" } ================================================ FILE: test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json ================================================ { "setDefinition": [ { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "1386d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Product Sessions.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "1386d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "session_id", "localizedDescription": { "value": "session_id" }, "definitionID": "1086d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "session_id", "definitionName": { "value": "Session ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Product Sessions.Session ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "1086d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "session_id", "storageFieldReferenceID": { "type": "guid", "value": "1ca32e3d-4f4e-4771-8d99-057f8bad3733" }, "valueDefinitionID": "1086d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "session_id", "name": "Session ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_id", "localizedDescription": { "value": "user_id" }, "definitionID": "1286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "User_ID", "definitionName": { "value": "User ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Product Sessions.User ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "1286d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_id", "storageFieldReferenceID": { "type": "guid", "value": "f2e9ddf5-e18d-43db-ad52-cc754c929811" }, "valueDefinitionID": "1286d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "User_ID", "name": "User ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Batch_ID", "localizedDescription": { "value": "Batch_ID" }, "definitionID": "0c86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Batch_ID", "definitionName": { "value": "Batch ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Product Sessions.Batch ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0c86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Batch_ID", "storageFieldReferenceID": { "type": "guid", "value": "fed66cad-7da4-469c-b49c-79e8c82ae37f" }, "valueDefinitionID": "0c86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Batch_ID", "name": "Batch ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "List_ID", "localizedDescription": { "value": "List_ID" }, "definitionID": "0f86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "List_ID", "definitionName": { "value": "List ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Product Sessions.List ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0f86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "List_ID", "storageFieldReferenceID": { "type": "guid", "value": "39471713-05c1-43d5-ac0f-9ecb66bae213" }, "valueDefinitionID": "0f86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "List_ID", "name": "List ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Job_ID", "localizedDescription": { "value": "Job_ID" }, "definitionID": "0d86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Job_ID", "definitionName": { "value": "Job ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Product Sessions.Job ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0d86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Job_ID", "storageFieldReferenceID": { "type": "guid", "value": "5c73cf1c-8fbd-4275-bca1-5a232c5ebb35" }, "valueDefinitionID": "0d86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Job_ID", "name": "Job ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Landing_URL_ID", "localizedDescription": { "value": "Landing_URL_ID" }, "definitionID": "0e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Landing_URL_ID", "definitionName": { "value": "Landing URL ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Predictive Intelligence Product Sessions.Landing URL ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0e86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Landing_URL_ID", "storageFieldReferenceID": { "type": "guid", "value": "60fd37ce-3306-4197-a0e2-7c1b51b46d3a" }, "valueDefinitionID": "0e86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Landing_URL_ID", "name": "Landing URL ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Subscriber_ID", "localizedDescription": { "value": "Subscriber_ID" }, "definitionID": "1186d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Subscriber_ID", "definitionName": { "value": "Subscriber_ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "Predictive Intelligence Product Sessions.Subscriber_ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "1186d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 8, "parentDefinition": { "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductSessions", "definitionName": { "value": "Predictive Intelligence Product Sessions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Subscriber_ID", "storageFieldReferenceID": { "type": "guid", "value": "f239f3c3-3ecc-4ec4-a4c9-de258fdefdea" }, "valueDefinitionID": "1186d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Subscriber_ID", "name": "Subscriber_ID", "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "setDefinitionName": { "value": "Predictive Intelligence Product Sessions" }, "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Product Sessions", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "PI_SESSIONS", "storageObjectIDs": ["0286d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "dd52de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductSessions", "name": "Predictive Intelligence Product Sessions" }, { "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailAddresses", "definitionName": { "value": "Email Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "8f93dc39-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "4" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "1451de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "1051de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "1251de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ListID", "definitionName": { "value": "List ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 0, "fullyQualifiedName": "Email Addresses.List ID", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 0, "parentDefinition": { "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailAddresses", "definitionName": { "value": "Email Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ListID", "valueDefinitionID": "1251de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ListID", "name": "List ID", "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailAddresses", "setDefinitionName": { "value": "Email Addresses" }, "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "1351de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MemberID", "definitionName": { "value": "Member ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 0, "fullyQualifiedName": "Email Addresses.Member ID", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 0, "parentDefinition": { "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailAddresses", "definitionName": { "value": "Email Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "MemberID_", "valueDefinitionID": "1351de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "MemberID", "name": "Member ID", "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailAddresses", "setDefinitionName": { "value": "Email Addresses" }, "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "customerDataID": 4, "dataSourceID": 2, "dataSourceName": {}, "dataType": "EmailAddress", "description": "", "localizedDescription": { "value": "" }, "definitionID": "1151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailAddress", "definitionName": { "value": "Email Address" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Email Addresses.Email Address", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailAddresses", "definitionName": { "value": "Email Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "EmailAddr_", "valueDefinitionID": "1151de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "EmailAddress", "name": "Email Address", "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailAddresses", "setDefinitionName": { "value": "Email Addresses" }, "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Boolean", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b951de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "HTMLEnabled", "definitionName": { "value": "HTML Enabled" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Email Addresses.HTML Enabled", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "ordinal": 2, "parentDefinition": { "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailAddresses", "definitionName": { "value": "Email Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "IsHTMLEnabled", "valueDefinitionID": "b951de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "HTMLEnabled", "name": "HTML Enabled", "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailAddresses", "setDefinitionName": { "value": "Email Addresses" }, "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "b2ca1f50-3cc4-4fd7-a3a3-88bf09fb59fa", "applicationKey": "com.exacttarget.email", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "localizedDescription": {}, "fullyQualifiedName": "Email Addresses", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isSystemDefined": true, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageObjectIDs": [ "92492fc1-7a08-4c96-8536-0344719009e1", "c336765a-f24f-49b2-8a1f-b54f903def2a" ], "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailAddresses", "name": "Email Addresses" }, { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "1e86d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "1f86d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "3086d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "3586d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "2e86d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "2486d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Content Views.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "2486d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "setDefinitionName": { "value": "Predictive Intelligence Content Views" }, "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "content_id", "localizedDescription": { "value": "content_id" }, "definitionID": "1f86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Content_ID", "definitionName": { "value": "Content ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Content Views.Content ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "1f86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "content_id", "storageFieldReferenceID": { "type": "guid", "value": "1abf7b9d-1222-469f-9df9-7835829ec41f" }, "valueDefinitionID": "1f86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Content_ID", "name": "Content ID", "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "setDefinitionName": { "value": "Predictive Intelligence Content Views" }, "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_Id", "localizedDescription": { "value": "user_Id" }, "definitionID": "2386d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "User_ID", "definitionName": { "value": "User ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Content Views.User ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2386d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_Id", "storageFieldReferenceID": { "type": "guid", "value": "a6c60012-6673-4402-8262-c6f06e1b0d13" }, "valueDefinitionID": "2386d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "User_ID", "name": "User ID", "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "setDefinitionName": { "value": "Predictive Intelligence Content Views" }, "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "session_id", "localizedDescription": { "value": "session_id" }, "definitionID": "2186d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Session_ID", "definitionName": { "value": "Session ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Content Views.Session ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2186d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "session_id", "storageFieldReferenceID": { "type": "guid", "value": "78820841-1579-42dd-8300-3cfe4eec96cc" }, "valueDefinitionID": "2186d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Session_ID", "name": "Session ID", "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "setDefinitionName": { "value": "Predictive Intelligence Content Views" }, "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Search", "localizedDescription": { "value": "Search" }, "definitionID": "2086d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Search", "definitionName": { "value": "Search" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Content Views.Search", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2086d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Search", "storageFieldReferenceID": { "type": "guid", "value": "f1ecc397-6be7-4a53-8792-0fdbaff63505" }, "valueDefinitionID": "2086d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Search", "name": "Search", "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "setDefinitionName": { "value": "Predictive Intelligence Content Views" }, "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "description": "Timestamp", "localizedDescription": { "value": "Timestamp" }, "definitionID": "2286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Timestamp", "definitionName": { "value": "Timestamp" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Content Views.Timestamp", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2286d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentViews", "definitionName": { "value": "Predictive Intelligence Content Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Timestamp", "storageFieldReferenceID": { "type": "guid", "value": "e5c8ef5d-f2df-464d-b0ba-aa06536ac934" }, "valueDefinitionID": "2286d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Timestamp", "name": "Timestamp", "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "setDefinitionName": { "value": "Predictive Intelligence Content Views" }, "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Content Views", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "DataExtension", "storageName": "PI_CONTENTVIEWS", "storageObjectIDs": ["1786d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "da52de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentViews", "name": "Predictive Intelligence Content Views" }, { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "4351de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "2" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "2f51de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "4651de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "3651de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "3452de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "4352de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "3152de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "2c51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CarrierID", "definitionName": { "value": "Carrier ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "MobileConnect Demographics.Carrier ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2c51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 1, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CarrierID", "storageFieldReferenceID": { "type": "guid", "value": "3fdc8842-cc0f-407c-a3ec-930d7a027d1d" }, "valueDefinitionID": "2c51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CarrierID", "name": "Carrier ID", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "2d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Channel", "definitionName": { "value": "Channel" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "MobileConnect Demographics.Channel", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2d51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Channel", "storageFieldReferenceID": { "type": "guid", "value": "ef36ded9-67b2-4daf-899f-6862af8e5ee7" }, "valueDefinitionID": "2d51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Channel", "name": "Channel", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "2e51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "City", "definitionName": { "value": "City" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "MobileConnect Demographics.City", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2e51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_City", "storageFieldReferenceID": { "type": "guid", "value": "be7b4554-bf03-4a80-9101-3e396b2e345f" }, "valueDefinitionID": "2e51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "City", "name": "City", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "2f51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ContactID", "definitionName": { "value": "Contact ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "MobileConnect Demographics.Contact ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2f51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ContactID", "storageFieldReferenceID": { "type": "guid", "value": "b0e31883-cae8-4bc5-aa24-88565d375a18" }, "valueDefinitionID": "2f51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ContactID", "name": "Contact ID", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "MobileConnect Demographics.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3151de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedBy", "storageFieldReferenceID": { "type": "guid", "value": "1671a32a-8eb0-4dc5-b30d-8ad16e55a601" }, "valueDefinitionID": "3151de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3251de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "MobileConnect Demographics.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3251de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "de543ca5-5920-4309-adb9-33472144defe" }, "valueDefinitionID": "3251de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3351de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "FirstName", "definitionName": { "value": "First Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "MobileConnect Demographics.First Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3351de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 9, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_FirstName", "storageFieldReferenceID": { "type": "guid", "value": "125f7c91-2f11-44bd-9687-f22cf2461496" }, "valueDefinitionID": "3351de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "FirstName", "name": "First Name", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "defaultValue": "False", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3451de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "IsHonorDST", "definitionName": { "value": "Is Honor DST" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "MobileConnect Demographics.Is Honor DST", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3451de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 10, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_IsHonorDST", "storageFieldReferenceID": { "type": "guid", "value": "17abe00a-4306-43c5-b27f-a81f015d6dfb" }, "valueDefinitionID": "3451de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "IsHonorDST", "name": "Is Honor DST", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "LastName", "definitionName": { "value": "Last Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "MobileConnect Demographics.Last Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3551de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 11, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_LastName", "storageFieldReferenceID": { "type": "guid", "value": "e31f18f4-5422-410b-adcc-1b60f61cce5f" }, "valueDefinitionID": "3551de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "LastName", "name": "Last Name", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CountryCode", "definitionName": { "value": "Locale" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "MobileConnect Demographics.Locale", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 2, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3051de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 12, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CountryCode", "storageFieldReferenceID": { "type": "guid", "value": "4b5fda70-47cb-4f4b-8ba6-f5cac53ee344" }, "valueDefinitionID": "3051de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CountryCode", "name": "Locale", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "2ddd5f89-bca1-ed11-b852-48df37d1df5b", "definitionKey": "MobileID", "definitionName": { "value": "Mobile ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "MobileConnect Demographics.Mobile ID", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 13, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_MobileId", "valueDefinitionID": "2ddd5f89-bca1-ed11-b852-48df37d1df5b", "valueDefinitionKey": "MobileID", "name": "Mobile ID", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "customerDataID": 5, "dataSourceID": 3, "dataSourceName": {}, "dataType": "Phone", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3651de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileNumber", "definitionName": { "value": "Mobile Number" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "MobileConnect Demographics.Mobile Number", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 15, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3651de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 14, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_MobileNumber", "storageFieldReferenceID": { "type": "guid", "value": "e31a7e3b-e943-440e-9be6-77224a4928fe" }, "valueDefinitionID": "3651de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "MobileNumber", "name": "Mobile Number", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3751de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "MobileConnect Demographics.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3751de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 15, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedBy", "storageFieldReferenceID": { "type": "guid", "value": "a9be58ef-884d-44f4-9926-d73ebe587847" }, "valueDefinitionID": "3751de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3851de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 16, "fullyQualifiedName": "MobileConnect Demographics.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3851de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 16, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedDate", "storageFieldReferenceID": { "type": "guid", "value": "216659c1-9512-47de-a9ee-822f48148514" }, "valueDefinitionID": "3851de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3951de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Priority", "definitionName": { "value": "Priority" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 17, "fullyQualifiedName": "MobileConnect Demographics.Priority", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3951de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 17, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Priority", "storageFieldReferenceID": { "type": "guid", "value": "71153ee5-a33f-4cf6-a963-0c3a893d9348" }, "valueDefinitionID": "3951de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Priority", "name": "Priority", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3a51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Source", "definitionName": { "value": "Source" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 18, "fullyQualifiedName": "MobileConnect Demographics.Source", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3a51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 18, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 5, "storageName": "_Source", "storageFieldReferenceID": { "type": "guid", "value": "f6bafdfb-86bf-45e8-9b76-b878c904d6c5" }, "valueDefinitionID": "3a51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Source", "name": "Source", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SourceObjectID", "definitionName": { "value": "Source Object ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 19, "fullyQualifiedName": "MobileConnect Demographics.Source Object ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3b51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 19, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SourceObjectId", "storageFieldReferenceID": { "type": "guid", "value": "c67a7922-44e5-4c4b-a4c8-2ac3550a5f07" }, "valueDefinitionID": "3b51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SourceObjectID", "name": "Source Object ID", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 4, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "67ace0e3-8563-e811-80d4-1402ec721f75", "definitionKey": "SFContactID", "definitionName": { "value": "SFContactID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 19, "fullyQualifiedName": "MobileConnect Demographics.SFContactID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "67ace0e3-8563-e811-80d4-1402ec721f75" }, "ordinal": 19, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SFContactID", "storageFieldReferenceID": { "type": "guid", "value": "ce5a90ea-88eb-4683-9a1a-5c776b5763ce" }, "valueDefinitionID": "67ace0e3-8563-e811-80d4-1402ec721f75", "valueDefinitionKey": "SFContactID", "name": "SFContactID", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3c51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "State", "definitionName": { "value": "State" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 20, "fullyQualifiedName": "MobileConnect Demographics.State", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3c51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 20, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_State", "storageFieldReferenceID": { "type": "guid", "value": "c0ea1fac-d939-4dde-b45a-16586f661924" }, "valueDefinitionID": "3c51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "State", "name": "State", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Status", "definitionName": { "value": "Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 21, "fullyQualifiedName": "MobileConnect Demographics.Status", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3d51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 21, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 6, "storageName": "_Status", "storageFieldReferenceID": { "type": "guid", "value": "fafff407-c055-411c-81ec-78907f5dbd58" }, "valueDefinitionID": "3d51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Status", "name": "Status", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3e51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "UTCOffset", "definitionName": { "value": "UTC Offset" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 22, "fullyQualifiedName": "MobileConnect Demographics.UTC Offset", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 4, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3e51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 22, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "_UTCOffset", "storageFieldReferenceID": { "type": "guid", "value": "84d29656-a348-43c2-ac2f-8c7ec5b18a3e" }, "valueDefinitionID": "3e51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "UTCOffset", "name": "UTC Offset", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3f51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ZipCode", "definitionName": { "value": "Zip Code" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 23, "fullyQualifiedName": "MobileConnect Demographics.Zip Code", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3f51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 23, "parentDefinition": { "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileDemographics", "definitionName": { "value": "MobileConnect Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ZipCode", "storageFieldReferenceID": { "type": "guid", "value": "11ce9d05-a1e3-47ba-9077-11097e0b4c8d" }, "valueDefinitionID": "3f51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ZipCode", "name": "Zip Code", "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "setDefinitionName": { "value": "MobileConnect Demographics" }, "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", "applicationKey": "com.exacttarget.mobileconnect", "attributeCount": 0, "canAddValues": true, "canChangeValues": true, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "MobileConnect Demographics", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": true, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 2, "sendAttributeStorageName": "_ContactID", "sendContactKeyStorageName": "_SubscriberID", "storageLogicalType": "MobileAttributes", "storageName": "_MobileAddress", "storageObjectIDs": ["1651de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "7693dc39-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileDemographics", "name": "MobileConnect Demographics" }, { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContent", "definitionName": { "value": "Predictive Intelligence Content" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "2e86d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "3086d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "4286d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "4686d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "3e86d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3386d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Content.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContent", "definitionName": { "value": "Predictive Intelligence Content" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "3386d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContent", "setDefinitionName": { "value": "Predictive Intelligence Content" }, "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "content_id", "localizedDescription": { "value": "content_id" }, "definitionID": "3086d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Content_ID", "definitionName": { "value": "Content ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Content.Content ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3086d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContent", "definitionName": { "value": "Predictive Intelligence Content" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "content_id", "storageFieldReferenceID": { "type": "guid", "value": "9fd67d4d-cae5-4230-8cf1-f19cd230a233" }, "valueDefinitionID": "3086d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Content_ID", "name": "Content ID", "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContent", "setDefinitionName": { "value": "Predictive Intelligence Content" }, "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Boolean", "description": "availability", "localizedDescription": { "value": "availability" }, "definitionID": "2f86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Availability", "definitionName": { "value": "Availability" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Content.Availability", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "2f86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContent", "definitionName": { "value": "Predictive Intelligence Content" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "availability", "storageFieldReferenceID": { "type": "guid", "value": "d32b9706-78a0-40fd-aae5-e345b1f217a6" }, "valueDefinitionID": "2f86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Availability", "name": "Availability", "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContent", "setDefinitionName": { "value": "Predictive Intelligence Content" }, "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "title", "localizedDescription": { "value": "title" }, "definitionID": "3186d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Title", "definitionName": { "value": "Title" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Content.Title", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3186d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContent", "definitionName": { "value": "Predictive Intelligence Content" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "title", "storageFieldReferenceID": { "type": "guid", "value": "93497a91-7e2d-4c5f-8546-fd035fea3e92" }, "valueDefinitionID": "3186d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Title", "name": "Title", "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContent", "setDefinitionName": { "value": "Predictive Intelligence Content" }, "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "uuid", "localizedDescription": { "value": "uuid" }, "definitionID": "3286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "UUID", "definitionName": { "value": "UUID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Content.UUID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3286d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContent", "definitionName": { "value": "Predictive Intelligence Content" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "uuid", "storageFieldReferenceID": { "type": "guid", "value": "d42586c8-bb5b-46a1-ac88-32fc232dbcc7" }, "valueDefinitionID": "3286d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "UUID", "name": "UUID", "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContent", "setDefinitionName": { "value": "Predictive Intelligence Content" }, "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Content", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "DataExtension", "storageName": "PI_CONTENT", "storageObjectIDs": ["2886d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "db52de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContent", "name": "Predictive Intelligence Content" }, { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "MobileConnect Subscriptions.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 1, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedBy", "storageFieldReferenceID": { "type": "guid", "value": "a64a3ed9-b8fd-46cc-a10b-1d5fdf074ce6" }, "valueDefinitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "MobileConnect Subscriptions.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "dfc3f6fb-a250-4ef8-93ed-bb079ced468d" }, "valueDefinitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SubscriptionDefinitionID", "definitionName": { "value": "Keyword" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "MobileConnect Subscriptions.Keyword", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 7, "storageName": "_SubscriptionDefinitionID", "storageFieldReferenceID": { "type": "guid", "value": "c13ab46d-6e65-475a-990d-291bd43e5063" }, "valueDefinitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SubscriptionDefinitionID", "name": "Keyword", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Phone", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileNumber", "definitionName": { "value": "Mobile Number" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "MobileConnect Subscriptions.Mobile Number", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 15, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_MobileNumber", "storageFieldReferenceID": { "type": "guid", "value": "ead8a6d2-bc6c-4768-a6e3-c3cc749bfc1d" }, "valueDefinitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "MobileNumber", "name": "Mobile Number", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "53dd5f89-bca1-ed11-b852-48df37d1df5b", "definitionKey": "MobileSubscriptionID", "definitionName": { "value": "Mobile Subscription ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "MobileConnect Subscriptions.Mobile Subscription ID", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 5, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_MobileSubscriptionID", "valueDefinitionID": "53dd5f89-bca1-ed11-b852-48df37d1df5b", "valueDefinitionKey": "MobileSubscriptionID", "name": "Mobile Subscription ID", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "MobileConnect Subscriptions.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedBy", "storageFieldReferenceID": { "type": "guid", "value": "30d7ec39-85d1-46dc-9888-771f11ffe10d" }, "valueDefinitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "MobileConnect Subscriptions.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedDate", "storageFieldReferenceID": { "type": "guid", "value": "b68155cc-e483-4949-82f9-fb47cbd59764" }, "valueDefinitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInDate", "definitionName": { "value": "Opt In Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 8, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptInDate", "storageFieldReferenceID": { "type": "guid", "value": "8da557ee-7ba7-44f4-99ba-0681cbeb1ba1" }, "valueDefinitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInDate", "name": "Opt In Date", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInMethodID", "definitionName": { "value": "Opt In Method" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Method", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 9, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 2, "storageName": "_OptInMethodID", "storageFieldReferenceID": { "type": "guid", "value": "da2713ab-a802-4cd6-9e05-0a7444d62388" }, "valueDefinitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInMethodID", "name": "Opt In Method", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInStatusID", "definitionName": { "value": "Opt In Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Status", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 10, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 1, "storageName": "_OptInStatusID", "storageFieldReferenceID": { "type": "guid", "value": "c733b80d-2ed5-4fb6-94a3-9c996cbae558" }, "valueDefinitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInStatusID", "name": "Opt In Status", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutDate", "definitionName": { "value": "Opt Out Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 11, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptOutDate", "storageFieldReferenceID": { "type": "guid", "value": "27c3ccec-47ad-4578-9051-a41f85178049" }, "valueDefinitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutDate", "name": "Opt Out Date", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutMethodID", "definitionName": { "value": "Opt Out Method" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Method", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 12, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 4, "storageName": "_OptOutMethodID", "storageFieldReferenceID": { "type": "guid", "value": "089b96fc-bfc6-402e-a481-1e18d3e18a8d" }, "valueDefinitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutMethodID", "name": "Opt Out Method", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutStatusID", "definitionName": { "value": "Opt Out Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Status", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 13, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 3, "storageName": "_OptOutStatusID", "storageFieldReferenceID": { "type": "guid", "value": "67194503-acd8-4c1c-b042-9dfb3f3ebd44" }, "valueDefinitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutStatusID", "name": "Opt Out Status", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Source", "definitionName": { "value": "Source" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "MobileConnect Subscriptions.Source", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 14, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 5, "storageName": "_Source", "storageFieldReferenceID": { "type": "guid", "value": "2e903257-43e8-4a7b-8ed4-757ca772ddbb" }, "valueDefinitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Source", "name": "Source", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SourceObjectID", "definitionName": { "value": "Source Object ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "MobileConnect Subscriptions.Source Object ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 15, "parentDefinition": { "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "MobileSubscriptions", "definitionName": { "value": "MobileConnect Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SourceObjectId", "storageFieldReferenceID": { "type": "guid", "value": "1d4f26f5-ec91-46de-9fc1-d819832f07e7" }, "valueDefinitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SourceObjectID", "name": "Source Object ID", "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "setDefinitionName": { "value": "MobileConnect Subscriptions" }, "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", "applicationKey": "com.exacttarget.mobileconnect", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "MobileConnect Subscriptions", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "_MobileSubscription", "storageObjectIDs": ["2252de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "7793dc39-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "MobileSubscriptions", "name": "MobileConnect Subscriptions" }, { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "4486d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Content Attributes.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "4486d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "setDefinitionName": { "value": "Predictive Intelligence Content Attributes" }, "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "content_id", "localizedDescription": { "value": "content_id" }, "definitionID": "4286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Content_ID", "definitionName": { "value": "Content ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Content Attributes.Content ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "4286d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "content_id", "storageFieldReferenceID": { "type": "guid", "value": "d1abd045-4670-41f2-a368-9e0a6f732146" }, "valueDefinitionID": "4286d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Content_ID", "name": "Content ID", "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "setDefinitionName": { "value": "Predictive Intelligence Content Attributes" }, "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "AttribName", "localizedDescription": { "value": "AttribName" }, "definitionID": "3f86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_Name", "definitionName": { "value": "Attribute Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Content Attributes.Attribute Name", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "3f86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "AttribName", "storageFieldReferenceID": { "type": "guid", "value": "a55251d7-c1c5-49b3-bdc1-8ebdbf7cb517" }, "valueDefinitionID": "3f86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_Name", "name": "Attribute Name", "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "setDefinitionName": { "value": "Predictive Intelligence Content Attributes" }, "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "AttribValue", "localizedDescription": { "value": "AttribValue" }, "definitionID": "4186d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_Value", "definitionName": { "value": "Attribute Value" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Content Attributes.Attribute Value", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "4186d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "AttribValue", "storageFieldReferenceID": { "type": "guid", "value": "1742dd68-39af-4da9-ace4-0ad50ae08f05" }, "valueDefinitionID": "4186d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_Value", "name": "Attribute Value", "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "setDefinitionName": { "value": "Predictive Intelligence Content Attributes" }, "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "description": "updated_at", "localizedDescription": { "value": "updated_at" }, "definitionID": "4386d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Updated_At", "definitionName": { "value": "Updated At" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Content Attributes.Updated At", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "4386d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "updated_at", "storageFieldReferenceID": { "type": "guid", "value": "4ad58eb4-5e13-4064-ae43-71ab9786be00" }, "valueDefinitionID": "4386d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Updated_At", "name": "Updated At", "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "setDefinitionName": { "value": "Predictive Intelligence Content Attributes" }, "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Number", "description": "attributeValueIndex", "localizedDescription": { "value": "attributeValueIndex" }, "definitionID": "4086d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_Value_Index", "definitionName": { "value": "Attribute Value Index" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Content Attributes.Attribute Value Index", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "4086d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelContentAttribs", "definitionName": { "value": "Predictive Intelligence Content Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "attributeValueIndex", "storageFieldReferenceID": { "type": "guid", "value": "3635848d-5e04-4fed-95ed-d487202a80b8" }, "valueDefinitionID": "4086d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_Value_Index", "name": "Attribute Value Index", "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "setDefinitionName": { "value": "Predictive Intelligence Content Attributes" }, "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Content Attributes", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "PI_CONTENTATTRIBS", "storageObjectIDs": ["3786d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "dc52de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelContentAttribs", "name": "Predictive Intelligence Content Attributes" }, { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "5286d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "5386d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "6686d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "6c86d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "6586d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "5b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Custom_Object_Key", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "5b86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Custom_Object_Key", "name": "Custom Object Key", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_id", "localizedDescription": { "value": "user_id" }, "definitionID": "5a86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "user_id", "definitionName": { "value": "user_id" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.user_id", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5a86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_id", "storageFieldReferenceID": { "type": "guid", "value": "e6f01b13-78b2-4cf7-956a-7a9a5db31a82" }, "valueDefinitionID": "5a86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "user_id", "name": "user_id", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "cart_id", "localizedDescription": { "value": "cart_id" }, "definitionID": "5386d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Cart_ID", "definitionName": { "value": "Cart ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Cart ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5386d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "cart_id", "storageFieldReferenceID": { "type": "guid", "value": "3f7d9be8-3af9-425b-9537-442a9e389582" }, "valueDefinitionID": "5386d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Cart_ID", "name": "Cart ID", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "contact_key", "localizedDescription": { "value": "contact_key" }, "definitionID": "5586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Contact_Key", "definitionName": { "value": "Contact Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Contact Key", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5586d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "contact_key", "storageFieldReferenceID": { "type": "guid", "value": "7a8eb4a3-5270-4e28-9562-96067a13a6fd" }, "valueDefinitionID": "5586d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Contact_Key", "name": "Contact Key", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "currency_type", "localizedDescription": { "value": "currency_type" }, "definitionID": "5686d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Currency_Type", "definitionName": { "value": "Currency Type" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Currency Type", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5686d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "currency_type", "storageFieldReferenceID": { "type": "guid", "value": "32d910c3-7e8e-4cf6-af31-596b395246f0" }, "valueDefinitionID": "5686d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Currency_Type", "name": "Currency Type", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Number", "description": "no_items_cart", "localizedDescription": { "value": "no_items_cart" }, "definitionID": "5886d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "No_Items_Cart", "definitionName": { "value": "No Items Cart" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.No Items Cart", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5886d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "no_items_cart", "storageFieldReferenceID": { "type": "guid", "value": "74f890d4-eb4b-46c1-9cd5-f2f89702825d" }, "valueDefinitionID": "5886d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "No_Items_Cart", "name": "No Items Cart", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Decimal", "description": "cart_value", "localizedDescription": { "value": "cart_value" }, "definitionID": "5486d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Cart_Value", "definitionName": { "value": "Cart Value" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Cart Value", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5486d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "cart_value", "storageFieldReferenceID": { "type": "guid", "value": "dc3238a5-1546-47b1-95ac-cfebae4bb4b6" }, "valueDefinitionID": "5486d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Cart_Value", "name": "Cart Value", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "defaultValue": "getdate()", "description": "timestamp", "localizedDescription": { "value": "timestamp" }, "definitionID": "5986d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Time_Stamp", "definitionName": { "value": "Time Stamp" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Time Stamp", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5986d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 8, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "timestamp", "storageFieldReferenceID": { "type": "guid", "value": "e8051d08-f6e2-492b-9476-db03d0b4e71b" }, "valueDefinitionID": "5986d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Time_Stamp", "name": "Time Stamp", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "email_address", "localizedDescription": { "value": "email_address" }, "definitionID": "5786d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "email_address", "definitionName": { "value": "email_address" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.email_address", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "5786d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 9, "parentDefinition": { "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartEvents", "definitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "email_address", "storageFieldReferenceID": { "type": "guid", "value": "1a242f2d-4161-4713-b7b1-6426f26f5157" }, "valueDefinitionID": "5786d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "email_address", "name": "email_address", "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartEvents" }, "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "DataExtension", "storageName": "PI_ABANDONED_CART_EVENT", "storageObjectIDs": ["4886d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "df52de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", "name": "Predictive Intelligence AbandonedCartEvents" }, { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartItems", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "6586d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "6686d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "6686d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "7887d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "6586d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "6a86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Custom_Object_Key", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartItems", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "6a86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Custom_Object_Key", "name": "Custom Object Key", "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartItems", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "sku", "localizedDescription": { "value": "sku" }, "definitionID": "6986d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "sku", "definitionName": { "value": "sku" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.sku", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "6986d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartItems", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "sku", "storageFieldReferenceID": { "type": "guid", "value": "85feb2dd-3ea4-4e33-93ca-a0b2e129342f" }, "valueDefinitionID": "6986d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "sku", "name": "sku", "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartItems", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "cart_id", "localizedDescription": { "value": "cart_id" }, "definitionID": "6686d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "cart_id", "definitionName": { "value": "Cart ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Cart ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "6686d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartItems", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "cart_id", "storageFieldReferenceID": { "type": "guid", "value": "686a5045-b1b9-497f-9226-9e43b5b09906" }, "valueDefinitionID": "6686d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "cart_id", "name": "Cart ID", "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartItems", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Decimal", "description": "price", "localizedDescription": { "value": "price" }, "definitionID": "6786d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Price", "definitionName": { "value": "Price" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Price", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "6786d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartItems", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "price", "storageFieldReferenceID": { "type": "guid", "value": "9a62ef64-4993-4876-a16c-9786eae6fd53" }, "valueDefinitionID": "6786d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Price", "name": "Price", "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartItems", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Number", "description": "quantity", "localizedDescription": { "value": "quantity" }, "definitionID": "6886d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Quantity", "definitionName": { "value": "Quantity" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Quantity", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "6886d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelAbandonedCartItems", "definitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "quantity", "storageFieldReferenceID": { "type": "guid", "value": "20d85be0-e56d-4888-b66e-bb8b6466d07c" }, "valueDefinitionID": "6886d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Quantity", "name": "Quantity", "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartItems", "setDefinitionName": { "value": "Predictive Intelligence AbandonedCartItems" }, "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "DataExtension", "storageName": "PI_ABANDONED_CART_ITEMS", "storageObjectIDs": ["5f86d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "e052de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelAbandonedCartItems", "name": "Predictive Intelligence AbandonedCartItems" }, { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "9351de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "2" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "7351de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "9651de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "b452de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } }, { "leftAttributeID": "7751de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "b552de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "bc52de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "b352de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "c752de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } }, { "leftAttributeID": "7751de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "ca52de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "d052de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "c652de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "6e51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Alias", "definitionName": { "value": "Alias" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "MobilePush Demographics.Alias", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "6e51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 1, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Alias", "storageFieldReferenceID": { "type": "guid", "value": "dcef58d9-dcaa-4a68-9ecf-6c663a57fb33" }, "valueDefinitionID": "6e51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Alias", "name": "Alias", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "customerDataID": 7, "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushAppID", "definitionName": { "value": "Application" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "MobilePush Demographics.Application", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 38, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "6f51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 11, "storageName": "_APID", "storageFieldReferenceID": { "type": "guid", "value": "4e82734e-ff8a-4868-a786-20e9596a94d2" }, "valueDefinitionID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PushAppID", "name": "Application", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Badge", "definitionName": { "value": "Badge" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "MobilePush Demographics.Badge", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7051de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Badge", "storageFieldReferenceID": { "type": "guid", "value": "ae73cf07-6b58-4ae4-a75e-ccd1d4bdb98f" }, "valueDefinitionID": "7051de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Badge", "name": "Badge", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Channel", "definitionName": { "value": "Channel" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "MobilePush Demographics.Channel", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7151de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Channel", "storageFieldReferenceID": { "type": "guid", "value": "84490d74-3c83-46b1-8a0b-b073dc45c208" }, "valueDefinitionID": "7151de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Channel", "name": "Channel", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7251de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "City", "definitionName": { "value": "City" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "MobilePush Demographics.City", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7251de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_City", "storageFieldReferenceID": { "type": "guid", "value": "905b7a96-ba4e-4265-a271-6b8d32fdf56e" }, "valueDefinitionID": "7251de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "City", "name": "City", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7351de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ContactID", "definitionName": { "value": "Contact ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "MobilePush Demographics.Contact ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7351de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ContactID", "storageFieldReferenceID": { "type": "guid", "value": "f5c616a4-6ba4-4c3f-a55b-85d12dd41932" }, "valueDefinitionID": "7351de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ContactID", "name": "Contact ID", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7451de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "MobilePush Demographics.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7451de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedBy", "storageFieldReferenceID": { "type": "guid", "value": "bf010c22-fd43-4303-a732-aff2510133f8" }, "valueDefinitionID": "7451de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "MobilePush Demographics.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7551de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 8, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "1b450c10-bd4e-448e-ae6f-583ac616cc46" }, "valueDefinitionID": "7551de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "MobilePush Demographics.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 9, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "9151de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7651de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Device", "definitionName": { "value": "Device" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "MobilePush Demographics.Device", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7651de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 10, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Device", "storageFieldReferenceID": { "type": "guid", "value": "1aa7b10f-f32a-4620-af79-4210aeacf996" }, "valueDefinitionID": "7651de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Device", "name": "Device", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "customerDataID": 6, "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7751de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDeviceID", "definitionName": { "value": "Device ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "MobilePush Demographics.Device ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7751de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 11, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_DeviceID", "storageFieldReferenceID": { "type": "guid", "value": "9d8db1d4-c00e-49bc-98d9-e30d2e3ed7cf" }, "valueDefinitionID": "7751de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PushDeviceID", "name": "Device ID", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7851de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "DeviceType", "definitionName": { "value": "Device Type" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "MobilePush Demographics.Device Type", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7851de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 12, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_DeviceType", "storageFieldReferenceID": { "type": "guid", "value": "75f38dcd-559f-4663-8e84-a5f85abc3e0a" }, "valueDefinitionID": "7851de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "DeviceType", "name": "Device Type", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7951de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "FirstName", "definitionName": { "value": "First Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "MobilePush Demographics.First Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7951de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 13, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_FirstName", "storageFieldReferenceID": { "type": "guid", "value": "cf0e8f08-bba3-4ca3-b05c-e1360897f0f6" }, "valueDefinitionID": "7951de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "FirstName", "name": "First Name", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7a51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "HardwareID", "definitionName": { "value": "Hardware ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "MobilePush Demographics.Hardware ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7a51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 14, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_HardwareId", "storageFieldReferenceID": { "type": "guid", "value": "a7c7ac11-c93d-4512-ae1b-25e9debbdddc" }, "valueDefinitionID": "7a51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "HardwareID", "name": "Hardware ID", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "defaultValue": "False", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "IsHonorDST", "definitionName": { "value": "Is Honor DST" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "MobilePush Demographics.Is Honor DST", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7b51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 15, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_IsHonorDST", "storageFieldReferenceID": { "type": "guid", "value": "e5d1a20d-ec5a-40a2-a474-64513204cbac" }, "valueDefinitionID": "7b51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "IsHonorDST", "name": "Is Honor DST", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7c51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "LastName", "definitionName": { "value": "Last Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 16, "fullyQualifiedName": "MobilePush Demographics.Last Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7c51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 16, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_LastName", "storageFieldReferenceID": { "type": "guid", "value": "92c01cad-907d-48c0-ac6a-691c12d62358" }, "valueDefinitionID": "7c51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "LastName", "name": "Last Name", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "LocationEnabled", "definitionName": { "value": "Location Enabled" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 17, "fullyQualifiedName": "MobilePush Demographics.Location Enabled", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7d51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 17, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_LocationEnabled", "storageFieldReferenceID": { "type": "guid", "value": "30b5144d-9b73-4804-b17b-fbf4d2d03bfe" }, "valueDefinitionID": "7d51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "LocationEnabled", "name": "Location Enabled", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7e51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 18, "fullyQualifiedName": "MobilePush Demographics.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7e51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 18, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedBy", "storageFieldReferenceID": { "type": "guid", "value": "46975e48-0dbb-4ec4-91e9-9823aa2a5d0a" }, "valueDefinitionID": "7e51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7f51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 19, "fullyQualifiedName": "MobilePush Demographics.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7f51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 19, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedDate", "storageFieldReferenceID": { "type": "guid", "value": "4602d692-06de-4974-84e4-e8facfa25be9" }, "valueDefinitionID": "7f51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInDate", "definitionName": { "value": "Opt In Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 20, "fullyQualifiedName": "MobilePush Demographics.Opt In Date", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8051de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 20, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptInDate", "storageFieldReferenceID": { "type": "guid", "value": "68c6681d-6f0f-4ec2-9407-55c5eb19fc19" }, "valueDefinitionID": "8051de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInDate", "name": "Opt In Date", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInMethodID", "definitionName": { "value": "Opt In Method" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 21, "fullyQualifiedName": "MobilePush Demographics.Opt In Method", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8151de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 21, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 9, "storageName": "_OptInMethodID", "storageFieldReferenceID": { "type": "guid", "value": "8b821a18-6cee-4204-9ef9-18d94112e84f" }, "valueDefinitionID": "8151de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInMethodID", "name": "Opt In Method", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8251de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInStatusID", "definitionName": { "value": "Opt In Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 22, "fullyQualifiedName": "MobilePush Demographics.Opt In Status", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8251de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 22, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 8, "storageName": "_OptInStatusID", "storageFieldReferenceID": { "type": "guid", "value": "673470b8-8503-4c4c-b9ae-9bf554d0a235" }, "valueDefinitionID": "8251de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInStatusID", "name": "Opt In Status", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8351de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutDate", "definitionName": { "value": "Opt Out Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 23, "fullyQualifiedName": "MobilePush Demographics.Opt Out Date", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8351de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 23, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptOutDate", "storageFieldReferenceID": { "type": "guid", "value": "8424262e-6904-4915-a4b3-2957b044b3ee" }, "valueDefinitionID": "8351de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutDate", "name": "Opt Out Date", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8451de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutMethodID", "definitionName": { "value": "Opt Out Method" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 24, "fullyQualifiedName": "MobilePush Demographics.Opt Out Method", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8451de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 24, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 10, "storageName": "_OptOutMethodID", "storageFieldReferenceID": { "type": "guid", "value": "3919bba5-e953-435d-8874-66be31cb1821" }, "valueDefinitionID": "8451de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutMethodID", "name": "Opt Out Method", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutStatusID", "definitionName": { "value": "Opt Out Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 25, "fullyQualifiedName": "MobilePush Demographics.Opt Out Status", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8551de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 25, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptOutStatusID", "storageFieldReferenceID": { "type": "guid", "value": "df789a9d-cfbc-4ed9-8a2b-e6427a631e28" }, "valueDefinitionID": "8551de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutStatusID", "name": "Opt Out Status", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8651de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Platform", "definitionName": { "value": "Platform" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 26, "fullyQualifiedName": "MobilePush Demographics.Platform", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8651de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 26, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Platform", "storageFieldReferenceID": { "type": "guid", "value": "353dc3ed-7578-4ee1-a1c1-e843f8b487f5" }, "valueDefinitionID": "8651de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Platform", "name": "Platform", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8751de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PlatformVersion", "definitionName": { "value": "Platform Version" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 27, "fullyQualifiedName": "MobilePush Demographics.Platform Version", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8751de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 27, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_PlatformVersion", "storageFieldReferenceID": { "type": "guid", "value": "99c03236-d908-498f-936a-6b7e110ef76a" }, "valueDefinitionID": "8751de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PlatformVersion", "name": "Platform Version", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8851de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ProviderToken", "definitionName": { "value": "Provider Token" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 28, "fullyQualifiedName": "MobilePush Demographics.Provider Token", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8851de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 28, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ProviderToken", "storageFieldReferenceID": { "type": "guid", "value": "03b1ac7c-3cc4-4b82-b3db-7e6b43cefd7c" }, "valueDefinitionID": "8851de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ProviderToken", "name": "Provider Token", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8951de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Source", "definitionName": { "value": "Source" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 29, "fullyQualifiedName": "MobilePush Demographics.Source", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8951de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 29, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 12, "storageName": "_Source", "storageFieldReferenceID": { "type": "guid", "value": "a0c5a9fe-d72b-41dd-9307-77db3da0b9f4" }, "valueDefinitionID": "8951de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Source", "name": "Source", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8a51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SourceObjectID", "definitionName": { "value": "Source Object ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 30, "fullyQualifiedName": "MobilePush Demographics.Source Object ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8a51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 30, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SourceObjectId", "storageFieldReferenceID": { "type": "guid", "value": "020d90c4-4c9c-4a00-b661-5b75ec0c9b88" }, "valueDefinitionID": "8a51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SourceObjectID", "name": "Source Object ID", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8b51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "State", "definitionName": { "value": "State" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 31, "fullyQualifiedName": "MobilePush Demographics.State", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8b51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 31, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_State", "storageFieldReferenceID": { "type": "guid", "value": "e65c52fd-e623-45cc-bb7a-1842617c5491" }, "valueDefinitionID": "8b51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "State", "name": "State", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8c51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Status", "definitionName": { "value": "Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 32, "fullyQualifiedName": "MobilePush Demographics.Status", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8c51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 32, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 13, "storageName": "_Status", "storageFieldReferenceID": { "type": "guid", "value": "a1c13a7c-566e-487f-8cc9-439064b6bfb4" }, "valueDefinitionID": "8c51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Status", "name": "Status", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SystemToken", "definitionName": { "value": "System Token" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 33, "fullyQualifiedName": "MobilePush Demographics.System Token", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 4000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8d51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 33, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SystemToken", "storageFieldReferenceID": { "type": "guid", "value": "d7e80e54-124c-4260-986b-b32b58b8c0ee" }, "valueDefinitionID": "8d51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SystemToken", "name": "System Token", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8e51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "TimeZone", "definitionName": { "value": "Time Zone" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 34, "fullyQualifiedName": "MobilePush Demographics.Time Zone", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8e51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 34, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_TimeZone", "storageFieldReferenceID": { "type": "guid", "value": "980d0010-a443-4044-9ca1-5d1cfeaedec7" }, "valueDefinitionID": "8e51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "TimeZone", "name": "Time Zone", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8f51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "UTCOffset", "definitionName": { "value": "UTC Offset" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 35, "fullyQualifiedName": "MobilePush Demographics.UTC Offset", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 4, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8f51de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 35, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "_UTCOffset", "storageFieldReferenceID": { "type": "guid", "value": "5c7c2a61-80da-4233-b895-54fd7e957e48" }, "valueDefinitionID": "8f51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "UTCOffset", "name": "UTC Offset", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9051de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ZipCode", "definitionName": { "value": "Zip Code" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 36, "fullyQualifiedName": "MobilePush Demographics.Zip Code", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "9051de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 36, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ZipCode", "storageFieldReferenceID": { "type": "guid", "value": "ac282849-4bc1-4373-8412-16a5d9ab31e4" }, "valueDefinitionID": "9051de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ZipCode", "name": "Zip Code", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "08b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "PushAddressExtensionID", "definitionName": { "value": "Push Address Extension ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 37, "fullyQualifiedName": "MobilePush Demographics.Push Address Extension ID", "isHidden": true, "isIdentityValue": true, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 37, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "PushAddressExtensionId", "valueDefinitionID": "08b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "PushAddressExtensionID", "name": "Push Address Extension ID", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "09b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "DeviceLanguage", "definitionName": { "value": "Device Language" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 38, "fullyQualifiedName": "MobilePush Demographics.Device Language", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": -1, "ordinal": 38, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "DeviceLanguage", "valueDefinitionID": "09b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "DeviceLanguage", "name": "Device Language", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0ab0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "GcmSenderId", "definitionName": { "value": "GCM Sender ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 39, "fullyQualifiedName": "MobilePush Demographics.GCM Sender ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": -1, "ordinal": 39, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "GcmSenderId", "valueDefinitionID": "0ab0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "GcmSenderId", "name": "GCM Sender ID", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0bb0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "AppVersion", "definitionName": { "value": "Application Version" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 40, "fullyQualifiedName": "MobilePush Demographics.Application Version", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": -1, "ordinal": 40, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "AppVersion", "valueDefinitionID": "0bb0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "AppVersion", "name": "Application Version", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0cb0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "SdkVersion", "definitionName": { "value": "SDK Version" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 41, "fullyQualifiedName": "MobilePush Demographics.SDK Version", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": -1, "ordinal": 41, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SdkVersion", "valueDefinitionID": "0cb0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "SdkVersion", "name": "SDK Version", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0db0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "LastAppOpen", "definitionName": { "value": "Last Application Open" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 42, "fullyQualifiedName": "MobilePush Demographics.Last Application Open", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 42, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "LastAppOpen", "valueDefinitionID": "0db0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "LastAppOpen", "name": "Last Application Open", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0eb0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "LastMessageOpen", "definitionName": { "value": "Last Message Open" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 43, "fullyQualifiedName": "MobilePush Demographics.Last Message Open", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 43, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "LastMessageOpen", "valueDefinitionID": "0eb0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "LastMessageOpen", "name": "Last Message Open", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0fb0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "LastSend", "definitionName": { "value": "Last Send" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 44, "fullyQualifiedName": "MobilePush Demographics.Last Send", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 44, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "LastSend", "valueDefinitionID": "0fb0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "LastSend", "name": "Last Send", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "10b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "SendCount", "definitionName": { "value": "Send Count" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 45, "fullyQualifiedName": "MobilePush Demographics.Send Count", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 45, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SendCount", "valueDefinitionID": "10b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "SendCount", "name": "Send Count", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "11b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "MessageOpenCount", "definitionName": { "value": "Message Open Count" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 46, "fullyQualifiedName": "MobilePush Demographics.Message Open Count", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 46, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "MessageOpenCount", "valueDefinitionID": "11b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "MessageOpenCount", "name": "Message Open Count", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "description": "", "localizedDescription": { "value": "" }, "definitionID": "12b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "ProximityEnabled", "definitionName": { "value": "Proximity Enabled" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 47, "fullyQualifiedName": "MobilePush Demographics.Proximity Enabled", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 47, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ProximityEnabled", "valueDefinitionID": "12b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "ProximityEnabled", "name": "Proximity Enabled", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "description": "", "localizedDescription": { "value": "" }, "definitionID": "13b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "BackgroundRefreshEnabled", "definitionName": { "value": "Background Refresh Enabled" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 48, "fullyQualifiedName": "MobilePush Demographics.Background Refresh Enabled", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 48, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "BackgroundRefreshEnabled", "valueDefinitionID": "13b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "BackgroundRefreshEnabled", "name": "Background Refresh Enabled", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "description": "", "localizedDescription": { "value": "" }, "definitionID": "14b0ae24-ee46-ea11-a2e0-1402ec94ec41", "definitionKey": "QuietPushEnabled", "definitionName": { "value": "Quiet Push Enabled" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 49, "fullyQualifiedName": "MobilePush Demographics.Quiet Push Enabled", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 49, "parentDefinition": { "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDemographics", "definitionName": { "value": "MobilePush Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "QuietPushEnabled", "valueDefinitionID": "14b0ae24-ee46-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "QuietPushEnabled", "name": "Quiet Push Enabled", "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "setDefinitionName": { "value": "MobilePush Demographics" }, "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", "applicationKey": "com.exacttarget.mobilepush", "attributeCount": 0, "canAddValues": true, "canChangeValues": true, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "MobilePush Demographics", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": true, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 3, "sendAttributeStorageName": "_ContactID", "sendContactKeyStorageName": "_SubscriberID", "storageLogicalType": "PushAttributes", "storageName": "_PushAddress", "storageObjectIDs": [ "4851de3f-31e2-e611-80cc-1402ec7222b4", "9552de3f-31e2-e611-80cc-1402ec7222b4" ], "storageReferenceID": { "type": "guid", "value": "7893dc39-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushDemographics", "name": "MobilePush Demographics" }, { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7b86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Custom_Object_Key", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Session Ends.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "7b86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Custom_Object_Key", "name": "Custom Object Key", "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "setDefinitionName": { "value": "Predictive Intelligence Session Ends" }, "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_id", "localizedDescription": { "value": "user_id" }, "definitionID": "7a86d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "user_id", "definitionName": { "value": "User Id" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Session Ends.User Id", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7a86d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_id", "storageFieldReferenceID": { "type": "guid", "value": "037a4978-3ce8-4311-95c3-b59d2e3f1a7f" }, "valueDefinitionID": "7a86d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "user_id", "name": "User Id", "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "setDefinitionName": { "value": "Predictive Intelligence Session Ends" }, "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "session_id", "localizedDescription": { "value": "session_id" }, "definitionID": "7886d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "session_id", "definitionName": { "value": "Session Id" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Session Ends.Session Id", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7886d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "session_id", "storageFieldReferenceID": { "type": "guid", "value": "67b9fcff-4136-4b07-b5f6-e86d616e4136" }, "valueDefinitionID": "7886d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "session_id", "name": "Session Id", "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "setDefinitionName": { "value": "Predictive Intelligence Session Ends" }, "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "email_address", "localizedDescription": { "value": "email_address" }, "definitionID": "7786d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "email_address", "definitionName": { "value": "Email Address" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Session Ends.Email Address", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7786d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "email_address", "storageFieldReferenceID": { "type": "guid", "value": "8f1bc9c8-32a3-4b54-83aa-ffb6e56ec709" }, "valueDefinitionID": "7786d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "email_address", "name": "Email Address", "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "setDefinitionName": { "value": "Predictive Intelligence Session Ends" }, "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "contact_key", "localizedDescription": { "value": "contact_key" }, "definitionID": "7686d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "contact_key", "definitionName": { "value": "Contact Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Session Ends.Contact Key", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7686d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "contact_key", "storageFieldReferenceID": { "type": "guid", "value": "0dc0b53e-ce26-4508-89b2-f9cb0ab8404a" }, "valueDefinitionID": "7686d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "contact_key", "name": "Contact Key", "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "setDefinitionName": { "value": "Predictive Intelligence Session Ends" }, "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "defaultValue": "getdate()", "description": "timestamp", "localizedDescription": { "value": "timestamp" }, "definitionID": "7986d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "timestamp", "definitionName": { "value": "Time stamp" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Session Ends.Time stamp", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "7986d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelSessionEnds", "definitionName": { "value": "Predictive Intelligence Session Ends" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "timestamp", "storageFieldReferenceID": { "type": "guid", "value": "0c87ce00-c3f1-4c88-b652-ba8dfc3cc10f" }, "valueDefinitionID": "7986d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "timestamp", "name": "Time stamp", "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "setDefinitionName": { "value": "Predictive Intelligence Session Ends" }, "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Session Ends", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "PI_SESSION_ENDS", "storageObjectIDs": ["6e86d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "d652de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelSessionEnds", "name": "Predictive Intelligence Session Ends" }, { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "ab51de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "2" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "7c86d247-3045-ea11-a2e0-1402ec94ec41", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "8686d247-3045-ea11-a2e0-1402ec94ec41", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "a251de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "9386d247-3045-ea11-a2e0-1402ec94ec41", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "a151de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "e651de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "a686d247-3045-ea11-a2e0-1402ec94ec41", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "e551de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Text", "customerDataID": 8, "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "AddressID", "definitionName": { "value": "Address ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "GroupConnect LINE Addresses.Address ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 100, "ordinal": 1, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "AddressId", "valueDefinitionID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "AddressID", "name": "Address ID", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7c86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "ContactID", "definitionName": { "value": "Contact ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "GroupConnect LINE Addresses.Contact ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 2, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ContactId", "valueDefinitionID": "7c86d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "ContactID", "name": "Contact ID", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7d86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "ContactKey", "definitionName": { "value": "Contact Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "GroupConnect LINE Addresses.Contact Key", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "ordinal": 3, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ContactKey", "valueDefinitionID": "7d86d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "ContactKey", "name": "Contact Key", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "defaultValue": "True", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7e86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "IsActive", "definitionName": { "value": "Is Active" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "GroupConnect LINE Addresses.Is Active", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 7, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "IsActive", "valueDefinitionID": "7e86d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "IsActive", "name": "Is Active", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "7f86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "GroupConnect LINE Addresses.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 8, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "CreatedDate", "valueDefinitionID": "7f86d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8086d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "GroupConnect LINE Addresses.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 9, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "CreatedBy", "valueDefinitionID": "8086d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8186d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "GroupConnect LINE Addresses.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 10, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ModifiedDate", "valueDefinitionID": "8186d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8286d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "GroupConnect LINE Addresses.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 11, "parentDefinition": { "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "definitionKey": "GroupConnectLineAddress", "definitionName": { "value": "GroupConnect LINE Addresses" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ModifiedBy", "valueDefinitionID": "8286d247-3045-ea11-a2e0-1402ec94ec41", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "setDefinitionName": { "value": "GroupConnect LINE Addresses" }, "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" } ], "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", "applicationKey": "com.exacttarget.GroupConnect", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "createDate": "2020-02-01T14:20:00", "localizedDescription": {}, "fullyQualifiedName": "GroupConnect LINE Addresses", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isSystemDefined": true, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 3, "storageObjectIDs": ["9851de3f-31e2-e611-80cc-1402ec7222b4"], "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", "setDefinitionKey": "GroupConnectLineAddress", "name": "GroupConnect LINE Addresses" }, { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "e152de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "4" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "9174266c-c416-ec11-b839-48df37d1dc79", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "c80f6472-c416-ec11-b839-48df37d1dc79", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "8574266c-c416-ec11-b839-48df37d1dc79", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9274266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "CustomObjectKey", "definitionName": { "value": "_CustomObjectKey" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "fullyQualifiedName": "Einstein MC Predictive Scores._CustomObjectKey", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": false, "isUpdateable": false, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "9274266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "CustomObjectKey", "name": "_CustomObjectKey", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9174266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Email Address", "definitionName": { "value": "Email Address" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 0, "fullyQualifiedName": "Einstein MC Predictive Scores.Email Address", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "9174266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 0, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "email_address", "storageFieldReferenceID": { "type": "guid", "value": "29554274-39da-460d-b721-15badcd533e0" }, "valueDefinitionID": "9174266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Email Address", "name": "Email Address", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8b74266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Email Open Likelihood", "definitionName": { "value": "Email Open Likelihood" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Einstein MC Predictive Scores.Email Open Likelihood", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8b74266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 2, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "EmailOpenLikelihood", "storageFieldReferenceID": { "type": "guid", "value": "6a64b510-d27a-4d35-9bb4-23760adaa1f4" }, "valueDefinitionID": "8b74266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Email Open Likelihood", "name": "Email Open Likelihood", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8d74266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Email Click Likelihood", "definitionName": { "value": "Email Click Likelihood" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Einstein MC Predictive Scores.Email Click Likelihood", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8d74266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 2, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "EmailClickLikelihood", "storageFieldReferenceID": { "type": "guid", "value": "6602de48-581e-497a-afae-2f97434db9b4" }, "valueDefinitionID": "8d74266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Email Click Likelihood", "name": "Email Click Likelihood", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Numeric", "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8f74266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Email Open Score", "definitionName": { "value": "Email Open Score" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Einstein MC Predictive Scores.Email Open Score", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8f74266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 3, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "EmailOpenScore", "storageFieldReferenceID": { "type": "guid", "value": "5e315b7d-7135-4ffc-8520-8c9ec91e33fa" }, "valueDefinitionID": "8f74266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Email Open Score", "name": "Email Open Score", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8774266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Email Subscribe Likelihood", "definitionName": { "value": "Email Subscribe Likelihood" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Einstein MC Predictive Scores.Email Subscribe Likelihood", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8774266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 4, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "EmailSubscribeLikelihood", "storageFieldReferenceID": { "type": "guid", "value": "be9bdd26-6875-4c1d-b9cc-64667e9155aa" }, "valueDefinitionID": "8774266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Email Subscribe Likelihood", "name": "Email Subscribe Likelihood", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Numeric", "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8e74266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EmailClickScore", "definitionName": { "value": "EmailClickScore" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Einstein MC Predictive Scores.EmailClickScore", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8e74266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 5, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "EmailClickScore", "storageFieldReferenceID": { "type": "guid", "value": "64515ffd-067d-4abe-9a4e-c72eb303db0b" }, "valueDefinitionID": "8e74266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "EmailClickScore", "name": "EmailClickScore", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Numeric", "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8674266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Email Subscribe Score", "definitionName": { "value": "Email Subscribe Score" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Einstein MC Predictive Scores.Email Subscribe Score", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8674266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 6, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "EmailSubscribeScore", "storageFieldReferenceID": { "type": "guid", "value": "d392d512-6c6e-40dd-8bbf-a50c36321372" }, "valueDefinitionID": "8674266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Email Subscribe Score", "name": "Email Subscribe Score", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8c74266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EmailEngagementPersona", "definitionName": { "value": "EmailEngagementPersona" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Einstein MC Predictive Scores.EmailEngagementPersona", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8c74266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 7, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "EmailEngagementPersona", "storageFieldReferenceID": { "type": "guid", "value": "67b5a098-1374-4d0a-9ffa-ad9a465eac66" }, "valueDefinitionID": "8c74266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "EmailEngagementPersona", "name": "EmailEngagementPersona", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8974266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Conversion Likelihood", "definitionName": { "value": "Conversion Likelihood" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "Einstein MC Predictive Scores.Conversion Likelihood", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8974266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 8, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ConversionLikelihood", "storageFieldReferenceID": { "type": "guid", "value": "a293ae7a-dc35-462d-8909-32eccc22fc58" }, "valueDefinitionID": "8974266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Conversion Likelihood", "name": "Conversion Likelihood", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Numeric", "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8a74266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Conversion Score", "definitionName": { "value": "Conversion Score" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Einstein MC Predictive Scores.Conversion Score", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8a74266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 9, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "ConversionScore", "storageFieldReferenceID": { "type": "guid", "value": "75a99602-df46-4fcc-a731-1b56c0d24d0e" }, "valueDefinitionID": "8a74266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Conversion Score", "name": "Conversion Score", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Date", "dataSourceName": {}, "dataType": "Date", "defaultValue": "getdate()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9074266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Updated Date", "definitionName": { "value": "Updated Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Einstein MC Predictive Scores.Updated Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "9074266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 10, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "UpdatedDate", "storageFieldReferenceID": { "type": "guid", "value": "4457d74f-2c14-4a3f-baf2-2cc34cf8858b" }, "valueDefinitionID": "9074266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Updated Date", "name": "Updated Date", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" }, { "baseType": "Date", "dataSourceName": {}, "dataType": "Date", "defaultValue": "getdate()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8874266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "Created Date", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "Einstein MC Predictive Scores.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8874266c-c416-ec11-b839-48df37d1dc79" }, "ordinal": 11, "parentDefinition": { "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "definitionKey": "EinsteinMCPredictiveScores", "definitionName": { "value": "Einstein MC Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "a4852a5f-2952-4648-911a-452533298dab" }, "valueDefinitionID": "8874266c-c416-ec11-b839-48df37d1dc79", "valueDefinitionKey": "Created Date", "name": "Created Date", "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "setDefinitionName": { "value": "Einstein MC Predictive Scores" }, "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" } ], "applicationID": "aed181bc-d7b7-465e-a3dd-9cdfb13943e2", "applicationKey": "com.sfmc-einstein.Einstein Engagement Scoring", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2021-09-16T02:03:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79" }, "localizedDescription": {}, "fullyQualifiedName": "Einstein MC Predictive Scores", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "ExactTargetSchema", "storageName": "Einstein_MC_Predictive_Scores", "storageObjectIDs": ["c90f6472-c416-ec11-b839-48df37d1dc79"], "storageReferenceID": { "type": "guid", "value": "e5ca7d21-aba6-e811-a2bf-1402ec94ecf1" }, "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", "setDefinitionKey": "EinsteinMCPredictiveScores", "name": "Einstein MC Predictive Scores" }, { "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Contact", "definitionName": { "value": "Contact" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "8f93dc39-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "2" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "9893dc39-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "9093dc39-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "customerDataID": 2, "dataSourceID": 1, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ContactID", "definitionName": { "value": "Contact ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "fullyQualifiedName": "Contact.Contact ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "parentDefinition": { "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Contact", "definitionName": { "value": "Contact" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SubscriberID", "valueDefinitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ContactID", "name": "Contact ID", "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "Contact", "setDefinitionName": { "value": "Contact" }, "parentIdentifier": "9093dc39-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "customerDataID": 3, "dataSourceID": 1, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ContactKey", "definitionName": { "value": "Contact Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "fullyQualifiedName": "Contact.Contact Key", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": -1, "parentDefinition": { "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Contact", "definitionName": { "value": "Contact" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SubscriberKey", "valueDefinitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ContactKey", "name": "Contact Key", "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "Contact", "setDefinitionName": { "value": "Contact" }, "parentIdentifier": "9093dc39-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "customerDataID": 1, "dataSourceID": 1, "dataSourceName": {}, "dataType": "Number", "description": "", "localizedDescription": { "value": "" }, "definitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "BusinessUnitID", "definitionName": { "value": "Business Unit ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "fullyQualifiedName": "Contact.Business Unit ID", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "parentDefinition": { "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Contact", "definitionName": { "value": "Contact" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ClientID", "valueDefinitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "BusinessUnitID", "name": "Business Unit ID", "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "Contact", "setDefinitionName": { "value": "Contact" }, "parentIdentifier": "9093dc39-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "ce703ed3-e01f-4f5f-900d-76a95b363e29", "applicationKey": "com.exacttarget.contacts", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "localizedDescription": {}, "fullyQualifiedName": "Contact", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isSystemDefined": true, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageObjectIDs": ["2ba72136-9f31-4a79-ab62-4ba5d19cd759"], "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "Contact", "name": "Contact" }, { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "a251de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "AddressID", "definitionName": { "value": "Address ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "GroupConnect LINE Demographics.Address ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 100, "ordinal": 1, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "AddressId", "valueDefinitionID": "a251de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "AddressID", "name": "Address ID", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "da51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "DisplayName", "definitionName": { "value": "Display Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "GroupConnect LINE Demographics.Display Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "ordinal": 2, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "DisplayName", "valueDefinitionID": "da51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "DisplayName", "name": "Display Name", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "db51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PictureUrl", "definitionName": { "value": "Picture Url" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "GroupConnect LINE Demographics.Picture Url", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "ordinal": 3, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "PictureUrl", "valueDefinitionID": "db51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PictureUrl", "name": "Picture Url", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dc51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "StatusMessage", "definitionName": { "value": "Status Message" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "GroupConnect LINE Demographics.Status Message", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "ordinal": 4, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "StatusMessage", "valueDefinitionID": "dc51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "StatusMessage", "name": "Status Message", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "a651de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "GroupConnect LINE Demographics.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 8, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "CreatedDate", "valueDefinitionID": "a651de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "a751de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "GroupConnect LINE Demographics.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 9, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "CreatedBy", "valueDefinitionID": "a751de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "a851de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "GroupConnect LINE Demographics.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 10, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ModifiedDate", "valueDefinitionID": "a851de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "a951de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "GroupConnect LINE Demographics.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 11, "parentDefinition": { "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineDemographics", "definitionName": { "value": "GroupConnect LINE Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ModifiedBy", "valueDefinitionID": "a951de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "setDefinitionName": { "value": "GroupConnect LINE Demographics" }, "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", "applicationKey": "com.exacttarget.GroupConnect", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "localizedDescription": {}, "fullyQualifiedName": "GroupConnect LINE Demographics", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isSystemDefined": true, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageObjectIDs": [ "9851de3f-31e2-e611-80cc-1402ec7222b4", "d351de3f-31e2-e611-80cc-1402ec7222b4" ], "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineDemographics", "name": "GroupConnect LINE Demographics" }, { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "e152de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "3" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9393dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "a585d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "a985d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "a185d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "a785d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Scores.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "a785d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "setDefinitionName": { "value": "Predictive Scores" }, "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "subscriber_key", "localizedDescription": { "value": "subscriber_key" }, "definitionID": "a585d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Subscriber Key", "definitionName": { "value": "Subscriber Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Scores.Subscriber Key", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "a585d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "subscriber_key", "storageFieldReferenceID": { "type": "guid", "value": "f6ce2639-bfff-40c0-835c-9fa89e627592" }, "valueDefinitionID": "a585d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Subscriber Key", "name": "Subscriber Key", "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "setDefinitionName": { "value": "Predictive Scores" }, "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "goal_name", "localizedDescription": { "value": "goal_name" }, "definitionID": "a285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Goal Name", "definitionName": { "value": "Goal Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Scores.Goal Name", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "a285d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "goal_name", "storageFieldReferenceID": { "type": "guid", "value": "62f73dda-4116-4fdd-ae38-a5cb74fafc6b" }, "valueDefinitionID": "a285d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Goal Name", "name": "Goal Name", "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "setDefinitionName": { "value": "Predictive Scores" }, "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "goal_name_key", "localizedDescription": { "value": "goal_name_key" }, "definitionID": "a385d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Goal Name Key", "definitionName": { "value": "Goal Name Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Scores.Goal Name Key", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "a385d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "goal_name_key", "storageFieldReferenceID": { "type": "guid", "value": "5c34b4cc-5d35-460e-a0b7-ba8e349d725b" }, "valueDefinitionID": "a385d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Goal Name Key", "name": "Goal Name Key", "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "setDefinitionName": { "value": "Predictive Scores" }, "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Decimal", "description": "score", "localizedDescription": { "value": "score" }, "definitionID": "a485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Score", "definitionName": { "value": "Score" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Scores.Score", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "a485d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 4, "storageName": "score", "storageFieldReferenceID": { "type": "guid", "value": "8baf5deb-f215-4984-9d91-6e05b88c2f94" }, "valueDefinitionID": "a485d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Score", "name": "Score", "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "setDefinitionName": { "value": "Predictive Scores" }, "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "description": "updated_at", "localizedDescription": { "value": "updated_at" }, "definitionID": "a685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Updated At", "definitionName": { "value": "Updated At" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Scores.Updated At", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "a685d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelScores", "definitionName": { "value": "Predictive Scores" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "updated_at", "storageFieldReferenceID": { "type": "guid", "value": "d6fefe2f-e2d5-42bb-bee2-5dd8da16b8e4" }, "valueDefinitionID": "a685d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Updated At", "name": "Updated At", "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "setDefinitionName": { "value": "Predictive Scores" }, "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Scores", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "DataExtension", "storageName": "PREDICTIVE_SCORES", "storageObjectIDs": ["9a85d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "de52de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelScores", "name": "Predictive Scores" }, { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "b451de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "2" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "b351de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "b751de3f-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "b151de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 2, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b351de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ContactsID", "definitionName": { "value": "Contacts ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 0, "fullyQualifiedName": "Email Demographics.Contacts ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": true, "ordinal": 0, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SubscriberID", "valueDefinitionID": "b351de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ContactsID", "name": "Contacts ID", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b4e96cfc-85f7-e611-80cc-1402ec7222b4", "definitionKey": "First Name", "definitionName": { "value": "First Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Email Demographics.First Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b4e96cfc-85f7-e611-80cc-1402ec7222b4" }, "ordinal": 1, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "First Name", "storageFieldReferenceID": { "type": "guid", "value": "eef81ae9-14e8-47b3-bede-5a691614c7c3" }, "storageFieldValueID": { "type": "int32", "value": "10025" }, "valueDefinitionID": "b4e96cfc-85f7-e611-80cc-1402ec7222b4", "valueDefinitionKey": "First Name", "name": "First Name", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b6e96cfc-85f7-e611-80cc-1402ec7222b4", "definitionKey": "Last Name", "definitionName": { "value": "Last Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Email Demographics.Last Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b6e96cfc-85f7-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Last Name", "storageFieldReferenceID": { "type": "guid", "value": "4434d534-4fb8-4ec4-9ffc-fe386781f8ef" }, "storageFieldValueID": { "type": "int32", "value": "10026" }, "valueDefinitionID": "b6e96cfc-85f7-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Last Name", "name": "Last Name", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b2e96cfc-85f7-e611-80cc-1402ec7222b4", "definitionKey": "Language", "definitionName": { "value": "Language" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Email Demographics.Language", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b2e96cfc-85f7-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Language", "storageFieldReferenceID": { "type": "guid", "value": "4b06d940-5f23-461f-859d-9c2aeee53525" }, "storageFieldValueID": { "type": "int32", "value": "10027" }, "valueDefinitionID": "b2e96cfc-85f7-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Language", "name": "Language", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "720e6c78-9709-e711-80cc-1402ec7222b4", "definitionKey": "Transaction Points1", "definitionName": { "value": "Transaction Points" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Email Demographics.Transaction Points", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "720e6c78-9709-e711-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Transaction Points", "storageFieldReferenceID": { "type": "guid", "value": "fdcb28a8-59fd-489a-bdce-b286bccc147e" }, "storageFieldValueID": { "type": "int32", "value": "10033" }, "valueDefinitionID": "720e6c78-9709-e711-80cc-1402ec7222b4", "valueDefinitionKey": "Transaction Points1", "name": "Transaction Points", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f05cc16f-8a14-e711-80cc-1402ec7222b4", "definitionKey": "Market", "definitionName": { "value": "Market" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Email Demographics.Market", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f05cc16f-8a14-e711-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Market", "storageFieldReferenceID": { "type": "guid", "value": "d6f80d57-488f-401b-822b-1b556d631d1c" }, "storageFieldValueID": { "type": "int32", "value": "10034" }, "valueDefinitionID": "f05cc16f-8a14-e711-80cc-1402ec7222b4", "valueDefinitionKey": "Market", "name": "Market", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "32c8b204-85ff-e711-80d0-1402ec7222b5", "definitionKey": "SFOrg", "definitionName": { "value": "SFOrg" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "Email Demographics.SFOrg", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "32c8b204-85ff-e711-80d0-1402ec7222b5" }, "ordinal": 8, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SFOrg", "storageFieldReferenceID": { "type": "guid", "value": "5d1032d3-5c92-4de4-bfb8-0e377f4483e2" }, "storageFieldValueID": { "type": "int32", "value": "10081" }, "valueDefinitionID": "32c8b204-85ff-e711-80d0-1402ec7222b5", "valueDefinitionKey": "SFOrg", "name": "SFOrg", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "8775d770-e194-e911-a2cf-1402ec94ecf1", "definitionKey": "Username", "definitionName": { "value": "Username" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Email Demographics.Username", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 255, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "8775d770-e194-e911-a2cf-1402ec94ecf1" }, "ordinal": 9, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Username", "storageFieldReferenceID": { "type": "guid", "value": "55ac244c-2afd-4134-8495-9c1c188debdc" }, "storageFieldValueID": { "type": "int32", "value": "10299" }, "valueDefinitionID": "8775d770-e194-e911-a2cf-1402ec94ecf1", "valueDefinitionKey": "Username", "name": "Username", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "570dea88-6e94-ea11-a2e5-1402ec9386e5", "definitionKey": "Account Id", "definitionName": { "value": "Account Id" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Email Demographics.Account Id", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "570dea88-6e94-ea11-a2e5-1402ec9386e5" }, "ordinal": 10, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Account Id", "storageFieldReferenceID": { "type": "guid", "value": "eb2f7e92-f7f8-435c-835a-3c24d5e003d5" }, "storageFieldValueID": { "type": "int32", "value": "10334" }, "valueDefinitionID": "570dea88-6e94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Account Id", "name": "Account Id", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "74c1c047-9e94-ea11-a2e5-1402ec9386e5", "definitionKey": "AccountId", "definitionName": { "value": "AccountId" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Email Demographics.AccountId", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "74c1c047-9e94-ea11-a2e5-1402ec9386e5" }, "ordinal": 10, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Account Id", "storageFieldReferenceID": { "type": "guid", "value": "eb2f7e92-f7f8-435c-835a-3c24d5e003d5" }, "storageFieldValueID": { "type": "int32", "value": "10334" }, "valueDefinitionID": "74c1c047-9e94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "AccountId", "name": "AccountId", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "560dea88-6e94-ea11-a2e5-1402ec9386e5", "definitionKey": "Preferred language", "definitionName": { "value": "Preferred language" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "Email Demographics.Preferred language", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "560dea88-6e94-ea11-a2e5-1402ec9386e5" }, "ordinal": 12, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Preferred language", "storageFieldReferenceID": { "type": "guid", "value": "be1fac02-93ef-4c9e-b06d-22757e1aeda8" }, "storageFieldValueID": { "type": "int32", "value": "10336" }, "valueDefinitionID": "560dea88-6e94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Preferred language", "name": "Preferred language", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "550dea88-6e94-ea11-a2e5-1402ec9386e5", "definitionKey": "Flex Parameter 1", "definitionName": { "value": "Flex Parameter 1" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "Email Demographics.Flex Parameter 1", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "550dea88-6e94-ea11-a2e5-1402ec9386e5" }, "ordinal": 13, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Flex Parameter 1", "storageFieldReferenceID": { "type": "guid", "value": "96436704-494e-4bb1-914a-3ad6994bbf2d" }, "storageFieldValueID": { "type": "int32", "value": "10337" }, "valueDefinitionID": "550dea88-6e94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Flex Parameter 1", "name": "Flex Parameter 1", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "866d4451-7d94-ea11-a2e5-1402ec9386e5", "definitionKey": "Flex Parameter 2", "definitionName": { "value": "Flex Parameter 2" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "Email Demographics.Flex Parameter 2", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "866d4451-7d94-ea11-a2e5-1402ec9386e5" }, "ordinal": 14, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Flex Parameter 2", "storageFieldReferenceID": { "type": "guid", "value": "02a5b26c-05f6-426b-8735-de6033503f8f" }, "storageFieldValueID": { "type": "int32", "value": "10338" }, "valueDefinitionID": "866d4451-7d94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Flex Parameter 2", "name": "Flex Parameter 2", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "876d4451-7d94-ea11-a2e5-1402ec9386e5", "definitionKey": "Flex Parameter 3", "definitionName": { "value": "Flex Parameter 3" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "Email Demographics.Flex Parameter 3", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "876d4451-7d94-ea11-a2e5-1402ec9386e5" }, "ordinal": 15, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Flex Parameter 3", "storageFieldReferenceID": { "type": "guid", "value": "058f7489-c272-466c-88ce-b528b5b17955" }, "storageFieldValueID": { "type": "int32", "value": "10339" }, "valueDefinitionID": "876d4451-7d94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Flex Parameter 3", "name": "Flex Parameter 3", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "886d4451-7d94-ea11-a2e5-1402ec9386e5", "definitionKey": "Flex Parameter 4", "definitionName": { "value": "Flex Parameter 4" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 16, "fullyQualifiedName": "Email Demographics.Flex Parameter 4", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "886d4451-7d94-ea11-a2e5-1402ec9386e5" }, "ordinal": 16, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Flex Parameter 4", "storageFieldReferenceID": { "type": "guid", "value": "2702b318-539d-4fe3-9c52-c7ba3e32a949" }, "storageFieldValueID": { "type": "int32", "value": "10340" }, "valueDefinitionID": "886d4451-7d94-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Flex Parameter 4", "name": "Flex Parameter 4", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 2, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "1a4f88cd-a194-ea11-a2e5-1402ec9386e5", "definitionKey": "Contact Role", "definitionName": { "value": "Contact Role" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 17, "fullyQualifiedName": "Email Demographics.Contact Role", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "1a4f88cd-a194-ea11-a2e5-1402ec9386e5" }, "ordinal": 17, "parentDefinition": { "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "EmailDemographics", "definitionName": { "value": "Email Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Contact Role", "storageFieldReferenceID": { "type": "guid", "value": "f3412d1f-bf50-4e3a-8db8-7e1bc15e019b" }, "storageFieldValueID": { "type": "int32", "value": "10341" }, "valueDefinitionID": "1a4f88cd-a194-ea11-a2e5-1402ec9386e5", "valueDefinitionKey": "Contact Role", "name": "Contact Role", "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "setDefinitionName": { "value": "Email Demographics" }, "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "b2ca1f50-3cc4-4fd7-a3a3-88bf09fb59fa", "applicationKey": "com.exacttarget.email", "attributeCount": 0, "canAddValues": true, "canChangeValues": true, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 0, "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Email Demographics", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "EnterpriseAttributes", "storageName": "_EnterpriseAttribute", "storageObjectIDs": ["b051de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "1ba7e67d-2647-4537-beb3-b0c5bac65d3c" }, "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "EmailDemographics", "name": "Email Demographics" }, { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "b285d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "b485d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "7886d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "7d86d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "7586d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "b285d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "b585d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "c885d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "cd85d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "c485d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b885d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Product Views.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "b885d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "setDefinitionName": { "value": "Predictive Intelligence Product Views" }, "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "sku", "localizedDescription": { "value": "sku" }, "definitionID": "b585d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SKU", "definitionName": { "value": "SKU" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Product Views.SKU", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b585d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "sku", "storageFieldReferenceID": { "type": "guid", "value": "f8553b64-8076-449d-aea0-450aed1a793c" }, "valueDefinitionID": "b585d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SKU", "name": "SKU", "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "setDefinitionName": { "value": "Predictive Intelligence Product Views" }, "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_id", "localizedDescription": { "value": "user_id" }, "definitionID": "b785d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "User_ID", "definitionName": { "value": "User ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Product Views.User ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b785d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_id", "storageFieldReferenceID": { "type": "guid", "value": "f8e9c116-3218-4064-92e4-dcccaf730a4f" }, "valueDefinitionID": "b785d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "User_ID", "name": "User ID", "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "setDefinitionName": { "value": "Predictive Intelligence Product Views" }, "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "session_id", "localizedDescription": { "value": "session_id" }, "definitionID": "b485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Session_ID", "definitionName": { "value": "Session ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Product Views.Session ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b485d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "session_id", "storageFieldReferenceID": { "type": "guid", "value": "bbca44f6-6353-464d-aba1-4285ae5072b6" }, "valueDefinitionID": "b485d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Session_ID", "name": "Session ID", "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "setDefinitionName": { "value": "Predictive Intelligence Product Views" }, "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Search", "localizedDescription": { "value": "Search" }, "definitionID": "b385d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Search", "definitionName": { "value": "Search" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Product Views.Search", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b385d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Search", "storageFieldReferenceID": { "type": "guid", "value": "68949690-06d5-452d-b4c7-b8daab2f3681" }, "valueDefinitionID": "b385d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Search", "name": "Search", "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "setDefinitionName": { "value": "Predictive Intelligence Product Views" }, "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "description": "Timestamp", "localizedDescription": { "value": "Timestamp" }, "definitionID": "b685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Timestamp", "definitionName": { "value": "Timestamp" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Product Views.Timestamp", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b685d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductViews", "definitionName": { "value": "Predictive Intelligence Product Views" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Timestamp", "storageFieldReferenceID": { "type": "guid", "value": "4fb7775d-277f-4f87-ba60-da24b120ba49" }, "valueDefinitionID": "b685d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Timestamp", "name": "Timestamp", "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "setDefinitionName": { "value": "Predictive Intelligence Product Views" }, "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Product Views", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 2, "storageLogicalType": "DataExtension", "storageName": "IGO_VIEWS", "storageObjectIDs": ["ab85d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "d552de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductViews", "name": "Predictive Intelligence Product Views" }, { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushAppID", "definitionName": { "value": "Application" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "MobilePush Subscriptions.Application", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 38, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b452de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 11, "storageName": "_APID", "storageFieldReferenceID": { "type": "guid", "value": "4e82734e-ff8a-4868-a786-20e9596a94d2" }, "valueDefinitionID": "b452de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PushAppID", "name": "Application", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "bb52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "MobilePush Subscriptions.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 9, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "bb52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b552de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDeviceID", "definitionName": { "value": "Device ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "MobilePush Subscriptions.Device ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b552de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 11, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_DeviceID", "storageFieldReferenceID": { "type": "guid", "value": "9d8db1d4-c00e-49bc-98d9-e30d2e3ed7cf" }, "valueDefinitionID": "b552de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PushDeviceID", "name": "Device ID", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInDate", "definitionName": { "value": "Opt In Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 20, "fullyQualifiedName": "MobilePush Subscriptions.Opt In Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b652de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 20, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptInDate", "storageFieldReferenceID": { "type": "guid", "value": "68c6681d-6f0f-4ec2-9407-55c5eb19fc19" }, "valueDefinitionID": "b652de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInDate", "name": "Opt In Date", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b752de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInMethodID", "definitionName": { "value": "Opt In Method" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 21, "fullyQualifiedName": "MobilePush Subscriptions.Opt In Method", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b752de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 21, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 9, "storageName": "_OptInMethodID", "storageFieldReferenceID": { "type": "guid", "value": "8b821a18-6cee-4204-9ef9-18d94112e84f" }, "valueDefinitionID": "b752de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInMethodID", "name": "Opt In Method", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b852de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptInStatusID", "definitionName": { "value": "Opt In Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 22, "fullyQualifiedName": "MobilePush Subscriptions.Opt In Status", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b852de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 22, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 8, "storageName": "_OptInStatusID", "storageFieldReferenceID": { "type": "guid", "value": "673470b8-8503-4c4c-b9ae-9bf554d0a235" }, "valueDefinitionID": "b852de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptInStatusID", "name": "Opt In Status", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "b952de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutDate", "definitionName": { "value": "Opt Out Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 23, "fullyQualifiedName": "MobilePush Subscriptions.Opt Out Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "b952de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 23, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptOutDate", "storageFieldReferenceID": { "type": "guid", "value": "8424262e-6904-4915-a4b3-2957b044b3ee" }, "valueDefinitionID": "b952de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutDate", "name": "Opt Out Date", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "ba52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "OptOutMethodID", "definitionName": { "value": "Opt Out Method" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 24, "fullyQualifiedName": "MobilePush Subscriptions.Opt Out Method", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "ba52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 24, "parentDefinition": { "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushSubscriptions", "definitionName": { "value": "MobilePush Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 10, "storageName": "_OptOutMethodID", "storageFieldReferenceID": { "type": "guid", "value": "3919bba5-e953-435d-8874-66be31cb1821" }, "valueDefinitionID": "ba52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "OptOutMethodID", "name": "Opt Out Method", "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "setDefinitionName": { "value": "MobilePush Subscriptions" }, "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", "applicationKey": "com.exacttarget.mobilepush", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "MobilePush Subscriptions", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "sendAttributeStorageName": "_ContactID", "sendContactKeyStorageName": "_SubscriberID", "storageLogicalType": "PushAttributes", "storageName": "_PushAddress", "storageObjectIDs": ["4851de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "7893dc39-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushSubscriptions", "name": "MobilePush Subscriptions" }, { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "c485d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "c885d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "da85d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "de85d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "d685d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cb85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Products.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "cb85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "name", "localizedDescription": { "value": "name" }, "definitionID": "c585d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Name", "definitionName": { "value": "Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Products.Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c585d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "name", "storageFieldReferenceID": { "type": "guid", "value": "116f93a1-da7c-4b0a-876c-7f6f107881c5" }, "valueDefinitionID": "c585d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Name", "name": "Name", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Decimal", "description": "regPrice", "localizedDescription": { "value": "regPrice" }, "definitionID": "c685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Regular_Price", "definitionName": { "value": "Regular Price" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Products.Regular Price", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c685d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "regPrice", "storageFieldReferenceID": { "type": "guid", "value": "d651f3d5-5b32-4fd7-907d-2d6caf42f827" }, "valueDefinitionID": "c685d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Regular_Price", "name": "Regular Price", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Decimal", "description": "salePrice", "localizedDescription": { "value": "salePrice" }, "definitionID": "c785d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Sale_Price", "definitionName": { "value": "Sale Price" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Products.Sale Price", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c785d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "salePrice", "storageFieldReferenceID": { "type": "guid", "value": "b10ebf49-6195-40c2-beaa-810d2c5b39d4" }, "valueDefinitionID": "c785d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Sale_Price", "name": "Sale Price", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Uuid", "localizedDescription": { "value": "Uuid" }, "definitionID": "ca85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "UUID", "definitionName": { "value": "UUID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Products.UUID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "ca85d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Uuid", "storageFieldReferenceID": { "type": "guid", "value": "7fc0495c-f03d-496a-a74d-770a9e672518" }, "valueDefinitionID": "ca85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "UUID", "name": "UUID", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "sku", "localizedDescription": { "value": "sku" }, "definitionID": "c885d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SKU", "definitionName": { "value": "SKU" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Products.SKU", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c885d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "sku", "storageFieldReferenceID": { "type": "guid", "value": "603870ea-b2e0-4613-bb22-08f582f34a94" }, "valueDefinitionID": "c885d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SKU", "name": "SKU", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "type", "localizedDescription": { "value": "type" }, "definitionID": "c985d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Type", "definitionName": { "value": "Type" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Predictive Intelligence Products.Type", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c985d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProducts", "definitionName": { "value": "Predictive Intelligence Products" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "type", "storageFieldReferenceID": { "type": "guid", "value": "9f3e8ffe-c631-4397-ab2e-8cbc50d7f6c1" }, "valueDefinitionID": "c985d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Type", "name": "Type", "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "setDefinitionName": { "value": "Predictive Intelligence Products" }, "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Products", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "storageLogicalType": "DataExtension", "storageName": "IGO_PRODUCTS", "storageObjectIDs": ["bc85d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "d852de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProducts", "name": "Predictive Intelligence Products" }, { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "c752de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushAppID", "definitionName": { "value": "Application" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "MobilePush Tags.Application", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 38, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c752de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 1, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 11, "storageName": "_APID", "storageFieldReferenceID": { "type": "guid", "value": "7f711754-1b97-4c7d-86d8-507f9fcb877d" }, "valueDefinitionID": "c752de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PushAppID", "name": "Application", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "ce52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "MobilePush Tags.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 2, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "ce52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "c852de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "MobilePush Tags.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c852de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedBy", "storageFieldReferenceID": { "type": "guid", "value": "dbc7917c-95cd-4294-b116-eb215d1c5c0b" }, "valueDefinitionID": "c852de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "c952de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "MobilePush Tags.Created Date", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "c952de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "30e22e41-0415-4d8a-b817-c56b0bffa168" }, "valueDefinitionID": "c952de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "ca52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushDeviceID", "definitionName": { "value": "Device ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "MobilePush Tags.Device ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "ca52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_DeviceID", "storageFieldReferenceID": { "type": "guid", "value": "ee23b0fd-76ad-46b5-9e14-aef0e17ec28f" }, "valueDefinitionID": "ca52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "PushDeviceID", "name": "Device ID", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cb52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "MobilePush Tags.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cb52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedBy", "storageFieldReferenceID": { "type": "guid", "value": "36b8827e-6017-4cba-bd0f-ba2261480736" }, "valueDefinitionID": "cb52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cc52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "MobilePush Tags.Modified Date", "isHidden": true, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cc52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedDate", "storageFieldReferenceID": { "type": "guid", "value": "685ea0db-0ecb-4111-8676-0a7c0a29c79f" }, "valueDefinitionID": "cc52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cd52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Value", "definitionName": { "value": "Value" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "MobilePush Tags.Value", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 128, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cd52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 8, "parentDefinition": { "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PushTags", "definitionName": { "value": "MobilePush Tags" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Value", "storageFieldReferenceID": { "type": "guid", "value": "cd7e2a3c-2551-4518-96c7-5c6b0d42423e" }, "valueDefinitionID": "cd52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Value", "name": "Value", "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "setDefinitionName": { "value": "MobilePush Tags" }, "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", "applicationKey": "com.exacttarget.mobilepush", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 2, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "MobilePush Tags", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "_PushTag", "storageObjectIDs": ["bd52de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "7993dc39-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PushTags", "name": "MobilePush Tags" }, { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "cae9847d-696d-eb11-b81e-48df37d1df5a", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "2" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "cee9847d-696d-eb11-b81e-48df37d1df5a", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "9a42dcad-ae72-4cde-9937-193e17485ad6", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "d5e9847d-696d-eb11-b81e-48df37d1df5a", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "f7e9847d-696d-eb11-b81e-48df37d1df5a", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "04ea847d-696d-eb11-b81e-48df37d1df5a", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cbe9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "CarrierID", "definitionName": { "value": "Carrier ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Chat Message Demographics.Carrier ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cbe9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 1, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CarrierID", "storageFieldReferenceID": { "type": "guid", "value": "3fdc8842-cc0f-407c-a3ec-930d7a027d1d" }, "valueDefinitionID": "cbe9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "CarrierID", "name": "Carrier ID", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cce9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "Channel", "definitionName": { "value": "Channel" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Chat Message Demographics.Channel", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cce9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 2, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Channel", "storageFieldReferenceID": { "type": "guid", "value": "ef36ded9-67b2-4daf-899f-6862af8e5ee7" }, "valueDefinitionID": "cce9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "Channel", "name": "Channel", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cde9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "City", "definitionName": { "value": "City" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Chat Message Demographics.City", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cde9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 3, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_City", "storageFieldReferenceID": { "type": "guid", "value": "be7b4554-bf03-4a80-9101-3e396b2e345f" }, "valueDefinitionID": "cde9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "City", "name": "City", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cee9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ContactID", "definitionName": { "value": "Contact ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Chat Message Demographics.Contact ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cee9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 4, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ContactID", "storageFieldReferenceID": { "type": "guid", "value": "b0e31883-cae8-4bc5-aa24-88565d375a18" }, "valueDefinitionID": "cee9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "ContactID", "name": "Contact ID", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d0e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Chat Message Demographics.Created By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d0e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 5, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedBy", "storageFieldReferenceID": { "type": "guid", "value": "1671a32a-8eb0-4dc5-b30d-8ad16e55a601" }, "valueDefinitionID": "d0e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d1e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Chat Message Demographics.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d1e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 6, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "de543ca5-5920-4309-adb9-33472144defe" }, "valueDefinitionID": "d1e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "FirstName", "definitionName": { "value": "First Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Chat Message Demographics.First Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d2e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 9, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_FirstName", "storageFieldReferenceID": { "type": "guid", "value": "125f7c91-2f11-44bd-9687-f22cf2461496" }, "valueDefinitionID": "d2e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "FirstName", "name": "First Name", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "defaultValue": "False", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d3e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "IsHonorDST", "definitionName": { "value": "Is Honor DST" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Chat Message Demographics.Is Honor DST", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d3e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 10, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_IsHonorDST", "storageFieldReferenceID": { "type": "guid", "value": "17abe00a-4306-43c5-b27f-a81f015d6dfb" }, "valueDefinitionID": "d3e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "IsHonorDST", "name": "Is Honor DST", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d4e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "LastName", "definitionName": { "value": "Last Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "Chat Message Demographics.Last Name", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 100, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d4e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 11, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_LastName", "storageFieldReferenceID": { "type": "guid", "value": "e31f18f4-5422-410b-adcc-1b60f61cce5f" }, "valueDefinitionID": "d4e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "LastName", "name": "Last Name", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "cfe9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "CountryCode", "definitionName": { "value": "Locale" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "Chat Message Demographics.Locale", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 2, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "cfe9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 12, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CountryCode", "storageFieldReferenceID": { "type": "guid", "value": "4b5fda70-47cb-4f4b-8ba6-f5cac53ee344" }, "valueDefinitionID": "cfe9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "CountryCode", "name": "Locale", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Phone", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d5e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "MobileNumber", "definitionName": { "value": "Mobile Number" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "Chat Message Demographics.Mobile Number", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 15, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d5e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 14, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_MobileNumber", "storageFieldReferenceID": { "type": "guid", "value": "e31a7e3b-e943-440e-9be6-77224a4928fe" }, "valueDefinitionID": "d5e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "MobileNumber", "name": "Mobile Number", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d6e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "Chat Message Demographics.Modified By", "isHidden": true, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d6e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 15, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedBy", "storageFieldReferenceID": { "type": "guid", "value": "a9be58ef-884d-44f4-9926-d73ebe587847" }, "valueDefinitionID": "d6e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d7e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 16, "fullyQualifiedName": "Chat Message Demographics.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d7e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 16, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedDate", "storageFieldReferenceID": { "type": "guid", "value": "216659c1-9512-47de-a9ee-822f48148514" }, "valueDefinitionID": "d7e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d8e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "Priority", "definitionName": { "value": "Priority" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 17, "fullyQualifiedName": "Chat Message Demographics.Priority", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d8e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 17, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Priority", "storageFieldReferenceID": { "type": "guid", "value": "71153ee5-a33f-4cf6-a963-0c3a893d9348" }, "valueDefinitionID": "d8e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "Priority", "name": "Priority", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "d9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "Source", "definitionName": { "value": "Source" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 18, "fullyQualifiedName": "Chat Message Demographics.Source", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d9e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 18, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 5, "storageName": "_Source", "storageFieldReferenceID": { "type": "guid", "value": "f6bafdfb-86bf-45e8-9b76-b878c904d6c5" }, "valueDefinitionID": "d9e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "Source", "name": "Source", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dae9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "SourceObjectID", "definitionName": { "value": "Source Object ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 19, "fullyQualifiedName": "Chat Message Demographics.Source Object ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "dae9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 19, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SourceObjectId", "storageFieldReferenceID": { "type": "guid", "value": "c67a7922-44e5-4c4b-a4c8-2ac3550a5f07" }, "valueDefinitionID": "dae9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "SourceObjectID", "name": "Source Object ID", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 4, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dfe9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "SFContactID", "definitionName": { "value": "SFContactID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 19, "fullyQualifiedName": "Chat Message Demographics.SFContactID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "dfe9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 19, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "SFContactID", "storageFieldReferenceID": { "type": "guid", "value": "ce5a90ea-88eb-4683-9a1a-5c776b5763ce" }, "valueDefinitionID": "dfe9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "SFContactID", "name": "SFContactID", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dbe9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "State", "definitionName": { "value": "State" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 20, "fullyQualifiedName": "Chat Message Demographics.State", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 200, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "dbe9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 20, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_State", "storageFieldReferenceID": { "type": "guid", "value": "c0ea1fac-d939-4dde-b45a-16586f661924" }, "valueDefinitionID": "dbe9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "State", "name": "State", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dce9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "Status", "definitionName": { "value": "Status" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 21, "fullyQualifiedName": "Chat Message Demographics.Status", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "dce9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 21, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 6, "storageName": "_Status", "storageFieldReferenceID": { "type": "guid", "value": "fafff407-c055-411c-81ec-78907f5dbd58" }, "valueDefinitionID": "dce9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "Status", "name": "Status", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Decimal", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dde9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "UTCOffset", "definitionName": { "value": "UTC Offset" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 22, "fullyQualifiedName": "Chat Message Demographics.UTC Offset", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": 4, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "dde9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 22, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "_UTCOffset", "storageFieldReferenceID": { "type": "guid", "value": "84d29656-a348-43c2-ac2f-8c7ec5b18a3e" }, "valueDefinitionID": "dde9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "UTCOffset", "name": "UTC Offset", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "e0e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ZipCode", "definitionName": { "value": "Zip Code" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 23, "fullyQualifiedName": "Chat Message Demographics.Zip Code", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": false, "length": 20, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "e0e9847d-696d-eb11-b81e-48df37d1df5a" }, "ordinal": 23, "parentDefinition": { "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageDemographics", "definitionName": { "value": "Chat Message Demographics" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ZipCode", "storageFieldReferenceID": { "type": "guid", "value": "11ce9d05-a1e3-47ba-9077-11097e0b4c8d" }, "valueDefinitionID": "e0e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "ZipCode", "name": "Zip Code", "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "setDefinitionName": { "value": "Chat Message Demographics" }, "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" } ], "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", "applicationKey": "com.exacttarget.mobileconnect", "attributeCount": 0, "canAddValues": true, "canChangeValues": true, "canModify": false, "canRemove": false, "categoryID": 2, "createDate": "2021-02-12T13:36:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a" }, "localizedDescription": {}, "fullyQualifiedName": "Chat Message Demographics", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": true, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 2, "sendAttributeStorageName": "_ContactID", "sendContactKeyStorageName": "_SubscriberID", "storageLogicalType": "MobileAttributes", "storageName": "_MobileAddress", "storageObjectIDs": ["1651de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "7693dc39-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageDemographics", "name": "Chat Message Demographics" }, { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "dc85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Product Attributes.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "dc85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "setDefinitionName": { "value": "Predictive Intelligence Product Attributes" }, "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "attribName", "localizedDescription": { "value": "attribName" }, "definitionID": "d785d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_Name", "definitionName": { "value": "Attribute Name" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Product Attributes.Attribute Name", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d785d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "attribName", "storageFieldReferenceID": { "type": "guid", "value": "a29facf4-9173-43b7-98d5-57bef44c832f" }, "valueDefinitionID": "d785d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_Name", "name": "Attribute Name", "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "setDefinitionName": { "value": "Predictive Intelligence Product Attributes" }, "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "attribValue", "localizedDescription": { "value": "attribValue" }, "definitionID": "d985d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_Value", "definitionName": { "value": "Attribute Value" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Product Attributes.Attribute Value", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 1000, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d985d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "attribValue", "storageFieldReferenceID": { "type": "guid", "value": "b023eb98-10c7-481d-a809-38af6af65b17" }, "valueDefinitionID": "d985d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_Value", "name": "Attribute Value", "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "setDefinitionName": { "value": "Predictive Intelligence Product Attributes" }, "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "sku", "localizedDescription": { "value": "sku" }, "definitionID": "da85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SKU", "definitionName": { "value": "SKU" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Product Attributes.SKU", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "da85d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "sku", "storageFieldReferenceID": { "type": "guid", "value": "35919388-7813-48d0-a45f-2c0cf64d6e1e" }, "valueDefinitionID": "da85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SKU", "name": "SKU", "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "setDefinitionName": { "value": "Predictive Intelligence Product Attributes" }, "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "description": "updated_at", "localizedDescription": { "value": "updated_at" }, "definitionID": "db85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Updated_At", "definitionName": { "value": "Updated At" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Product Attributes.Updated At", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "db85d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "updated_at", "storageFieldReferenceID": { "type": "guid", "value": "a8a96a08-576c-4b45-842c-fe6c36da6f41" }, "valueDefinitionID": "db85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Updated_At", "name": "Updated At", "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "setDefinitionName": { "value": "Predictive Intelligence Product Attributes" }, "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Number", "description": "attributeValueIndex", "localizedDescription": { "value": "attributeValueIndex" }, "definitionID": "d885d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_Value_Index", "definitionName": { "value": "Attribute Value Index" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Product Attributes.Attribute Value Index", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "d885d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductAttribs", "definitionName": { "value": "Predictive Intelligence Product Attributes" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "attributeValueIndex", "storageFieldReferenceID": { "type": "guid", "value": "619fe747-d142-4522-91dd-4228546d282d" }, "valueDefinitionID": "d885d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_Value_Index", "name": "Attribute Value Index", "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "setDefinitionName": { "value": "Predictive Intelligence Product Attributes" }, "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Product Attributes", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "IGO_PRODUCTATTRIBS", "storageObjectIDs": ["cf85d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "d952de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductAttribs", "name": "Predictive Intelligence Product Attributes" }, { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "e651de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "AddressID", "definitionName": { "value": "Address ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Address ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "length": -1, "ordinal": 1, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "AddressId", "valueDefinitionID": "e651de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "AddressID", "name": "Address ID", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "e751de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ChannelID", "definitionName": { "value": "Channel ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Channel ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": -1, "ordinal": 2, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ChannelId", "valueDefinitionID": "e751de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ChannelID", "name": "Channel ID", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Boolean", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Boolean", "defaultValue": "False", "description": "", "localizedDescription": { "value": "" }, "definitionID": "e851de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "IsSubscribed", "definitionName": { "value": "Is Subscribed" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Is Subscribed", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 3, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "IsSubscribed", "valueDefinitionID": "e851de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "IsSubscribed", "name": "Is Subscribed", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "e951de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedDate", "definitionName": { "value": "Created Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 4, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "CreatedDate", "valueDefinitionID": "e951de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedDate", "name": "Created Date", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "ea51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CreatedBy", "definitionName": { "value": "Created By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Created By", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 5, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "CreatedBy", "valueDefinitionID": "ea51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CreatedBy", "name": "Created By", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 3, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "eb51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedDate", "definitionName": { "value": "Modified Date" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Modified Date", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 6, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ModifiedDate", "valueDefinitionID": "eb51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedDate", "name": "Modified Date", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 3, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "ec51de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "ModifiedBy", "definitionName": { "value": "Modified By" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "GroupConnect LINE Subscriptions.Modified By", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 7, "parentDefinition": { "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "GroupConnectLineSubscriptions", "definitionName": { "value": "GroupConnect LINE Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ModifiedBy", "valueDefinitionID": "ec51de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "ModifiedBy", "name": "Modified By", "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "setDefinitionName": { "value": "GroupConnect LINE Subscriptions" }, "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", "applicationKey": "com.exacttarget.GroupConnect", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "localizedDescription": {}, "fullyQualifiedName": "GroupConnect LINE Subscriptions", "isCustomObjectBacked": false, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isSystemDefined": true, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageObjectIDs": ["dd51de3f-31e2-e611-80cc-1402ec7222b4"], "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "GroupConnectLineSubscriptions", "name": "GroupConnect LINE Subscriptions" }, { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "ee85d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "f785d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "c885d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "0086d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "c485d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "ee85d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "fa85d645-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "1286d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "1586d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "0b86d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "fb85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "fb85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Sku", "localizedDescription": { "value": "Sku" }, "definitionID": "f785d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "SKU", "definitionName": { "value": "SKU" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Product Purchases.SKU", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f785d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Sku", "storageFieldReferenceID": { "type": "guid", "value": "8fbf489f-b82c-4c03-ab47-e8576a5625db" }, "valueDefinitionID": "f785d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "SKU", "name": "SKU", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Decimal", "description": "Price", "localizedDescription": { "value": "Price" }, "definitionID": "f485d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Price", "definitionName": { "value": "Price" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Price", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 18, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f485d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "scale": 2, "storageName": "Price", "storageFieldReferenceID": { "type": "guid", "value": "f6942680-95e1-4000-9026-77fbfd8d5e41" }, "valueDefinitionID": "f485d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Price", "name": "Price", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Number", "description": "Quantity", "localizedDescription": { "value": "Quantity" }, "definitionID": "f585d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Quantity", "definitionName": { "value": "Quantity" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Quantity", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f585d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Quantity", "storageFieldReferenceID": { "type": "guid", "value": "29508cf9-fac3-4d64-8e28-e691978bd659" }, "valueDefinitionID": "f585d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Quantity", "name": "Quantity", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "order_number", "localizedDescription": { "value": "order_number" }, "definitionID": "f385d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Order_Number", "definitionName": { "value": "Order Number" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Order Number", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f385d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "order_number", "storageFieldReferenceID": { "type": "guid", "value": "d4024f16-8e2a-4f19-a852-6736071d8ec6" }, "valueDefinitionID": "f385d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Order_Number", "name": "Order Number", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_id", "localizedDescription": { "value": "user_id" }, "definitionID": "fa85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "User_ID", "definitionName": { "value": "User ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Product Purchases.User ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "fa85d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_id", "storageFieldReferenceID": { "type": "guid", "value": "c318e0f3-c386-4beb-ab78-be4067c5520d" }, "valueDefinitionID": "fa85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "User_ID", "name": "User ID", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Date", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Date", "description": "Timestamp", "localizedDescription": { "value": "Timestamp" }, "definitionID": "f985d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Timestamp", "definitionName": { "value": "Timestamp" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Timestamp", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f985d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Timestamp", "storageFieldReferenceID": { "type": "guid", "value": "499933ee-cc51-4a79-8db1-bf6bf304d61f" }, "valueDefinitionID": "f985d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Timestamp", "name": "Timestamp", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Job_ID", "localizedDescription": { "value": "Job_ID" }, "definitionID": "f085d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Job_ID", "definitionName": { "value": "Job_ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Job_ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f085d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 9, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Job_ID", "storageFieldReferenceID": { "type": "guid", "value": "f021da2f-c005-46ca-a561-b6c3d9e095d0" }, "valueDefinitionID": "f085d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Job_ID", "name": "Job_ID", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "List_ID", "localizedDescription": { "value": "List_ID" }, "definitionID": "f285d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "List_ID", "definitionName": { "value": "List_ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Predictive Intelligence Product Purchases.List_ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f285d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 10, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "List_ID", "storageFieldReferenceID": { "type": "guid", "value": "6a8da7cf-8496-4ffe-8c5c-057fce68cccc" }, "valueDefinitionID": "f285d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "List_ID", "name": "List_ID", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Batch_ID", "localizedDescription": { "value": "Batch_ID" }, "definitionID": "ef85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Batch_ID", "definitionName": { "value": "Batch_ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Batch_ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "ef85d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 11, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Batch_ID", "storageFieldReferenceID": { "type": "guid", "value": "053d483c-62a0-4361-80a4-e99d8bde4550" }, "valueDefinitionID": "ef85d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Batch_ID", "name": "Batch_ID", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Number", "description": "Landing_URL_ID", "localizedDescription": { "value": "Landing_URL_ID" }, "definitionID": "f185d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Landing_URL_ID", "definitionName": { "value": "Landing_URL_ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Landing_URL_ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f185d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 12, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Landing_URL_ID", "storageFieldReferenceID": { "type": "guid", "value": "d37c4358-5810-4d47-bcec-92829b828703" }, "valueDefinitionID": "f185d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Landing_URL_ID", "name": "Landing_URL_ID", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Numeric", "dataSourceID": 5, "dataSourceName": {}, "dataType": "LongNumber", "description": "Subscriber_ID", "localizedDescription": { "value": "Subscriber_ID" }, "definitionID": "f885d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Subscriber_ID", "definitionName": { "value": "Subscriber_ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "Predictive Intelligence Product Purchases.Subscriber_ID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f885d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 13, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Subscriber_ID", "storageFieldReferenceID": { "type": "guid", "value": "5c0c3f04-baec-434a-b463-4f82e3a9fb9c" }, "valueDefinitionID": "f885d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Subscriber_ID", "name": "Subscriber_ID", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "session_id", "localizedDescription": { "value": "session_id" }, "definitionID": "f685d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "session_id", "definitionName": { "value": "session_id" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "Predictive Intelligence Product Purchases.session_id", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f685d645-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 14, "parentDefinition": { "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProductPurchases", "definitionName": { "value": "Predictive Intelligence Product Purchases" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "session_id", "storageFieldReferenceID": { "type": "guid", "value": "33bf36ba-c6b7-43cd-b996-abf12ced61fb" }, "valueDefinitionID": "f685d645-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "session_id", "name": "session_id", "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "setDefinitionName": { "value": "Predictive Intelligence Product Purchases" }, "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Product Purchases", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 2, "storageLogicalType": "DataExtension", "storageName": "IGO_PURCHASES", "storageObjectIDs": ["e085d645-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "d752de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProductPurchases", "name": "Predictive Intelligence Product Purchases" }, { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "02ea847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "fullyQualifiedName": "Chat Message Subscriptions.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "02ea847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f7e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_MobileNumber", "definitionName": { "value": "MobileNumber" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Chat Message Subscriptions.MobileNumber", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 254, "ordinal": 2, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_MobileNumber", "storageFieldReferenceID": { "type": "guid", "value": "169e88d8-d9fe-43f4-82e2-f325674328ee" }, "valueDefinitionID": "f7e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_MobileNumber", "name": "MobileNumber", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f3e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_ChannelId", "definitionName": { "value": "ChannelId" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Chat Message Subscriptions.ChannelId", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 50, "ordinal": 3, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ChannelId", "storageFieldReferenceID": { "type": "guid", "value": "5f56cbc2-6799-4b37-b24d-38b16e9ed30a" }, "valueDefinitionID": "f3e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_ChannelId", "name": "ChannelId", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f4e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_ChannelType", "definitionName": { "value": "ChannelType" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Chat Message Subscriptions.ChannelType", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 20, "ordinal": 4, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ChannelType", "storageFieldReferenceID": { "type": "guid", "value": "d442b162-248b-4546-b0ee-7d86d4444d3b" }, "valueDefinitionID": "f4e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_ChannelType", "name": "ChannelType", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "ffe9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_OptOutStatusID", "definitionName": { "value": "OptOutStatusID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Chat Message Subscriptions.OptOutStatusID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "ordinal": 5, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "restrictionLookupListID": 15, "storageName": "_OptOutStatusID", "storageFieldReferenceID": { "type": "guid", "value": "ca82f469-ea9e-44d8-ad4f-d8ed7536518f" }, "valueDefinitionID": "ffe9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_OptOutStatusID", "name": "OptOutStatusID", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "fee9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_OptOutMethodID", "definitionName": { "value": "OptOutMethodID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Chat Message Subscriptions.OptOutMethodID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 6, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptOutMethodID", "storageFieldReferenceID": { "type": "guid", "value": "c47ca0dc-f8b3-4476-8ffb-1cbf22b6254e" }, "valueDefinitionID": "fee9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_OptOutMethodID", "name": "OptOutMethodID", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Date", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "fde9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_OptOutDate", "definitionName": { "value": "OptOutDate" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Chat Message Subscriptions.OptOutDate", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 7, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptOutDate", "storageFieldReferenceID": { "type": "guid", "value": "0b8b6cdd-86ba-4d36-8e27-0e0b4bde256f" }, "valueDefinitionID": "fde9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_OptOutDate", "name": "OptOutDate", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "fce9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_OptInStatusID", "definitionName": { "value": "OptInStatusID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "Chat Message Subscriptions.OptInStatusID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "ordinal": 8, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptInStatusID", "storageFieldReferenceID": { "type": "guid", "value": "c0f3cd62-55cb-4f61-bb97-d3676e9c7eea" }, "valueDefinitionID": "fce9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_OptInStatusID", "name": "OptInStatusID", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "fbe9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_OptInMethodID", "definitionName": { "value": "OptInMethodID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Chat Message Subscriptions.OptInMethodID", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 9, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptInMethodID", "storageFieldReferenceID": { "type": "guid", "value": "a4d5dea8-cd22-435c-b389-9cdce054149c" }, "valueDefinitionID": "fbe9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_OptInMethodID", "name": "OptInMethodID", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Date", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Date", "description": "", "localizedDescription": { "value": "" }, "definitionID": "fae9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_OptInDate", "definitionName": { "value": "OptInDate" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Chat Message Subscriptions.OptInDate", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": true, "isUpdateable": false, "ordinal": 10, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_OptInDate", "storageFieldReferenceID": { "type": "guid", "value": "4fbd9715-9b10-4e4b-bf89-215786c84e96" }, "valueDefinitionID": "fae9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_OptInDate", "name": "OptInDate", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Byte", "description": "", "localizedDescription": { "value": "" }, "definitionID": "00ea847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_Source", "definitionName": { "value": "Source" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "Chat Message Subscriptions.Source", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 11, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_Source", "storageFieldReferenceID": { "type": "guid", "value": "2b7a081b-127c-4d65-bdfe-f80f274f4580" }, "valueDefinitionID": "00ea847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_Source", "name": "Source", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Text", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "01ea847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_SourceObjectId ", "definitionName": { "value": "SourceObjectId" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "Chat Message Subscriptions.SourceObjectId", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 200, "ordinal": 12, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_SourceObjectId ", "storageFieldReferenceID": { "type": "guid", "value": "47505922-899e-45b8-a1cc-c0049d280504" }, "valueDefinitionID": "01ea847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_SourceObjectId ", "name": "SourceObjectId", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Date", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f6e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_CreatedDate", "definitionName": { "value": "CreatedDate" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "Chat Message Subscriptions.CreatedDate", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 13, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedDate", "storageFieldReferenceID": { "type": "guid", "value": "ae8a3f3e-1020-484e-8e24-5c11c7393d56" }, "valueDefinitionID": "f6e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_CreatedDate", "name": "CreatedDate", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f5e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_CreatedBy ", "definitionName": { "value": "CreatedBy" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "Chat Message Subscriptions.CreatedBy", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 14, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CreatedBy ", "storageFieldReferenceID": { "type": "guid", "value": "0b7dac0b-728a-4fb7-a63e-c21311d784d3" }, "valueDefinitionID": "f5e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_CreatedBy ", "name": "CreatedBy", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Date", "dataSourceID": 1, "dataSourceName": {}, "dataType": "Date", "defaultValue": "GETDATE()", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f9e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_ModifiedDate", "definitionName": { "value": "ModifiedDate" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "Chat Message Subscriptions.ModifiedDate", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 15, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedDate", "storageFieldReferenceID": { "type": "guid", "value": "10d39942-4628-4e99-a927-523fe48d1068" }, "valueDefinitionID": "f9e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_ModifiedDate", "name": "ModifiedDate", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "f8e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "_ModifiedBy ", "definitionName": { "value": "ModifiedBy" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 16, "fullyQualifiedName": "Chat Message Subscriptions.ModifiedBy", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 16, "parentDefinition": { "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "definitionKey": "ChatMessageSubscriptions", "definitionName": { "value": "Chat Message Subscriptions" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_ModifiedBy ", "storageFieldReferenceID": { "type": "guid", "value": "a0486cff-d96e-41dd-9286-c77ddad92f75" }, "valueDefinitionID": "f8e9847d-696d-eb11-b81e-48df37d1df5a", "valueDefinitionKey": "_ModifiedBy ", "name": "ModifiedBy", "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "setDefinitionName": { "value": "Chat Message Subscriptions" }, "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" } ], "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", "applicationKey": "com.exacttarget.mobileconnect", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 2, "createDate": "2021-02-12T13:36:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a" }, "localizedDescription": {}, "fullyQualifiedName": "Chat Message Subscriptions", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 0, "storageLogicalType": "DataExtension", "storageName": "_ChatMessagingSubscription", "storageObjectIDs": ["e1e9847d-696d-eb11-b81e-48df37d1df5a"], "storageReferenceID": { "type": "guid", "value": "38042500-a868-eb11-b81e-48df37d1df5a" }, "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", "setDefinitionKey": "ChatMessageSubscriptions", "name": "Chat Message Subscriptions" }, { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "e152de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "4" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "fc52de3f-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "9885d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "2386d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "2686d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "1e86d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "5a86d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "5d86d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "5286d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "b785d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "ba85d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "b285d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } }, { "canModify": false, "canRemove": false, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": false, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" }, "relationshipAttributes": [ { "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "fa85d645-31e2-e611-80cc-1402ec7222b4", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "fd85d645-31e2-e611-80cc-1402ec7222b4", "rightItem": { "cardinality": "Many", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "ee85d645-31e2-e611-80cc-1402ec7222b4", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceID": 1, "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "0453de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "Predictive Intelligence Profiles.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "ordinal": 1, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "0453de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "user_id", "localizedDescription": { "value": "user_id" }, "definitionID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "User_ID", "definitionName": { "value": "User ID" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "Predictive Intelligence Profiles.User ID", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "fe52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 2, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "user_id", "storageFieldReferenceID": { "type": "guid", "value": "eceebc11-78ad-421f-a94f-020667aac6d4" }, "valueDefinitionID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "User_ID", "name": "User ID", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "email", "localizedDescription": { "value": "email" }, "definitionID": "fc52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Email", "definitionName": { "value": "Email" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 3, "fullyQualifiedName": "Predictive Intelligence Profiles.Email", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "fc52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 3, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "email", "storageFieldReferenceID": { "type": "guid", "value": "71e4d8c6-e3d4-430e-9c9f-7e56b092d36a" }, "valueDefinitionID": "fc52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Email", "name": "Email", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Value_1", "localizedDescription": { "value": "Value_1" }, "definitionID": "ff52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Value_1", "definitionName": { "value": "Value 1" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "Predictive Intelligence Profiles.Value 1", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "ff52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 4, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Value_1", "storageFieldReferenceID": { "type": "guid", "value": "8e0573f4-8bc8-4fb3-afc8-ad933a8d823b" }, "valueDefinitionID": "ff52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Value_1", "name": "Value 1", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Value_2", "localizedDescription": { "value": "Value_2" }, "definitionID": "0053de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Value_2", "definitionName": { "value": "Value 2" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 5, "fullyQualifiedName": "Predictive Intelligence Profiles.Value 2", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0053de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 5, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Value_2", "storageFieldReferenceID": { "type": "guid", "value": "dcf6690a-4fbe-418c-baa7-e1c50443560b" }, "valueDefinitionID": "0053de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Value_2", "name": "Value 2", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Value_3", "localizedDescription": { "value": "Value_3" }, "definitionID": "0153de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Value_3", "definitionName": { "value": "Value 3" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 6, "fullyQualifiedName": "Predictive Intelligence Profiles.Value 3", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0153de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 6, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Value_3", "storageFieldReferenceID": { "type": "guid", "value": "b2a7de94-c985-4337-afcc-445aa80c2ced" }, "valueDefinitionID": "0153de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Value_3", "name": "Value 3", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Value_4", "localizedDescription": { "value": "Value_4" }, "definitionID": "0253de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Value_4", "definitionName": { "value": "Value 4" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 7, "fullyQualifiedName": "Predictive Intelligence Profiles.Value 4", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0253de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 7, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Value_4", "storageFieldReferenceID": { "type": "guid", "value": "28984526-60dc-4768-aaff-4018d9842e77" }, "valueDefinitionID": "0253de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Value_4", "name": "Value 4", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Value_5", "localizedDescription": { "value": "Value_5" }, "definitionID": "0353de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Value_5", "definitionName": { "value": "Value 5" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 8, "fullyQualifiedName": "Predictive Intelligence Profiles.Value 5", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "0353de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 8, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Value_5", "storageFieldReferenceID": { "type": "guid", "value": "aa50e6f3-6863-41fa-a536-8ed1d0fca989" }, "valueDefinitionID": "0353de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Value_5", "name": "Value 5", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Attribute_1", "localizedDescription": { "value": "Attribute_1" }, "definitionID": "f552de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_1", "definitionName": { "value": "Attribute 1" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 9, "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 1", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f552de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 9, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Attribute_1", "storageFieldReferenceID": { "type": "guid", "value": "16934a3e-d869-4b8c-b817-48ff5b554f30" }, "valueDefinitionID": "f552de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_1", "name": "Attribute 1", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Attribute_2", "localizedDescription": { "value": "Attribute_2" }, "definitionID": "f652de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_2", "definitionName": { "value": "Attribute 2" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 10, "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 2", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f652de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 10, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Attribute_2", "storageFieldReferenceID": { "type": "guid", "value": "121ce628-61aa-4344-91b1-7f27413a16e5" }, "valueDefinitionID": "f652de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_2", "name": "Attribute 2", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Attribute_3", "localizedDescription": { "value": "Attribute_3" }, "definitionID": "f752de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_3", "definitionName": { "value": "Attribute 3" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 11, "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 3", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f752de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 11, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Attribute_3", "storageFieldReferenceID": { "type": "guid", "value": "34e53678-e867-4526-9fd6-d31e2771a003" }, "valueDefinitionID": "f752de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_3", "name": "Attribute 3", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Attribute_4", "localizedDescription": { "value": "Attribute_4" }, "definitionID": "f852de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_4", "definitionName": { "value": "Attribute 4" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 12, "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 4", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f852de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 12, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Attribute_4", "storageFieldReferenceID": { "type": "guid", "value": "b3efb625-de9a-4eef-b6eb-6add451d2f7a" }, "valueDefinitionID": "f852de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_4", "name": "Attribute 4", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "Attribute_5", "localizedDescription": { "value": "Attribute_5" }, "definitionID": "f952de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Attribute_5", "definitionName": { "value": "Attribute 5" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 13, "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 5", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "f952de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 13, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "Attribute_5", "storageFieldReferenceID": { "type": "guid", "value": "f4836380-72eb-49c2-a8af-5a283d168683" }, "valueDefinitionID": "f952de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Attribute_5", "name": "Attribute 5", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "city", "localizedDescription": { "value": "city" }, "definitionID": "fa52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "City", "definitionName": { "value": "City" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 14, "fullyQualifiedName": "Predictive Intelligence Profiles.City", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "fa52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 14, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "city", "storageFieldReferenceID": { "type": "guid", "value": "486ae151-74f7-4b98-ba9b-6ad927399de9" }, "valueDefinitionID": "fa52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "City", "name": "City", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "region", "localizedDescription": { "value": "region" }, "definitionID": "fd52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Region", "definitionName": { "value": "Region" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 15, "fullyQualifiedName": "Predictive Intelligence Profiles.Region", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "fd52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 15, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "region", "storageFieldReferenceID": { "type": "guid", "value": "4b8bb8f1-0bcb-4201-9c26-fdd8e10c7ad8" }, "valueDefinitionID": "fd52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Region", "name": "Region", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, { "baseType": "Text", "dataSourceID": 5, "dataSourceName": {}, "dataType": "Text", "description": "country", "localizedDescription": { "value": "country" }, "definitionID": "fb52de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "Country", "definitionName": { "value": "Country" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 16, "fullyQualifiedName": "Predictive Intelligence Profiles.Country", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "length": 256, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "fb52de3f-31e2-e611-80cc-1402ec7222b4" }, "ordinal": 16, "parentDefinition": { "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "definitionKey": "PredictiveIntelProfiles", "definitionName": { "value": "Predictive Intelligence Profiles" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "country", "storageFieldReferenceID": { "type": "guid", "value": "f9e65e6a-45dc-4f08-9a44-715e6e4763f7" }, "valueDefinitionID": "fb52de3f-31e2-e611-80cc-1402ec7222b4", "valueDefinitionKey": "Country", "name": "Country", "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "setDefinitionName": { "value": "Predictive Intelligence Profiles" }, "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" } ], "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", "applicationKey": "com.exacttarget.Predictive Web", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, "canModify": false, "canRemove": false, "categoryID": 386, "createdBy": -1000, "createDate": "2017-01-24T06:33:00", "customObjectOwnerMID": 1111111, "dataRetentionProperties": { "isRowBasedRetention": false, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodUnitOfMeasure": 4, "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4" }, "localizedDescription": {}, "fullyQualifiedName": "Predictive Intelligence Profiles", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": true, "isRoot": false, "isSendable": false, "isShared": false, "isSystemDefined": true, "isTestaable": false, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 5, "storageLogicalType": "DataExtension", "storageName": "IGO_PROFILES", "storageObjectIDs": ["e352de3f-31e2-e611-80cc-1402ec7222b4"], "storageReferenceID": { "type": "guid", "value": "d452de3f-31e2-e611-80cc-1402ec7222b4" }, "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", "setDefinitionKey": "PredictiveIntelProfiles", "name": "Predictive Intelligence Profiles" }, { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "testExisting_dataExtensionShared", "definitionName": { "value": "testExisting_dataExtensionShared" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "relationships": [ { "canModify": true, "canRemove": true, "isHidden": false, "isSystemDefined": false, "isGroupToSetRelationship": true, "leftItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "79846c6e-5238-ee11-b85a-48df37d1de8a", "relationshipType": "AttributeGroup" }, "leftRelationshipIDs": [ { "type": "int16", "value": "3" } ], "leftRelationshipReferenceType": "CustomerData", "relationshipAttributes": [ { "leftAttributeID": "9393dc39-31e2-e611-80cc-1402ec7222b4", "leftConnectingID": { "identifierType": "FullyQualifiedName" }, "rightAttributeID": "558b787a-5238-ee11-b85a-48df37d1de8a", "rightConnectingID": { "identifierType": "FullyQualifiedName" } } ], "relationshipID": "598b787a-5238-ee11-b85a-48df37d1de8a", "rightItem": { "cardinality": "One", "connectingID": { "identifierType": "FullyQualifiedName" }, "identifier": "528b787a-5238-ee11-b85a-48df37d1de8a", "relationshipType": "AttributeSet" } } ], "valueDefinitions": [ { "baseType": "Numeric", "dataSourceName": {}, "dataType": "LongNumber", "description": "", "localizedDescription": { "value": "" }, "definitionID": "548b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "CustomObjectKey", "definitionName": { "value": "Custom Object Key" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "fullyQualifiedName": "testExisting_dataExtensionShared.Custom Object Key", "isHidden": true, "isIdentityValue": true, "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": true, "parentDefinition": { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "testExisting_dataExtensionShared", "definitionName": { "value": "testExisting_dataExtensionShared" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "_CustomObjectKey", "valueDefinitionID": "548b787a-5238-ee11-b85a-48df37d1de8a", "valueDefinitionKey": "CustomObjectKey", "name": "Custom Object Key", "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "setDefinitionKey": "testExisting_dataExtensionShared", "setDefinitionName": { "value": "testExisting_dataExtensionShared" }, "parentIdentifier": "528b787a-5238-ee11-b85a-48df37d1de8a" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "588b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "FirstName", "definitionName": { "value": "FirstName" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 0, "fullyQualifiedName": "testExisting_dataExtensionShared.FirstName", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "588b787a-5238-ee11-b85a-48df37d1de8a" }, "ordinal": 0, "parentDefinition": { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "testExisting_dataExtensionShared", "definitionName": { "value": "testExisting_dataExtensionShared" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "FirstName", "storageFieldReferenceID": { "type": "guid", "value": "391bfc9e-ea85-4610-a24b-d8400a36cdfc" }, "valueDefinitionID": "588b787a-5238-ee11-b85a-48df37d1de8a", "valueDefinitionKey": "FirstName", "name": "FirstName", "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "setDefinitionKey": "testExisting_dataExtensionShared", "setDefinitionName": { "value": "testExisting_dataExtensionShared" }, "parentIdentifier": "528b787a-5238-ee11-b85a-48df37d1de8a" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "578b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "LastName", "definitionName": { "value": "LastName" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 1, "fullyQualifiedName": "testExisting_dataExtensionShared.LastName", "isHidden": false, "isIdentityValue": false, "isNullable": true, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 55, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "578b787a-5238-ee11-b85a-48df37d1de8a" }, "ordinal": 1, "parentDefinition": { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "testExisting_dataExtensionShared", "definitionName": { "value": "testExisting_dataExtensionShared" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "LastName", "storageFieldReferenceID": { "type": "guid", "value": "3f80ba1f-f957-400f-88cb-a9303491026d" }, "valueDefinitionID": "578b787a-5238-ee11-b85a-48df37d1de8a", "valueDefinitionKey": "LastName", "name": "LastName", "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "setDefinitionKey": "testExisting_dataExtensionShared", "setDefinitionName": { "value": "testExisting_dataExtensionShared" }, "parentIdentifier": "528b787a-5238-ee11-b85a-48df37d1de8a" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "EmailAddress", "description": "", "localizedDescription": { "value": "" }, "definitionID": "568b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "EmailAddress", "definitionName": { "value": "EmailAddress" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 2, "fullyQualifiedName": "testExisting_dataExtensionShared.EmailAddress", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": false, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 254, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "568b787a-5238-ee11-b85a-48df37d1de8a" }, "ordinal": 2, "parentDefinition": { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "testExisting_dataExtensionShared", "definitionName": { "value": "testExisting_dataExtensionShared" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "EmailAddress", "storageFieldReferenceID": { "type": "guid", "value": "41b9575b-da06-41ed-8551-f76868451a51" }, "valueDefinitionID": "568b787a-5238-ee11-b85a-48df37d1de8a", "valueDefinitionKey": "EmailAddress", "name": "EmailAddress", "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "setDefinitionKey": "testExisting_dataExtensionShared", "setDefinitionName": { "value": "testExisting_dataExtensionShared" }, "parentIdentifier": "528b787a-5238-ee11-b85a-48df37d1de8a" }, { "baseType": "Text", "dataSourceName": {}, "dataType": "Text", "description": "", "localizedDescription": { "value": "" }, "definitionID": "558b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "ContactKey", "definitionName": { "value": "ContactKey" }, "connectingID": { "identifierType": "FullyQualifiedName" }, "displayOrder": 4, "fullyQualifiedName": "testExisting_dataExtensionShared.ContactKey", "isHidden": false, "isIdentityValue": false, "isNullable": false, "isPrimaryKey": true, "isReadOnly": false, "isSystemDefined": false, "isUpdateable": true, "length": 50, "obfuscationProperties": { "maskType": "None", "maskTypeID": 0, "storageTypeID": 1, "storageType": "Plain", "valueDefinitionID": "558b787a-5238-ee11-b85a-48df37d1de8a" }, "ordinal": 4, "parentDefinition": { "definitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "definitionKey": "testExisting_dataExtensionShared", "definitionName": { "value": "testExisting_dataExtensionShared" }, "connectingID": { "identifierType": "FullyQualifiedName" } }, "parentType": "Set", "storageName": "ContactKey", "storageFieldReferenceID": { "type": "guid", "value": "49d0db37-dff0-49d9-9d82-eb29b345f238" }, "valueDefinitionID": "558b787a-5238-ee11-b85a-48df37d1de8a", "valueDefinitionKey": "ContactKey", "name": "ContactKey", "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "setDefinitionKey": "testExisting_dataExtensionShared", "setDefinitionName": { "value": "testExisting_dataExtensionShared" }, "parentIdentifier": "528b787a-5238-ee11-b85a-48df37d1de8a" } ], "attributeCount": 0, "canAddValues": true, "canChangeValues": true, "canModify": true, "canRemove": true, "categoryID": 89356, "createdBy": 700301950, "createDate": "2023-08-11T08:22:00", "customObjectOwnerMID": 7281698, "dataRetentionProperties": { "isRowBasedRetention": true, "isResetRetentionPeriodOnImport": false, "isDeleteAtEndOfRetentionPeriod": false, "periodLength": 6, "periodUnitOfMeasure": 5, "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a" }, "localizedDescription": { "value": "Container for my test emails" }, "fullyQualifiedName": "testExisting_dataExtensionShared", "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, "isReadOnly": false, "isRoot": false, "isSendable": true, "isShared": true, "isSystemDefined": false, "isTestaable": true, "parentID": "00000000-0000-0000-0000-000000000000", "relationshipCount": 1, "sendAttributeStorageName": "ContactKey", "sendContactKeyStorageName": "_SubscriberKey", "storageLogicalType": "DataExtension", "storageName": "testExisting_dataExtensionShared", "storageObjectIDs": ["5b8b787a-5238-ee11-b85a-48df37d1de8a"], "storageReferenceID": { "type": "guid", "value": "21711373-72c1-ec11-b83b-shared" }, "setDefinitionID": "528b787a-5238-ee11-b85a-48df37d1de8a", "setDefinitionKey": "testExisting_dataExtensionShared", "name": "testExisting_dataExtensionShared" } ], "responseContext": { "operationStatus": "OK", "schemaType": "Contacts", "populateInternalProperties": false }, "requestServiceMessageID": "ae488366-fa20-449a-ba74-ee353a7ab446", "responseDateTime": "2023-07-12T09:17:32.1332068-06:00", "resultMessages": [], "serviceMessageID": "3206d5b6-f603-4049-bce8-6afce627a7c6" } ================================================ FILE: test/resources/9999999/importDefinition/retrieve-CustomerKey=testExisting_importFile-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:58a4181c-9ea7-4d26-835b-f1eb50877b0b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:dab39bb4-2262-453a-9cb1-c591db9222d9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-b8a68a2b-ad18-4ac0-8cea-dabe7d7d55c9"> <wsu:Created>2024-01-25T21:59:01Z</wsu:Created> <wsu:Expires>2024-01-25T22:04:01Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>fdc476c9-46dc-43f5-b8a6-57f2299c65ac</RequestID> <Results xsi:type="ImportDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>9d16f42c-2260-ed11-b849-48df37d1de8b</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/importDefinition/retrieve-Name=testExisting_importFile-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:58a4181c-9ea7-4d26-835b-f1eb50877b0b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:dab39bb4-2262-453a-9cb1-c591db9222d9</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-b8a68a2b-ad18-4ac0-8cea-dabe7d7d55c9"> <wsu:Created>2024-01-25T21:59:01Z</wsu:Created> <wsu:Expires>2024-01-25T22:04:01Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>fdc476c9-46dc-43f5-b8a6-57f2299c65ac</RequestID> <Results xsi:type="ImportDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>9d16f42c-2260-ed11-b849-48df37d1de8b</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/importFile/build-expected.json ================================================ { "allowErrors": true, "c__blankFileProcessing": "Skip", "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "customerKey": "testTemplated_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "17.11.2022", "encodingName": "utf-8", "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "blabla", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "name": "testTemplated_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testTemplated_dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/resources/9999999/importFile/get-dataImport-expected.json ================================================ { "allowErrors": true, "customerKey": "testExisting_importFileDataImport", "createdDate": "2024-07-24T04:10:42.15", "modifiedDate": "2024-07-24T04:10:42.15", "dateFormatLocale": "en-US", "deleteFile": false, "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "_CustomObject", "fileSpec": "_CustomObject", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxImportFrequencyHours": 0, "maxFileAgeScheduleOffsetHours": 0, "name": "testExisting_importFileDataImport", "sendEmailNotification": false, "standardQuotedStrings": true, "encodingName": "utf-8", "c__blankFileProcessing": "Fail", "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_journey_Quicksend" }, "source": { "c__type": "DataExtension", "r__fileLocation_name": "ExactTarget Enhanced FTP", "r__dataExtension_key": "testExisting_dataExtension" }, "c__subscriberImportType": "DataExtension", "c__dataAction": "Overwrite" } ================================================ FILE: test/resources/9999999/importFile/get-expected.json ================================================ { "allowErrors": true, "c__blankFileProcessing": "Skip", "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "createdDate": "2022-11-09T05:32:30.533", "customerKey": "testExisting_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "17.11.2022", "encodingName": "utf-8", "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "blabla", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "modifiedDate": "2022-11-17T07:13:03.95", "name": "testExisting_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/resources/9999999/importFile/get-sms-expected.json ================================================ { "allowErrors": true, "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "createdDate": "2022-11-24T03:29:01.05", "customerKey": "testExisting_importFileSMS", "dateFormatLocale": "en-US", "deleteFile": false, "description": "Unsub for Keyword", "fieldMappingType": "ManualMap", "fieldMappings": [ { "destinationFieldName": "_CountryCode", "sourceFieldName": "Locale" }, { "destinationFieldName": "_FirstName", "sourceFieldName": "FirstName" }, { "destinationFieldName": "_IsHonorDST", "sourceFieldName": "IsHonorDST" }, { "destinationFieldName": "_LastName", "sourceFieldName": "LastName" }, { "destinationFieldName": "_MobileNumber", "sourceFieldName": "MobileNumber" }, { "destinationFieldName": "_Status", "sourceFieldName": "Status" }, { "destinationFieldName": "_SubscriberKey", "sourceFieldName": "ContactKey" }, { "destinationFieldName": "_UTCOffset", "sourceFieldName": "UTCoffset" }, { "destinationFieldName": "Action", "sourceFieldName": "Action" }, { "destinationFieldName": "SalesforceModified", "sourceFieldName": "ModifiedDate" }, { "destinationFieldName": "SFContactID", "sourceFieldName": "SFContactID" } ], "fileNamingPattern": "_CustomObject", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": false, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "modifiedDate": "2023-07-19T23:06:33.577", "name": "testExisting_importFileSMS", "notificationEmailAddress": "joern.berkefeld@accenture.com", "sendEmailNotification": true, "standardQuotedStrings": false, "destination": { "c__type": "SMS", "r__mobileKeyword_key": "4912312345678.TESTEXISTING_KEYWORD" }, "source": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_dataExtension", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/resources/9999999/importFile/patch-expected.json ================================================ { "allowErrors": true, "c__blankFileProcessing": "Process", "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "createdDate": "2022-11-09T05:32:30.533", "customerKey": "testExisting_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "updated on deploy", "encodingName": "utf-8", "fieldMappings": [], "fieldMappingType": "InferFromColumnHeadings", "fileNamingPattern": "blabla", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "modifiedDate": "2023-07-18T09:11:26.19", "name": "testExisting_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/resources/9999999/importFile/post-expected.json ================================================ { "allowErrors": true, "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "createdDate": "2022-11-09T05:53:03.243", "customerKey": "testNew_importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "created via deploy", "fieldMappingType": "InferFromColumnHeadings", "fieldMappings": [], "fileNamingPattern": "blabla", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "modifiedDate": "2023-07-18T09:11:26.19", "name": "testNew_importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "destination": { "c__type": "DataExtension", "r__dataExtension_key": "testExisting_dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/resources/9999999/importFile/template-expected.json ================================================ { "allowErrors": true, "c__blankFileProcessing": "Skip", "c__dataAction": "AddUpdate", "c__subscriberImportType": "DataExtension", "customerKey": "{{{prefix}}}importFile", "dateFormatLocale": "en-US", "deleteFile": false, "description": "17.11.2022", "encodingName": "utf-8", "fieldMappingType": "InferFromColumnHeadings", "fieldMappings": [], "fileNamingPattern": "blabla", "fileType": "CSV", "filter": "", "hasColumnHeader": true, "isOrderedImport": true, "isSequential": true, "maxFileAgeHours": 0, "maxFileAgeScheduleOffsetHours": 0, "maxImportFrequencyHours": 0, "name": "{{{prefix}}}importFile", "sendEmailNotification": false, "standardQuotedStrings": true, "destination": { "c__type": "DataExtension", "r__dataExtension_key": "{{{prefix}}}dataExtension" }, "source": { "c__type": "File Location", "r__fileLocation_name": "ExactTarget Enhanced FTP" } } ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/get-response.json ================================================ { "count": 5, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": "161b64a1-1867-4272-8c5c-4d7abe880702", "type": "AutomationAudience", "name": "testExisting_event_automation", "description": "", "createdDate": "2024-11-07T04:58:46.51", "createdBy": 700301950, "modifiedDate": "2024-11-07T04:58:46.51", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "testExisting_event_automation", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7", "dataExtensionName": "testExisting_automation_event", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "arguments": { "serializedObjectType": 9, "useHighWatermark": true, "resetHighWatermark": false, "automationId": "8f82c2a7-0bae-45a9-bdee-e631ab25c0d5", "eventDefinitionId": "161b64a1-1867-4272-8c5c-4d7abe880702", "eventDefinitionKey": "testExisting_event_automation", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7", "criteria": "" }, "configurationArguments": { "unconfigured": false }, "metaData": { "criteriaDescription": "", "scheduleFlowMode": "automation" }, "schedule": { "startDateTime": "2024-11-07T12:15:00", "endDateTime": "2079-06-06T00:00:00", "timeZone": "W. Europe Standard Time", "occurrences": 478403, "endType": "EndDate", "frequency": "Hourly", "recurrencePattern": "Interval", "interval": 1 }, "interactionCount": 1, "isVisibleInPicker": false, "isPlatformObject": false, "category": "Audience", "publishedInteractionCount": 1, "automationId": "8f82c2a7-0bae-45a9-bdee-e631ab25c0d5", "disableDEDataLogging": false }, { "id": "33b4dbc5-4b58-4a54-ab57-24388f1eefe4", "type": "APIEvent", "name": "TestContact_Event", "description": "", "createdDate": "2018-08-03T07:55:27.38", "createdBy": 700301950, "modifiedDate": "2018-08-03T08:22:03.76", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "APIEvent-60130566-e2fe-eb29-4140-15c27093a80b", "dataExtensionId": "1c8064d5-6502-ef11-a5c8-5cba2c702db8", "dataExtensionName": "testExisting_journey_Quicksend", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "filterDefinitionTemplate": "", "iconUrl": "/events/images/icon_journeyBuilder-event-api-blue.svg", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "APIEvent-60130566-e2fe-eb29-4140-15c27093a80b", "dataExtensionId": "C25D5A59-5EBC-40C9-8D27-149831881D89", "automationId": "00000000-0000-0000-0000-000000000000", "criteria": "", "useHighWatermark": false }, "metaData": { "scheduleState": "No Schedule", "criteriaDescription": "" }, "interactionCount": 1, "isVisibleInPicker": true, "isPlatformObject": false, "category": "Event", "publishedInteractionCount": 1, "automationId": "00000000-0000-0000-0000-000000000000", "disableDEDataLogging": false }, { "id": "9e1995f8-951d-4019-855c-826b45e5b028", "type": "EmailAudience", "name": "testExisting_journey_Quicksend", "description": "", "createdDate": "2024-04-24T12:18:40.573", "createdBy": 700301950, "modifiedDate": "2024-04-24T12:18:40.573", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "dataExtensionId": "1c8064d5-6502-ef11-a5c8-5cba2c702db8", "dataExtensionName": "testExisting_journey_Quicksend", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "arguments": { "serializedObjectType": 3, "useHighWatermark": false, "eventDefinitionId": "9e1995f8-951d-4019-855c-826b45e5b028", "eventDefinitionKey": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "dataExtensionId": "1c8064d5-6502-ef11-a5c8-5cba2c702db8", "criteria": "" }, "configurationArguments": { "unconfigured": false }, "metaData": { "criteriaDescription": "", "scheduleFlowMode": "runOnce", "runOnceScheduleMode": "onPublish", "scheduleState": "No Schedule" }, "interactionCount": 1, "isVisibleInPicker": false, "isPlatformObject": false, "category": "Audience", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000", "disableDEDataLogging": false }, { "id": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "type": "EmailAudience", "name": "testExisting_journey_Multistep", "description": "", "createdDate": "2024-05-04T05:54:44.95", "createdBy": 700301950, "modifiedDate": "2024-05-04T05:54:44.95", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "dataExtensionId": "ed305df3-6502-ef11-a5c8-5cba2c702db8", "dataExtensionName": "testExisting_journey_Multistep", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "arguments": { "serializedObjectType": 3, "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "dataExtensionId": "ed305df3-6502-ef11-a5c8-5cba2c702db8", "criteria": "" }, "configurationArguments": { "unconfigured": true }, "metaData": { "criteriaDescription": "", "scheduleState": "No Schedule" }, "interactionCount": 1, "isVisibleInPicker": false, "isPlatformObject": false, "category": "Audience", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000", "disableDEDataLogging": false }, { "id": "d8d57832-ce9c-4bf6-8c24-3044ece5dffd", "type": "APIEvent", "name": "testExisting_event", "description": "", "createdDate": "2024-07-05T06:12:24.227", "createdBy": 700301950, "modifiedDate": "2024-07-05T08:01:55.4", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "testExisting_event", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "dataExtensionName": "testExisting_event - 2024-07-05T080154625", "schema": { "id": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "name": "testExisting_event - 2024-07-05T080154625", "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey", "isPlatformObject": false }, "sourceApplicationExtensionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "testExisting_event", "eventDefinitionId": "d8d57832-ce9c-4bf6-8c24-3044ece5dffd", "dataExtensionId": "00000000-0000-0000-0000-000000000000", "criteria": "" }, "metaData": { "scheduleState": "No Schedule" }, "interactionCount": 0, "isVisibleInPicker": true, "isPlatformObject": false, "category": "Event", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000", "disableDEDataLogging": false } ] } ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/key_DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e/get-response.json ================================================ { "id": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "type": "EmailAudience", "name": "testExisting_journey_Multistep", "description": "", "createdDate": "2024-05-04T05:54:44.95", "createdBy": 700301950, "modifiedDate": "2024-05-04T05:54:44.95", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "dataExtensionId": "ed305df3-6502-ef11-a5c8-5cba2c702db8", "dataExtensionName": "testExisting_journey_Multistep", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "arguments": { "serializedObjectType": 3, "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "dataExtensionId": "ed305df3-6502-ef11-a5c8-5cba2c702db8", "criteria": "" }, "configurationArguments": { "unconfigured": true }, "metaData": { "criteriaDescription": "", "scheduleState": "No Schedule" }, "interactionCount": 1, "isVisibleInPicker": false, "isPlatformObject": false, "category": "Audience", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000", "disableDEDataLogging": false } ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/key_testExisting_event/delete-response.txt ================================================ ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/key_testExisting_event/put-response.json ================================================ { "id": "d8d57832-ce9c-4bf6-8c24-3044ece5dffd", "type": "APIEvent", "name": "testExisting_event", "description": "updated on deploy", "createdDate": "0001-01-01T00:00:00", "createdBy": 0, "modifiedDate": "0001-01-01T00:00:00", "modifiedBy": 0, "mode": "Production", "eventDefinitionKey": "testExisting_event", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "schema": { "id": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "name": "testExisting_event - 2024-07-05T080154625", "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey", "isPlatformObject": false }, "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "testExisting_event", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "eventDefinitionId": "d8d57832-ce9c-4bf6-8c24-3044ece5dffd" }, "metaData": {}, "interactionCount": 0, "isVisibleInPicker": false, "isPlatformObject": false, "category": "Event", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000" } ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/key_testExisting_event_automation/get-response.json ================================================ { "id": "161b64a1-1867-4272-8c5c-4d7abe880702", "type": "AutomationAudience", "name": "testExisting_event_automation", "description": "", "createdDate": "2024-11-07T04:58:46.51", "createdBy": 700301950, "modifiedDate": "2024-11-07T04:58:46.51", "modifiedBy": 700301950, "mode": "Production", "eventDefinitionKey": "testExisting_event_automation", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7", "dataExtensionName": "testExisting_dataExtension", "sourceApplicationExtensionId": "97e942ee-6914-4d3d-9e52-37ecb71f79ed", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "filterDefinitionTemplate": "", "iconUrl": "/images/icon-data-extension.svg", "arguments": { "serializedObjectType": 9, "useHighWatermark": true, "resetHighWatermark": false, "automationId": "8f82c2a7-0bae-45a9-bdee-e631ab25c0d5", "eventDefinitionId": "161b64a1-1867-4272-8c5c-4d7abe880702", "eventDefinitionKey": "testExisting_event_automation", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7", "criteria": "" }, "configurationArguments": { "unconfigured": false }, "metaData": { "criteriaDescription": "", "scheduleFlowMode": "automation" }, "schedule": { "startDateTime": "2024-11-07T12:15:00", "endDateTime": "2079-06-06T00:00:00", "timeZone": "W. Europe Standard Time", "occurrences": 478403, "endType": "EndDate", "frequency": "Hourly", "recurrencePattern": "Interval", "interval": 1 }, "interactionCount": 1, "isVisibleInPicker": false, "isPlatformObject": false, "category": "Audience", "publishedInteractionCount": 1, "automationId": "8f82c2a7-0bae-45a9-bdee-e631ab25c0d5", "disableDEDataLogging": false } ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/post_withExistingDE-response.json ================================================ { "id": "21ab68de-2e2f-40b2-b455-c977cbdd4335", "type": "APIEvent", "name": "testNew_event_withExistingDE", "description": "created on deploy", "createdDate": "0001-01-01T00:00:00", "createdBy": 0, "modifiedDate": "0001-01-01T00:00:00", "modifiedBy": 0, "mode": "Production", "eventDefinitionKey": "testNew_event_withExistingDE", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8", "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "testNew_event_withExistingDE", "eventDefinitionId": "21ab68de-2e2f-40b2-b455-c977cbdd4335", "dataExtensionId": "f2cc2b21-d73a-ef11-a5c8-5cba2c702db8" }, "metaData": {}, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000" } ================================================ FILE: test/resources/9999999/interaction/v1/eventDefinitions/post_withSchema-response.json ================================================ { "id": "b9cb2b05-738d-4f49-b53d-28e3bbe52d12", "type": "APIEvent", "name": "testNew_event_withSchema", "description": "created on deploy", "createdDate": "0001-01-01T00:00:00", "createdBy": 0, "modifiedDate": "0001-01-01T00:00:00", "modifiedBy": 0, "mode": "Production", "eventDefinitionKey": "testNew_event_withSchema", "iconUrl": "/images/icon_journeyBuilder-event-api-blue.svg", "sourceApplicationExtensionId": "7db1f972-f8b7-49b6-91b5-fa218e13953d", "dataExtensionId": "4342972c-a43c-ef11-a5c8-5cba2c702db8", "dataExtensionName": "testNew_event_withSchema - 2024-07-08T014814443", "schema": { "id": "4342972c-a43c-ef11-a5c8-5cba2c702db8", "name": "testNew_event_withSchema - 2024-07-08T014814443", "fields": [ { "name": "ContactId", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Type", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Status", "dataType": "Text", "maxLength": "50", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Respondent", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "LastName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "PreferredLanguage", "dataType": "Text", "maxLength": "50", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TouchPoint", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Datestamp", "dataType": "Date", "isNullable": true, "defaultValue": "GetDate()", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "StartDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "EndDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "BroadcastedNotificationDate", "dataType": "Date", "isNullable": true, "defaultValue": "", "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderDate", "dataType": "Date", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Title", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "DisplayName", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Text", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Description", "dataType": "Text", "maxLength": "4000", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Channel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "FirstReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "SecondReminderChannel", "dataType": "Text", "maxLength": "256", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "Email", "dataType": "Email", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "ArticleOrTaskID", "dataType": "Text", "maxLength": "18", "isNullable": false, "isPrimaryKey": true, "isDevicePreference": false }, { "name": "Points", "dataType": "Number", "maxLength": "", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskType", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false }, { "name": "TaskArea", "dataType": "Text", "maxLength": "255", "isNullable": true, "isPrimaryKey": false, "isDevicePreference": false } ], "sendableCustomObjectField": "ContactId", "sendableSubscriberField": "_SubscriberKey", "isPlatformObject": false }, "filterDefinitionId": "00000000-0000-0000-0000-000000000000", "arguments": { "serializedObjectType": 11, "eventDefinitionKey": "testNew_event_withSchema", "eventDefinitionId": "b9cb2b05-738d-4f49-b53d-28e3bbe52d12", "dataExtensionId": "00000000-0000-0000-0000-000000000000" }, "metaData": {}, "interactionCount": 0, "isVisibleInPicker": true, "category": "Event", "publishedInteractionCount": 0, "automationId": "00000000-0000-0000-0000-000000000000" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/audit/all/get-response-versionNumber=1.json ================================================ { "count": 5, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Stop", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-24T02:00:00.73", "key": "testExisting_journey_Multistep", "versionNumber": 1, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Publish", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-09-05T01:58:55.43", "key": "testExisting_journey_Multistep", "versionNumber": 1, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production", "publishStatus": "PublishCompleted", "publishRequestId": "98c2d709-5c9a-4610-804b-ae8f72ff29ce" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Publish", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-09-05T01:58:04.913", "key": "testExisting_journey_Multistep", "versionNumber": 1, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production", "publishStatus": "PublishCompleted", "publishRequestId": "651bc5e1-688a-4d68-bc51-c404bc20bf9c" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Modify", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-09-05T01:57:55.043", "key": "testExisting_journey_Multistep", "versionNumber": 1, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Create", "user": { "name": "joern.berkefeld app user", "userId": 710420432 }, "timeStamp": "2024-09-04T06:50:21.85", "key": "testExisting_journey_Multistep", "versionNumber": 1, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/audit/all/get-response-versionNumber=2.json ================================================ { "count": 6, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Stop", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-28T08:03:18.297", "key": "testExisting_journey_Multistep", "versionNumber": 2, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Publish", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-24T02:11:04.73", "key": "testExisting_journey_Multistep", "versionNumber": 2, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production", "publishStatus": "PublishCompleted", "publishRequestId": "1d100137-575d-40d9-9266-0e3be8461190" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Publish", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-24T02:09:55.743", "key": "testExisting_journey_Multistep", "versionNumber": 2, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production", "publishStatus": "PublishCompleted", "publishRequestId": "6e9efccd-7561-4385-a8ca-cba45342183a" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Modify", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-24T02:09:43.423", "key": "testExisting_journey_Multistep", "versionNumber": 2, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Modify", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-24T02:08:32.047", "key": "testExisting_journey_Multistep", "versionNumber": 2, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Create", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-24T02:00:17.683", "key": "testExisting_journey_Multistep", "versionNumber": 2, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/audit/all/get-response-versionNumber=3.json ================================================ { "count": 6, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Stop", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-11-26T08:07:00.867", "key": "testExisting_journey_Multistep", "versionNumber": 3, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Publish", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-28T08:05:01.087", "key": "testExisting_journey_Multistep", "versionNumber": 3, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production", "publishStatus": "PublishCompleted", "publishRequestId": "f91be603-e9d0-4f12-b75a-6f4d6dae760c" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Publish", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-28T08:04:22.4", "key": "testExisting_journey_Multistep", "versionNumber": 3, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production", "publishStatus": "PublishCompleted", "publishRequestId": "8ee64518-181d-4c49-b1ba-de8314c306dd" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Modify", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-28T08:04:14.607", "key": "testExisting_journey_Multistep", "versionNumber": 3, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "action": "Create", "user": { "name": "Jörn Berkefeld", "userId": 710355723 }, "timeStamp": "2024-10-28T08:03:21.383", "key": "testExisting_journey_Multistep", "versionNumber": 3, "originalDefinitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "name": "testExisting_journey_Multistep", "description": "", "executionMode": "Production" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/delete-response-versionNumber=1.txt ================================================ 0175b971-71a3-4d8e-98ac-48121f3fbf4f ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/delete-response.txt ================================================ 0175b971-71a3-4d8e-98ac-48121f3fbf4f ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/get-response-versionNumber=1.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSendId": "b3150cf0-6e78-e811-80d4-1402ec721c9d", "triggeredSendKey": "testExisting_triggeredSend", "triggeredSend": { "id": "outdated id", "key": "outdated key", "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "testExisting_ email subject", "emailId": 808714, "emailSubject": "testExisting_ email subject", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Published", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/get-response-versionNumber=3.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 3, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSendId": "b3150cf0-6e78-e811-80d4-1402ec721c9d", "triggeredSendKey": "testExisting_triggeredSend", "triggeredSend": { "id": "outdated id", "key": "outdated key", "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "testExisting_ email subject", "emailId": 808714, "emailSubject": "testExisting_ email subject", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Published", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/get-response.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSendId": "b3150cf0-6e78-e811-80d4-1402ec721c9d", "triggeredSendKey": "testExisting_triggeredSend", "triggeredSend": { "id": "outdated id", "key": "outdated key", "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "testExisting_ email subject", "emailId": 808714, "emailSubject": "testExisting_ email subject", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/delete-response.txt ================================================ 3c3f4112-9b43-43ca-8a89-aa0375b2c1a2 ================================================ FILE: test/resources/9999999/interaction/v1/interactions/3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/get-response.json ================================================ { "id": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "id": "e20dcaa3-a750-44cf-9ce8-42d00378b8b4", "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "ccEmail": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "created": {}, "description": "my activity info text", "domainExclusions": [ { "id": "5a7194ad-6602-ef11-a5c8-5cba2c702db8", "name": "testExisting_DomainExclusion" } ], "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "emailId": 531213, "emailSubject": "testExisting_ email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "priority": 3, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "suppressionLists": [ { "id": 75520, "name": "testExisting_suppressionList" } ], "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "abe42b4d-736d-4d26-a8f0-ce67d410782f", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "eventDefinitionId": "9e1995f8-951d-4019-855c-826b45e5b028", "eventDefinitionKey": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/dsfdsafdsa-922c-4568-85a5-e5cc77efc3be/audit/all/get-response-versionNumber=1.json ================================================ { "count": 1, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "action": "Delete", "user": { "name": "joern.berkefeld app user", "userId": 710420432 }, "timeStamp": "2024-10-02T09:37:07.99", "key": "testExisting_temail", "versionNumber": 1, "originalDefinitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "name": "testExisting_temail", "description": "", "executionMode": "Production" }, { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "action": "Create", "user": { "name": "joern.berkefeld app user", "userId": 710420432 }, "timeStamp": "2024-10-01T07:07:51.967", "key": "testExisting_temail", "versionNumber": 1, "originalDefinitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "name": "testExisting_temail", "description": "", "executionMode": "Production" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/dsfdsafdsa-922c-4568-85a5-e5cc77efc3be/audit/all/get-response-versionNumber=2.json ================================================ { "count": 3, "page": 1, "pageSize": 50, "links": {}, "items": [ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "action": "Modify", "user": { "name": "Jörn Berkefeld", "userId": 710420418 }, "timeStamp": "2024-10-04T09:17:51.967", "key": "testExisting_temail", "versionNumber": 2, "originalDefinitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "name": "testExisting_temail", "description": "", "executionMode": "Production" }, { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "action": "Modify", "user": { "name": "joern.berkefeld app user", "userId": 710420432 }, "timeStamp": "2024-10-04T07:07:51.967", "key": "testExisting_temail", "versionNumber": 2, "originalDefinitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "name": "testExisting_temail", "description": "", "executionMode": "Production" }, { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "action": "Create", "user": { "name": "joern.berkefeld app user", "userId": 710420432 }, "timeStamp": "2024-10-03T07:07:51.967", "key": "testExisting_temail", "versionNumber": 2, "originalDefinitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "name": "testExisting_temail", "description": "", "executionMode": "Production" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/dsfdsafdsa-922c-4568-85a5-e5cc77efc3be/delete-response.txt ================================================ dsfdsafdsa-922c-4568-85a5-e5cc77efc3be ================================================ FILE: test/resources/9999999/interaction/v1/interactions/get-response-status=Published.json ================================================ { "count": 1, "page": 1, "pageSize": 500, "links": {}, "items": [ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 2, "workflowApiVersion": 1, "createdDate": "2022-03-24T02:20:32.74", "modifiedDate": "2022-03-24T02:20:40.45", "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "categoryId": 6298, "status": "Published", "scheduledStatus": "Draft", "definitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/get-response.json ================================================ { "count": 6, "page": 1, "pageSize": 500, "links": {}, "items": [ { "id": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": [ "{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "scheduledStatus": "Draft" }, { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 3, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T05:54:48.027", "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" }, { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 2, "workflowApiVersion": 1, "createdDate": "2022-03-24T02:20:32.74", "modifiedDate": "2022-03-24T02:20:40.45", "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "categoryId": 6298, "status": "Published", "scheduledStatus": "Draft", "definitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be" }, { "id": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "key": "testExisting_temail_notPublished", "name": "testExisting_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-08-23T00:29:39.55", "modifiedDate": "2024-08-23T00:29:39.55", "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "scheduledStatus": "Draft" }, { "key": "testExisting_journey_updatecontact", "name": "testExisting_journey_updatecontact", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" }, { "key": "testExisting_journey_updatecontact_sharedDE", "name": "testExisting_journey_updatecontact_sharedDE", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Multistep/get-response-versionNumber=1.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSendId": "b3150cf0-6e78-e811-80d4-1402ec721c9d", "triggeredSendKey": "wrong key", "triggeredSend": { "id": "outdated id", "key": "outdated key", "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "testExisting_ email subject", "emailId": 808714, "emailSubject": "testExisting_ email subject", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Multistep/get-response.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSendId": "b3150cf0-6e78-e811-80d4-1402ec721c9d", "triggeredSendKey": "wrong key", "triggeredSend": { "id": "outdated id", "key": "outdated key", "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "testExisting_ email subject", "emailId": 808714, "emailSubject": "testExisting_ email subject", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Multistep/put-response.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "id": "342dd0aa-a6be-401e-8614-3538800bfd7c", "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "id": "7ba1e59a-6be4-46c7-b76f-4c06feb1268a", "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSendId": "b3150cf0-6e78-e811-80d4-1402ec721c9d", "triggeredSendKey": "wrong key", "triggeredSend": { "id": "outdated id", "key": "outdated key", "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "testExisting_ email subject", "emailId": 808714, "emailSubject": "testExisting_ email subject", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "70572b1a-e274-4f09-a3fa-6fc0732ec52b", "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "e2a486cf-c85f-4543-88a2-d579cac1e0de", "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Quicksend/get-response-versionNumber=1.json ================================================ { "id": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "id": "e20dcaa3-a750-44cf-9ce8-42d00378b8b4", "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "ccEmail": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "created": {}, "description": "my activity info text", "domainExclusions": [ { "id": "5a7194ad-6602-ef11-a5c8-5cba2c702db8", "name": "testExisting_DomainExclusion" } ], "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "emailId": 531213, "emailSubject": "testExisting_ email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "priority": 3, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "suppressionLists": [ { "id": 75520, "name": "testExisting_suppressionList" } ], "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "abe42b4d-736d-4d26-a8f0-ce67d410782f", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "eventDefinitionId": "9e1995f8-951d-4019-855c-826b45e5b028", "eventDefinitionKey": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Quicksend/get-response.json ================================================ { "id": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "id": "e20dcaa3-a750-44cf-9ce8-42d00378b8b4", "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "ccEmail": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "created": {}, "description": "my activity info text", "domainExclusions": [ { "id": "5a7194ad-6602-ef11-a5c8-5cba2c702db8", "name": "testExisting_DomainExclusion" } ], "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "emailId": 531213, "emailSubject": "testExisting_ email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "priority": 3, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "suppressionLists": [ { "id": 75520, "name": "testExisting_suppressionList" } ], "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "abe42b4d-736d-4d26-a8f0-ce67d410782f", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "eventDefinitionId": "9e1995f8-951d-4019-855c-826b45e5b028", "eventDefinitionKey": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "3c3f4112-9b43-43ca-8a89-aa0375b2c1a2", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_updatecontact/get-response.json ================================================ { "id": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "key": "testExisting_journey_updatecontact", "name": "testExisting_journey_updatecontact", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7", "field": "bea0e308-5d45-4181-a673-da9972a7c674", "value": "TEST" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "0175b971-71a3-4d8e-98ac-48121f3fbf4f", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_updatecontact/put-response.json ================================================ { "key": "testExisting_journey_updatecontact", "name": "testExisting_journey_updatecontact", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "field": "bea0e308-5d45-4181-a673-da9972a7c674", "value": "TEST", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_updatecontact_sharedDE/get-response.json ================================================ { "id": "shared-journey-id-1234", "key": "testExisting_journey_updatecontact_sharedDE", "name": "testExisting_journey_updatecontact_sharedDE", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "dataExtensionId": "21711373-72c1-ec11-b83b-shared", "field": "shared-bea0e308-5d45-4181-a673-da9972a7c674", "value": "TEST" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "92753481-1258-49bd-8a84-921ed63bcc2e", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "eventDefinitionId": "649d512b-4d08-4eca-a14e-fc7b64b4ada8", "eventDefinitionKey": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "shared-journey-id-1234", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_updatecontact_sharedDE/put-response.json ================================================ { "key": "testExisting_journey_updatecontact_sharedDE", "name": "testExisting_journey_updatecontact_sharedDE", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "field": "shared-bea0e308-5d45-4181-a673-da9972a7c674", "value": "TEST", "dataExtensionId": "21711373-72c1-ec11-b83b-shared" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys", "id": "shared-journey-id-1234", "definitionId": "shared-journey-id-1234" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail/get-response-versionNumber=1.json ================================================ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2022-03-24T02:20:32.74", "modifiedDate": "2022-03-24T02:20:40.45", "activities": [ { "id": "9606bcb0-9246-4610-9800-963bc77fc20a", "key": "EMAILV2-4", "name": "testExisting_temail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "1f44021a-74ac-49be-a07c-67862228214d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "test email", "emailId": 531213, "emailSubject": "test email", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "0a650d90-755e-ed11-b852-48df37d1df5b", "triggeredSendKey": "testExisting_temail" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "categoryId": 6298, "status": "Published", "scheduledStatus": "Draft", "definitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail/get-response.json ================================================ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2022-03-24T02:20:32.74", "modifiedDate": "2022-03-24T02:20:40.45", "activities": [ { "id": "9606bcb0-9246-4610-9800-963bc77fc20a", "key": "EMAILV2-4", "name": "testExisting_temail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "1f44021a-74ac-49be-a07c-67862228214d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "test email", "emailId": 531213, "emailSubject": "test email", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "0a650d90-755e-ed11-b852-48df37d1df5b", "triggeredSendKey": "testExisting_temail" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "categoryId": 6298, "status": "Published", "scheduledStatus": "Draft", "definitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail/put-response-paused.json ================================================ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "2022-03-24T02:20:40.45", "activities": [ { "id": "9606bcb0-9246-4610-9800-963bc77fc20a", "key": "EMAILV2-4", "name": "testExisting_temail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "1f44021a-74ac-49be-a07c-67862228214d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "test email", "emailId": 531213, "emailSubject": "test email", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "ae8511d0-9bf0-42d0-af4f-bd9c1218c812", "triggeredSendKey": "testExisting_temail" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "categoryId": 6298, "status": "Paused", "scheduledStatus": "Draft", "definitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail/put-response.json ================================================ { "id": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be", "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "2022-03-24T02:20:40.45", "activities": [ { "id": "9606bcb0-9246-4610-9800-963bc77fc20a", "key": "EMAILV2-4", "name": "testExisting_temail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "1f44021a-74ac-49be-a07c-67862228214d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "test email", "emailId": 531213, "emailSubject": "test email", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "0a650d90-755e-ed11-b852-48df37d1df5b", "triggeredSendKey": "testExisting_temail" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "categoryId": 6298, "status": "Published", "scheduledStatus": "Draft", "definitionId": "dsfdsafdsa-922c-4568-85a5-e5cc77efc3be" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail_notPublished/get-response-versionNumber=1.json ================================================ { "id": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "key": "testExisting_temail_notPublished", "name": "testExisting_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-08-23T01:29:33.233", "modifiedDate": "2024-08-23T02:00:44.57", "activities": [ { "id": "4ae63473-ea1e-4963-a257-6fea45a9038a", "key": "EMAILV2-3", "name": "my email activity", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "067f20ba-af36-4401-99d8-934100e1935d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailId": 531213, "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "6a2f70c5-2561-ef11-b876-f40343c95928", "triggeredSendKey": "testExisting_temail_notPublished" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail_notPublished", "dataExtensionId": "3c3a54a5-d55f-ef11-b876-f40343c95928" }, "isConfigured": true, "sections": {} }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "64a93832-fd23-487e-b585-8f3af3b5b6eb", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Published", "definitionId": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail_notPublished/get-response.json ================================================ { "id": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "key": "testExisting_temail_notPublished", "name": "testExisting_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-08-23T01:29:33.233", "modifiedDate": "2024-08-23T02:00:44.57", "activities": [ { "id": "4ae63473-ea1e-4963-a257-6fea45a9038a", "key": "EMAILV2-3", "name": "my email activity", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "067f20ba-af36-4401-99d8-934100e1935d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailId": 531213, "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "6a2f70c5-2561-ef11-b876-f40343c95928", "triggeredSendKey": "testExisting_temail_notPublished" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail_notPublished", "dataExtensionId": "3c3a54a5-d55f-ef11-b876-f40343c95928" }, "isConfigured": true, "sections": {} }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "64a93832-fd23-487e-b585-8f3af3b5b6eb", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Published", "definitionId": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testExisting_temail_notPublished/put-response.json ================================================ { "id": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "key": "testExisting_temail_notPublished", "name": "testExisting_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "0001-01-01T00:00:00", "modifiedDate": "2024-08-23T02:00:44.57", "activities": [ { "id": "4ae63473-ea1e-4963-a257-6fea45a9038a", "key": "EMAILV2-3", "name": "my email activity", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "067f20ba-af36-4401-99d8-934100e1935d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailId": 531213, "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "priority": 4, "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "isTrackingClicks": true, "publicationListId": 15 }, "triggeredSendId": "6a2f70c5-2561-ef11-b876-f40343c95928", "triggeredSendKey": "testExisting_temail_notPublished" }, "metaData": { "highThroughput": { "definitionKey": "testExisting_temail_notPublished", "dataExtensionId": "3c3a54a5-d55f-ef11-b876-f40343c95928" }, "isConfigured": true, "sections": {} }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "64a93832-fd23-487e-b585-8f3af3b5b6eb", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "stats": { "currentPopulation": 0, "cumulativePopulation": 0, "metGoal": 0, "metExitCriteria": 0, "goalPerformance": 0 }, "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "d4a900fe-3a8f-4cc5-9a49-81286e3e2cd2", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/key_testNew_temail_notPublished/get-response.json ================================================ { "id": "4c39662b-7c47-4df4-8bd6-65f01c313e8c", "key": "testNew_temail_notPublished", "name": "testNew_temail_notPublished", "lastPublishedDate": "2025-01-31T03:46:39.267", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2025-01-31T03:46:39.267", "modifiedDate": "2025-01-31T03:46:39.267", "activities": [ { "id": "1ce8a9e3-bee4-43e3-88a5-a1b3d21f1813", "key": "EMAILV2-1", "name": "testNew_temail_notPublished_24Q3", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "920e8b4c-1598-48d0-b2c4-8a5072e0b738", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isMultipart": true, "isSalesforceTracking": true, "isSendLogging": false, "isStoppedOnJobError": false, "isTrackingClicks": true, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "throttleCloses": "1/1/0001 12:00:00 AM", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleLimit": 0, "publicationListId": 15, "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "priority": 4, "emailId": 531213 }, "triggeredSendId": "6a2f70c5-2561-ef11-b876-f40343c95929" }, "metaData": { "highThroughput": { "definitionKey": "testNew_temail_notPublished", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" }, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "6a33ad9b-a46d-4758-902b-35ce1759650d", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Published", "definitionId": "4c39662b-7c47-4df4-8bd6-65f01c313e8c", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/post-response.json ================================================ { "id": "4c39662b-7c47-4df4-8bd6-65f01c313e8c", "key": "testNew_temail_notPublished", "name": "testNew_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2025-01-31T03:46:39.267", "modifiedDate": "2025-01-31T03:46:39.267", "activities": [ { "id": "1ce8a9e3-bee4-43e3-88a5-a1b3d21f1813", "key": "EMAILV2-1", "name": "Email", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "b9a05a3c-0bd6-49b6-a4a1-4b8f8d08da6a", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": "", "ccEmail": "", "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isMultipart": true, "isSalesforceTracking": true, "isSendLogging": false, "isStoppedOnJobError": false, "isTrackingClicks": true, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "throttleCloses": "1/1/0001 12:00:00 AM", "throttleOpens": "1/1/0001 12:00:00 AM", "publicationListId": 15, "senderProfileId": "a75d452b-7ef4-eb11-b82d-48df37d1da95", "sendClassificationId": "95da425b-a06f-e611-96fe-38eaa7142c61", "deliveryProfileId": "163f8417-13f7-e911-a2d8-1402ec938a35", "priority": 4, "emailId": 531213 } }, "metaData": { "highThroughput": { "definitionKey": "testNew_temail_notPublished", "dataExtensionId": "21711373-72c1-ec11-b83b-48df37d1deb7" }, "isConfigured": false }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "id": "6a33ad9b-a46d-4758-902b-35ce1759650d", "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "categoryId": 6298, "status": "Draft", "definitionId": "4c39662b-7c47-4df4-8bd6-65f01c313e8c", "scheduledStatus": "Draft" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/publishAsync/0175b971-71a3-4d8e-98ac-48121f3fbf4f/post-response-versionNumber=1.json ================================================ { "statusUrl": "/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c", "statusId": "45f06c0a-3ed2-48b2-a6a8-b5119253f01c" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/publishAsync/0175b971-71a3-4d8e-98ac-48121f3fbf4f/post-response-versionNumber=3.json ================================================ { "statusUrl": "/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c", "statusId": "45f06c0a-3ed2-48b2-a6a8-b5119253f01c" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-failed.json ================================================ { "status": "Error", "errors": [ { "errorDetail": "The default email or mobile address in Journey Settings is invalid. Select a different one.", "errorCode": "121226", "errorType": "Error", "additionalInfo": {} }, { "errorDetail": "Email Activity: CCE OpsIssue Satisfaction Email -- The email specified for the job did not pass validation. EmailID: 72604 An unverified from email address was detected. ", "errorCode": "121008", "errorType": "Error", "additionalInfo": { "activityKey": "EMAILV2-1", "activityId": "620dbe27-665a-49a3-ad61-ceea5aab720f", "activityType": "EMAILV2", "definitionId": "2d5f37b8-7acf-4ac4-b76a-74690255600c" } } ], "warnings": [ { "errorDetail": "Last modified date for email activity is more then 6 months ago. Please review the content or use path optimizer to test it.", "errorCode": "121546", "errorType": "Warning", "additionalInfo": { "activityKey": "EMAILV2-1", "activityId": "620dbe27-665a-49a3-ad61-ceea5aab720f", "activityType": "EMAILV2" } } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-success.json ================================================ { "status": "PublishCompleted", "errors": [], "warnings": [] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-successWarnings.json ================================================ { "status": "PublishCompleted", "errors": [], "warnings": [ { "errorDetail": "The journey has a long wait (1 days), please consider reducing wait to under 4 minutes.", "errorCode": "121547", "errorType": "Warning", "additionalInfo": { "activityKey": "WAITBYDURATION-5", "activityId": "2d0b5dbf-14cc-4635-acee-64071c8e1022", "activityType": "WAIT" } }, { "errorDetail": "The journey has a long wait (1 days), please consider reducing wait to under 4 minutes.", "errorCode": "121547", "errorType": "Warning", "additionalInfo": { "activityKey": "WAITBYDURATION-4", "activityId": "26298616-e89b-4166-8e7e-8417031f276b", "activityType": "WAIT" } }, { "errorDetail": "Last modified date for email activity is more then 6 months ago. Please review the content or use path optimizer to test it.", "errorCode": "121546", "errorType": "Warning", "additionalInfo": { "activityKey": "EMAILV2-1", "activityId": "966651f8-e1b6-4261-849c-e95589001c75", "activityType": "EMAILV2" } } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/transactional/create/post-response.json ================================================ { "errors": [] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/transactional/pause/post-response.json ================================================ { "errors": [] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/transactional/resume/post-response.json ================================================ { "errors": [] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/validateAsync/0175b971-71a3-4d8e-98ac-48121f3fbf4f/post-response.json ================================================ { "statusUrl": "/interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c", "statusId": "45f06c0a-3ed2-48b2-a6a8-b5119253f01c" } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-failed.json ================================================ { "status": "Error", "errors": [ { "errorDetail": "The default email or mobile address in Journey Settings is invalid. Select a different one.", "errorCode": "121226", "errorType": "Error", "additionalInfo": {} }, { "errorDetail": "Email Activity: CCE OpsIssue Satisfaction Email -- The email specified for the job did not pass validation. EmailID: 72604 An unverified from email address was detected. ", "errorCode": "121008", "errorType": "Error", "additionalInfo": { "activityKey": "EMAILV2-1", "activityId": "620dbe27-665a-49a3-ad61-ceea5aab720f", "activityType": "EMAILV2", "definitionId": "2d5f37b8-7acf-4ac4-b76a-74690255600c" } } ], "warnings": [ { "errorDetail": "Last modified date for email activity is more then 6 months ago. Please review the content or use path optimizer to test it.", "errorCode": "121546", "errorType": "Warning", "additionalInfo": { "activityKey": "EMAILV2-1", "activityId": "620dbe27-665a-49a3-ad61-ceea5aab720f", "activityType": "EMAILV2" } } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-success.json ================================================ { "status": "ValidateCompleted", "errors": [], "warnings": [] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-successWarnings.json ================================================ { "status": "ValidateCompleted", "errors": [], "warnings": [ { "errorDetail": "The journey has a long wait (1 days), please consider reducing wait to under 4 minutes.", "errorCode": "121547", "errorType": "Warning", "additionalInfo": { "activityKey": "WAITBYDURATION-5", "activityId": "2d0b5dbf-14cc-4635-acee-64071c8e1022", "activityType": "WAIT" } }, { "errorDetail": "The journey has a long wait (1 days), please consider reducing wait to under 4 minutes.", "errorCode": "121547", "errorType": "Warning", "additionalInfo": { "activityKey": "WAITBYDURATION-4", "activityId": "26298616-e89b-4166-8e7e-8417031f276b", "activityType": "WAIT" } }, { "errorDetail": "Last modified date for email activity is more then 6 months ago. Please review the content or use path optimizer to test it.", "errorCode": "121546", "errorType": "Warning", "additionalInfo": { "activityKey": "EMAILV2-1", "activityId": "966651f8-e1b6-4261-849c-e95589001c75", "activityType": "EMAILV2" } } ] } ================================================ FILE: test/resources/9999999/interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json ================================================ ================================================ FILE: test/resources/9999999/journey/build-expected.json ================================================ { "key": "testTemplated_journey_Quicksend", "name": "testTemplated_journey_Quicksend", "description": "", "workflowApiVersion": 1, "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "key": "EMAILV2-1", "name": "testTemplated_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [ "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%" ], "ccEmail": ["%%= ContentBlockByKey(\"testTemplated_asset_htmlblock\") =%%"], "created": {}, "description": "my activity info text", "dynamicEmailSubject": "testTemplated_ dynamic email subject %%= ContentBlockByKey(\"testTemplated_asset_htmlblock\") =%%", "emailSubject": "testTemplated_ email subject %%= ContentBlockByKey(\"testTemplated_asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testTemplated_ email preheader %%= ContentBlockByKey(\"testTemplated_asset_htmlblock\") =%%", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/testTemplated_suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["testTemplated_DomainExclusion"] }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testTemplated_senderProfile", "r__sendClassification_key": "testTemplated_sendClassification", "c__priority": "High", "r__asset_key": "testTemplated_asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/create-transactionaEmail-publish-expected.json ================================================ { "key": "testNew_temail_notPublished", "name": "testNew_temail_notPublished", "description": "", "workflowApiVersion": 1, "version": 1, "lastPublishedDate": "2025-01-31T03:46:39.267", "modifiedDate": "2025-01-31T03:46:39.267", "createdDate": "2025-01-31T03:46:39.267", "activities": [ { "key": "EMAILV2-1", "name": "testNew_temail_notPublished_24Q3", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "920e8b4c-1598-48d0-b2c4-8a5072e0b738", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [], "c__priority": "Medium", "ccEmail": [], "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isMultipart": true, "isSalesforceTracking": true, "isSendLogging": false, "isStoppedOnJobError": false, "isTrackingClicks": true, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile", "throttleCloses": "1/1/0001 12:00:00 AM", "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM" }, "r__transactionalEmail_key": "testNew_temail_notPublished" }, "metaData": { "highThroughput": { "r__dataExtension_key": "testExisting_dataExtension" }, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": {} }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "scheduledStatus": "Draft", "status": "Published", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-multistep-expected.json ================================================ { "key": "testExisting_journey_Multistep", "name": "testExisting_journey_Multistep", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "EMAILV2-1", "name": "my custom activity name", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "ff60a294-3804-4165-85cd-c7c19c8e3a6d", "next": "WAITBYDURATION-1", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "googleAnalyticsCampaignName": "", "r__triggeredSend_key": "testExisting_triggeredSend", "triggeredSend": { "autoAddSubscribers": false, "autoUpdateSubscribers": false, "bccEmail": [], "ccEmail": [], "created": { "name": "", "date": "" }, "description": "my custom description", "domainExclusions": [], "dynamicEmailSubject": "You are successfully unsubscribed", "emailSubject": "You are successfully unsubscribed", "exclusionFilter": "", "isSalesforceTracking": false, "isMultipart": false, "isSendLogging": true, "isStoppedOnJobError": false, "modified": { "name": "", "date": "" }, "preHeader": "testExisting_ email preheader", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "suppressTracking": false, "triggeredSendStatus": "New", "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "Medium", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message", "r__triggeredSend_key": "testExisting_triggeredSend" } }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "key": "MULTICRITERIADECISIONV2-1", "name": "", "description": "", "type": "MULTICRITERIADECISION", "outcomes": [ { "key": "default_path_1", "next": "EMAILV2-1", "arguments": {}, "metaData": { "label": "send message", "skipI18n": true, "isLabelFromConversion": false, "criteriaDescription": "Email is not null" } }, { "key": "remainder_path", "next": "WAITBYDURATION-2", "arguments": {}, "metaData": { "label": null } } ], "arguments": {}, "configurationArguments": { "criteria": { "default_path_1": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"><Condition IsEphemeralAttribute=\"true\" Key=\"Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.Email\" Operator=\"IsNotNull\" UiMetaData=\"{}\"><Value><![CDATA[]]></Value></Condition></ConditionSet></FilterDefinition>" }, "schemaVersionId": "252" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "actualChoice": { "dataType": "Number", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "filterResult": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": true, "access": "Hidden" } } } }, { "key": "WAITBYDURATION-1", "name": "1 day", "description": "", "type": "WAIT", "outcomes": [ { "key": "97af222a-450a-429e-8925-649b72f01ccf", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "key": "WAITBYDURATION-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "a0908f9f-bc3c-47f7-9489-7fef5af25ce3", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS" }, "metaData": { "isConfigured": true, "uiType": "WAITBYDURATION" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-published-expected.json ================================================ { "activities": [ { "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "r__transactionalEmail_key": "testExisting_temail_notPublished", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [], "c__priority": "Medium", "ccEmail": [], "created": {}, "domainExclusions": [], "dynamicEmailSubject": "%%=treatascontent(@subject)=%%", "emailSubject": "%%=treatascontent(@subject)=%%", "exclusionFilter": "", "isMultipart": true, "isSalesforceTracking": true, "isSendLogging": false, "isStoppedOnJobError": false, "isTrackingClicks": true, "modified": {}, "preHeader": "%%=treatascontent(@preheader)=%%\n", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__deliveryProfile_key": "Default", "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__sendClassification_key": "Default Transactional", "r__senderProfile_key": "Default", "throttleCloses": "1/1/0001 12:00:00 AM", "throttleOpens": "1/1/0001 12:00:00 AM" } }, "description": "", "key": "EMAILV2-3", "metaData": { "highThroughput": { "r__dataExtension_key": "testExisting_temail_notPublished" }, "isConfigured": true, "sections": {} }, "name": "my email activity", "outcomes": [ { "arguments": {}, "key": "067f20ba-af36-4401-99d8-934100e1935d", "metaData": { "invalid": false } } ], "schema": { "arguments": { "activityId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "contactId": { "access": "Hidden", "dataType": "Number", "direction": "In", "isNullable": true, "readOnly": false }, "contactKey": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": false, "readOnly": false }, "customObjectKey": { "access": "Hidden", "dataType": "LongNumber", "direction": "In", "isNullable": true, "readOnly": true }, "definitionId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": true }, "definitionInstanceId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": false, "readOnly": false }, "emailAddress": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": false, "readOnly": false }, "emailSubjectDataBound": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": true }, "eventData": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "fieldType": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "messageKey": { "access": "Hidden", "dataType": "Text", "direction": "Out", "isNullable": true, "readOnly": false }, "obfuscationProperties": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "requestID": { "access": "Hidden", "dataType": "Text", "direction": "Out", "isNullable": true, "readOnly": false }, "sourceCustomObjectId": { "access": "Hidden", "dataType": "Text", "direction": "In", "isNullable": true, "readOnly": false }, "sourceCustomObjectKey": { "access": "Hidden", "dataType": "LongNumber", "direction": "In", "isNullable": true, "readOnly": false } } }, "type": "EMAILV2" } ], "channel": "email", "createdDate": "2024-08-23T01:29:33.233", "defaults": { "properties": {} }, "definitionType": "Transactional", "description": "", "entryMode": "MultipleEntries", "executionMode": "Production", "exits": [], "goals": [], "key": "testExisting_temail_notPublished", "lastPublishedDate": "0001-01-01T00:00:00", "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "modifiedDate": "2024-08-23T02:00:44.57", "name": "testExisting_temail_notPublished", "notifiers": [], "r__folder_Path": "my journeys", "scheduledStatus": "Draft", "status": "Published", "triggers": [ { "arguments": {}, "configurationArguments": {}, "description": "", "key": "TRIGGER", "metaData": { "category": "Transactional", "chainType": "none", "configurationRequired": false, "entrySourceGroupConfigUrl": "null", "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event" }, "name": "TRIGGER", "outcomes": [], "type": "transactional-api" } ], "version": 1, "workflowApiVersion": 1 } ================================================ FILE: test/resources/9999999/journey/get-quicksend-expected.json ================================================ { "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [ "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%" ], "ccEmail": ["%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%"], "created": {}, "description": "my activity info text", "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "emailSubject": "testExisting_ email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/testExisting_suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["testExisting_DomainExclusion"] }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "High", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-quicksend-rcb-id-expected.json ================================================ { "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": ["%%= ContentBlockById(1295064) =%%"], "ccEmail": ["%%= ContentBlockById(1295064) =%%"], "created": {}, "description": "my activity info text", "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockById(1295064) =%%", "emailSubject": "testExisting_ email subject %%= ContentBlockById(1295064) =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockById(1295064) =%%", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/testExisting_suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["testExisting_DomainExclusion"] }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "High", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-quicksend-rcb-key-expected.json ================================================ { "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": ["%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%"], "ccEmail": ["%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%"], "created": {}, "description": "my activity info text", "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "emailSubject": "testExisting_ email subject %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/testExisting_suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["testExisting_DomainExclusion"] }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "High", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-quicksend-rcb-name-expected.json ================================================ { "key": "testExisting_journey_Quicksend", "name": "testExisting_journey_Quicksend", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-04-24T12:18:43.47", "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "key": "EMAILV2-1", "name": "testExisting_asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [ "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%" ], "ccEmail": [ "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%" ], "created": {}, "description": "my activity info text", "dynamicEmailSubject": "testExisting_ dynamic email subject %%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "emailSubject": "testExisting_ email subject %%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "testExisting_ email preheader %%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/testExisting_suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["testExisting_DomainExclusion"] }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testExisting_senderProfile", "r__sendClassification_key": "testExisting_sendClassification", "c__priority": "High", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-transactionalEmail-expected.json ================================================ { "key": "testExisting_temail", "name": "testExisting_temail", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2022-03-24T02:20:32.74", "modifiedDate": "2022-03-24T02:20:40.45", "activities": [ { "key": "EMAILV2-4", "name": "testExisting_temail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "1f44021a-74ac-49be-a07c-67862228214d", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "applicationExtensionKey": "jb-email-activity", "isModified": true, "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [], "ccEmail": [], "created": {}, "domainExclusions": [], "dynamicEmailSubject": "test email", "emailSubject": "test email", "exclusionFilter": "", "isSalesforceTracking": true, "isMultipart": true, "isSendLogging": false, "isStoppedOnJobError": false, "modified": {}, "preHeader": "", "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers" }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "Default", "r__sendClassification_key": "Default Transactional", "c__priority": "Medium", "r__asset_name_readOnly": "testExisting_asset_message", "r__asset_key": "testExisting_asset_message" }, "r__transactionalEmail_key": "testExisting_temail" }, "metaData": { "highThroughput": { "r__dataExtension_key": "testExisting_dataExtension" }, "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "transactional-api", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "chainType": "none", "configurationRequired": false, "iconUrl": "/images/icon_journeyBuilder-event-transactional-blue.svg", "title": "Transactional API Event", "category": "Transactional", "entrySourceGroupConfigUrl": "null" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Transactional", "channel": "email", "defaults": { "properties": { "analyticsTracking": { "enabled": false, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": {}, "executionMode": "Production", "status": "Published", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-updatecontact-expected.json ================================================ { "key": "testExisting_journey_updatecontact", "name": "testExisting_journey_updatecontact", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "r__dataExtensionField_name": "LastName", "value": "TEST", "r__dataExtension_key": "testExisting_dataExtension" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/get-updatecontact-sharedDE-expected.json ================================================ { "key": "testExisting_journey_updatecontact_sharedDE", "name": "testExisting_journey_updatecontact_sharedDE", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "r__dataExtensionField_name": "LastName", "value": "TEST", "r__dataExtension_key": "testExisting_dataExtensionShared" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/post-expected.json ================================================ { "key": "testNew_interaction", "name": "testNew_interaction", "lastPublishedDate": "2017-04-12T08:07:48", "description": "created on deploy", "version": 1, "workflowApiVersion": 1, "createdDate": "2017-04-12T05:38:05.837", "modifiedDate": "2017-04-12T08:07:48.333", "activities": [ { "id": "69213026-bd2c-433b-8332-5f52d3e87ca5", "key": "WAIT-1", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "bd3dff6b-565c-4b56-b9cb-60cd5b6d080b", "next": "DATAEXTENSIONUPDATE-1", "arguments": {}, "metaData": {} } ], "arguments": { "waitDefinitionId": "546704c0-9384-4a41-b20e-97615cc6cc6a", "waitForEventId": "", "executionMode": "{{Context.ExecutionMode}}", "startActivityKey": "{{Context.StartActivityKey}}", "waitQueueId": "{{Context.WaitQueueId}}" }, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS", "specifiedTime": "", "timeZone": "", "description": "", "waitForEventKey": "" }, "metaData": { "waitType": "duration" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "5d93cda9-2015-4c07-a1db-0d5853d25bf6", "key": "WAIT-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "e3d3258a-891b-4838-b5a6-af37f8cb769a", "arguments": {}, "metaData": {} } ], "arguments": { "waitDefinitionId": "deed4c9d-f487-4371-bfd9-76fca44ec49b", "waitForEventId": "", "executionMode": "{{Context.ExecutionMode}}", "startActivityKey": "{{Context.StartActivityKey}}", "waitQueueId": "{{Context.WaitQueueId}}" }, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS", "specifiedTime": "", "timeZone": "", "description": "", "waitForEventKey": "" }, "metaData": { "waitType": "duration" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "ef4db13e-83f0-4d41-981d-4bf5810c0daa", "key": "DATAEXTENSIONUPDATE-1", "name": "", "description": "", "type": "DATAEXTENSIONUPDATE", "outcomes": [ { "key": "a49ecf04-4612-4582-85fe-d7193f872fa8", "next": "WAIT-2", "arguments": {}, "metaData": {} } ], "arguments": { "contactKey": "{{Contact.Key}}", "value": "{{DateTime.Now}}" }, "configurationArguments": { "dataExtensionId": "ace267f0-b81d-e711-80cc-1402ec7222b4", "field": "4e875b26-0317-4525-bfa0-50c8d1b7a7b5" }, "metaData": { "dataExtensionName": "test_TestData", "cachedFieldName": "JourneyConfirmed", "cachedDisplayValue": "" }, "schema": { "arguments": { "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "value": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "test_TESTDataentry", "description": "", "type": "APIEvent", "outcomes": [], "arguments": { "filterResult": "{{Contact.FilterId.e4ddb887-6f2d-46b1-9f64-9a020f217339}}" }, "configurationArguments": { "schemaVersionId": 133, "criteria": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"></ConditionSet></FilterDefinition>", "filterDefinitionId": "e4ddb887-6f2d-46b1-9f64-9a020f217339" }, "metaData": { "scheduleState": "No Schedule", "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "APIEvent-60130566-e2fe-eb29-4140-15c27093a80b", "chainType": "None", "configurationRequired": false, "iconUrl": "/events/images/icon_journeyBuilder-event-api-blue.svg", "title": "", "category": "Event" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "OnceAndDone", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.APIEvent-60130566-e2fe-eb29-4140-15c27093a80b.\"emailAddress\"}}"], "properties": {} }, "metaData": {}, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/publish-callout-expected.json ================================================ {} ================================================ FILE: test/resources/9999999/journey/put-expected.json ================================================ { "key": "testExisting_interaction", "name": "testExisting_interaction", "lastPublishedDate": "2017-04-12T08:07:48", "description": "updated via deploy - test", "version": 1, "workflowApiVersion": 1, "createdDate": "2017-04-12T05:38:05.837", "modifiedDate": "2017-04-12T08:07:48.333", "activities": [ { "id": "69213026-bd2c-433b-8332-5f52d3e87ca5", "key": "WAIT-1", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "bd3dff6b-565c-4b56-b9cb-60cd5b6d080b", "next": "DATAEXTENSIONUPDATE-1", "arguments": {}, "metaData": {} } ], "arguments": { "waitDefinitionId": "546704c0-9384-4a41-b20e-97615cc6cc6a", "waitForEventId": "", "executionMode": "{{Context.ExecutionMode}}", "startActivityKey": "{{Context.StartActivityKey}}", "waitQueueId": "{{Context.WaitQueueId}}" }, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS", "specifiedTime": "", "timeZone": "", "description": "", "waitForEventKey": "" }, "metaData": { "waitType": "duration" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "5d93cda9-2015-4c07-a1db-0d5853d25bf6", "key": "WAIT-2", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "e3d3258a-891b-4838-b5a6-af37f8cb769a", "next": "SMSSYNC-1", "arguments": {}, "metaData": {} } ], "arguments": { "waitDefinitionId": "deed4c9d-f487-4371-bfd9-76fca44ec49b", "waitForEventId": "", "executionMode": "{{Context.ExecutionMode}}", "startActivityKey": "{{Context.StartActivityKey}}", "waitQueueId": "{{Context.WaitQueueId}}" }, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS", "specifiedTime": "", "timeZone": "", "description": "", "waitForEventKey": "" }, "metaData": { "waitType": "duration" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "79213026-bd2c-433b-8332-5f52d3e87ca5", "key": "WAIT-3", "name": "", "description": "", "type": "WAIT", "outcomes": [ { "key": "bd3dff6b-565c-4b56-b9cb-60cd5b6d080b", "arguments": {}, "metaData": {} } ], "arguments": { "waitDefinitionId": "546704c0-9384-4a41-b20e-97615cc6cc6a", "waitForEventId": "", "executionMode": "{{Context.ExecutionMode}}", "startActivityKey": "{{Context.StartActivityKey}}", "waitQueueId": "{{Context.WaitQueueId}}" }, "configurationArguments": { "waitDuration": 1, "waitUnit": "DAYS", "specifiedTime": "", "timeZone": "", "description": "", "waitForEventKey": "" }, "metaData": { "waitType": "duration" }, "schema": { "arguments": { "endDate": { "dataType": "Date", "isNullable": false, "direction": "Out", "readOnly": false, "access": "Hidden" }, "waitEndDateAttributeDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitDefinitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitForEventId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "executionMode": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "startActivityKey": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "waitQueueId": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "ef4db13e-83f0-4d41-981d-4bf5810c0daa", "key": "DATAEXTENSIONUPDATE-1", "name": "", "description": "", "type": "DATAEXTENSIONUPDATE", "outcomes": [ { "key": "a49ecf04-4612-4582-85fe-d7193f872fa8", "next": "WAIT-2", "arguments": {}, "metaData": {} } ], "arguments": { "contactKey": "{{Contact.Key}}", "value": "{{DateTime.Now}}" }, "configurationArguments": { "dataExtensionId": "ace267f0-b81d-e711-80cc-1402ec7222b4", "field": "4e875b26-0317-4525-bfa0-50c8d1b7a7b5" }, "metaData": { "dataExtensionName": "test_TestData", "cachedFieldName": "JourneyConfirmed", "cachedDisplayValue": "" }, "schema": { "arguments": { "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "value": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } }, { "id": "cfc3ec53-4314-4504-9f9d-1fe53fdf0bcf", "key": "SMSSYNC-1", "name": "Kate Test SMS", "description": "", "type": "SMSSYNC", "outcomes": [ { "key": "d4d46c46-bf8c-4c62-bd34-4979548796cd", "next": "WAIT-3", "arguments": {}, "metaData": {} } ], "arguments": { "contactKey": "{{Contact.Key}}", "defaultSMSAddress": "{{Contact.Default.SMS}}", "mobileNumber": "{{InteractionDefaults.MobileNumber}}", "contactId": "{{Contact.Id}}", "definitionInstanceId": "{{Context.DefinitionInstanceId}}", "definitionId": "{{Context.DefinitionId}}" }, "configurationArguments": { "c__mobileMessage_id": "NTIzOjc4OjA", "r__mobileKeyword_codeKeyword": "4912312345678.TESTEXISTING_KEYWORD", "isOptIn": false, "honorBlackoutWindowEnum": 0, "mobileBlackoutWindowStartTime": "", "mobileBlackoutWindowEndTime": "", "applicationExtensionKey": "jb-mobile-connect-send-sms-sync" }, "metaData": { "isConfigured": true }, "schema": { "arguments": { "smsJobId": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "isAddressCreated": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "isSubscriptionCreated": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "isTriggeredSend": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "isWithinBlackout": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "isValidMobileNumber": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outMessageId": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outKeywordId": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outIsOptIn": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outHonorBlackoutWindowEnum": { "dataType": "Number", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outMobileBlackoutWindowStartTime": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outMobileBlackoutWindowEndTime": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outUtcOffset": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outWindowStart": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outWindowEnd": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outTimeZoneId": { "dataType": "Number", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outIsTZValid": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outIsMobileBlackoutWindowEnabled": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outIsUsingDEAttributesForPersonalization": { "dataType": "Boolean", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "outCountProcessedSingletonDuringBatchMethod": { "dataType": "LongNumber", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "defaultSMSAddress": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "mobileNumber": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "test_TESTDataentry", "description": "", "type": "APIEvent", "outcomes": [], "arguments": { "filterResult": "{{Contact.FilterId.e4ddb887-6f2d-46b1-9f64-9a020f217339}}" }, "configurationArguments": { "schemaVersionId": 133, "criteria": "<FilterDefinition><ConditionSet Operator=\"AND\" ConditionSetName=\"Individual Filter Grouping\"></ConditionSet></FilterDefinition>", "filterDefinitionId": "e4ddb887-6f2d-46b1-9f64-9a020f217339" }, "metaData": { "scheduleState": "No Schedule", "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "APIEvent-60130566-e2fe-eb29-4140-15c27093a80b", "chainType": "None", "configurationRequired": false, "iconUrl": "/events/images/icon_journeyBuilder-event-api-blue.svg", "title": "", "category": "Event" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "OnceAndDone", "definitionType": "Multistep", "channel": "", "defaults": { "email": ["{{Event.APIEvent-60130566-e2fe-eb29-4140-15c27093a80b.\"emailAddress\"}}"], "properties": {} }, "metaData": {}, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/put-updatecontact-expected.json ================================================ { "key": "testExisting_journey_updatecontact", "name": "testExisting_journey_updatecontact", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "r__dataExtensionField_name": "LastName", "value": "TEST", "r__dataExtension_key": "testExisting_dataExtension" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/put-updatecontact-sharedDE-expected.json ================================================ { "key": "testExisting_journey_updatecontact_sharedDE", "name": "testExisting_journey_updatecontact_sharedDE", "lastPublishedDate": "0001-01-01T00:00:00", "description": "", "version": 1, "workflowApiVersion": 1, "createdDate": "2024-05-04T05:54:48.027", "modifiedDate": "2024-05-04T17:25:57.9", "activities": [ { "key": "UPDATECONTACTDATAV2-1", "name": "Update Contact - TEST", "description": "", "type": "UPDATECONTACTDATA", "outcomes": [ { "key": "9f21d42b-4679-4561-911a-4bccf84672ba", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": { "activityData": { "updateContactFields": [ { "r__dataExtensionField_name": "LastName", "value": "TEST", "r__dataExtension_key": "testExisting_dataExtensionShared" } ] } }, "configurationArguments": {}, "metaData": { "isConfigured": true }, "schema": { "arguments": { "activityData": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "r__event_key": "DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json", "sourceInteractionId": "00000000-0000-0000-0000-000000000000" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "NotSet", "definitionType": "Multistep", "channel": "", "defaults": { "email": [ "{{Event.DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e.\"Email\"}}" ], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "highThroughputSending": { "email": false } }, "executionMode": "Production", "status": "Draft", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/template-expected.json ================================================ { "key": "{{{prefix}}}journey_Quicksend", "name": "{{{prefix}}}journey_Quicksend", "description": "", "workflowApiVersion": 1, "modifiedDate": "2024-04-24T12:19:12.803", "activities": [ { "key": "EMAILV2-1", "name": "{{{prefix}}}asset_mail", "description": "", "type": "EMAILV2", "outcomes": [ { "key": "a6b9c1af-cd89-4ce8-ba4f-bd4289188dc2", "arguments": {}, "metaData": { "invalid": false } } ], "arguments": {}, "configurationArguments": { "isModified": true, "googleAnalyticsCampaignName": "", "triggeredSend": { "autoAddSubscribers": true, "autoUpdateSubscribers": true, "bccEmail": [ "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%" ], "ccEmail": ["%%= ContentBlockByKey(\"{{{prefix}}}asset_htmlblock\") =%%"], "created": {}, "description": "my activity info text", "dynamicEmailSubject": "{{{prefix}}} dynamic email subject %%= ContentBlockByKey(\"{{{prefix}}}asset_htmlblock\") =%%", "emailSubject": "{{{prefix}}} email subject %%= ContentBlockByKey(\"{{{prefix}}}asset_htmlblock\") =%%", "exclusionFilter": "/* insert ampscript here */ %%= ContentBlockById(1295064) =%%", "isSalesforceTracking": false, "isMultipart": true, "isSendLogging": true, "isStoppedOnJobError": false, "keyword": "", "modified": {}, "preHeader": "{{{prefix}}} email preheader %%= ContentBlockByKey(\"{{{prefix}}}asset_htmlblock\") =%%", "suppressTracking": true, "throttleLimit": 0, "throttleOpens": "1/1/0001 12:00:00 AM", "throttleCloses": "1/1/0001 12:00:00 AM", "isTrackingClicks": true, "r__list_PathName": { "publicationList": "my subscribers/All Subscribers", "suppressionLists": ["Suppression Lists/{{{prefix}}}suppressionList"] }, "r__dataExtension_key": { "domainExclusions": ["{{{prefix}}}DomainExclusion"] }, "r__deliveryProfile_key": "Default", "r__senderProfile_key": "{{{prefix}}}senderProfile", "r__sendClassification_key": "{{{prefix}}}sendClassification", "c__priority": "High", "r__asset_key": "{{{prefix}}}asset_message" }, "applicationExtensionKey": "jb-email-activity" }, "metaData": { "category": "message", "version": "1.0", "icon": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "iconSmall": "https://jb-email-activity.s7.marketingcloudapps.com/img/email-icon.svg", "statsContactIcon": null, "original_icon": "/img/email-icon.svg", "original_iconSmall": "/img/email-icon.svg", "sections": {}, "isConfigured": true }, "schema": { "arguments": { "requestID": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "messageKey": { "dataType": "Text", "isNullable": true, "direction": "Out", "readOnly": false, "access": "Hidden" }, "activityId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "definitionId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "emailSubjectDataBound": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "contactId": { "dataType": "Number", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "contactKey": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "emailAddress": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectId": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "sourceCustomObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "fieldType": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "eventData": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "obfuscationProperties": { "dataType": "Text", "isNullable": true, "direction": "In", "readOnly": false, "access": "Hidden" }, "customObjectKey": { "dataType": "LongNumber", "isNullable": true, "direction": "In", "readOnly": true, "access": "Hidden" }, "definitionInstanceId": { "dataType": "Text", "isNullable": false, "direction": "In", "readOnly": false, "access": "Hidden" } } } } ], "triggers": [ { "key": "TRIGGER", "name": "TRIGGER", "description": "", "type": "EmailAudience", "outcomes": [], "arguments": {}, "configurationArguments": {}, "metaData": { "sourceInteractionId": "00000000-0000-0000-0000-000000000000", "r__event_key": "DEAudience-11be962d-064c-83d9-2804-7d1befc10325", "chainType": "None", "configurationRequired": false, "iconUrl": "/images/icon-data-extension.svg", "title": "Data Extension", "entrySourceGroupConfigUrl": "jb:///data/entry/audience/entrysourcegroupconfig.json" } } ], "goals": [], "exits": [], "notifiers": [], "entryMode": "MultipleEntries", "definitionType": "Quicksend", "channel": "email", "defaults": { "email": ["{{Event.DEAudience-11be962d-064c-83d9-2804-7d1befc10325.\"Email\"}}"], "properties": { "analyticsTracking": { "enabled": true, "analyticsType": "google", "urlDomainsToTrack": [] } } }, "metaData": { "dataSource": "ContactsModel", "isScheduleSet": true, "highThroughputSending": { "email": false } }, "executionMode": "Production", "scheduledStatus": "Draft", "r__folder_Path": "my journeys" } ================================================ FILE: test/resources/9999999/journey/validate-callout-expected.json ================================================ {} ================================================ FILE: test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/get-response.json ================================================ { "programId": "ZGQ4N2M2ZjEtYjJlZi00MDljLTg3MDctYzYwNWQ0MzdiYWI4OjI1OjA", "workers": [ { "programId": "ZGQ4N2M2ZjEtYjJlZi00MDljLTg3MDctYzYwNWQ0MzdiYWI4OjI1OjA", "id": "YjA2NmVlODEtODllOS00NTE4LTkwYzYtMTY4Mzg2ZTk3MGE4OjEyOjA", "notificationType": "Complete", "definition": "complete@test.accenture.com", "body": "", "channelType": "Account" }, { "programId": "ZGQ4N2M2ZjEtYjJlZi00MDljLTg3MDctYzYwNWQ0MzdiYWI4OjI1OjA", "id": "NGIzZGQ5N2EtMDI0ZS00MzFiLTg5ZWYtNTdjYTI4ODVjMjQ0OjEyOjA", "notificationType": "Error", "definition": "error@test.accenture.com", "body": "test", "channelType": "Account" } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/post-response.json ================================================ ================================================ FILE: test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED/get-response.json ================================================ { "programId": "ZGQ4N2M2ZjEtYjJlZi00MDljLTg3MDctYzYwNWQ0MzdiYWI4OjI1OjA" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/automations/notifications/bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToyNTow/get-response.json ================================================ { "programId": "MGZjMmFjOTYtMTRiYS00OTVhLThkYjktM2RkZDRmOGFjNDQ0OjI1OjA" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/automations/notifications/cDhLQ2o2NExxVVc5N3VZeHF5WEExUToyNTow/get-response.json ================================================ { "programId": "MzIxMjAzMmYtM2Y0OC00ZTdlLWIyODktMzE5YWQyODA2NTc1OjI1OjA" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/NewRkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/get-response.json ================================================ { "guidId": "a8afb0e2-b00a-4c88-ad2e-1f7f8788c560", "id": "NewRkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "name": "testNew_automation", "description": "created on deploy", "key": "testNew_automation", "clientId": 9999999, "lastSavedDate": "2023-07-04T07:49:08.577", "lastSavedByName": "SFMC DevTools app user", "createdDate": "2023-07-04T07:49:08.297", "createdByName": "SFMC DevTools app user", "updateInProgress": false, "automationType": "scheduled", "scheduleObject": { "id": "WkNtUVIxN21WRTZndGxkTnZIS1JWUTozNjow", "key": "921", "createdDate": "2025-03-18T09:57:00Z", "createdBy": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzEwNDIwNDMyOjQ6MA", "lastUpdated": "2025-03-18T09:57:00Z", "lastUpdatedBy": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzEwNDIwNDMyOjQ6MA", "name": "", "description": "Will run every hour, effective 5-3-2025 at 10:45 through Wednesday 7 June 2079", "startDate": "2025-03-05T10:45:00", "iCalRecur": "FREQ=HOURLY;UNTIL=20790607T080000;INTERVAL=1", "timeZone": "W. Europe Standard Time", "timeZoneId": 5, "scheduleStatus": "scheduled" } } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/get-response.json ================================================ { "id": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "key": "testExisting_automation", "createdDate": "2022-01-12T08:41:35.773Z", "name": "testExisting_automation", "description": "bla bla", "clientId": 9999999, "status": "PausedSchedule", "createdBy": { "id": "NzE3MzUzNDA1OjQ6MA", "name": "Tom Tester", "email": "tom.tester@accenture.com" }, "modifiedDate": "2022-11-11T16:42:36.513Z", "modifiedBy": { "id": "NzE3MzUzNDA1OjQ6MA", "name": "Tom Tester", "email": "tom.tester@accenture.com" }, "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoxMjow", "automationType": "scheduled", "lastPausedDate": "2025-03-14T15:21:57.62Z", "lastPausedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "lastSaveDate": "2024-11-04T17:42:13.143Z", "lastSavedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "scheduleObject": { "id": "WkNtUVIxN21WRTZndGxkTnZIS1JWUTozNjow", "key": "921", "createdDate": "2025-03-18T09:57:00Z", "createdBy": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzEwNDIwNDMyOjQ6MA", "lastUpdated": "2025-03-18T09:57:00Z", "lastUpdatedBy": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzEwNDIwNDMyOjQ6MA", "name": "", "description": "Will run every hour, effective 5-3-2025 at 10:45 through Wednesday 7 June 2079", "startDate": "2025-03-05T10:45:00", "iCalRecur": "FREQ=HOURLY;UNTIL=20790607T080000;INTERVAL=1", "timeZone": "W. Europe Standard Time", "timeZoneId": 5, "scheduleStatus": "paused" } } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED/get-response.json ================================================ { "id": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED", "key": "testExisting_automation_pause", "createdDate": "2022-01-12T08:41:35.773Z", "name": "testExisting_automation_pause", "description": "bla bla", "clientId": 9999999, "status": "Scheduled", "createdBy": { "id": "NzE3MzUzNDA1OjQ6MA", "name": "Tom Tester", "email": "tom.tester@accenture.com" }, "modifiedDate": "2022-11-11T16:42:36.513Z", "modifiedBy": { "id": "NzE3MzUzNDA1OjQ6MA", "name": "Tom Tester", "email": "tom.tester@accenture.com" }, "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoxMjow", "automationType": "scheduled", "lastPausedDate": "2025-03-14T15:21:57.62Z", "lastPausedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "lastSaveDate": "2024-11-04T17:42:13.143Z", "lastSavedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "guidId": "08afb0e2-b00a-4c88-fixKey_pause", "scheduleObject": { "id": "WkNtUVIxN21WRTZndGxkTnZIS1JWUTozNjow", "key": "921", "createdDate": "2025-03-18T09:57:00Z", "createdBy": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzEwNDIwNDMyOjQ6MA", "lastUpdated": "2025-03-18T09:57:00Z", "lastUpdatedBy": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzEwNDIwNDMyOjQ6MA", "name": "", "description": "Will run every hour, effective 5-3-2025 at 10:45 through Wednesday 7 June 2079", "startDate": "2025-03-05T10:45:00", "iCalRecur": "FREQ=HOURLY;UNTIL=20790607T080000;INTERVAL=1", "timeZone": "W. Europe Standard Time", "timeZoneId": 5, "scheduleStatus": "scheduled" } } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToyNTow/get-response.json ================================================ { "id": "bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToyNTow", "key": "testExisting_automation_wait", "createdDate": "2024-11-04T17:30:12.973Z", "updateInProgress": false, "name": "testExisting_automation_wait", "description": "", "createdBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "modifiedDate": "2024-11-04T17:42:13.203Z", "status": "Ready", "memberId": 510004860, "processes": [ { "id": "OXJtc2M5STlma3FpVzN3NkF4Y0pWdzoyNzow", "name": "", "description": "", "sequence": 0, "workers": [ { "id": "ZC1YQS1Jd25uMGV6Z1dFRmFiQzFMZzoyOTow", "key": "07801bb9-0fd1-4ed0-9349-625c5a03b957", "sequence": 0, "name": "1 Years", "description": "", "activityObjectId": "1bd41a92-2c57-463c-a1e6-6e1549e481a1", "objectTypeId": 467, "serializedObject": "{\"duration\":1,\"durationUnits\":\"Years\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "f8c0e577-278c-479f-b381-610569b0b52e" } ], "guidId": "73acb9f6-3dd2-4a7e-a25b-7c3a03170957" }, { "id": "YllfOWc3dFVCRXU4RGQxaTRXOUZLZzoyNzow", "name": "", "description": "", "sequence": 1, "workers": [ { "id": "cWZwazAtTUdPRTJmdnBPWWF4MVVIZzoyOTow", "key": "41fed5be-317a-425a-a81d-94485042ad26", "sequence": 0, "name": "1 Months", "description": "", "activityObjectId": "76f255e3-1603-4d8b-be59-32ac6fe61e15", "objectTypeId": 467, "serializedObject": "{\"duration\":1,\"durationUnits\":\"Months\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "d364faa9-06e3-4d38-9fbe-93986b1d541e" } ], "guidId": "83fd8f6d-54bb-4b04-bc0d-dd62e16f452a" }, { "id": "d1VwZGsxN0dwa3V0dEtQSTZOeXlRUToyNzow", "name": "", "description": "", "sequence": 2, "workers": [ { "id": "TnJHdVdodWJIMDJWOHIzWTFTTHdHQToyOTow", "key": "984a2011-87d9-4219-b609-ee3f13be7520", "sequence": 0, "name": "1 Weeks", "description": "", "activityObjectId": "85a405e4-e77b-4a2e-8d1b-9ad34244ac10", "objectTypeId": 467, "serializedObject": "{\"duration\":1,\"durationUnits\":\"Weeks\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "5aaeb136-9b1b-4d1f-95f2-bdd8d522f018" } ], "guidId": "935d4ac1-c65e-4ba6-adb4-a3c8e8dcb241" }, { "id": "cG5GWTY1a1RiRVNnWnpvRDBhUTJmdzoyNzow", "name": "", "description": "", "sequence": 3, "workers": [ { "id": "Tkw0dkFMQVFJVUd4bXVuQWM4dlhBQToyOTow", "key": "29cc7a78-7a98-49bb-821d-f68f3695f386", "sequence": 0, "name": "1 Days", "description": "", "activityObjectId": "562cf01a-6cca-4fd9-9d3c-f2649379a282", "objectTypeId": 467, "serializedObject": "{\"duration\":1,\"durationUnits\":\"Days\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "002fbe34-10b0-4121-b19a-e9c073cbd700" } ], "guidId": "eb5871a6-1399-446c-a067-3a03d1a4367f" }, { "id": "VjFyRUptR0hyRTJSdE1IR1RScG5RUToyNzow", "name": "", "description": "", "sequence": 4, "workers": [ { "id": "endvNktPM1ZOVVdpcHpnLUxJeFIydzoyOTow", "key": "d83889a8-7d08-4234-979f-e8356ca6a9d2", "sequence": 0, "name": "1 Hours", "description": "", "activityObjectId": "2722bb7c-2ea2-4cf5-8891-96c5a4362a72", "objectTypeId": 467, "serializedObject": "{\"duration\":1,\"durationUnits\":\"Hours\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "283a0acf-d5ed-4535-a2a7-383e2c8c51db" } ], "guidId": "26c45a57-8761-4dac-91b4-c1c64d1a6741" }, { "id": "SjFFR2s4eXR5ME93UU85anZpS0Y3QToyNzow", "name": "", "description": "", "sequence": 5, "workers": [ { "id": "R2hCN0ZnbXZBa0NoVF9VMzNpWnM0QToyOTow", "key": "8c51a35a-65dc-4675-93e5-c30037fc6a77", "sequence": 0, "name": "1 Minutes", "description": "", "activityObjectId": "5d5f816b-b024-45a9-8ce9-726c6dd61bf4", "objectTypeId": 467, "serializedObject": "{\"duration\":1,\"durationUnits\":\"Minutes\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "167b101a-af09-4002-a14f-f537de266ce0" } ], "guidId": "93065127-adcc-43cb-b040-ef63be2285ec" }, { "id": "a0JPTkRiNTFmVUtRQ3dyMXlRYWdHdzoyNzow", "name": "", "description": "", "sequence": 6, "workers": [ { "id": "YXBCU1o1bk9fa3V4MVUyNDYwb2tzQToyOTow", "key": "933b7da5-ef25-4e5a-b92c-ff061d05ba7f", "sequence": 0, "name": "03:00 PM", "description": "", "activityObjectId": "1c9836b8-0242-4620-9421-21d36a0df751", "objectTypeId": 467, "serializedObject": "{\"specifiedTime\":\"15:00\",\"timeZone\":\"GMT Standard Time\"}", "selectedObject": [ { "categoryId": -1 } ], "guidId": "6752906a-ce99-4bfe-b1d5-4db8eb4a24b0" } ], "guidId": "0d8d1390-75be-427d-900b-0af5c906a01b" } ], "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToxMjow", "automationType": "unspecified", "categoryId": 4700, "folderPath": "my automations", "lastPausedDate": "2025-03-14T15:21:57.62Z", "lastPausedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "lastSaveDate": "2024-11-04T17:42:13.143Z", "lastSavedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "selectedCategoryId": [ { "categoryId": 4700 } ], "guidId": "0fc2ac96-14ba-495a-8db9-3ddd4f8ac444-wait" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/cDhLQ2o2NExxVVc5N3VZeHF5WEExUToyNTow/get-response.json ================================================ { "id": "cDhLQ2o2NExxVVc5N3VZeHF5WEExUToyNTow", "key": "testExisting_automation_event", "createdDate": "2024-11-07T10:20:18.877Z", "name": "testExisting_automation_event", "description": "", "clientId": 9999999, "status": "Scheduled", "createdBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "modifiedDate": "2024-11-07T22:17:24.457Z", "modifiedBy": { "id": "LTEwMDA6NDow", "name": "System" }, "processes": [ { "id": "Q3FPcDlGeGc1VTJHcE9mZmlmNW9oUToyNzow", "createdDate": "2024-11-07T10:26:58.62Z", "name": "", "description": "", "sequence": 0, "status": "Complete", "workerCounts": [ { "name": "QueryDefinition", "objectTypeId": 300, "count": 1, "status": "Complete" } ], "instanceId": "aDJvYXJPR2Z5MHVNNHdBVVA0cG5xUToyODow" }, { "id": "UDF0MWd4SlF0RW1CRWdLUnlIbTUxUToyNzow", "createdDate": "2024-11-07T10:59:15.813Z", "name": "", "description": "", "sequence": 2, "status": "Complete", "workerCounts": [ { "name": "JourneyBuilderAudience", "objectTypeId": 952, "count": 1, "status": "Complete" } ], "instanceId": "VjBzTVVjZHJja0M3TS12ZlRPMmZ6QToyODow" } ], "schedule": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/automations/schedule/dXZSTUJ0Q2xDa0tLVHlZRldqVlF1ZzozNjow", "scheduledTime": "2024-11-07T23:15:00Z", "startTime": "2024-11-07T22:15:19.057Z", "completedTime": "2024-11-07T22:17:24.453Z", "lastRunTime": "2024-11-07T22:15:19.057Z", "lastRunInstance": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/bulk/automations/automation/instance/VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "instanceId": "VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "automationInstance": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/bulk/automations/automation/instance/VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/cDhLQ2o2NExxVVc5N3VZeHF5WEExUToxMjow", "automationType": "scheduled", "lastPausedDate": "2025-03-14T15:21:57.62Z", "lastPausedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "lastSaveDate": "2024-11-04T17:42:13.143Z", "lastSavedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "lastRunStatus": "Complete" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 4, "entry": [ { "id": "cDhLQ2o2NExxVVc5N3VZeHF5WEExUToyNTow", "key": "testExisting_automation_event", "createdDate": "2024-11-07T10:20:18.877Z", "name": "testExisting_automation_event", "description": "", "clientId": 9999999, "status": "Scheduled", "createdBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "modifiedDate": "2024-11-07T22:17:24.457Z", "modifiedBy": { "id": "LTEwMDA6NDow", "name": "System" }, "processes": [ { "id": "Q3FPcDlGeGc1VTJHcE9mZmlmNW9oUToyNzow", "createdDate": "2024-11-07T10:26:58.62Z", "name": "", "description": "", "sequence": 0, "status": "Complete", "workerCounts": [ { "name": "QueryDefinition", "objectTypeId": 300, "count": 1, "status": "Complete" } ], "instanceId": "aDJvYXJPR2Z5MHVNNHdBVVA0cG5xUToyODow" }, { "id": "UDF0MWd4SlF0RW1CRWdLUnlIbTUxUToyNzow", "createdDate": "2024-11-07T10:59:15.813Z", "name": "", "description": "", "sequence": 2, "status": "Complete", "workerCounts": [ { "name": "JourneyBuilderAudience", "objectTypeId": 952, "count": 1, "status": "Complete" } ], "instanceId": "VjBzTVVjZHJja0M3TS12ZlRPMmZ6QToyODow" } ], "schedule": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/automations/schedule/dXZSTUJ0Q2xDa0tLVHlZRldqVlF1ZzozNjow", "scheduledTime": "2024-11-07T23:15:00Z", "startTime": "2024-11-07T22:15:19.057Z", "completedTime": "2024-11-07T22:17:24.453Z", "lastRunTime": "2024-11-07T22:15:19.057Z", "lastRunInstance": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/bulk/automations/automation/instance/VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "instanceId": "VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "automationInstance": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/bulk/automations/automation/instance/VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/cDhLQ2o2NExxVVc5N3VZeHF5WEExUToxMjow", "automationType": "scheduled", "lastRunStatus": "Complete" }, { "id": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED", "name": "testExisting_automation_pause", "description": "updated on deploy", "key": "testExisting_automation_pause", "typeId": 1, "statusId": 4, "status": "Scheduled", "processes": [ { "workerCounts": [ { "name": "testExisting_dataExtract", "objectTypeId": 73, "count": 1 }, { "name": "testExisting_emailSend", "objectTypeId": 42, "count": 2 }, { "name": "testExisting_fileTransfer", "objectTypeId": 53, "count": 3 }, { "name": "testExisting_importFile", "objectTypeId": 43, "count": 4 }, { "name": "testExisting_query_WRONG_NAME", "objectTypeId": 300, "count": 5 }, { "name": "testExisting_script", "objectTypeId": 423, "count": 6 } ], "annotation": "", "stepNumber": 0 } ], "schedule": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/automations/schedule/dXZSTUJ0Q2xDa0tLVHlZRldqVlF1ZzozNjow", "scheduledTime": "2024-11-07T23:15:00Z", "startTime": "2024-11-07T22:15:19.057Z", "completedTime": "2024-11-07T22:17:24.453Z", "lastRunTime": "2024-11-07T22:15:19.057Z", "lastRunInstance": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/bulk/automations/automation/instance/VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "instanceId": "VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "automationInstance": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/bulk/automations/automation/instance/VEhxcm1sTk5DMEdhZnQ1S0ZsMURIZzoyNjow", "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/cDhLQ2o2NExxVVc5N3VZeHF5WEExUToxMjow", "automationType": "scheduled", "lastRunStatus": "Complete" }, { "id": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "key": "testExisting_automation", "createdDate": "2022-01-12T08:41:35.773Z", "name": "testExisting_automation", "description": "bla bla", "clientId": 9999999, "status": "PausedSchedule", "createdBy": { "id": "NzE3MzUzNDA1OjQ6MA", "name": "Tom Tester", "email": "tom.tester@accenture.com" }, "modifiedDate": "2022-11-11T16:42:36.513Z", "modifiedBy": { "id": "NzE3MzUzNDA1OjQ6MA", "name": "Tom Tester", "email": "tom.tester@accenture.com" }, "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoxMjow", "automationType": "scheduled" }, { "id": "bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToyNTow", "key": "testExisting_automation_wait", "createdDate": "2024-11-04T17:30:12.973Z", "name": "testExisting_automation_wait", "description": "", "clientId": 9999999, "status": "Ready", "createdBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "modifiedDate": "2024-11-04T17:42:13.203Z", "modifiedBy": { "id": "NzEwNDIwNDE4OjQ6MA", "name": "Jörn Berkefeld", "email": "joern.berkefeld@accenture.com" }, "processes": [ { "id": "OXJtc2M5STlma3FpVzN3NkF4Y0pWdzoyNzow", "createdDate": "2024-11-04T17:42:13.167Z", "name": "", "description": "", "sequence": 0, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] }, { "id": "YllfOWc3dFVCRXU4RGQxaTRXOUZLZzoyNzow", "createdDate": "2024-11-04T17:42:13.17Z", "name": "", "description": "", "sequence": 1, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] }, { "id": "d1VwZGsxN0dwa3V0dEtQSTZOeXlRUToyNzow", "createdDate": "2024-11-04T17:42:13.177Z", "name": "", "description": "", "sequence": 2, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] }, { "id": "cG5GWTY1a1RiRVNnWnpvRDBhUTJmdzoyNzow", "createdDate": "2024-11-04T17:42:13.18Z", "name": "", "description": "", "sequence": 3, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] }, { "id": "VjFyRUptR0hyRTJSdE1IR1RScG5RUToyNzow", "createdDate": "2024-11-04T17:42:13.183Z", "name": "", "description": "", "sequence": 4, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] }, { "id": "SjFFR2s4eXR5ME93UU85anZpS0Y3QToyNzow", "createdDate": "2024-11-04T17:42:13.187Z", "name": "", "description": "", "sequence": 5, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] }, { "id": "a0JPTkRiNTFmVUtRQ3dyMXlRYWdHdzoyNzow", "createdDate": "2024-11-04T17:42:13.19Z", "name": "", "description": "", "sequence": 6, "status": "Initialized", "workerCounts": [ { "name": "ProgramWait", "objectTypeId": 467, "count": 1 } ] } ], "isPlatformObject": false, "notifications": "https://mcxxxxx.rest.marketingcloudapis.com/legacy/v1/beta/hub/notifications/bHF6Q0Q3b1VXa21OdVQzZFQ0ckVSQToxMjow", "automationType": "unspecified" } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/post-response-pauseSchedule.json ================================================ { "id": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow-PAUSED" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/post-response-schedule.json ================================================ { "id": "RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/messaging/deliverypolicy/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 1, "entry": [ { "id": "ejQ1Y2Q5SzVFZXU0UHZRRFE4bFptQTo0ODow", "key": "Default", "createdDate": "2021-06-21T17:55:00Z", "lastUpdated": "2021-06-21T17:55:00Z", "name": "Default", "description": "Account defaults" } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/code/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 1, "entry": [ { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "createdDate": "2017-05-05T10:33:15.953Z", "lastUpdated": "2022-11-25T15:51:14.225Z", "code": "4912312345678", "countryCode": "HK", "startDate": "2017-05-05T06:00:00Z", "endDate": "2047-05-05T06:00:00Z", "keywordLimit": "Unlimited", "keywordsUsed": "0", "codeType": "PRIVATE", "isShortCode": false, "keywordsUsedOther": "0", "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 1, "moEngineVersion": 1, "sendableCountries": [ { "countryCode": "HK", "vendor": "CLX", "fromNameSupported": true } ], "supportsConcatenation": true, "isClientOwned": false, "isOwner": false } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/imports/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 3, "entry": [ { "id": "ZTFXX0hpNDNFZXU0RzBqZk45SGIxdzo0MTow", "name": "testExisting_importFileSMS", "sourceFile": "_CustomObject", "audience": { "id": "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQTo2Mzow", "name": "testExisting_importFileSMS", "description": "" }, "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "code": "4912312345678", "codeType": "PRIVATE", "isShortCode": false, "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 0, "moEngineVersion": 0, "supportsConcatenation": false, "isClientOwned": false, "isOwner": false }, "keyword": { "id": "cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow", "keyword": "TESTEXISTING_KEYWORD", "restriction": "NONE", "isInherited": false, "isLinkShorteningEnabled": false, "isSubscriberTrackingEnabled": false, "shortenerType": "BitLy" }, "sourceObjectId": "NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow", "sourceObjectName": "testExisting_dataExtension" }, { "id": "MVZtWUtidEVFZWlpdnhRQzdKVHM4UTo0MTow", "name": "ContactSMS_DEV", "sourceFile": "_CustomObject", "audience": { "id": "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQTo2Mzow", "name": "ContactSMS_DEV", "description": "" }, "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "code": "4912312345678", "codeType": "PRIVATE", "isShortCode": false, "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 0, "moEngineVersion": 0, "supportsConcatenation": false, "isClientOwned": false, "isOwner": false }, "keyword": { "id": "X2RqemdvVHFja1dpTzlKcERRQ25MZzo4Njow", "keyword": "COMMUNITYCLOUD_DEV", "restriction": "NONE", "isInherited": false, "isLinkShorteningEnabled": false, "isSubscriberTrackingEnabled": false, "shortenerType": "BitLy" }, "sourceObjectId": "NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow", "sourceObjectName": "testExisting_dataExtension" }, { "id": "NHNwUFR5YTdFZTY0WVVqZk45SGNlUTo0MTow", "name": "ContactSMS_DEV3", "sourceFile": "_CustomObject", "audience": { "id": "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQTo2Mzow", "name": "ContactSMS_DEV3", "description": "" }, "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "code": "4912312345678", "codeType": "PRIVATE", "isShortCode": false, "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 0, "moEngineVersion": 0, "supportsConcatenation": false, "isClientOwned": false, "isOwner": false }, "keyword": { "id": "X2RqemdvVHFja1dpTzlKcERRQ25MZzo4Njow", "keyword": "COMMUNITYCLOUD_DEV", "restriction": "NONE", "isInherited": false, "isLinkShorteningEnabled": false, "isSubscriberTrackingEnabled": false, "shortenerType": "BitLy" }, "sourceObjectId": "NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow", "sourceObjectName": "testExisting_dataExtension" } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/keyword/NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow/get-response.json ================================================ { "id": "NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow", "createdDate": "2023-03-30T14:00:11.907Z", "lastUpdated": "2023-03-30T14:00:12.295Z", "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "createdDate": "2017-05-05T10:33:15.953Z", "lastUpdated": "2022-11-25T15:51:14.225Z", "code": "4912312345678", "countryCode": "HK", "startDate": "2017-05-05T06:00:00Z", "endDate": "2047-05-05T06:00:00Z", "keywordLimit": "Unlimited", "keywordsUsed": "0", "codeType": "PRIVATE", "isShortCode": false, "keywordsUsedOther": "0", "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 1, "moEngineVersion": 1, "sendableCountries": [{ "countryCode": "HK", "vendor": "CLX", "fromNameSupported": true }], "supportsConcatenation": true, "isClientOwned": false, "isOwner": false }, "keyword": "TESTNEW_KEYWORD", "startDate": "2023-03-30T14:00:11.843Z", "endDate": "2043-03-30T14:00:11.843Z", "status": "Active", "createdBy": { "id": "NzE3NDkxNDI2OjQ6MA", "lastUpdated": "2023-03-30T14:00:12.733Z", "name": "API_JornBerkefeld app user" }, "restriction": "NONE", "keywordType": "NORMAL", "responseMessage": "line1\nline2", "isInherited": false, "dipSwitches": 0 } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/keyword/cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow/delete-response.json ================================================ ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/keyword/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 1, "entry": [ { "id": "cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow", "createdDate": "2018-03-27T12:37:18.12Z", "lastUpdated": "2018-03-27T12:37:18.167Z", "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "createdDate": "2017-05-05T10:33:15.953Z", "lastUpdated": "2022-11-25T15:51:14.225Z", "code": "4912312345678", "countryCode": "HK", "startDate": "2017-05-05T06:00:00Z", "endDate": "2047-05-05T06:00:00Z", "keywordLimit": "Unlimited", "keywordsUsed": "0", "codeType": "PRIVATE", "isShortCode": false, "keywordsUsedOther": "0", "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 1, "moEngineVersion": 1, "sendableCountries": [ { "countryCode": "HK", "vendor": "CLX", "fromNameSupported": true } ], "supportsConcatenation": true, "isClientOwned": false, "isOwner": false }, "keyword": "TESTEXISTING_KEYWORD", "startDate": "2018-03-27T12:37:18.197Z", "endDate": "2038-03-27T12:37:18.197Z", "status": "Active", "createdBy": { "id": "abcabcabc", "name": "xyz app user" }, "restriction": "NONE", "keywordType": "NORMAL", "responseMessage": "line1 %%[ SET @test='bla bla' ]%% line2 %%= v(@test) =%% still line2\nline3", "isInherited": false, "decodedId": "9e2192ab-f611-4039-86a8-7ce0ccf3a453" } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/keyword/post-response.json ================================================ { "id": "NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/delete-response.json ================================================ ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/get-response.json ================================================ { "id": "NTIzOjc4OjA", "lastUpdated": "2023-03-08T16:30:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testExisting_mobileMessage", "text": "test message jb new", "origin": "SMS Send", "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "code": "4912312345678", "codeType": "PRIVATE", "isShortCode": false, "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 0, "moEngineVersion": 0, "sendableCountries": [{ "countryCode": "HK", "vendor": "CLX", "fromNameSupported": true }], "supportsConcatenation": true, "isClientOwned": false, "isOwner": false }, "campaigns": [ { "id": "MjMxOjQ2OjA", "name": "testExisting_campaign", "display": { "name": "color", "value": "f6efb6" } } ], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "", "publishedMessage": "Text '<keyword>' to 4912312345678.", "nextJob": { "id": "MjY3Ojc5OjA", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsJobEntity", "isTest": false, "sendDate": "2020-07-16T22:46:00Z" }, "isTest": false, "currentEditStep": 13, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "triggeredSendId": "00000000-0000-0000-0000-000000000000", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statistics": { "outbound": { "sent": 45, "delivered": 33, "undelivered": 0, "unknown": 0 } }, "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "nextKeyword": { "id": "cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow", "keyword": "TESTEXISTING_KEYWORD", "restriction": "NONE", "isInherited": false }, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "programId": "00000000-0000-0000-0000-000000000000", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/post-response.json ================================================ ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/message/NTQ3Ojc4OjA/get-response.json ================================================ { "id": "NTQ3Ojc4OjA", "lastUpdated": "2023-03-28T13:16:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "jb test 3", "text": "New Task Available", "origin": "SMS Send", "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "code": "4912312345678", "codeType": "PRIVATE", "isShortCode": false, "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 0, "moEngineVersion": 0, "sendableCountries": [{ "countryCode": "HK", "vendor": "CLX", "fromNameSupported": true }], "supportsConcatenation": true, "isClientOwned": false, "isOwner": false }, "mtSendDate": "2017-07-03T14:03:00Z", "template": { "id": "Mzo4MDow", "lastUpdated": "2023-03-28T13:15:58.354Z", "name": "Outbound", "description": "Send a SMS message to your subscribers", "icon": "outbound.png" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "", "publishedMessage": "Text '<keyword>' to 4912312345678.", "nextJob": { "id": "NTQ3Ojc5OjA", "lastUpdated": "2023-03-28T13:15:58.323Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsJobEntity", "message": { "id": "NTQ3Ojc4OjA", "lastUpdated": "2023-03-28T13:15:58.323Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "isTest": false, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "triggeredSendId": "00000000-0000-0000-0000-000000000000", "isDuplicationAllowed": false, "triggeredSendName": "", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 1, "doubleOptinValidResponses": "", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "USER", "allowSingleOptin": false, "isSentImmediately": false, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "00000000-0000-0000-0000-000000000000", "fromName": "", "concatenateMessage": false, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "programId": "00000000-0000-0000-0000-000000000000", "outboundSendBehaviorFlag": "AutoAddSubscribers" }, "isTest": false }, "isTest": false, "currentEditStep": 0, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "triggeredSendId": "00000000-0000-0000-0000-000000000000", "isDuplicationAllowed": true, "triggeredSendName": "OneUserOneDevice_DEV - 93", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "X1pERmhqajlVMGkzMEdtVTJPYUxVZzo2MjU6MA", "allowSingleOptin": false, "duplicateOptInResponseMessage": "", "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "58d59e53-f85f-e711-80cc-1402ec7222b4", "fromName": "PMI_DEV", "concatenateMessage": false, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "programId": "00000000-0000-0000-0000-000000000000", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/message/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 1, "entry": [ { "id": "NTIzOjc4OjA", "lastUpdated": "2023-03-08T16:30:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testExisting_mobileMessage", "text": "line1 %%[ SET @test='bla bla' ]%% line2 %%= v(@test) =%% still line2\nline3", "origin": "SMS Send", "code": { "id": "RXBwc0JoNk9jVTY0YWJNWFZDaGxvdzo4MTow", "code": "4912312345678", "codeType": "PRIVATE", "isShortCode": false, "isGsmCharacterSetOnly": false, "isMms": false, "isStackIndependant": false, "dipSwitches": 0, "moEngineVersion": 0, "sendableCountries": [ { "countryCode": "AE", "vendor": "CLX", "fromNameSupported": true }, { "countryCode": "AL", "vendor": "CLX", "fromNameSupported": true }, { "countryCode": "AM", "vendor": "CLX", "fromNameSupported": true } ], "supportsConcatenation": true, "isClientOwned": false, "isOwner": false }, "campaigns": [ { "id": "MjMxOjQ2OjA", "name": "testExisting_campaign", "display": { "name": "color", "value": "f6efb6" } } ], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "bla bla", "publishedMessage": "Text '<keyword>' to 4912312345678.", "nextJob": { "id": "MjY3Ojc5OjA", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsJobEntity", "isTest": false, "sendDate": "2020-07-16T22:46:00Z" }, "isTest": false, "currentEditStep": 13, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "triggeredSendId": "00000000-0000-0000-0000-000000000000", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statistics": { "outbound": { "sent": 45, "delivered": 33, "undelivered": 0, "unknown": 0 } }, "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "nextKeyword": { "id": "cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow", "keyword": "TESTEXISTING_KEYWORD", "restriction": "NONE", "isInherited": false }, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "programId": "00000000-0000-0000-0000-000000000000", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ] } ================================================ FILE: test/resources/9999999/legacy/v1/beta/mobile/message/post-response.json ================================================ { "id": "NTQ3Ojc4OjA" } ================================================ FILE: test/resources/9999999/legacy/v1/beta/object/NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow/get-response.json ================================================ { "id": "NWQwdnhEU3dFZWVBekJRQzdISWl0QTo0NTow", "key": "testExisting_dataExtension", "dataExtensionName": "testExisting_dataExtension", "description": "", "isSendable": true, "sendableDataExtensionField": "ContactKey", "sendableSubscriberField": "_SubscriberKey", "isTestable": false, "isPublic": false, "isPlatformObject": false } ================================================ FILE: test/resources/9999999/legacy/v1/beta2/data/campaign/get-response.json ================================================ { "startIndex": 0, "itemsPerPage": 50, "totalResults": 1, "entry": [ { "id": "MjMxOjQ2OjA", "type": "Campaign", "createdDate": "2021-05-17T11:52:40Z", "lastUpdated": "2023-03-28T14:35:34.213Z", "createdBy": "https://mcabcdefghijkl-mnopqrs.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/Nzc1MTU2ODo0OjA", "name": "testExisting_campaign", "description": "Test Campaign", "externalKey": "TEST CAMPAIGN", "campaignCode": "", "ownerId": "https://mcabcdefghijkl-mnopqrs.rest.marketingcloudapis.com/legacy/v1/beta/organization/user/NzI5NzMwMTo0OjA", "display": { "name": "color", "value": "f6efb6" }, "isFavorite": false, "plannedDeploymentDate": "2021-05-16T22:00:00Z", "campaignOwnerName": "Jörn Berkefeld", "campaignId": 231, "campaignStatus": "InProcess", "campaignOwner": "MDo0OjE" } ] } ================================================ FILE: test/resources/9999999/list/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:fc7c8368-c8f0-4b86-a4ac-c420bb2517cf</wsa:MessageID> <wsa:RelatesTo>urn:uuid:eaad475d-1129-4cf5-bbe6-a1d90a80f6da</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-e7686d6f-36cb-4c39-b845-f4a4ae521504"> <wsu:Created>2022-11-29T19:42:18Z</wsu:Created> <wsu:Expires>2022-11-29T19:47:18Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e5b8151e-8780-4543-9856-971f3023769f</RequestID> <Results xsi:type="List"> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-02-16T01:59:27.29</CreatedDate> <ModifiedDate>2017-02-16T01:59:27.29</ModifiedDate> <ID>23</ID> <ObjectID>95e7f560-dca9-4ad2-8bc6-850ea7506e88</ObjectID> <CustomerKey>All Subscribers - 412</CustomerKey> <ListName>All Subscribers</ListName> <Category>412</Category> <Type>Private</Type> <Description>Contains all subscribers</Description> <ListClassification>ExactTargetList</ListClassification> </Results> <Results xsi:type="List"> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-06-13T06:03:10.8</CreatedDate> <ModifiedDate>2017-06-13T06:03:10.8</ModifiedDate> <ID>109</ID> <ObjectID>3d03a584-453e-41e0-9ed7-3ef418d5f79c</ObjectID> <CustomerKey>Test_List - 404</CustomerKey> <ListName>Test_List</ListName> <Category>404</Category> <Type>Private</Type> <Description>Test_List</Description> <ListClassification>ExactTargetList</ListClassification> </Results> <Results xsi:type="List"> <PartnerKey xsi:nil="true" /> <CreatedDate>2017-06-26T04:46:40.887</CreatedDate> <ModifiedDate>2017-06-26T04:46:40.887</ModifiedDate> <ID>114</ID> <ObjectID>b3e9f648-0588-4cc4-90a5-26624cdd2e1e</ObjectID> <CustomerKey>Demo Publication List - 424</CustomerKey> <ListName>Demo Publication List</ListName> <Category>424</Category> <Type>Public</Type> <Description /> <ListClassification>PublicationList</ListClassification> </Results> <Results xsi:type="List"> <PartnerKey xsi:nil="true" /> <CreatedDate>2022-02-17T11:58:08.273</CreatedDate> <ModifiedDate>2022-02-17T11:59:40.01</ModifiedDate> <ID>1120</ID> <ObjectID>ebe40007-8776-46d7-9c9f-dc4578ac08b7</ObjectID> <CustomerKey>sfmcTest - 419</CustomerKey> <ListName>sfmcTest</ListName> <Category>419</Category> <Type>Private</Type> <Description /> <ListClassification>SuppressionList</ListClassification> </Results> <Results xsi:type="List"> <PartnerKey xsi:nil="true" /> <CreatedDate>2024-04-24T12:17:15.423</CreatedDate> <ModifiedDate>2024-04-24T12:17:15.423</ModifiedDate> <ID>75520</ID> <ObjectID>97382359-b292-49aa-97a1-e53cedc18911</ObjectID> <CustomerKey>testExisting_suppressionList - 419</CustomerKey> <ListName>testExisting_suppressionList</ListName> <Category>419</Category> <Type>Public</Type> <Description>blabla</Description> <ListClassification>SuppressionList</ListClassification> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/messaging/v1/domainverification/delete/post-response.txt ================================================ 1 records successfully updated! ================================================ FILE: test/resources/9999999/messaging/v1/domainverification/get-response.json ================================================ { "page": 1, "pageSize": 500, "count": 5, "items": [ { "enterpriseId": 1111111, "domain": "joern.berkefeld@accenture.com", "status": "Verified", "domainType": "UserDomain", "isSendable": true, "memberId": 9999999, "emailSendTime": "2024-05-15T08:37:08.587" }, { "enterpriseId": 1111111, "domain": "joern.berkefeld+test@accenture.com", "status": "Verified", "domainType": "UserDomain", "isSendable": true, "memberId": 9999999, "emailSendTime": "2024-05-15T08:37:08.587" }, { "enterpriseId": 1111111, "domain": "mcdev.accenture.com", "status": "Verified", "domainType": "SAP", "isSendable": true, "memberId": 9999999, "emailSendTime": "2023-06-19T11:11:17.32" }, { "enterpriseId": 1111111, "domain": "adhoc.accenture.com", "status": "Verified", "domainType": "PrivateDomain", "isSendable": true, "memberId": 9999999, "emailSendTime": "2024-07-18T06:42:09.943" }, { "enterpriseId": 1111111, "domain": "mcdev-transferrable.accenture.com", "status": "Verified", "domainType": "RegisteredDomain", "isSendable": true, "memberId": 9999999, "emailSendTime": "2023-09-20T06:05:53.873" } ] } ================================================ FILE: test/resources/9999999/messaging/v1/domainverification/post-response.txt ================================================ joern.berkefeld.New@accenture.com successfully added. ================================================ FILE: test/resources/9999999/messaging/v1/domainverification/update/post-response.txt ================================================ 1 records successfully updated! ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/get-response.json ================================================ { "requestId": "b0a6c5aa-83fa-43c2-a6a8-1e2055c85a43", "definitions": [ { "name": "testExisting_temail", "definitionKey": "testExisting_temail", "status": "Active", "createdDate": "2020-08-17T01:37:00", "modifiedDate": "2020-08-17T01:37:00" }, { "name": "testExisting_temail_notPublished", "definitionKey": "testExisting_temail_notPublished", "status": "Active", "createdDate": "2020-08-17T01:37:00", "modifiedDate": "2020-08-17T01:37:00" }, { "name": "testNew_temail_notPublished", "definitionKey": "testNew_temail_notPublished", "status": "Active", "createdDate": "2020-08-17T01:37:00", "modifiedDate": "2020-08-17T01:37:00" } ], "count": 1, "page": 1, "pageSize": 50 } ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/post-response.json ================================================ { "requestId": "51f09ca1-1e5e-444a-8ddc-8e4ff80a9fa1", "name": "testNew_temail", "definitionKey": "testNew_temail", "description": "created on deploy", "classification": "Default Transactional", "status": "Active", "createdDate": "2022-12-06T06:08:00", "modifiedDate": "2022-12-06T06:08:00", "content": { "customerKey": "testExisting_asset_message" }, "subscriptions": { "dataExtension": "testExisting_dataExtension", "list": "All Subscribers - 277", "autoAddSubscriber": true, "updateSubscriber": true }, "options": { "trackLinks": true }, "journey": { "interactionKey": "testNew_RANDOM_interaction" } } ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/delete-response.json ================================================ { "requestId": "b6ad9f29-1ea4-486d-b826-e3dda072bbcd", "message": "Success", "deletedDefinitionKey": "1b24da84-7e55-47cb-a190-585a3b49da20", "journey": {} } ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/get-response.json ================================================ { "requestId": "ae8511d0-9bf0-42d0-af4f-bd9c1218c812", "name": "testExisting_temail", "definitionKey": "testExisting_temail", "definitionId": "0a650d90-755e-ed11-b852-48df37d1df5b", "description": "bla bla", "classification": "Default Transactional", "status": "Active", "createdDate": "2020-09-10T03:29:00", "modifiedDate": "2020-09-10T03:29:00", "content": { "customerKey": "testExisting_asset_message" }, "subscriptions": { "list": "All Subscribers - 277", "dataExtension": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true }, "options": { "trackLinks": true }, "journey": { "interactionKey": "testExisting_temail" } } ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/patch-response.json ================================================ { "requestId": "ae8511d0-9bf0-42d0-af4f-bd9c1218c812", "name": "testExisting_temail", "definitionKey": "testExisting_temail", "definitionId": "0a650d90-755e-ed11-b852-48df37d1df5b", "description": "updated via deploy", "classification": "Default Transactional", "status": "Active", "createdDate": "2020-09-10T03:29:00", "modifiedDate": "2020-09-10T03:29:00", "content": { "customerKey": "testExisting_asset_message" }, "subscriptions": { "list": "All Subscribers - 277", "dataExtension": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true }, "options": { "trackLinks": true }, "journey": { "interactionKey": "testExisting_temail" } } ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/testExisting_temail_notPublished/get-response.json ================================================ { "requestId": "37ef06bd-4790-40c2-809f-41d0a8f1b068", "name": "testExisting_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "definitionKey": "testExisting_temail_notPublished", "definitionId": "6a2f70c5-2561-ef11-b876-f40343c95928", "description": "testExisting_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "classification": "Default Transactional", "status": "Active", "createdDate": "2024-08-23T02:01:00", "modifiedDate": "2024-08-23T02:01:00", "content": { "customerKey": "testExisting_asset_message" }, "subscriptions": { "dataExtension": "testExisting_temail_notPublished", "list": "All Subscribers - 277", "autoAddSubscriber": true, "updateSubscriber": true }, "options": { "trackLinks": true }, "journey": { "interactionKey": "testExisting_temail_notPublished" } } ================================================ FILE: test/resources/9999999/messaging/v1/email/definitions/testNew_temail_notPublished/get-response.json ================================================ { "requestId": "37ef06bd-4790-40c2-809f-41d0a8f1b068", "name": "testNew_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "definitionKey": "testNew_temail_notPublished", "definitionId": "6a2f70c5-2561-ef11-b876-f40343c95929", "description": "testNew_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "classification": "testExisting_sendClassification", "status": "Active", "createdDate": "2024-08-23T02:01:00", "modifiedDate": "2024-08-23T02:01:00", "content": { "customerKey": "testExisting_asset_message" }, "subscriptions": { "dataExtension": "testExisting_dataExtension", "list": "All Subscribers - 277", "autoAddSubscriber": true, "updateSubscriber": true }, "options": { "trackLinks": true }, "journey": { "interactionKey": "testNew_temail_notPublished" } } ================================================ FILE: test/resources/9999999/messaging/v1/push/definitions/get-response.json ================================================ { "requestId": "4a89b42d-9e71-4ddd-9b4e-a3b00edbfdfb", "definitions": [ { "name": "testExisting_tpush", "definitionKey": "testExisting_tpush", "status": "Active", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T02:56:00" } ], "count": 1, "page": 1, "pageSize": 50 } ================================================ FILE: test/resources/9999999/messaging/v1/push/definitions/post-response.json ================================================ { "requestId": "ee81df03-ab61-454d-a54a-025675cf2b41", "name": "testNew_tpush", "definitionKey": "testNew_tpush", "definitionId": "2106d3f9-0c76-ed11-b849-48df37d1de8b", "description": "created on deploy; note that applicationId can only be manually set up in Setup - Mobile Push", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "status": "Active", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T03:26:00", "content": { "customerKey": "mobileMessage_test" }, "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/messaging/v1/push/definitions/testExisting_tpush/get-response.json ================================================ { "requestId": "64dac58f-f6d0-4bea-9489-eb058c491a87", "name": "testExisting_tpush", "definitionKey": "testExisting_tpush", "definitionId": "2106d3f9-0c76-ed11-b849-48df37d1de8b", "description": "bla bla. note that applicationId can only be manually set up in Setup - Mobile Push", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "status": "Active", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T02:56:00", "content": { "customerKey": "mobileMessage_test" }, "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/messaging/v1/push/definitions/testExisting_tpush/patch-response.json ================================================ { "requestId": "6d796b32-dff3-4564-ae36-f51edb0e5ec6", "name": "testExisting_tpush", "definitionKey": "testExisting_tpush", "definitionId": "2106d3f9-0c76-ed11-b849-48df37d1de8b", "description": "updated via deploy; note that applicationId can only be manually set up in Setup - Mobile Push", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "status": "Active", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T03:26:00", "content": { "customerKey": "mobileMessage_test" }, "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/messaging/v1/sms/definitions/get-response.json ================================================ { "requestId": "60c26a29-e1b0-4952-a566-476a937e4a5d", "definitions": [ { "name": "testExisting_tsms", "definitionKey": "testExisting_tsms", "status": "Active", "createdDate": "2022-11-23T02:50:00", "modifiedDate": "2022-11-25T08:01:00" } ], "count": 1, "page": 1, "pageSize": 50 } ================================================ FILE: test/resources/9999999/messaging/v1/sms/definitions/post-response.json ================================================ { "requestId": "582bec09-6d04-4222-bbba-cea616495596", "name": "testNew_tsms", "definitionKey": "testNew_tsms", "description": "created on deploy", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "content": { "message": "\n%%[\n SET @key = 'new secret'\n]%%\n%%[\n\nSET @unsubMessages = 'UnsubscribeSMSMessages_DEV'\nSET @unsubEvents = 'UnsubscribeSMS_DEV'\n\nSET @num = concat('+',[MOBILE_NUMBER])\nSET @rs= RetrieveSalesforceObjects('Contact','Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=',@num) \nSET @count = rowCount(@rs)\nVAR @response\nSET @rx = '^\\+((?:9[679]\\d8[035789]\\d|6[789]\\d|5[90]\\d|42\\d|3[578]\\d|2[1-689]\\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)'\nSET @prefix = concat('+',RegExMatch(@num, @rx, 1))\nIF @count>0 THEN\n\tFOR @i = 1 TO @count DO\n\t\tSET @sk = Field(Row(@rs,@i),'Id')\n\t\tIF Field(Row(@rs,1),'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN\n\t\t\tSET @result = UpdateSingleSalesforceObject('Contact',@sk,'et4ae5__HasOptedOutOfMobile__c','true')\n\t\t\tIF @result == 0 THEN \n\t\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Error Updating')\n\t\t\tELSE \n\t\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Successfully Unsubscribed')\n\t\t\tENDIF\n\t\tELSE \n\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Already Unsubscribed')\n\t\tENDIF\n\n\tNEXT @i\n\n\tSET @msg = Lookup(@unsubMessages,'Message','Prefix',@prefix,'Type', 'Found')\n\tIF Length(@msg) == 0 THEN\n\t\tSET @response ='You have unsubscribed and will no longer receive any messages.|'\n\tELSE \n\t\tSET @response = @msg\n\tENDIF\nELSE \n\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'Status', 'Not Found') \n\tSET @msg = Lookup(@unsubMessages,'Message','Prefix',@prefix,'Type', 'NotFound')\n\tIF Length(@msg) == 0 THEN\n\t\tSET @response ='Sorry, we could not find you'\n\tELSE \n\t\tSET @response = @msg\n\tENDIF\nENDIF\n]%%\n%%=v(@response)=%%" }, "subscriptions": { "shortCode": "4912312345678", "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "keyword": "TESTEXISTING_KEYWORD" } } ================================================ FILE: test/resources/9999999/messaging/v1/sms/definitions/testExisting_tsms/get-response.json ================================================ { "requestId": "ae8511d0-9bf0-42d0-af4f-bd9c1218c812", "name": "testExisting_tsms", "definitionKey": "testExisting_tsms", "definitionId": "0a650d90-755e-ed11-b852-48df37d1df5b", "description": "bla bla", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "content": { "message": "line1 %%[ SET @test='bla bla' ]%% line2 %%= v(@test) =%% still line2\nline3 %%[ SET @key = 'secret' ]%%\n%%[\n\nSET @unsubMessages = 'UnsubscribeSMSMessages_DEV'\nSET @unsubEvents = 'UnsubscribeSMS_DEV'\n\nSET @num = concat('+',[MOBILE_NUMBER])\nSET @rs= RetrieveSalesforceObjects('Contact','Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=',@num) \nSET @count = rowCount(@rs)\nVAR @response\nSET @rx = '^\\+((?:9[679]\\d8[035789]\\d|6[789]\\d|5[90]\\d|42\\d|3[578]\\d|2[1-689]\\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)'\nSET @prefix = concat('+',RegExMatch(@num, @rx, 1))\nIF @count>0 THEN\n\tFOR @i = 1 TO @count DO\n\t\tSET @sk = Field(Row(@rs,@i),'Id')\n\t\tIF Field(Row(@rs,1),'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN\n\t\t\tSET @result = UpdateSingleSalesforceObject('Contact',@sk,'et4ae5__HasOptedOutOfMobile__c','true')\n\t\t\tIF @result == 0 THEN \n\t\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Error Updating')\n\t\t\tELSE \n\t\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Successfully Unsubscribed')\n\t\t\tENDIF\n\t\tELSE \n\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Already Unsubscribed')\n\t\tENDIF\n\n\tNEXT @i\n\n\tSET @msg = Lookup(@unsubMessages,'Message','Prefix',@prefix,'Type', 'Found')\n\tIF Length(@msg) == 0 THEN\n\t\tSET @response ='You have unsubscribed and will no longer receive any messages.|'\n\tELSE \n\t\tSET @response = @msg\n\tENDIF\nELSE \n\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'Status', 'Not Found') \n\tSET @msg = Lookup(@unsubMessages,'Message','Prefix',@prefix,'Type', 'NotFound')\n\tIF Length(@msg) == 0 THEN\n\t\tSET @response ='Sorry, we could not find you'\n\tELSE \n\t\tSET @response = @msg\n\tENDIF\nENDIF\n]%%\n%%=v(@response)=%%" }, "subscriptions": { "shortCode": "4912312345678", "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "keyword": "TESTEXISTING_KEYWORD" } } ================================================ FILE: test/resources/9999999/messaging/v1/sms/definitions/testExisting_tsms/patch-response.json ================================================ { "requestId": "ae8511d0-9bf0-42d0-af4f-bd9c1218c812", "name": "testExisting_tsms", "definitionKey": "testExisting_tsms", "definitionId": "0a650d90-755e-ed11-b852-48df37d1df5b", "description": "bla bla", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "content": { "message": "%%[ SET @key = 'secret' ]%%\n%%[\n\nSET @unsubMessages = 'UnsubscribeSMSMessages_DEV'\nSET @unsubEvents = 'UnsubscribeSMS_DEV'\n\nSET @num = concat('+',[MOBILE_NUMBER])\nSET @rs= RetrieveSalesforceObjects('Contact','Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=',@num) \nSET @count = rowCount(@rs)\nVAR @response\nSET @rx = '^\\+((?:9[679]\\d8[035789]\\d|6[789]\\d|5[90]\\d|42\\d|3[578]\\d|2[1-689]\\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)'\nSET @prefix = concat('+',RegExMatch(@num, @rx, 1))\nIF @count>0 THEN\n\tFOR @i = 1 TO @count DO\n\t\tSET @sk = Field(Row(@rs,@i),'Id')\n\t\tIF Field(Row(@rs,1),'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN\n\t\t\tSET @result = UpdateSingleSalesforceObject('Contact',@sk,'et4ae5__HasOptedOutOfMobile__c','true')\n\t\t\tIF @result == 0 THEN \n\t\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Error Updating')\n\t\t\tELSE \n\t\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Successfully Unsubscribed')\n\t\t\tENDIF\n\t\tELSE \n\t\t\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'ContactId',@sk,'Status', 'Already Unsubscribed')\n\t\tENDIF\n\n\tNEXT @i\n\n\tSET @msg = Lookup(@unsubMessages,'Message','Prefix',@prefix,'Type', 'Found')\n\tIF Length(@msg) == 0 THEN\n\t\tSET @response ='You have unsubscribed and will no longer receive any messages.|'\n\tELSE \n\t\tSET @response = @msg\n\tENDIF\nELSE \n\tInsertData(@unsubEvents,'MobileNumber',@num,'Message',[MSG(0).NOUNS],'Status', 'Not Found') \n\tSET @msg = Lookup(@unsubMessages,'Message','Prefix',@prefix,'Type', 'NotFound')\n\tIF Length(@msg) == 0 THEN\n\t\tSET @response ='Sorry, we could not find you'\n\tELSE \n\t\tSET @response = @msg\n\tENDIF\nENDIF\n]%%\n%%=v(@response)=%%" }, "subscriptions": { "shortCode": "4912312345678", "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "keyword": "TESTEXISTING_KEYWORD" } } ================================================ FILE: test/resources/9999999/mobileKeyword/build-expected.amp ================================================ line1 %%[ SET @test = 'foobar' ]%% line2 %%= v(@test) =%% still line2 line3 ================================================ FILE: test/resources/9999999/mobileKeyword/build-expected.json ================================================ { "c__codeKeyword": "4912312345678.TESTTEMPLATED_KEYWORD", "r__mobileCode_key": "4912312345678", "keywordType": "NORMAL", "isInherited": false, "restriction": "NONE" } ================================================ FILE: test/resources/9999999/mobileKeyword/get-expected.amp ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= v(@test) =%% still line2 line3 ================================================ FILE: test/resources/9999999/mobileKeyword/get-expected.json ================================================ { "createdDate": "2018-03-27T12:37:18.12Z", "lastUpdated": "2018-03-27T12:37:18.167Z", "c__codeKeyword": "4912312345678.TESTEXISTING_KEYWORD", "r__mobileCode_key": "4912312345678", "startDate": "2018-03-27T12:37:18.197Z", "endDate": "2038-03-27T12:37:18.197Z", "status": "Active", "createdBy": { "name": "xyz app user" }, "restriction": "NONE", "keywordType": "NORMAL", "isInherited": false } ================================================ FILE: test/resources/9999999/mobileKeyword/post-create-expected.amp ================================================ line1 line2 ================================================ FILE: test/resources/9999999/mobileKeyword/post-create-expected.json ================================================ { "createdBy": { "name": "API_JornBerkefeld app user" }, "createdDate": "2023-03-30T14:00:11.907Z", "endDate": "2043-03-30T14:00:11.843Z", "isInherited": false, "c__codeKeyword": "4912312345678.TESTNEW_KEYWORD", "r__mobileCode_key": "4912312345678", "keywordType": "NORMAL", "lastUpdated": "2023-03-30T14:00:12.295Z", "restriction": "NONE", "startDate": "2023-03-30T14:00:11.843Z", "status": "Active" } ================================================ FILE: test/resources/9999999/mobileKeyword/template-expected.amp ================================================ line1 %%[ SET @test = '{{{description}}}' ]%% line2 %%= v(@test) =%% still line2 line3 ================================================ FILE: test/resources/9999999/mobileKeyword/template-expected.json ================================================ { "c__codeKeyword": "4912312345678.{{{prefixUpper}}}KEYWORD", "r__mobileCode_key": "4912312345678", "keywordType": "NORMAL", "isInherited": false, "restriction": "NONE" } ================================================ FILE: test/resources/9999999/mobileMessage/build-expected.amp ================================================ line1 %%[ SET @test = 'foobar' ]%% line2 %%= v(@test) =%% still line2 line3 ================================================ FILE: test/resources/9999999/mobileMessage/build-expected.json ================================================ { "id": "NTIzOjc4OjA", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testTemplated_mobileMessage", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "r__campaign_key": ["testTemplated_campaign"], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "foobar", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/mobileMessage/get-expected.amp ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= v(@test) =%% still line2 line3 ================================================ FILE: test/resources/9999999/mobileMessage/get-expected.json ================================================ { "id": "NTIzOjc4OjA", "lastUpdated": "2023-03-08T16:30:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testExisting_mobileMessage", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "r__campaign_key": ["testExisting_campaign"], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "bla bla", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/mobileMessage/post-create-expected.amp ================================================ New Task Available ================================================ FILE: test/resources/9999999/mobileMessage/post-create-expected.json ================================================ { "id": "NTQ3Ojc4OjA", "lastUpdated": "2023-03-28T13:16:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "jb test 3", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "mtSendDate": "2017-07-03T14:03:00Z", "template": { "id": "Mzo4MDow", "lastUpdated": "2023-03-28T13:15:58.354Z", "name": "Outbound", "description": "Send a SMS message to your subscribers", "icon": "outbound.png" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "OneUserOneDevice_DEV - 93", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "X1pERmhqajlVMGkzMEdtVTJPYUxVZzo2MjU6MA", "allowSingleOptin": false, "duplicateOptInResponseMessage": "", "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "58d59e53-f85f-e711-80cc-1402ec7222b4", "fromName": "PMI_DEV", "concatenateMessage": false, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/mobileMessage/post-update-expected.amp ================================================ test message jb new ================================================ FILE: test/resources/9999999/mobileMessage/post-update-expected.json ================================================ { "id": "NTIzOjc4OjA", "lastUpdated": "2023-03-08T16:30:00Z", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "testExisting_mobileMessage", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "r__campaign_key": ["testExisting_campaign"], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/mobileMessage/template-expected.amp ================================================ line1 %%[ SET @test = '{{{description}}}' ]%% line2 %%= v(@test) =%% still line2 line3 ================================================ FILE: test/resources/9999999/mobileMessage/template-expected.json ================================================ { "id": "NTIzOjc4OjA", "type": "ExactTarget.Mobile.Sms.Core.Entities.SmsMessageEntity", "name": "{{{prefix}}}mobileMessage", "origin": "SMS Send", "r__mobileCode_key": "4912312345678", "r__campaign_key": ["{{{prefix}}}campaign"], "mtSendDate": "2020-07-16T22:46:00Z", "template": { "id": "Mzo4MDow", "name": "Outbound" }, "status": "Active/Scheduled", "invalidMessage": "", "responseMessage": "{{{description}}}", "publishedMessage": "Text '<keyword>' to 4912312345678.", "isTest": false, "moTimezone": { "offset": 1, "name": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *" }, "optinType": "NO_OPTIN", "doubleOptinInitialMessage": "", "doubleOptinConfirmMessage": "", "optinMinimumAge": 0, "optinInvalidAgeMessage": "", "numberMessagesPerPeriod": 0, "periodType": "NO_PERIOD", "optinErrorMessage": "", "isDuplicationAllowed": true, "triggeredSendName": "DEV_InformUserAboutProposal - 267", "isTimeZoneBased": false, "surveyType": "NO_SURVEY", "surveyCorrectResponseMessage": "", "surveyTooManyEntriesMessage": "", "isExpireSet": false, "expireHours": 0, "surveyIncorrectResponseMessage": "", "statusId": 2, "doubleOptinValidResponses": "y|yes", "messagesPerPeriod": 0, "minutesPerPeriod": 0, "subscriberResponseMessage": "", "isSubscriberResponseToAnySubscriptionForShortCode": false, "sendMethod": "API", "messageObjectId": "MzN3MUV5YVpmRVMtV1R1UXJUR3NzUTo2MjU6MA", "allowSingleOptin": false, "isSentImmediately": true, "isSuppressMt": false, "smsTriggeredSendDefinitionId": "39d0e022-b6c7-ea11-a2e9-1402ec938719", "fromName": "4912312345678", "concatenateMessage": true, "isFromNameCertificationAccepted": false, "isCertified": false, "outboundSendTypeFlag": "Audience", "outboundSendBehaviorFlag": "AutoAddSubscribers" } ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_pause-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_pause</ObjectID> <Name>testExisting_automation_fixedKey_paused</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_fixKey_pause</CustomerKey> <!--only retrieved for cache--> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_schedule-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_schedule</ObjectID> <Name>testExisting_automation_fixedKey_scheduled</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_fixKey_schedule</CustomerKey> <!--only retrieved for cache--> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_paused-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_pause</ObjectID> <Name>testExisting_automation_fixedKey_paused</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_fixedKey_paused</CustomerKey> <!--only retrieved for cache--> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_scheduled-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_schedule</ObjectID> <Name>testExisting_automation_fixedKey_scheduled</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_fixedKey_scheduled</CustomerKey> <!--only retrieved for cache--> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-pause</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-CustomerKey=testNew_automation-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>a8afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-Name=testExisting_automation-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> <Name>testExisting_automation</Name> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/program/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298</wsa:MessageID> <wsa:RelatesTo>urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f95f3fd3-c763-4e2c-929f-33611e9d2eba"> <wsu:Created>2023-06-01T12:04:20Z</wsu:Created> <wsu:Expires>2023-06-01T12:09:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>3b1c8cee-b270-49cb-b77b-e7b33934d1b6</RequestID> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-1f7f8788c560</ObjectID> <Name>testExisting_automation</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation</CustomerKey> <!--only retrieved for cache--> </Results> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-ad2e-pause</ObjectID> <Name>testExisting_automation_pause</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_pause</CustomerKey> <!--only retrieved for cache--> </Results> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_schedule</ObjectID> <Name>testExisting_automation_fixedKey_scheduled</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_fixKey_schedule</CustomerKey> <!--only retrieved for cache--> </Results> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>08afb0e2-b00a-4c88-fixKey_pause</ObjectID> <Name>testExisting_automation_fixedKey_paused</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_fixKey_pause</CustomerKey> <!--only retrieved for cache--> </Results> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>0fc2ac96-14ba-495a-8db9-3ddd4f8ac444-wait</ObjectID> <Name>testExisting_automation_wait</Name> <!--only retrieved for cache--> <CustomerKey>testExisting_automation_wait</CustomerKey> <!--only retrieved for cache--> </Results> <Results xsi:type="Program"> <PartnerKey xsi:nil="true" /> <ObjectID>8f82c2a7-0bae-45a9-bdee-e631ab25c0d5</ObjectID> <CustomerKey>testExisting_automation_event</CustomerKey> <Name>testExisting_automation_event</Name> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/query/build-expected.json ================================================ { "name": "testTemplated_query", "key": "testTemplated_query", "description": "foobar", "r__dataExtension_key": "testTemplated_dataExtension", "targetUpdateTypeName": "Overwrite", "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/build-expected.sql ================================================ SELECT SubscriberKey AS testField, TRIM(last_name) AS name FROM _Subscribers WHERE country IN ('testTarget') ================================================ FILE: test/resources/9999999/query/clone-expected.json ================================================ { "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "targetUpdateTypeName": "Overwrite", "r__dataExtension_key": "testExisting_dataExtension", "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/clone-expected.sql ================================================ SELECT SubscriberKey AS testField, TRIM(last_name) AS name FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/resources/9999999/query/get-expected.json ================================================ { "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeName": "Overwrite", "r__folder_Path": "Query", "isFrozen": false } ================================================ FILE: test/resources/9999999/query/get-expected.sql ================================================ SELECT SubscriberKey AS testField, TRIM(last_name) AS name FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/resources/9999999/query/get2-expected.json ================================================ { "name": "testExisting_query2", "key": "testExisting_query2", "description": "bla bla", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeName": "Overwrite", "r__folder_Path": "Query", "isFrozen": false } ================================================ FILE: test/resources/9999999/query/get_sharedDE-expected.json ================================================ { "name": "testExisting_query_SharedDE", "key": "testExisting_query_SharedDE", "description": "bla bla", "r__dataExtension_key": "testExisting_dataExtensionShared", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:02:44.01", "targetUpdateTypeName": "Overwrite", "r__folder_Path": "Query", "isFrozen": false } ================================================ FILE: test/resources/9999999/query/get_sharedDE-expected.sql ================================================ SELECT SubscriberKey AS testField, TRIM(last_name) AS name FROM testExisting_dataExtensionShared WHERE country IN ('test') ================================================ FILE: test/resources/9999999/query/patch-expected.json ================================================ { "name": "testExisting_query", "key": "testExisting_query", "description": "updated on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/patch-expected.sql ================================================ SELECT SubscriberKey as testField FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/resources/9999999/query/patch_fixKeys-expected.json ================================================ { "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixedKeys", "description": "updated on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/patch_fixKeys-expected.sql ================================================ SELECT SubscriberKey AS testField FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/resources/9999999/query/patch_fixKeysSuffix-expected.json ================================================ { "name": "testExisting_query_fixedKeysSuffix", "key": "testExisting_query_fixedKeysSuff_DEV", "description": "updated on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/patch_fixKeysSuffix-expected.sql ================================================ SELECT SubscriberKey AS testField FROM _Subscribers WHERE country IN ('test') ================================================ FILE: test/resources/9999999/query/post-expected.json ================================================ { "name": "testNew_query", "key": "testNew_query", "description": "created on deploy", "r__dataExtension_key": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", "targetUpdateTypeName": "Overwrite", "isFrozen": false, "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/post-expected.sql ================================================ SELECT SubscriberKey as testField FROM _Subscribers ================================================ FILE: test/resources/9999999/query/template-expected.json ================================================ { "name": "{{{prefix}}}query", "key": "{{{prefix}}}query", "description": "{{{description}}}", "r__dataExtension_key": "{{{prefix}}}dataExtension", "targetUpdateTypeName": "Overwrite", "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/template-expected.sql ================================================ SELECT SubscriberKey AS testField, TRIM(last_name) AS name FROM _Subscribers WHERE country IN ({{{countryCodeIn}}}) ================================================ FILE: test/resources/9999999/query/template_sharedDE-expected.json ================================================ { "name": "{{{prefix}}}query_SharedDE", "key": "{{{prefix}}}query_SharedDE", "description": "{{{description}}}", "r__dataExtension_key": "{{{prefix}}}dataExtensionShared", "targetUpdateTypeName": "Overwrite", "r__folder_Path": "Query" } ================================================ FILE: test/resources/9999999/query/template_sharedDE-expected.sql ================================================ SELECT SubscriberKey AS testField, TRIM(last_name) AS name FROM {{{prefix}}}dataExtensionShared WHERE country IN ({{{countryCodeIn}}}) ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=badANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:ed6a40f5-98ec-48e9-a059-2a4b7254448b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:1b00729b-19f9-4eae-b856-f5ce837ec0c8</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-cd3b3dcd-ad61-43ad-9b80-3934f420befd"> <wsu:Created>2024-07-12T09:24:49Z</wsu:Created> <wsu:Expires>2024-07-12T09:29:49Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>57658276-aab0-4312-b305-3b7e9911817f</RequestID> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query2ANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-dfc4ae59-8642-4432-b505-554669b47186"> <wsu:Created>2023-04-11T16:33:48Z</wsu:Created> <wsu:Expires>2023-04-11T16:38:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e8eb2988-2f43-4243-a6b0-6ab6b841a6ac</RequestID> <Results xsi:type="QueryDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>abcde-607c-4940-afef-437965094dat</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-dfc4ae59-8642-4432-b505-554669b47186"> <wsu:Created>2023-04-11T16:33:48Z</wsu:Created> <wsu:Expires>2023-04-11T16:38:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e8eb2988-2f43-4243-a6b0-6ab6b841a6ab</RequestID> <Results xsi:type="QueryDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>549f0568-607c-4940-afef-437965094dat</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-dfc4ae59-8642-4432-b505-554669b47186"> <wsu:Created>2023-04-11T16:33:48Z</wsu:Created> <wsu:Expires>2023-04-11T16:38:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e8eb2988-2f43-4243-a6b0-6ab6b841a6ab</RequestID> <Results xsi:type="QueryDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>549f0568-607c-4940-afef-437965094dat_fixKeys</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysSuffixANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-dfc4ae59-8642-4432-b505-554669b47186"> <wsu:Created>2023-04-11T16:33:48Z</wsu:Created> <wsu:Expires>2023-04-11T16:38:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e8eb2988-2f43-4243-a6b0-6ab6b841a6ab</RequestID> <Results xsi:type="QueryDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>549f0568-607c-4940-afef-437965094dat_fixKeysSuffix</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixedKeysANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-dfc4ae59-8642-4432-b505-554669b47186"> <wsu:Created>2023-04-11T16:33:48Z</wsu:Created> <wsu:Expires>2023-04-11T16:38:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e8eb2988-2f43-4243-a6b0-6ab6b841a6ab</RequestID> <Results xsi:type="QueryDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>549f0568-607c-4940-afef-437965094dat</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-dfc4ae59-8642-4432-b505-554669b47186"> <wsu:Created>2023-04-11T16:33:48Z</wsu:Created> <wsu:Expires>2023-04-11T16:38:48Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e8eb2988-2f43-4243-a6b0-6ab6b841a6ab</RequestID> <Results xsi:type="QueryDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID>549f0568-607c-4940-afef-437965094dae</ObjectID> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/script/build-expected.json ================================================ { "description": "", "key": "testTemplated_script", "name": "testTemplated_script", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/build-expected.ssjs ================================================ //dummy ================================================ FILE: test/resources/9999999/script/get-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "", "key": "testExisting_script", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testExisting_script", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/get-expected.ssjs ================================================ //dummy ================================================ FILE: test/resources/9999999/script/get_ampincluded-expected.html ================================================ <script runat="server">line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockById(1295064) =%% still line2 line3 </script> <script runat="server"> Platform.Function.ContentBlockById(1295064);</script> ================================================ FILE: test/resources/9999999/script/get_ampincluded-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "", "key": "testExisting_script_ampincluded", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testExisting_script_ampincluded", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/get_ampincluded-rcb-id-expected.html ================================================ <script runat="server">line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockById(1295064) =%% still line2 line3 </script> <script runat="server"> Platform.Function.ContentBlockById(1295064);</script> ================================================ FILE: test/resources/9999999/script/get_ampincluded-rcb-key-expected.html ================================================ <script runat="server">line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% still line2 line3 </script> <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock");</script> ================================================ FILE: test/resources/9999999/script/get_ampincluded-rcb-name-expected.html ================================================ <script runat="server">line1 %%[ SET @test='bla bla' ]%% line2 %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% still line2 line3 </script> <script runat="server"> Platform.Function.ContentBlockByName("Content Builder\\dont strip non ssjs content");</script> ================================================ FILE: test/resources/9999999/script/get_ampscript-expected.html ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% still line2 line3 <script runat="server"> Platform.Function.ContentBlockByName( "Content Builder\\dont strip non ssjs content" ); Platform.Function.ContentBlockByKey("testExisting_htmlblock1"); </script> ================================================ FILE: test/resources/9999999/script/get_ampscript-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "", "key": "testExisting_script_ampscript", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testExisting_script_ampscript", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/get_ampscript-rcb-id-expected.html ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockById(1295064) =%% still line2 line3 <script runat="server"> Platform.Function.ContentBlockById(1295064); Platform.Function.ContentBlockById(1295065); </script> ================================================ FILE: test/resources/9999999/script/get_ampscript-rcb-key-expected.html ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% still line2 line3 <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock"); Platform.Function.ContentBlockByKey("testExisting_htmlblock1"); </script> ================================================ FILE: test/resources/9999999/script/get_ampscript-rcb-name-expected.html ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% still line2 line3 <script runat="server"> Platform.Function.ContentBlockByName( "Content Builder\\dont strip non ssjs content" ); Platform.Function.ContentBlockByName( "Content Builder\\testExisting_htmlblock1" ); </script> ================================================ FILE: test/resources/9999999/script/get_mixed-expected.html ================================================ <script runat="server"> //dummy </script> line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% still line2; collapsed to line2 because it's assumed HTML <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock"); </script> ================================================ FILE: test/resources/9999999/script/get_mixed-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "", "key": "testExisting_script_mixed", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testExisting_script_mixed", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/get_mixed-rcb-id-expected.html ================================================ <script runat="server"> //dummy </script> line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockById(1295064) =%% still line2; collapsed to line2 because it's assumed HTML <script runat="server"> Platform.Function.ContentBlockById(1295064); </script> ================================================ FILE: test/resources/9999999/script/get_mixed-rcb-key-expected.html ================================================ <script runat="server"> //dummy </script> line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockByKey("testExisting_asset_htmlblock") =%% still line2; collapsed to line2 because it's assumed HTML <script runat="server"> Platform.Function.ContentBlockByKey("testExisting_asset_htmlblock"); </script> ================================================ FILE: test/resources/9999999/script/get_mixed-rcb-name-expected.html ================================================ <script runat="server"> //dummy </script> line1 %%[ SET @test = 'bla bla' ]%% line2 %%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%% still line2; collapsed to line2 because it's assumed HTML <script runat="server"> Platform.Function.ContentBlockByName( "Content Builder\\dont strip non ssjs content" ); </script> ================================================ FILE: test/resources/9999999/script/get_noScriptTag-expected.html ================================================ // no script tag ================================================ FILE: test/resources/9999999/script/get_noScriptTag-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "", "key": "testExisting_script_noScriptTag", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testExisting_script_noScriptTag", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/patch-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "updated on deploy", "key": "testExisting_script", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testExisting_script", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/patch-expected.ssjs ================================================ // dummy updated ================================================ FILE: test/resources/9999999/script/post-expected.json ================================================ { "createdDate": "2022-10-20T00:41:26.163", "description": "created on deploy", "key": "testNew_script", "modifiedDate": "2022-10-20T00:41:26.163", "name": "testNew_script", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/post-expected.ssjs ================================================ // dummy created ================================================ FILE: test/resources/9999999/script/template-expected.json ================================================ { "description": "", "key": "{{{prefix}}}script", "name": "{{{prefix}}}script", "r__folder_Path": "Scripts" } ================================================ FILE: test/resources/9999999/script/template-expected.ssjs ================================================ //dummy ================================================ FILE: test/resources/9999999/sendClassification/build-expected.json ================================================ { "CustomerKey": "testTemplated_sendClassification", "Description": "", "Name": "testTemplated_sendClassification", "c__classification": "Commercial", "r__deliveryProfile_key": "Default", "r__senderProfile_key": "testTemplated_senderProfile" } ================================================ FILE: test/resources/9999999/sendClassification/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:bb642235-9021-414c-8f0e-31d693a573e8</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b49d6c14-33d7-4ba8-8aea-0fe3282fdbfd</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-3e603e14-dc4c-4733-be8a-e2d8d3e205cb"> <wsu:Created>2024-04-15T21:38:02Z</wsu:Created> <wsu:Expires>2024-04-15T21:43:02Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>SendClassification created</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>07cf2a6e-70fb-ee11-a5c8-5cba2c6fc270</NewObjectID> <Object xsi:type="SendClassification"> <PartnerKey xsi:nil="true" /> <ObjectID>07cf2a6e-70fb-ee11-a5c8-5cba2c6fc270</ObjectID> <CustomerKey>testNew_sendClassification</CustomerKey> <SendClassificationType>Operational</SendClassificationType> <Name>testNew_sendClassification</Name> <Description>created on deploy</Description> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>Default</CustomerKey> </DeliveryProfile> </Object> </Results> <RequestID>d5f798f9-02eb-4b76-a4b4-90cfee939ce2</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/sendClassification/delete-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>DeleteResponse</wsa:Action> <wsa:MessageID>urn:uuid:51ac7e8d-3d31-425c-8899-7ba4b2b09626</wsa:MessageID> <wsa:RelatesTo>urn:uuid:9ee7419c-06be-4dcd-b386-5b64df545f2c</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-9ce349c8-ba3c-450a-b67f-f190a29fc100"> <wsu:Created>2024-04-15T21:53:10Z</wsu:Created> <wsu:Expires>2024-04-15T21:58:10Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <DeleteResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>SendClassification deleted</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="SendClassification"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_sendClassification</CustomerKey> </Object> </Results> <RequestID>0451cd2c-ab68-4e1c-9ded-d67003287283</RequestID> <OverallStatus>OK</OverallStatus> </DeleteResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/sendClassification/get-expected.json ================================================ { "CreatedDate": "2016-08-31T11:29:00", "ModifiedDate": "2024-04-15T15:33:00", "CustomerKey": "testExisting_sendClassification", "Name": "testExisting_sendClassification", "Description": "", "c__classification": "Commercial", "r__senderProfile_key": "testExisting_senderProfile", "r__deliveryProfile_key": "Default" } ================================================ FILE: test/resources/9999999/sendClassification/patch-expected.json ================================================ { "CreatedDate": "2016-08-31T11:29:00", "ModifiedDate": "2024-04-15T15:33:00", "CustomerKey": "testExisting_sendClassification", "Name": "testExisting_sendClassification", "Description": "", "c__classification": "Commercial", "r__senderProfile_key": "testExisting_senderProfile", "r__deliveryProfile_key": "Default" } ================================================ FILE: test/resources/9999999/sendClassification/post-expected.json ================================================ { "CustomerKey": "testNew_sendClassification", "Name": "testNew_sendClassification", "Description": "created on deploy", "c__classification": "Transactional", "r__senderProfile_key": "testExisting_senderProfile", "r__deliveryProfile_key": "Default" } ================================================ FILE: test/resources/9999999/sendClassification/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:31b53ebd-b853-4f8c-b952-f176aed80aa9</wsa:MessageID> <wsa:RelatesTo>urn:uuid:cac816ee-0b59-4748-b629-4475b198708f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-94d58fe7-c739-4593-b44e-86af9511d712"> <wsu:Created>2024-04-15T21:11:54Z</wsu:Created> <wsu:Expires>2024-04-15T21:16:54Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>e7197c3d-0483-44fd-93ad-d7dd2e0cfb56</RequestID> <Results xsi:type="SendClassification"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:53:00</CreatedDate> <ModifiedDate>2016-07-22T11:53:00</ModifiedDate> <ObjectID>8ecfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Default Commercial</CustomerKey> <SendClassificationType>Marketing</SendClassificationType> <Name>Default Commercial</Name> <Description>Default Commercial Send Classification</Description> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>7acfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Default</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID>163f8417-13f7-e911-a2d8-1402ec938a35</ObjectID> <CustomerKey>Default</CustomerKey> </DeliveryProfile> </Results> <Results xsi:type="SendClassification"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:53:00</CreatedDate> <ModifiedDate>2016-07-22T11:53:00</ModifiedDate> <ObjectID>90cfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Default Transactional</CustomerKey> <SendClassificationType>Operational</SendClassificationType> <Name>Default Transactional</Name> <Description>Default Transactional Send Classification</Description> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>7acfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Default</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID>163f8417-13f7-e911-a2d8-1402ec938a35</ObjectID> <CustomerKey>Default</CustomerKey> </DeliveryProfile> </Results> <Results xsi:type="SendClassification"> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-08-31T11:29:00</CreatedDate> <ModifiedDate>2024-04-15T15:33:00</ModifiedDate> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> <SendClassificationType>Marketing</SendClassificationType> <Name>testExisting_sendClassification</Name> <Description /> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID>163f8417-13f7-e911-a2d8-1402ec938a35</ObjectID> <CustomerKey>Default</CustomerKey> </DeliveryProfile> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/sendClassification/template-expected.json ================================================ { "CustomerKey": "{{{prefix}}}sendClassification", "Description": "", "Name": "{{{prefix}}}sendClassification", "c__classification": "Commercial", "r__deliveryProfile_key": "Default", "r__senderProfile_key": "{{{prefix}}}senderProfile" } ================================================ FILE: test/resources/9999999/sendClassification/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:76f29c30-cfd5-41b5-8c8f-d58a7ce82964</wsa:MessageID> <wsa:RelatesTo>urn:uuid:e05b39ff-7e0b-4c3e-811d-362ee08f48f4</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-9d056168-651a-486b-b817-2a0caa906180"> <wsu:Created>2024-04-15T21:32:54Z</wsu:Created> <wsu:Expires>2024-04-15T21:37:54Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>SendClassification updated</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="SendClassification"> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> <SendClassificationType>Marketing</SendClassificationType> <Name>testExisting_sendClassification</Name> <Description>updated on deploy</Description> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <DeliveryProfile> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>Default</CustomerKey> </DeliveryProfile> </Object> </Results> <RequestID>0ff3e991-df4f-4206-b8e1-bdccf95d3931</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/senderProfile/build-expected.json ================================================ { "FallbackFromAddress": "joern.berkefeld+test@accenture.com", "AutoForwardToEmailAddress": "", "AutoForwardToName": "", "AutoReply": false, "CustomerKey": "testTemplated_senderProfile", "Description": "Send from joern.berkefeld@accenture.com", "DirectForward": false, "FromAddress": "joern.berkefeld@accenture.com", "FromName": "Jörn Berkefeld", "Name": "testTemplated_senderProfile", "SenderHeaderEmailAddress": "", "SenderHeaderName": "", "UseDefaultRMMRules": true } ================================================ FILE: test/resources/9999999/senderProfile/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:da5fb2ee-2ca9-4f56-a9e8-2b98d43379f7</wsa:MessageID> <wsa:RelatesTo>urn:uuid:3cbd2577-f0e6-4593-8657-e1f48d94624c</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-8768684a-59c7-44f4-977e-3a4e44db441d"> <wsu:Created>2024-04-12T12:53:28Z</wsu:Created> <wsu:Expires>2024-04-12T12:58:28Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>SenderProfile created</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>70accba4-cbf8-ee11-a5c8-5cba2c6fc270</NewObjectID> <Object xsi:type="SenderProfile"> <PartnerKey xsi:nil="true" /> <ObjectID>70accba4-cbf8-ee11-a5c8-5cba2c6fc270</ObjectID> <CustomerKey>testNew_senderProfile</CustomerKey> <Name>testNew_senderProfile</Name> <Description>created on deploy</Description> <FromName>Jörn Berkefeld</FromName> <FromAddress>joern.berkefeld@accenture.com</FromAddress> <UseDefaultRMMRules>false</UseDefaultRMMRules> <AutoForwardToEmailAddress>joern.berkefeld@accenture.com</AutoForwardToEmailAddress> <AutoForwardToName>Jörn Berkefeld</AutoForwardToName> <DirectForward>false</DirectForward> <AutoReply>false</AutoReply> <SenderHeaderEmailAddress /> <SenderHeaderName /> <FallbackFromAddress>joern.berkefeld.New@accenture.com</FallbackFromAddress> </Object> </Results> <RequestID>b6be1480-01a4-4e48-9f47-06bf51a301c1</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/senderProfile/delete-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>DeleteResponse</wsa:Action> <wsa:MessageID>urn:uuid:9d089538-9132-421c-b905-827dc760447b</wsa:MessageID> <wsa:RelatesTo>urn:uuid:2dbd051c-b714-4302-bb66-53d0916620ed</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-c7ba7ffe-ac41-4cb7-a0a1-471df321d8a6"> <wsu:Created>2024-04-12T13:05:55Z</wsu:Created> <wsu:Expires>2024-04-12T13:10:55Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <DeleteResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>SenderProfile deleted</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="SenderProfile"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_senderProfile</CustomerKey> </Object> </Results> <RequestID>0387ba17-c330-4239-a2dd-c0e15f968476</RequestID> <OverallStatus>OK</OverallStatus> </DeleteResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/senderProfile/get-expected.json ================================================ { "FallbackFromAddress": "joern.berkefeld+test@accenture.com", "CreatedDate": "2021-08-03T11:14:00", "ModifiedDate": "2021-08-03T11:14:00", "CustomerKey": "testExisting_senderProfile", "Name": "testExisting_senderProfile", "Description": "Send from joern.berkefeld@accenture.com", "FromName": "Jörn Berkefeld", "FromAddress": "joern.berkefeld@accenture.com", "UseDefaultRMMRules": true, "AutoForwardToEmailAddress": "", "AutoForwardToName": "", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "", "createdBy": "Jörn Berkefeld", "modifiedBy": "Jörn Berkefeld" } ================================================ FILE: test/resources/9999999/senderProfile/get-rcb-id-expected.json ================================================ { "FallbackFromAddress": "", "createdBy": "Jörn Berkefeld", "modifiedBy": "Jörn Berkefeld", "CreatedDate": "2021-08-03T11:14:00", "ModifiedDate": "2021-08-03T11:14:00", "CustomerKey": "testExisting_senderProfile_rcb", "Name": "testExisting_senderProfile_rcb", "Description": "Send from joern.berkefeld@accenture.com", "FromName": "%%= ContentBlockById(1295064) =%%", "FromAddress": "%%= ContentBlockById(1295064) =%%", "UseDefaultRMMRules": true, "AutoForwardToEmailAddress": "%%= ContentBlockById(1295064) =%%", "AutoForwardToName": "%%= ContentBlockById(1295064) =%%", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "" } ================================================ FILE: test/resources/9999999/senderProfile/get-rcb-key-expected.json ================================================ { "FallbackFromAddress": "", "createdBy": "Jörn Berkefeld", "modifiedBy": "Jörn Berkefeld", "CreatedDate": "2021-08-03T11:14:00", "ModifiedDate": "2021-08-03T11:14:00", "CustomerKey": "testExisting_senderProfile_rcb", "Name": "testExisting_senderProfile_rcb", "Description": "Send from joern.berkefeld@accenture.com", "FromName": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "FromAddress": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "UseDefaultRMMRules": true, "AutoForwardToEmailAddress": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "AutoForwardToName": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "" } ================================================ FILE: test/resources/9999999/senderProfile/get-rcb-name-expected.json ================================================ { "FallbackFromAddress": "", "createdBy": "Jörn Berkefeld", "modifiedBy": "Jörn Berkefeld", "CreatedDate": "2021-08-03T11:14:00", "ModifiedDate": "2021-08-03T11:14:00", "CustomerKey": "testExisting_senderProfile_rcb", "Name": "testExisting_senderProfile_rcb", "Description": "Send from joern.berkefeld@accenture.com", "FromName": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "FromAddress": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "UseDefaultRMMRules": true, "AutoForwardToEmailAddress": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "AutoForwardToName": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "" } ================================================ FILE: test/resources/9999999/senderProfile/patch-expected.json ================================================ { "FallbackFromAddress": "joern.berkefeld+test@accenture.com", "CreatedDate": "2021-08-03T11:14:00", "ModifiedDate": "2021-08-03T11:14:00", "CustomerKey": "testExisting_senderProfile", "Name": "testExisting_senderProfile", "Description": "Send from joern.berkefeld@accenture.com", "FromName": "Jörn Berkefeld", "FromAddress": "joern.berkefeld@accenture.com", "UseDefaultRMMRules": true, "AutoForwardToEmailAddress": "", "AutoForwardToName": "", "DirectForward": false, "AutoReply": false, "SenderHeaderEmailAddress": "", "SenderHeaderName": "", "createdBy": "Jörn Berkefeld", "modifiedBy": "Jörn Berkefeld" } ================================================ FILE: test/resources/9999999/senderProfile/post-expected.json ================================================ { "FallbackFromAddress": "joern.berkefeld.New@accenture.com", "AutoForwardToEmailAddress": "joern.berkefeld@accenture.com", "AutoForwardToName": "Jörn Berkefeld", "AutoReply": false, "CustomerKey": "testNew_senderProfile", "Description": "created on deploy", "DirectForward": false, "FromAddress": "joern.berkefeld@accenture.com", "FromName": "Jörn Berkefeld", "Name": "testNew_senderProfile", "SenderHeaderEmailAddress": "", "SenderHeaderName": "", "UseDefaultRMMRules": false } ================================================ FILE: test/resources/9999999/senderProfile/retrieve-CustomerKey=Default-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:cbecb68a-7bdf-417e-8fce-bef6c72febbd</wsa:MessageID> <wsa:RelatesTo>urn:uuid:2e88f8d2-82e7-4e2d-b780-b885a2205a0f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-ed420673-a71e-47b4-a2f4-4d4399b7e6a9"> <wsu:Created>2024-04-12T12:20:37Z</wsu:Created> <wsu:Expires>2024-04-12T12:25:37Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>4c6f37a1-7ab4-47a1-b341-f9912462ee97</RequestID> <Results xsi:type="SenderProfile"> <Client> <CreatedBy>700301950</CreatedBy> <ModifiedBy>700301950</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:53:00</CreatedDate> <ModifiedDate>2016-07-22T11:53:00</ModifiedDate> <ObjectID>7acfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Default</CustomerKey> <Name>Default</Name> <Description>Account defaults</Description> <FromName>Accenture</FromName> <FromAddress>joern.berkefeld@accenture.com</FromAddress> <UseDefaultRMMRules>true</UseDefaultRMMRules> <AutoForwardToEmailAddress /> <AutoForwardToName /> <DirectForward>false</DirectForward> <AutoReply>false</AutoReply> <SenderHeaderEmailAddress /> <SenderHeaderName /> <FallbackFromAddress /> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/senderProfile/retrieve-CustomerKey=wrong-key-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:d88db970-f769-4bf0-b883-e019d4324499</wsa:MessageID> <wsa:RelatesTo>urn:uuid:044b42db-b7c3-4286-be0c-b3420efb6c3a</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-346c69ce-29e8-4171-bb12-69bdd2a5c775"> <wsu:Created>2024-04-23T16:10:56Z</wsu:Created> <wsu:Expires>2024-04-23T16:15:56Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>4e5087e1-0ee3-4e6a-bd6f-76824abe451f</RequestID> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/senderProfile/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:cbecb68a-7bdf-417e-8fce-bef6c72febbd</wsa:MessageID> <wsa:RelatesTo>urn:uuid:2e88f8d2-82e7-4e2d-b780-b885a2205a0f</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-ed420673-a71e-47b4-a2f4-4d4399b7e6a9"> <wsu:Created>2024-04-12T12:20:37Z</wsu:Created> <wsu:Expires>2024-04-12T12:25:37Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>4c6f37a1-7ab4-47a1-b341-f9912462ee97</RequestID> <Results xsi:type="SenderProfile"> <Client> <CreatedBy>700301950</CreatedBy> <ModifiedBy>700301950</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2016-07-22T11:53:00</CreatedDate> <ModifiedDate>2016-07-22T11:53:00</ModifiedDate> <ObjectID>7acfb80f-3550-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>Default</CustomerKey> <Name>Default</Name> <Description>Account defaults</Description> <FromName>Accenture</FromName> <FromAddress>joern.berkefeld@accenture.com</FromAddress> <UseDefaultRMMRules>true</UseDefaultRMMRules> <AutoForwardToEmailAddress /> <AutoForwardToName /> <DirectForward>false</DirectForward> <AutoReply>false</AutoReply> <SenderHeaderEmailAddress /> <SenderHeaderName /> <FallbackFromAddress /> </Results> <Results xsi:type="SenderProfile"> <Client> <CreatedBy>700301950</CreatedBy> <ModifiedBy>700301950</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-03T11:14:00</CreatedDate> <ModifiedDate>2021-08-03T11:14:00</ModifiedDate> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> <Name>testExisting_senderProfile</Name> <Description>Send from joern.berkefeld@accenture.com</Description> <FromName>Jörn Berkefeld</FromName> <FromAddress>joern.berkefeld@accenture.com</FromAddress> <UseDefaultRMMRules>true</UseDefaultRMMRules> <AutoForwardToEmailAddress /> <AutoForwardToName /> <DirectForward>false</DirectForward> <AutoReply>false</AutoReply> <SenderHeaderEmailAddress /> <SenderHeaderName /> <FallbackFromAddress>joern.berkefeld+test@accenture.com</FallbackFromAddress> </Results> <Results xsi:type="SenderProfile"> <Client> <CreatedBy>700301950</CreatedBy> <ModifiedBy>700301950</ModifiedBy> </Client> <PartnerKey xsi:nil="true" /> <CreatedDate>2021-08-03T11:14:00</CreatedDate> <ModifiedDate>2021-08-03T11:14:00</ModifiedDate> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da99</ObjectID> <CustomerKey>testExisting_senderProfile_rcb</CustomerKey> <Name>testExisting_senderProfile_rcb</Name> <Description>Send from joern.berkefeld@accenture.com</Description> <FromName>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%%</FromName> <FromAddress>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%%</FromAddress> <UseDefaultRMMRules>true</UseDefaultRMMRules> <AutoForwardToEmailAddress>%%= ContentBlockById(1295064) =%%</AutoForwardToEmailAddress> <AutoForwardToName>%%= ContentBlockById(1295064) =%%</AutoForwardToName> <DirectForward>false</DirectForward> <AutoReply>false</AutoReply> <SenderHeaderEmailAddress /> <SenderHeaderName /> <FallbackFromAddress /> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/senderProfile/template-expected.json ================================================ { "FallbackFromAddress": "joern.berkefeld+test@accenture.com", "AutoForwardToEmailAddress": "", "AutoForwardToName": "", "AutoReply": false, "CustomerKey": "{{{prefix}}}senderProfile", "Description": "Send from joern.berkefeld@accenture.com", "DirectForward": false, "FromAddress": "joern.berkefeld@accenture.com", "FromName": "Jörn Berkefeld", "Name": "{{{prefix}}}senderProfile", "SenderHeaderEmailAddress": "", "SenderHeaderName": "", "UseDefaultRMMRules": true } ================================================ FILE: test/resources/9999999/senderProfile/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:4ba5314f-13c0-4fcf-a193-f6160531acd6</wsa:MessageID> <wsa:RelatesTo>urn:uuid:4f56d229-63e7-4d8b-9bfe-1ace0c596056</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-224bd293-15f1-40fb-8a6f-f4ed6e2d6b16"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2024-04-12T12:58:29Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>SenderProfile updated</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="SenderProfile"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>testExisting_senderProfile</CustomerKey> <Name>testExisting_senderProfile</Name> <Description>updated via deploy</Description> <FromName>Jörn Berkefeld</FromName> <FromAddress>joern.berkefeld@accenture.com</FromAddress> <UseDefaultRMMRules>false</UseDefaultRMMRules> <AutoForwardToEmailAddress>joern.berkefeld@accenture.com</AutoForwardToEmailAddress> <AutoForwardToName>Jörn Berkefeld</AutoForwardToName> <DirectForward>false</DirectForward> <AutoReply>false</AutoReply> <SenderHeaderEmailAddress /> <SenderHeaderName /> <FallbackFromAddress /> </Object> </Results> <RequestID>ef6e2933-b767-47ea-a1c4-d3dc44674a56</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/transactionalEmail/build-expected.json ================================================ { "name": "testTemplated_temail", "definitionKey": "testTemplated_temail", "description": "foobar", "status": "Active", "subscriptions": { "r__dataExtension_key": "testTemplated_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__asset_key": "testTemplated_asset_message", "r__journey_key": "testTemplated_temail", "r__sendClassification_key": "Default Transactional" } ================================================ FILE: test/resources/9999999/transactionalEmail/create-publish-expected.json ================================================ { "createdDate": "2024-08-23T02:01:00", "definitionKey": "testNew_temail_notPublished", "description": "testNew_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "modifiedDate": "2024-08-23T02:01:00", "name": "testNew_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "options": { "trackLinks": true }, "r__asset_key": "testExisting_asset_message", "r__journey_key": "testNew_temail_notPublished", "r__sendClassification_key": "testExisting_sendClassification", "status": "Active", "subscriptions": { "autoAddSubscriber": true, "r__dataExtension_key": "testExisting_dataExtension", "r__list_PathName": "my subscribers/All Subscribers", "updateSubscriber": true } } ================================================ FILE: test/resources/9999999/transactionalEmail/get-expected.json ================================================ { "name": "testExisting_temail", "definitionKey": "testExisting_temail", "description": "bla bla", "status": "Active", "createdDate": "2020-09-10T03:29:00", "modifiedDate": "2020-09-10T03:29:00", "subscriptions": { "r__dataExtension_key": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__asset_key": "testExisting_asset_message", "r__journey_key": "testExisting_temail", "r__sendClassification_key": "Default Transactional" } ================================================ FILE: test/resources/9999999/transactionalEmail/get-published-expected.json ================================================ { "createdDate": "2024-08-23T02:01:00", "definitionKey": "testExisting_temail_notPublished", "description": "testExisting_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "modifiedDate": "2024-08-23T02:01:00", "name": "testExisting_temail_notPublis - 754cc4a10da14f538ecbd5470d771eaf", "options": { "trackLinks": true }, "r__asset_key": "testExisting_asset_message", "r__journey_key": "testExisting_temail_notPublished", "r__sendClassification_key": "Default Transactional", "status": "Active", "subscriptions": { "autoAddSubscriber": true, "r__dataExtension_key": "testExisting_temail_notPublished", "r__list_PathName": "my subscribers/All Subscribers", "updateSubscriber": true } } ================================================ FILE: test/resources/9999999/transactionalEmail/patch-expected.json ================================================ { "name": "testExisting_temail", "definitionKey": "testExisting_temail", "description": "updated via deploy", "status": "Active", "createdDate": "2020-09-10T03:29:00", "modifiedDate": "2020-09-10T03:29:00", "subscriptions": { "r__dataExtension_key": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__asset_key": "testExisting_asset_message", "r__journey_key": "testExisting_temail", "r__sendClassification_key": "Default Transactional" } ================================================ FILE: test/resources/9999999/transactionalEmail/post-expected.json ================================================ { "name": "testNew_temail", "definitionKey": "testNew_temail", "description": "created on deploy", "status": "Active", "createdDate": "2022-12-06T06:08:00", "modifiedDate": "2022-12-06T06:08:00", "subscriptions": { "r__dataExtension_key": "testExisting_dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__asset_key": "testExisting_asset_message", "r__journey_key": "testNew_RANDOM_interaction", "r__sendClassification_key": "Default Transactional" } ================================================ FILE: test/resources/9999999/transactionalEmail/template-expected.json ================================================ { "name": "{{{prefix}}}temail", "definitionKey": "{{{prefix}}}temail", "description": "{{{description}}}", "status": "Active", "subscriptions": { "r__dataExtension_key": "{{{prefix}}}dataExtension", "autoAddSubscriber": true, "updateSubscriber": true, "r__list_PathName": "my subscribers/All Subscribers" }, "options": { "trackLinks": true }, "r__asset_key": "{{{prefix}}}asset_message", "r__journey_key": "{{{prefix}}}temail", "r__sendClassification_key": "Default Transactional" } ================================================ FILE: test/resources/9999999/transactionalPush/build-expected.json ================================================ { "name": "testTemplated_tpush", "definitionKey": "testTemplated_tpush", "description": "foobar. note that applicationId can only be manually set up in Setup - Mobile Push", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "r__asset_key": "mobileMessage_testTarget", "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/transactionalPush/get-expected.json ================================================ { "name": "testExisting_tpush", "definitionKey": "testExisting_tpush", "description": "bla bla. note that applicationId can only be manually set up in Setup - Mobile Push", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "status": "Active", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T02:56:00", "r__asset_key": "mobileMessage_test", "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/transactionalPush/patch-expected.json ================================================ { "definitionKey": "testExisting_tpush", "name": "testExisting_tpush", "status": "Active", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "description": "updated via deploy; note that applicationId can only be manually set up in Setup - Mobile Push", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T03:26:00", "r__asset_key": "mobileMessage_test", "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/transactionalPush/post-expected.json ================================================ { "definitionKey": "testNew_tpush", "name": "testNew_tpush", "status": "Active", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "description": "created on deploy; note that applicationId can only be manually set up in Setup - Mobile Push", "createdDate": "2022-12-07T02:56:00", "modifiedDate": "2022-12-07T03:26:00", "r__asset_key": "mobileMessage_test", "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/transactionalPush/template-expected.json ================================================ { "name": "{{{prefix}}}tpush", "definitionKey": "{{{prefix}}}tpush", "description": "{{{description}}}. note that applicationId can only be manually set up in Setup - Mobile Push", "applicationId": "ffbab4c9-fbf6-4b87-9c9a-10c6ce86e81d", "r__asset_key": "mobileMessage{{{suffix}}}", "options": { "sound": "temp.wmv", "badge": "1" } } ================================================ FILE: test/resources/9999999/transactionalSMS/build-expected.amp ================================================ line1 %%[ SET @test = 'foobar' ]%% line2 %%= v(@test) =%% still line2 line3 %%[ SET @key = 'target secret' ]%% %%[ SET @unsubMessages = 'UnsubscribeSMSMessages_DEV' SET @unsubEvents = 'UnsubscribeSMS_DEV' SET @num = concat('+', [MOBILE_NUMBER]) SET @rs = RetrieveSalesforceObjects( 'Contact', 'Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=', @num ) SET @count = rowCount(@rs) VAR @response SET @rx = '^\+((?:9[679]\d8[035789]\d|6[789]\d|5[90]\d|42\d|3[578]\d|2[1-689]\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)' SET @prefix = concat('+', RegExMatch(@num, @rx, 1)) IF @count>0 THEN FOR @i = 1 TO @count DO SET @sk = Field(Row(@rs, @i), 'Id') IF Field(Row(@rs, 1), 'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN SET @result = UpdateSingleSalesforceObject('Contact', @sk, 'et4ae5__HasOptedOutOfMobile__c', 'true') IF @result == 0 THEN InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Error Updating' ) ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Successfully Unsubscribed' ) ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Already Unsubscribed' ) ENDIF NEXT @i SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'Found' ) IF Length(@msg) == 0 THEN SET @response = 'You have unsubscribed and will no longer receive any messages.|' ELSE SET @response = @msg ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'Status', 'Not Found' ) SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'NotFound' ) IF Length(@msg) == 0 THEN SET @response = 'Sorry, we could not find you' ELSE SET @response = @msg ENDIF ENDIF ]%% %%=v(@response)=%% ================================================ FILE: test/resources/9999999/transactionalSMS/build-expected.json ================================================ { "name": "testTemplated_tsms", "definitionKey": "testTemplated_tsms", "description": "foobar", "status": "Active", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.TESTTEMPLATED_KEYWORD" } } ================================================ FILE: test/resources/9999999/transactionalSMS/get-expected.amp ================================================ line1 %%[ SET @test = 'bla bla' ]%% line2 %%= v(@test) =%% still line2 line3 %%[ SET @key = 'secret' ]%% %%[ SET @unsubMessages = 'UnsubscribeSMSMessages_DEV' SET @unsubEvents = 'UnsubscribeSMS_DEV' SET @num = concat('+', [MOBILE_NUMBER]) SET @rs = RetrieveSalesforceObjects( 'Contact', 'Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=', @num ) SET @count = rowCount(@rs) VAR @response SET @rx = '^\+((?:9[679]\d8[035789]\d|6[789]\d|5[90]\d|42\d|3[578]\d|2[1-689]\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)' SET @prefix = concat('+', RegExMatch(@num, @rx, 1)) IF @count>0 THEN FOR @i = 1 TO @count DO SET @sk = Field(Row(@rs, @i), 'Id') IF Field(Row(@rs, 1), 'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN SET @result = UpdateSingleSalesforceObject('Contact', @sk, 'et4ae5__HasOptedOutOfMobile__c', 'true') IF @result == 0 THEN InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Error Updating' ) ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Successfully Unsubscribed' ) ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Already Unsubscribed' ) ENDIF NEXT @i SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'Found' ) IF Length(@msg) == 0 THEN SET @response = 'You have unsubscribed and will no longer receive any messages.|' ELSE SET @response = @msg ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'Status', 'Not Found' ) SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'NotFound' ) IF Length(@msg) == 0 THEN SET @response = 'Sorry, we could not find you' ELSE SET @response = @msg ENDIF ENDIF ]%% %%=v(@response)=%% ================================================ FILE: test/resources/9999999/transactionalSMS/get-expected.json ================================================ { "name": "testExisting_tsms", "definitionKey": "testExisting_tsms", "description": "bla bla", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.TESTEXISTING_KEYWORD" } } ================================================ FILE: test/resources/9999999/transactionalSMS/patch-expected.amp ================================================ %%[ SET @key = 'secret' ]%% %%[ SET @unsubMessages = 'UnsubscribeSMSMessages_DEV' SET @unsubEvents = 'UnsubscribeSMS_DEV' SET @num = concat('+', [MOBILE_NUMBER]) SET @rs = RetrieveSalesforceObjects( 'Contact', 'Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=', @num ) SET @count = rowCount(@rs) VAR @response SET @rx = '^\+((?:9[679]\d8[035789]\d|6[789]\d|5[90]\d|42\d|3[578]\d|2[1-689]\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)' SET @prefix = concat('+', RegExMatch(@num, @rx, 1)) IF @count>0 THEN FOR @i = 1 TO @count DO SET @sk = Field(Row(@rs, @i), 'Id') IF Field(Row(@rs, 1), 'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN SET @result = UpdateSingleSalesforceObject('Contact', @sk, 'et4ae5__HasOptedOutOfMobile__c', 'true') IF @result == 0 THEN InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Error Updating' ) ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Successfully Unsubscribed' ) ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Already Unsubscribed' ) ENDIF NEXT @i SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'Found' ) IF Length(@msg) == 0 THEN SET @response = 'You have unsubscribed and will no longer receive any messages.|' ELSE SET @response = @msg ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'Status', 'Not Found' ) SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'NotFound' ) IF Length(@msg) == 0 THEN SET @response = 'Sorry, we could not find you' ELSE SET @response = @msg ENDIF ENDIF ]%% %%=v(@response)=%% ================================================ FILE: test/resources/9999999/transactionalSMS/patch-expected.json ================================================ { "name": "testExisting_tsms", "definitionKey": "testExisting_tsms", "description": "bla bla", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.TESTEXISTING_KEYWORD" } } ================================================ FILE: test/resources/9999999/transactionalSMS/post-expected.amp ================================================ %%[ SET @key = 'new secret' ]%% %%[ SET @unsubMessages = 'UnsubscribeSMSMessages_DEV' SET @unsubEvents = 'UnsubscribeSMS_DEV' SET @num = concat('+', [MOBILE_NUMBER]) SET @rs = RetrieveSalesforceObjects( 'Contact', 'Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=', @num ) SET @count = rowCount(@rs) VAR @response SET @rx = '^\+((?:9[679]\d8[035789]\d|6[789]\d|5[90]\d|42\d|3[578]\d|2[1-689]\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)' SET @prefix = concat('+', RegExMatch(@num, @rx, 1)) IF @count>0 THEN FOR @i = 1 TO @count DO SET @sk = Field(Row(@rs, @i), 'Id') IF Field(Row(@rs, 1), 'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN SET @result = UpdateSingleSalesforceObject('Contact', @sk, 'et4ae5__HasOptedOutOfMobile__c', 'true') IF @result == 0 THEN InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Error Updating' ) ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Successfully Unsubscribed' ) ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Already Unsubscribed' ) ENDIF NEXT @i SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'Found' ) IF Length(@msg) == 0 THEN SET @response = 'You have unsubscribed and will no longer receive any messages.|' ELSE SET @response = @msg ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'Status', 'Not Found' ) SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'NotFound' ) IF Length(@msg) == 0 THEN SET @response = 'Sorry, we could not find you' ELSE SET @response = @msg ENDIF ENDIF ]%% %%=v(@response)=%% ================================================ FILE: test/resources/9999999/transactionalSMS/post-expected.json ================================================ { "name": "testNew_tsms", "definitionKey": "testNew_tsms", "description": "created on deploy", "status": "Active", "createdDate": "2022-11-07T02:24:00", "modifiedDate": "2022-11-07T02:25:00", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.TESTEXISTING_KEYWORD" } } ================================================ FILE: test/resources/9999999/transactionalSMS/template-expected.amp ================================================ line1 %%[ SET @test = '{{{description}}}' ]%% line2 %%= v(@test) =%% still line2 line3 %%[ SET @key = '{{{secret}}}' ]%% %%[ SET @unsubMessages = 'UnsubscribeSMSMessages_DEV' SET @unsubEvents = 'UnsubscribeSMS_DEV' SET @num = concat('+', [MOBILE_NUMBER]) SET @rs = RetrieveSalesforceObjects( 'Contact', 'Id,et4ae5__HasOptedOutOfMobile__c', 'MobilePhone', '=', @num ) SET @count = rowCount(@rs) VAR @response SET @rx = '^\+((?:9[679]\d8[035789]\d|6[789]\d|5[90]\d|42\d|3[578]\d|2[1-689]\d)|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)' SET @prefix = concat('+', RegExMatch(@num, @rx, 1)) IF @count>0 THEN FOR @i = 1 TO @count DO SET @sk = Field(Row(@rs, @i), 'Id') IF Field(Row(@rs, 1), 'et4ae5__HasOptedOutOfMobile__c') == 'false' THEN SET @result = UpdateSingleSalesforceObject('Contact', @sk, 'et4ae5__HasOptedOutOfMobile__c', 'true') IF @result == 0 THEN InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Error Updating' ) ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Successfully Unsubscribed' ) ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'ContactId', @sk, 'Status', 'Already Unsubscribed' ) ENDIF NEXT @i SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'Found' ) IF Length(@msg) == 0 THEN SET @response = 'You have unsubscribed and will no longer receive any messages.|' ELSE SET @response = @msg ENDIF ELSE InsertData( @unsubEvents, 'MobileNumber', @num, 'Message', [MSG(0).NOUNS], 'Status', 'Not Found' ) SET @msg = Lookup( @unsubMessages, 'Message', 'Prefix', @prefix, 'Type', 'NotFound' ) IF Length(@msg) == 0 THEN SET @response = 'Sorry, we could not find you' ELSE SET @response = @msg ENDIF ENDIF ]%% %%=v(@response)=%% ================================================ FILE: test/resources/9999999/transactionalSMS/template-expected.json ================================================ { "name": "{{{prefix}}}tsms", "definitionKey": "{{{prefix}}}tsms", "description": "{{{description}}}", "status": "Active", "subscriptions": { "countryCode": "", "autoAddSubscriber": true, "updateSubscriber": true, "r__mobileKeyword_key": "4912312345678.{{{prefixUpper}}}KEYWORD" } } ================================================ FILE: test/resources/9999999/triggeredSend/build-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testTemplated_triggeredSend", "Description": "Unsubscribe_Email", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testTemplated_triggeredSend", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__asset_key": "testTemplated_asset_message", "r__asset_name_readOnly": "testTemplated_asset_message", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testTemplated_sendClassification", "r__senderProfile_key": "testTemplated_senderProfile" } ================================================ FILE: test/resources/9999999/triggeredSend/get-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testExisting_triggeredSend", "Description": "Unsubscribe_Email", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testExisting_triggeredSend", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/resources/9999999/triggeredSend/get-rcb-id-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testExisting_triggeredSend_rcb", "Description": "Unsubscribe_Email", "DynamicEmailSubject": "%%= ContentBlockById(1295064) =%%", "EmailSubject": "%%= ContentBlockById(1295064) =%%", "FromAddress": "%%= ContentBlockById(1295064) =%%", "FromName": "%%= ContentBlockById(1295064) =%%", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testExisting_triggeredSend_rcb", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile_rcb" } ================================================ FILE: test/resources/9999999/triggeredSend/get-rcb-key-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testExisting_triggeredSend_rcb", "Description": "Unsubscribe_Email", "DynamicEmailSubject": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "EmailSubject": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "FromAddress": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "FromName": "%%= ContentBlockByKey(\"testExisting_asset_htmlblock\") =%%", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testExisting_triggeredSend_rcb", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile_rcb" } ================================================ FILE: test/resources/9999999/triggeredSend/get-rcb-name-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testExisting_triggeredSend_rcb", "Description": "Unsubscribe_Email", "DynamicEmailSubject": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "EmailSubject": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "FromAddress": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "FromName": "%%= ContentBlockByName(\"Content Builder\\dont strip non ssjs content\") =%%", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testExisting_triggeredSend_rcb", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__asset_key": "testExisting_asset_message", "r__asset_name_readOnly": "testExisting_asset_message", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile_rcb" } ================================================ FILE: test/resources/9999999/triggeredSend/patch-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testExisting_triggeredSend", "Description": "updated on deploy", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testExisting_triggeredSend", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__email_name": "Sporting Goods for September", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/resources/9999999/triggeredSend/post-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "testNew_triggeredSend", "Description": "created on deploy", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "testNew_triggeredSend", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__email_name": "Sporting Goods for September", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "testExisting_sendClassification", "r__senderProfile_key": "testExisting_senderProfile" } ================================================ FILE: test/resources/9999999/triggeredSend/template-expected.json ================================================ { "AllowedSlots": 0, "AutoAddSubscribers": false, "AutoUpdateSubscribers": false, "BatchInterval": 0, "CreatedDate": "2018-06-25T05:58:00", "CustomerKey": "{{{prefix}}}triggeredSend", "Description": "Unsubscribe_Email", "DynamicEmailSubject": "You are successfully unsubscribed", "EmailSubject": "You are successfully unsubscribed", "FromAddress": "unsubscribe@emails.mcdev.accenture.com", "FromName": "unsubscribe", "IsMultipart": false, "IsWrapped": true, "Keyword": "", "ModifiedDate": "2018-06-25T05:58:00", "Name": "{{{prefix}}}triggeredSend", "NewSlotTrigger": 0, "c__priority": "Medium", "SuppressTracking": false, "TriggeredSendStatus": "New", "TriggeredSendType": "Continuous", "r__asset_key": "{{{prefix}}}asset_message", "r__asset_name_readOnly": "{{{prefix}}}asset_message", "r__folder_Path": "Triggered Sends", "r__sendClassification_key": "{{{prefix}}}sendClassification", "r__senderProfile_key": "{{{prefix}}}senderProfile" } ================================================ FILE: test/resources/9999999/triggeredSendDefinition/create-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>CreateResponse</wsa:Action> <wsa:MessageID>urn:uuid:9d4bb477-f79f-4f3f-8304-5c0dcd0e5b66</wsa:MessageID> <wsa:RelatesTo>urn:uuid:dd06e2ef-2adc-4227-b872-1fc34e48a984</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f09d192c-466f-410c-9cd4-dabfba315ec4"> <wsu:Created>2023-08-08T13:42:51Z</wsu:Created> <wsu:Expires>2023-08-08T13:47:51Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <CreateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results xsi:type="TriggeredSendDefinition"> <StatusCode>OK</StatusCode> <StatusMessage>TriggeredSendDefinition created</StatusMessage> <OrdinalID>0</OrdinalID> <NewID>0</NewID> <NewObjectID>6cfadead-f635-ee11-b85a-48df37d1de8a</NewObjectID> <Object xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>6cfadead-f635-ee11-b85a-48df37d1de8a</ObjectID> <CustomerKey>testNew_triggeredSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testNew_triggeredSend</Name> <Description>created on deploy</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <FromName>unsubscribe</FromName> <FromAddress>unsubscribe@emails.mcdev.accenture.com</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>New</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>483943</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>You are successfully unsubscribed</EmailSubject> <DynamicEmailSubject>You are successfully unsubscribed</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Object> </Results> <RequestID>25fe1ec4-1204-42fd-9f0e-32166b82a5a5</RequestID> <OverallStatus>OK</OverallStatus> </CreateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendDefinition/delete-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>DeleteResponse</wsa:Action> <wsa:MessageID>urn:uuid:9b7ec2d4-b9cf-4443-aa99-7d790b0d8ed9</wsa:MessageID> <wsa:RelatesTo>urn:uuid:b9274179-8dba-4434-9f06-7e3f5dcc5d36</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-0f3617a8-995a-43fc-a31c-984f314be995"> <wsu:Created>2023-08-08T13:33:37Z</wsu:Created> <wsu:Expires>2023-08-08T13:38:37Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <DeleteResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results> <StatusCode>OK</StatusCode> <StatusMessage>TriggeredSendDefinition deleted</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <ObjectID xsi:nil="true" /> <CustomerKey>TestKey-419705</CustomerKey> </Object> </Results> <RequestID>e63109fe-085f-4d9d-950b-05d827c74b0e</RequestID> <OverallStatus>OK</OverallStatus> </DeleteResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendDefinition/retrieve-CustomerKey=testExisting_triggeredSend-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:8fe86c01-56d5-4c56-8ac2-991578c79485</wsa:MessageID> <wsa:RelatesTo>urn:uuid:592f71ac-78a0-45a2-8cfe-37a91fc6cfd5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-675af14a-b6a1-44a5-b7e7-4a76c6d18424"> <wsu:Created>2023-02-01T10:29:21Z</wsu:Created> <wsu:Expires>2023-02-01T10:34:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>a90dda5e-aeba-440a-82ce-74fb2abf5eb2</RequestID> <Results xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9d</ObjectID> <CustomerKey>testExisting_triggeredSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend</Name> <Description>Unsubscribe_Email</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <FromName>unsubscribe</FromName> <FromAddress>unsubscribe@emails.mcdev.accenture.com</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>Active</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>You are successfully unsubscribed</EmailSubject> <DynamicEmailSubject>You are successfully unsubscribed</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendDefinition/retrieve-CustomerKey=testExisting_triggeredSend_rcb-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:8fe86c01-56d5-4c56-8ac2-991578c79485</wsa:MessageID> <wsa:RelatesTo>urn:uuid:592f71ac-78a0-45a2-8cfe-37a91fc6cfd5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-675af14a-b6a1-44a5-b7e7-4a76c6d18424"> <wsu:Created>2023-02-01T10:29:21Z</wsu:Created> <wsu:Expires>2023-02-01T10:34:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>a90dda5e-aeba-440a-82ce-74fb2abf5eb2</RequestID> <Results xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9a</ObjectID> <CustomerKey>testExisting_triggeredSend_rcb</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend_rcb</Name> <Description>Unsubscribe_Email</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da99</ObjectID> <CustomerKey>testExisting_senderProfile_rcb</CustomerKey> </SenderProfile> <FromName>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%%</FromName> <FromAddress>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%%</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>Active</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>%%= ContentBlockById(1295064) =%%</EmailSubject> <DynamicEmailSubject>%%= ContentBlockById(1295064) =%%</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:8fe86c01-56d5-4c56-8ac2-991578c79485</wsa:MessageID> <wsa:RelatesTo>urn:uuid:592f71ac-78a0-45a2-8cfe-37a91fc6cfd5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-675af14a-b6a1-44a5-b7e7-4a76c6d18424"> <wsu:Created>2023-02-01T10:29:21Z</wsu:Created> <wsu:Expires>2023-02-01T10:34:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>a90dda5e-aeba-440a-82ce-74fb2abf5eb2</RequestID> <Results xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9d</ObjectID> <CustomerKey>testExisting_triggeredSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend</Name> <Description>Unsubscribe_Email</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <FromName>unsubscribe</FromName> <FromAddress>unsubscribe@emails.mcdev.accenture.com</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>New</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>You are successfully unsubscribed</EmailSubject> <DynamicEmailSubject>You are successfully unsubscribed</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Results> <Results xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9a</ObjectID> <CustomerKey>testExisting_triggeredSend_rcb</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend_rcb</Name> <Description>Unsubscribe_Email</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da99</ObjectID> <CustomerKey>testExisting_senderProfile_rcb</CustomerKey> </SenderProfile> <FromName>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%%</FromName> <FromAddress>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%%</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>New</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>%%= ContentBlockById(1295064) =%%</EmailSubject> <DynamicEmailSubject>%%= ContentBlockById(1295064) =%%</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINdummy,Active-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:8fe86c01-56d5-4c56-8ac2-991578c79485</wsa:MessageID> <wsa:RelatesTo>urn:uuid:592f71ac-78a0-45a2-8cfe-37a91fc6cfd5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-675af14a-b6a1-44a5-b7e7-4a76c6d18424"> <wsu:Created>2023-02-01T10:29:21Z</wsu:Created> <wsu:Expires>2023-02-01T10:34:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>a90dda5e-aeba-440a-82ce-74fb2abf5eb2</RequestID> <Results xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9d</ObjectID> <CustomerKey>testExisting_triggeredSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend</Name> <Description>Unsubscribe_Email</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <FromName>unsubscribe</FromName> <FromAddress>unsubscribe@emails.mcdev.accenture.com</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>Active</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>You are successfully unsubscribed</EmailSubject> <DynamicEmailSubject>You are successfully unsubscribed</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Results> <Results xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9a</ObjectID> <CustomerKey>testExisting_triggeredSend_rcb</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend_rcb</Name> <Description>Unsubscribe_Email</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da99</ObjectID> <CustomerKey>testExisting_senderProfile_rcb</CustomerKey> </SenderProfile> <FromName>%%= ContentBlockByName("Content Builder\dont strip non ssjs content") =%%</FromName> <FromAddress>%%= ContentBlockByKey("testExisting_asset_htmlblock") =%%</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>Active</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>531213</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>%%= ContentBlockById(1295064) =%%</EmailSubject> <DynamicEmailSubject>%%= ContentBlockById(1295064) =%%</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendDefinition/update-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>UpdateResponse</wsa:Action> <wsa:MessageID>urn:uuid:9d4bb477-f79f-4f3f-8304-5c0dcd0e5b66</wsa:MessageID> <wsa:RelatesTo>urn:uuid:dd06e2ef-2adc-4227-b872-1fc34e48a984</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-f09d192c-466f-410c-9cd4-dabfba315ec4"> <wsu:Created>2023-08-08T13:42:51Z</wsu:Created> <wsu:Expires>2023-08-08T13:47:51Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <UpdateResponse xmlns="http://exacttarget.com/wsdl/partnerAPI"> <Results xsi:type="TriggeredSendDefinition"> <StatusCode>OK</StatusCode> <StatusMessage>TriggeredSendDefinition updated</StatusMessage> <OrdinalID>0</OrdinalID> <Object xsi:type="TriggeredSendDefinition"> <PartnerKey xsi:nil="true" /> <PartnerProperties> <Name>TestEmailAddr</Name> <Value /> </PartnerProperties> <CreatedDate>2018-06-25T05:58:00</CreatedDate> <ModifiedDate>2018-06-25T05:58:00</ModifiedDate> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9d</ObjectID> <CustomerKey>testExisting_triggeredSend</CustomerKey> <IsPlatformObject>false</IsPlatformObject> <Name>testExisting_triggeredSend</Name> <Description>updated on deploy</Description> <Keyword /> <CategoryID>89348</CategoryID> <SendClassification> <PartnerKey xsi:nil="true" /> <ObjectID>95da425b-a06f-e611-96fe-38eaa7142c61</ObjectID> <CustomerKey>testExisting_sendClassification</CustomerKey> </SendClassification> <SenderProfile> <PartnerKey xsi:nil="true" /> <ObjectID>a75d452b-7ef4-eb11-b82d-48df37d1da95</ObjectID> <CustomerKey>testExisting_senderProfile</CustomerKey> </SenderProfile> <FromName>unsubscribe</FromName> <FromAddress>unsubscribe@emails.mcdev.accenture.com</FromAddress> <SuppressTracking>false</SuppressTracking> <TriggeredSendType>Continuous</TriggeredSendType> <TriggeredSendStatus>New</TriggeredSendStatus> <Email> <PartnerKey xsi:nil="true" /> <ID>483943</ID> <ObjectID xsi:nil="true" /> </Email> <AutoAddSubscribers>false</AutoAddSubscribers> <AutoUpdateSubscribers>false</AutoUpdateSubscribers> <BatchInterval>0</BatchInterval> <EmailSubject>You are successfully unsubscribed</EmailSubject> <DynamicEmailSubject>You are successfully unsubscribed</DynamicEmailSubject> <IsMultipart>false</IsMultipart> <IsWrapped>true</IsWrapped> <AllowedSlots>0</AllowedSlots> <NewSlotTrigger>0</NewSlotTrigger> <Priority>4</Priority> </Object> </Results> <RequestID>25fe1ec4-1204-42fd-9f0e-32166b82a5a5</RequestID> <OverallStatus>OK</OverallStatus> </UpdateResponse> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/triggeredSendSummary/get-expected.json ================================================ { "CustomerKey": "testExisting_triggeredSend", "Sent": 10, "NotSentDueToOptOut": 0, "NotSentDueToUndeliverable": 0, "Bounces": 0, "Opens": 0, "Clicks": 0, "UniqueOpens": 0, "UniqueClicks": 0, "OptOuts": 0, "SurveyResponses": 0, "FTAFRequests": 0, "FTAFEmailsSent": 0, "FTAFOptIns": 0, "Conversions": 0, "UniqueConversions": 0, "InProcess": 0, "NotSentDueToError": 0, "Queued": 0, "r__folder_Path": "Triggered Sends", "r__triggeredSend_name": "testExisting_triggeredSend", "r__triggeredSend_key": "testExisting_triggeredSend" } ================================================ FILE: test/resources/9999999/triggeredSendSummary/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:8fe86c01-56d5-4c56-8ac2-991578c79485</wsa:MessageID> <wsa:RelatesTo>urn:uuid:592f71ac-78a0-45a2-8cfe-37a91fc6cfd5</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-675af14a-b6a1-44a5-b7e7-4a76c6d18424"> <wsu:Created>2023-02-01T10:29:21Z</wsu:Created> <wsu:Expires>2023-02-01T10:34:21Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>a90dda5e-aeba-440a-82ce-74fb2abf5eb2</RequestID> <Results xsi:type="TriggeredSendSummary"> <PartnerKey xsi:nil="true" /> <ObjectID>b3150cf0-6e78-e811-80d4-1402ec721c9d</ObjectID> <CustomerKey>testExisting_triggeredSend</CustomerKey> <Sent>10</Sent> <NotSentDueToOptOut>0</NotSentDueToOptOut> <NotSentDueToUndeliverable>0</NotSentDueToUndeliverable> <Bounces>0</Bounces> <Opens>0</Opens> <Clicks>0</Clicks> <UniqueOpens>0</UniqueOpens> <UniqueClicks>0</UniqueClicks> <OptOuts>0</OptOuts> <SurveyResponses>0</SurveyResponses> <FTAFRequests>0</FTAFRequests> <FTAFEmailsSent>0</FTAFEmailsSent> <FTAFOptIns>0</FTAFOptIns> <Conversions>0</Conversions> <UniqueConversions>0</UniqueConversions> <InProcess>0</InProcess> <NotSentDueToError>0</NotSentDueToError> <Queued>0</Queued> </Results> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/resources/9999999/verification/build-expected.json ================================================ { "c__automation_step": "testTemplated_automation__s1.7", "notificationEmailAddress": "", "notificationEmailMessage": "", "r__dataExtension_key": "testTemplated_dataExtension", "shouldEmailOnFailure": false, "shouldStopOnFailure": true, "value1": 1, "value2": 0, "verificationType": "IsEqualTo" } ================================================ FILE: test/resources/9999999/verification/get-expected.json ================================================ { "c__automation_step": "testExisting_automation__s1.7", "createdBy": "Jörn Berkefeld", "notificationEmailAddress": "", "notificationEmailMessage": "", "r__dataExtension_key": "testExisting_dataExtension", "shouldEmailOnFailure": false, "shouldStopOnFailure": true, "value1": 1, "value2": 0, "verificationType": "IsEqualTo" } ================================================ FILE: test/resources/9999999/verification/patch-expected.json ================================================ { "createdBy": "Jörn Berkefeld", "c__automation_step": "testExisting_automation__s1.7", "notificationEmailAddress": "test@accenture.com", "notificationEmailMessage": "", "r__dataExtension_key": "testExisting_dataExtension", "shouldEmailOnFailure": true, "shouldStopOnFailure": true, "value1": 1, "value2": 0, "verificationType": "IsEqualTo" } ================================================ FILE: test/resources/9999999/verification/post-expected.json ================================================ { "createdBy": "Jörn Berkefeld", "c__automation_step": "testNew_automation__s1.7", "r__dataExtension_key": "testExisting_dataExtension", "verificationType": "IsEqualTo", "value1": 2, "value2": 0, "shouldStopOnFailure": false, "shouldEmailOnFailure": false, "notificationEmailAddress": "", "notificationEmailMessage": "" } ================================================ FILE: test/resources/9999999/verification/template-expected.json ================================================ { "c__automation_step": "{{{prefix}}}automation__s1.7", "notificationEmailAddress": "", "notificationEmailMessage": "", "r__dataExtension_key": "{{{prefix}}}dataExtension", "shouldEmailOnFailure": false, "shouldStopOnFailure": true, "value1": 1, "value2": 0, "verificationType": "IsEqualTo" } ================================================ FILE: test/resources/auth.json ================================================ { "success": { "url": "https://mct0l7nxfq2r988t1kxfy8sc4xxx.auth.marketingcloudapis.com/v2/token", "response": { "access_token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjQiLCJ2ZXIiOiIxIiwidHlwIjoiSldUIn0.eyJhY2Nlc3NfdG9rZW4iOiI3UU9IYmJTd3JFOXRTYkdlTTQ4ZktXTXgiLCJjbGllbnRfaWQiOiIwbTBoZXQ2bXFrbnp2MHVlYnFsdm9vNDEiLCJlaWQiOjcyODE2OTgsInN0YWNrX2tleSI6IlM3IiwicGxhdGZvcm1fdmVyc2lvbiI6MiwiY2xpZW50X3R5cGUiOiJTZXJ2ZXJUb1NlcnZlciJ9.5TciRkgyCXpV232vUowRvGCR03-zT5d1NRBcZrIn1Z8.8_hnocm2nm2WkEu4KHNpyFrG60_TQ52XAVYmYSU8yyd452YL3Mzb6k_ieT9B2CWRI3dSvDARFK9bz59yjz1HWsUjP0ENXeyO6wEA8MpeVSkxlD6u6Q73ZtK2sAwsaFoSmx96HpjjhMWKxNEuESTl_Hp2Qfv_mXC2LNluVq3fYYKn7VSr4zaRTRB", "token_type": "Bearer", "expires_in": 1079, "scope": "offline documents_and_images_read documents_and_images_write saved_content_read saved_content_write automations_execute automations_read automations_write journeys_execute journeys_read journeys_write email_read email_send email_write push_read push_send push_write sms_read sms_send sms_write social_post social_publish social_read social_write web_publish web_read web_write audiences_read audiences_write list_and_subscribers_read list_and_subscribers_write data_extensions_read data_extensions_write file_locations_read file_locations_write tracking_events_read calendar_read calendar_write campaign_read campaign_write accounts_read accounts_write users_read users_write webhooks_read webhooks_write workflows_write approvals_write tags_write approvals_read tags_read workflows_read ott_chat_messaging_read ott_chat_messaging_send ott_channels_read ott_channels_write marketing_cloud_connect_read marketing_cloud_connect_write marketing_cloud_connect_send event_notification_callback_create event_notification_callback_read event_notification_callback_update event_notification_callback_delete event_notification_subscription_create event_notification_subscription_read event_notification_subscription_update event_notification_subscription_delete tracking_events_write key_manage_view key_manage_rotate key_manage_revoke dfu_configure journeys_aspr journeys_delete package_manager_package package_manager_deploy deep_linking_asset_read deep_linking_asset_write deep_linking_asset_delete deep_linking_settings_read deep_linking_settings_write", "soap_instance_url": "https://mct0l7nxfq2r988t1kxfy8sc4xxx.soap.marketingcloudapis.com/", "rest_instance_url": "https://mct0l7nxfq2r988t1kxfy8sc4xxx.rest.marketingcloudapis.com/" }, "status": 200 }, "unauthorized": { "url": "https://mct0l7nxfq2r988t1kxfy8sc47ma.auth.marketingcloudapis.com/v2/token", "response": { "error": "invalid_client", "error_description": "Client authentication failed. Make sure that the client ID and client secret are valid and that the package is installed and enabled.", "error_uri": "https://developer.salesforce.com/docs" }, "status": 401 }, "expired": { "url": "https://mct0l7nxfq2r988t1kxfy8sc47ma.auth.marketingcloudapis.com/v2/token", "response": { "documentation": "https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm", "errorcode": 0, "message": "Not Authorized" }, "status": 401 } } ================================================ FILE: test/resources/rest404-response.json ================================================ { "documentation": "https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm", "errorcode": 404, "message": "Not Found" } ================================================ FILE: test/resources/retrieve-response.xml ================================================ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>RetrieveResponse</wsa:Action> <wsa:MessageID>urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91</wsa:MessageID> <wsa:RelatesTo>urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988</wsa:RelatesTo> <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsse:Security> <wsu:Timestamp wsu:Id="Timestamp-32ecc81b-6020-473c-9e99-4b5338921220"> <wsu:Created>2022-04-19T20:03:41Z</wsu:Created> <wsu:Expires>2022-04-19T20:08:41Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body> <RetrieveResponseMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"> <OverallStatus>OK</OverallStatus> <RequestID>02cd5ccb-8f84-4651-826f-71169eeecf05</RequestID> </RetrieveResponseMsg> </soap:Body> </soap:Envelope> ================================================ FILE: test/type.asset.test.js ================================================ import File from '../lib/util/file.js'; import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); /** * gets file from Retrieve folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} subtype of metadata * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string>} file in string form */ async function getActualJson(customerKey, type, subtype, buName = 'testBU') { try { return await File.readJSON( `./retrieve/testInstance/${buName}/${type}/${subtype}/${customerKey}.${type}-${subtype}-meta.json` ); } catch { return await File.readJSON( `./retrieve/testInstance/${buName}/${type}/${subtype}/${customerKey}/${customerKey}.${type}-${subtype}-meta.json` ); } } /** * gets file from Retrieve folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} subtype of metadata * @param {string} ext file extension * @param {string} [filename] optional fileprefix that differs from customerKey * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string | null>} file path */ async function getActualFile(customerKey, type, subtype, ext, filename, buName = 'testBU') { const path = `./retrieve/testInstance/${buName}/${type}/${subtype}/${customerKey}.${type}-${subtype}-meta.${ext}`; const pathSub = `./retrieve/testInstance/${buName}/${type}/${subtype}/${customerKey}/${filename}.${type}-${subtype}-meta.${ext}`; try { return await File.readFile(filename ? pathSub : path, 'utf8'); } catch { console.log(`File not found: ${filename ? pathSub : path}`); // eslint-disable-line no-console return null; } } /** * gets file from Template folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} subtype of metadata * @returns {Promise.<string>} file in string form */ async function getActualTemplateJson(customerKey, type, subtype) { try { return await File.readJSON( `./template/${type}/${subtype}/${customerKey}.${type}-${subtype}-meta.json` ); } catch { return await File.readJSON( `./template/${type}/${subtype}/${customerKey}/${customerKey}.${type}-${subtype}-meta.json` ); } } /** * gets file from Template folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} subtype of metadata * @param {string} ext file extension * @param {string} [filename] optional fileprefix that differs from customerKey * @returns {Promise.<string | undefined>} file */ async function getActualTemplateFile(customerKey, type, subtype, ext, filename) { const path = `./template/${type}/${subtype}/${customerKey}.${type}-${subtype}-meta.${ext}`; const pathSub = `./template/${type}/${subtype}/${customerKey}/${filename}.${type}-${subtype}-meta.${ext}`; try { return File.readFile(filename ? pathSub : path, 'utf8'); } catch { console.log(`File not found: ${filename ? pathSub : path}`); // eslint-disable-line no-console return; } } /** * gets file from Deploy folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} subtype of metadata * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string>} file in string form */ async function getActualDeployJson(customerKey, type, subtype, buName = 'testBU') { try { return await File.readJSON( `./deploy/testInstance/${buName}/${type}/${subtype}/${customerKey}.${type}-${subtype}-meta.json` ); } catch { return await File.readJSON( `./deploy/testInstance/${buName}/${type}/${subtype}/${customerKey}/${customerKey}.${type}-${subtype}-meta.json` ); } } /** * gets file from Deploy folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} subtype of metadata * @param {string} ext file extension * @param {string} [filename] optional fileprefix that differs from customerKey * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string | undefined>} file content */ async function getActualDeployFile(customerKey, type, subtype, ext, filename, buName = 'testBU') { const path = `./deploy/testInstance/${buName}/${type}/${subtype}/${customerKey}.${type}-${subtype}-meta.${ext}`; const pathSub = `./deploy/testInstance/${buName}/${type}/${subtype}/${customerKey}/${filename}.${type}-${subtype}-meta.${ext}`; try { return File.readFile(filename ? pathSub : path, 'utf8'); } catch { console.log(`File not found: ${filename ? pathSub : path}`); // eslint-disable-line no-console return; } } describe('type: asset', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a asset & ensure non-ssjs code is not removed', async () => { // WHEN const retrieve = await handler.retrieve('testInstance/testBU', ['asset']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].asset ? Object.keys(retrieve['testInstance/testBU'].asset).length : 0, 12, 'Unexpected number of assets in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 15, 'Unexpected number of assets in cache' ); assert.deepEqual( await getActualJson('testExisting_asset_htmlblock', 'asset', 'block'), await testUtils.getExpectedJson( '9999999', 'asset', 'testExisting_asset_htmlblock-retrieve' ), 'returned metadata was not equal expected' ); expect( await getActualFile('testExisting_asset_htmlblock', 'asset', 'block', 'html') ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_htmlblock-retrieve', 'html' ) ); assert.deepEqual( await getActualJson('testExisting_asset_templatebasedemail', 'asset', 'message'), await testUtils.getExpectedJson('9999999', 'asset', 'retrieve-templatebasedemail'), 'returned metadata was not equal expected' ); expect( await getActualFile( 'testExisting_asset_templatebasedemail', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'retrieve-templatebasedemail-html', 'html' ) ); expect( await getActualFile( 'testExisting_asset_templatebasedemail', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'retrieve-templatebasedemail-preheader', 'amp' ) ); assert.deepEqual( await getActualJson('test_coderesource_js', 'asset', 'coderesource'), await testUtils.getExpectedJson( '9999999', 'asset', 'test_coderesource_js-retrieve' ), 'returned metadata was not equal expected' ); expect( await getActualFile('test_coderesource_js', 'asset', 'coderesource', 'js') ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'test_coderesource_js-retrieve', 'js' ) ); assert.deepEqual( await getActualJson('test_coderesource_json', 'asset', 'coderesource'), await testUtils.getExpectedJson( '9999999', 'asset', 'test_coderesource_json-retrieve' ), 'returned metadata was not equal expected' ); expect( await getActualFile('test_coderesource_json', 'asset', 'coderesource', 'jsonc') ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'test_coderesource_json-retrieve', 'jsonc' ) ); assert.deepEqual( await getActualJson('test_coderesource_xml', 'asset', 'coderesource'), await testUtils.getExpectedJson( '9999999', 'asset', 'test_coderesource_xml-retrieve' ), 'returned metadata was not equal expected' ); expect( await getActualFile('test_coderesource_xml', 'asset', 'coderesource', 'xml') ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'test_coderesource_xml-retrieve', 'xml' ) ); assert.equal( testUtils.getAPIHistoryLength(), 26, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve asset-cloudpage', async () => { // WHEN const retrieve = await handler.retrieve('testInstance/testBU', ['asset-cloudpage']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].asset ? Object.keys(retrieve['testInstance/testBU'].asset).length : 0, 3, 'Unexpected number of assets in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 13, 'Unexpected number of assets in cache' ); assert.deepEqual( await getActualJson('test_landingpage', 'asset', 'cloudpage'), await testUtils.getExpectedJson('9999999', 'asset', 'test_landingpage-retrieve'), 'returned metadata was not equal expected' ); assert.deepEqual( await getActualJson('test_microsite', 'asset', 'cloudpage'), await testUtils.getExpectedJson('9999999', 'asset', 'test_microsite-retrieve'), 'returned metadata was not equal expected' ); assert.deepEqual( await getActualJson('test_interactivecontent', 'asset', 'cloudpage'), await testUtils.getExpectedJson( '9999999', 'asset', 'test_interactivecontent-retrieve' ), 'returned metadata was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a asset by key', async () => { // WHEN const retrieve = await handler.retrieve( 'testInstance/testBU', ['asset'], ['testExisting_asset_htmlblock'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].asset ? Object.keys(retrieve['testInstance/testBU'].asset).length : 0, 1, 'Unexpected number of assets in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 10, 'Unexpected number of assets in cache' ); assert.deepEqual( await getActualJson('testExisting_asset_htmlblock', 'asset', 'block'), await testUtils.getExpectedJson( '9999999', 'asset', 'testExisting_asset_htmlblock-retrieve' ), 'returned metadata was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create an asset with mis-matching memberId, automatically adding the MID suffix', async () => { handler.setOptions({ autoMidSuffix: true }); // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['asset'], ['testNew_asset'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 1, 'Unexpected number of assets deployed' ); const upsertCallout = testUtils.getRestCallout('post', '/asset/v1/content/assets/'); assert.equal( upsertCallout?.customerKey, 'testNew_asset-9999999', 'customerKey should be testNew_asset-9999999 due to --autoMidSuffix' ); // insert assert.deepEqual( await getActualJson('testNew_asset-9999999', 'asset', 'block'), await testUtils.getExpectedJson('9999999', 'asset', 'create'), 'returned metadata was not equal expected for create' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update an asset with --matchName', async () => { handler.setOptions({ matchName: true }); // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['asset'], ['testExisting_asset_html-matchName'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 1, 'Unexpected number of assets deployed' ); const currentCache = cache.getCache(); const upsertCallout = testUtils.getRestCallout( 'patch', '/asset/v1/content/assets/1295064' ); assert.equal( upsertCallout?.customerKey, 'testExisting_asset_html-matchName', 'customerKey should be testExisting_asset_html-matchName' ); assert.equal( upsertCallout?.id, currentCache.asset['testExisting_asset_htmlblock'].id, 'id should be that of the existing testExisting_asset_htmlblock' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not update an asset with --matchName due to multiple potential matches', async () => { handler.setOptions({ matchName: true }); // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['asset'], ['testExisting_asset_html-matchNamFail'] ); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 0, 'Unexpected number of assets deployed' ); const upsertCallout = testUtils.getRestCallout('patch', '/asset/v1/content/assets/%'); assert.equal(upsertCallout, null, 'there should have been no patch'); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an asset with --matchName because it found no match', async () => { handler.setOptions({ matchName: true }); // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['asset'], ['testExisting_asset_html-matchNameAdd'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 1, 'Unexpected number of assets deployed' ); const upsertCallout = testUtils.getRestCallout('post', '/asset/v1/content/assets/'); assert.equal( upsertCallout?.customerKey, 'testExisting_asset_html-matchNameAdd', 'asset.customerKey should be testExisting_asset_html-matchNameAdd' ); assert.equal( upsertCallout?.id, undefined, 'asset.id should not be set as we are in a create call' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an asset with mis-matching memberId and --keySuffix', async () => { handler.setOptions({ keySuffix: '_DEV' }); // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['asset'], ['testNew_asset'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 1, 'Unexpected number of assets deployed' ); const upsertCallout = testUtils.getRestCallout('post', '/asset/v1/content/assets/'); assert.equal( upsertCallout?.customerKey, 'testNew_asset_DEV', 'customerKey should be testNew_asset_DEV due to --keySuffix' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an asset with mis-matching memberId', async () => { // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['asset'], ['testNew_asset'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 1, 'Unexpected number of assets deployed' ); const upsertCallout = testUtils.getRestCallout('post', '/asset/v1/content/assets/'); assert.equal( upsertCallout?.customerKey, 'testNew_asset', 'customerKey should be testNew_asset' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an asset that loads a pre-existing content block via CBBK', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', { asset: ['testNew_asset_withCBBK_preexisting'], }); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 1, 'Unexpected number of assets deployed' ); const upsertCallout = testUtils.getRestCallout('post', '/asset/v1/content/assets/'); assert.equal( upsertCallout?.customerKey, 'testNew_asset_withCBBK_preexisting', 'customerKey should be testNew_asset' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not create an asset that attempts to load a non-existent content block via CBBK', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', { asset: ['testNew_asset_withCBBK_notexisting'], }); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 0, 'Unexpected number of assets deployed' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an asset that loads a content block via CBBK that is also created in the same package', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', { asset: ['testNew_asset_withCBBK_notexisting', 'testNew_asset_htmlblock'], }); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.deepEqual( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset) : [], ['testNew_asset_htmlblock', 'testNew_asset_withCBBK_notexisting'], 'unexpected assets deployed' ); // check if we really issued callouts for those 2 blocks AND if they were run in the right order despite the key list for deploy() getting it in the wrong order const upsertCallouts = testUtils.getRestCallout( 'post', '/asset/v1/content/assets/', true ); assert.equal( upsertCallouts[0]?.customerKey, 'testNew_asset_htmlblock', 'first create callout not for expected asset' ); assert.equal( upsertCallouts[1]?.customerKey, 'testNew_asset_withCBBK_notexisting', 'second create callout not for expected asset' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not create an asset that attempts to load a non-existent content block via r__asset_key', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', { asset: ['testNew_assetMessage'], }); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset).length : 0, 0, 'Unexpected number of assets deployed' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an asset that loads a content block via r__asset_key that is also created in the same package', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', { asset: ['testNew_assetMessage', 'testNew_asset_htmlblock'], }); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.deepEqual( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset) : [], ['testNew_asset_htmlblock', 'testNew_assetMessage'], 'unexpected assets deployed' ); // check if we really issued callouts for those 2 blocks AND if they were run in the right order despite the key list for deploy() getting it in the wrong order const upsertCallouts = testUtils.getRestCallout( 'post', '/asset/v1/content/assets/', true ); assert.equal( upsertCallouts[0]?.customerKey, 'testNew_asset_htmlblock', 'first create callout not for expected asset' ); assert.equal( upsertCallouts[1]?.customerKey, 'testNew_assetMessage', 'second create callout not for expected asset' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a templatebased email and its template connected via r__asset_key', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', { asset: ['testNew_asset_templatebasedemail', 'testNew_asset_template'], }); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.deepEqual( deployResult['testInstance/testBU']?.asset ? Object.keys(deployResult['testInstance/testBU']?.asset) : [], ['testNew_asset_template', 'testNew_asset_templatebasedemail'], 'unexpected assets deployed' ); // check if we really issued callouts for those 2 blocks AND if they were run in the right order despite the key list for deploy() getting it in the wrong order const upsertCallouts = testUtils.getRestCallout( 'post', '/asset/v1/content/assets/', true ); assert.equal( upsertCallouts[0]?.customerKey, 'testNew_asset_template', 'first create callout not for expected asset' ); assert.equal( upsertCallouts[1]?.customerKey, 'testNew_asset_templatebasedemail', 'second create callout not for expected asset' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a asset template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['asset']); const expectedApiCallsRetrieve = 26; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/testBU', 'asset', ['testExisting_asset_templatebasedemail', 'testExisting_asset_htmlblock'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 2, 'unexpected number of assets templated' ); // testExisting_asset_templatebasedemail assert.deepEqual( await getActualTemplateJson( 'testExisting_asset_templatebasedemail', 'asset', 'message' ), await testUtils.getExpectedJson('9999999', 'asset', 'template-templatebasedemail'), 'returned template JSON of buildTemplate was not equal expected' ); expect( await getActualTemplateFile( 'testExisting_asset_templatebasedemail', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'template-templatebasedemail-html', 'html' ) ); expect( await getActualTemplateFile( 'testExisting_asset_templatebasedemail', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'template-templatebasedemail-preheader', 'amp' ) ); const definitions = await handler.buildDefinition( 'testInstance/testBU', 'asset', ['testExisting_asset_templatebasedemail', 'testExisting_asset_htmlblock'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.equal( definitions.asset ? Object.keys(definitions.asset).length : 0, 2, 'unexpected number of assets templated' ); // testTemplated_asset_templatebasedemail assert.deepEqual( await getActualDeployJson( 'testTemplated_asset_templatebasedemail', 'asset', 'message' ), await testUtils.getExpectedJson('9999999', 'asset', 'build-templatebasedemail'), 'returned deployment JSON was not equal expected' ); expect( await getActualDeployFile( 'testTemplated_asset_templatebasedemail', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'build-templatebasedemail-html', 'html' ) ); expect( await getActualDeployFile( 'testTemplated_asset_templatebasedemail', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'build-templatebasedemail-preheader', 'amp' ) ); // testTemplated_asset_htmlblock assert.deepEqual( await getActualDeployJson('testTemplated_asset_htmlblock', 'asset', 'block'), await testUtils.getExpectedJson('9999999', 'asset', 'build-asset_htmlblock'), 'returned deployment JSON was not equal expected' ); expect( await getActualDeployFile('testTemplated_asset_htmlblock', 'asset', 'block', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'asset', 'build-asset_htmlblock', 'html') ); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a asset template via buildTemplate with --dependencies', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['asset']); const expectedApiCallsRetrieve = 26; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); handler.setOptions({ dependencies: true, skipInteraction: true }); // GIVEN there is a template const templatedItems = await handler.buildTemplate( 'testInstance/testBU', 'asset', ['testExisting_asset_templatebasedemail'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( templatedItems.asset ? templatedItems.asset.length : 0, 6, 'Unexpted number of assets templated' ); assert.deepEqual( templatedItems.asset.map((item) => item.customerKey), [ '{{{prefix}}}asset_htmlblock', '{{{prefix}}}asset_template', '{{{prefix}}}asset_templatebasedemail', '{{{prefix}}}htmlblock 3 spaces', '{{{prefix}}}htmlblock1', '{{{prefix}}}htmlblock2', ], 'expected specific assets to be templated' ); // testExisting_asset_templatebasedemail assert.deepEqual( await getActualTemplateJson( 'testExisting_asset_templatebasedemail', 'asset', 'message' ), await testUtils.getExpectedJson('9999999', 'asset', 'template-templatebasedemail'), 'returned template JSON of buildTemplate was not equal expected' ); expect( await getActualTemplateFile( 'testExisting_asset_templatebasedemail', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'template-templatebasedemail-html', 'html' ) ); expect( await getActualTemplateFile( 'testExisting_asset_templatebasedemail', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'template-templatebasedemail-preheader', 'amp' ) ); // testExisting_asset_template assert.deepEqual( await getActualTemplateJson('testExisting_asset_template', 'asset', 'template'), await testUtils.getExpectedJson('9999999', 'asset', 'template-emailTemplate'), 'returned template JSON of buildTemplate was not equal expected' ); // testExisting_asset_htmlblock assert.deepEqual( await getActualTemplateJson('testExisting_asset_htmlblock', 'asset', 'block'), await testUtils.getExpectedJson( '9999999', 'asset', 'template-testExisting_asset_htmlblock' ), 'returned template JSON of buildTemplate was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'asset', 'testExisting_asset' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); describe('ResolveID ================', () => { it('Should resolve the id of the item but NOT find the asset locally', async () => { // WHEN const resolveIdJson = await handler.resolveId( 'testInstance/testBU', 'asset', '1295064' ); // THEN assert.equal(process.exitCode, 0, 'resolveId should not have thrown an error'); assert.deepEqual( resolveIdJson, await testUtils.getExpectedJson('9999999', 'asset', 'resolveId-1295064-noPath'), 'returned response was not equal expected' ); return; }); it('Should resolve the id with --json option enabled', async () => { handler.setOptions({ json: true }); // WHEN await handler.resolveId('testInstance/testBU', 'asset', '1295064'); // THEN assert.equal(process.exitCode, 0, 'resolveId should not have thrown an error'); return; }); it('Should resolve the id of the item AND find the asset locally', async () => { // prep test by retrieving the file await handler.retrieve( 'testInstance/testBU', ['asset-block'], ['testExisting_asset_htmlblock'] ); // WHEN const resolveIdJson = await handler.resolveId( 'testInstance/testBU', 'asset', '1295064' ); // THEN assert.equal(process.exitCode, 0, 'resolveId should not have thrown an error'); assert.deepEqual( resolveIdJson, await testUtils.getExpectedJson('9999999', 'asset', 'resolveId-1295064-withPath'), 'returned response was not equal expected' ); return; }); it('Should NOT resolve the id of the item', async () => { // WHEN const resolveIdJson = await handler.resolveId('testInstance/testBU', 'asset', '-1234'); // THEN assert.equal(process.exitCode, 404, 'resolveId should have thrown an error'); // IMPORTANT: this will throw a false "TEST-ERROR" but our testing framework currently needs to not find the file to throw a 404 assert.deepEqual( resolveIdJson, await testUtils.getExpectedJson('9999999', 'asset', 'resolveId-1234-notFound'), 'returned response was not equal expected' ); return; }); }); describe('ReplaceContentBlockByX ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { asset: null, }, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].asset, [ 'testExisting_asset_htmlblock', 'testExisting_htmlblock1', 'testExisting_htmlblock 3 spaces', 'testExisting_asset_message', ], 'should have found the right assets that need updating' ); // get results from cache const result = cache.getCache(); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 12, 'Unexpected number of assets in cache' ); // check if conversions happened expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-html-rcb-name', 'html' ) ); expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-preheader-rcb-name', 'amp' ) ); expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'amp', 'views.text.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-text-rcb-name', 'amp' ) ); assert.equal( testUtils.getAPIHistoryLength(), 28, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { asset: null, }, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].asset, [ 'testExisting_htmlblock1', 'testExisting_htmlblock 3 spaces', 'testExisting_asset_message', ], 'should have found the right assets that need updating' ); // get results from cache const result = cache.getCache(); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 12, 'Unexpected number of assets in cache' ); // check if conversions happened expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-html-rcb-id', 'html' ) ); expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-preheader-rcb-id', 'amp' ) ); expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'amp', 'views.text.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-text-rcb-id', 'amp' ) ); assert.equal( testUtils.getAPIHistoryLength(), 28, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { asset: null, }, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].asset, [ 'testExisting_asset_htmlblock', 'testExisting_htmlblock1', 'testExisting_asset_message', ], 'should have found the right assets that need updating' ); // get results from cache const result = cache.getCache(); assert.equal( result.asset ? Object.keys(result.asset).length : 0, 12, 'Unexpected number of assets in cache' ); // check if conversions happened expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'html', 'views.html.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-html-rcb-key', 'html' ) ); expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'amp', 'views.preheader.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-preheader-rcb-key', 'amp' ) ); expect( await getActualFile( 'testExisting_asset_message', 'asset', 'message', 'amp', 'views.text.content' ) ).to.equal( await testUtils.getExpectedFile( '9999999', 'asset', 'testExisting_asset_message-text-rcb-key', 'amp' ) ); assert.equal( testUtils.getAPIHistoryLength(), 28, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.attributeGroup.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: attributeGroup', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a attributeGroup', async () => { // WHEN const retrieve = await handler.retrieve('testInstance/testBU', ['attributeGroup']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].attributeGroup ? Object.keys(retrieve['testInstance/testBU'].attributeGroup).length : 0, 8, 'only 8 attributeGroups expected in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.attributeGroup ? Object.keys(result.attributeGroup).length : 0, 8, 'only 8 attributeGroups expected in cache' ); assert.deepEqual( await testUtils.getActualJson('ETMobileConnect', 'attributeGroup'), await testUtils.getExpectedJson('9999999', 'attributeGroup', 'retrieve'), 'returned metadata was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.attributeSet.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: attributeSet', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a attributeSet', async () => { // WHEN const retrieve = await handler.retrieve('testInstance/testBU', ['attributeSet']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].attributeSet ? Object.keys(retrieve['testInstance/testBU'].attributeSet).length : 0, 28, 'only 28 attributeSets expected in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.attributeSet ? Object.keys(result.attributeSet).length : 0, 28, 'only 28 attributeSets expected in cache' ); assert.deepEqual( await testUtils.getActualJson('testExisting_dataExtensionShared', 'attributeSet'), await testUtils.getExpectedJson('9999999', 'attributeSet', 'retrieve'), 'returned metadata was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 7, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should resolve shared dataExtensions in attributeSet when retrieved together with dataExtension', async () => { // WHEN // this test verifies the fix for: shared DEs not resolved if attributeSet+dataExtension is retrieved together const retrieve = await handler.retrieve('testInstance/testBU', [ 'dataExtension', 'attributeSet', ]); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].attributeSet ? Object.keys(retrieve['testInstance/testBU'].attributeSet).length : 0, 28, 'only 28 attributeSets expected in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.attributeSet ? Object.keys(result.attributeSet).length : 0, 28, 'only 28 attributeSets expected in cache' ); // verify that shared DE was resolved correctly in attributeSet (this is the key bug fix check) assert.deepEqual( await testUtils.getActualJson('testExisting_dataExtensionShared', 'attributeSet'), await testUtils.getExpectedJson('9999999', 'attributeSet', 'retrieve'), 'returned metadata was not equal expected - shared DE should be resolved even when dataExtension is retrieved together with attributeSet' ); assert.equal( testUtils.getAPIHistoryLength(), 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.automation.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: automation', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a automation', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['automation']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.automation ? Object.keys(result.automation).length : 0, 6, 'unexpected number of automations' ); assert.deepEqual( await testUtils.getActualJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'retrieve'), 'returned metadata was not equal expected' ); // check if MD file was created and equals expectations expect(await testUtils.getActualDoc('testExisting_automation', 'automation')).to.equal( await testUtils.getExpectedFile( '9999999', 'automation', 'retrieve-testExisting_automation', 'md' ) ); assert.deepEqual( await testUtils.getActualJson('testExisting_automation_wait', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'retrieve-wait'), 'returned metadata was not equal expected' ); expect( await testUtils.getActualDoc('testExisting_automation_wait', 'automation') ).to.equal( await testUtils.getExpectedFile('9999999', 'automation', 'retrieve-wait', 'md') ); assert.equal( testUtils.getAPIHistoryLength(), 34, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & update a automation', async () => { // WHEN const deployResult = await handler.deploy( 'testInstance/testBU', ['automation', 'verification'], ['testExisting_automation', 'testNew_automation', 'testNew_automation__s1.7'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check how many items were deployed assert.equal( deployResult['testInstance/testBU']?.automation ? Object.keys(deployResult['testInstance/testBU']?.automation).length : 0, 2, 'two automations to be deployed' ); // get results from cache const cacheResult = cache.getCache(); assert.equal( cacheResult.automation ? Object.keys(cacheResult.automation).length : 0, 7, 'unexpected number of automations in cache' ); // get what was sent to the server API const createCallout = testUtils.getRestCallout('post', '/automation/v1/automations/%'); const updateCallout = testUtils.getRestCallout('patch', '/automation/v1/automations/%'); // insert assert.deepEqual( createCallout, await testUtils.getExpectedJson('9999999', 'automation', 'create-callout'), 'sent metadata was not equal expected for create' ); assert.deepEqual( await testUtils.getActualJson('testNew_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'create'), 'returned metadata was not equal expected for create' ); // update assert.deepEqual( updateCallout, await testUtils.getExpectedJson('9999999', 'automation', 'update-callout'), 'sent metadata was not equal expected for create' ); assert.deepEqual( await testUtils.getActualJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'update'), 'returned metadata was not equal expected for update' ); // check if MD file was created and equals expectations expect(await testUtils.getActualDoc('testExisting_automation', 'automation')).to.equal( await testUtils.getExpectedFile( '9999999', 'automation', 'update-testExisting_automation', 'md' ) ); // check if MD file was created and equals expectations expect(await testUtils.getActualDoc('testNew_automation', 'automation')).to.equal( await testUtils.getExpectedFile( '9999999', 'automation', 'create-testNew_automation', 'md' ) ); assert.equal( testUtils.getAPIHistoryLength(), 52, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update & schedule an automation with --schedule option', async () => { // WHEN handler.setOptions({ schedule: true }); const deployed = await handler.deploy( 'testInstance/testBU', ['automation', 'verification'], ['testExisting_automation', 'testNew_automation', 'testNew_automation__s1.7'] ); // THEN assert.equal( process.exitCode, 0, 'deploy with --execute should not have thrown an error' ); // get results from cache const cached = cache.getCache(); assert.equal( cached.automation ? Object.keys(cached.automation).length : 0, 7, 'unexpected number of automations in cache' ); assert.equal( deployed['testInstance/testBU'].automation ? Object.keys(deployed['testInstance/testBU'].automation).length : 0, 2, 'two deployed automation expected' ); assert.equal( deployed['testInstance/testBU'].automation ? Object.keys(deployed['testInstance/testBU'].automation)[0] : null, 'testNew_automation', 'expected specific automation to have been deployed' ); assert.equal( deployed['testInstance/testBU'].automation ? Object.keys(deployed['testInstance/testBU'].automation)[1] : null, 'testExisting_automation', 'expected specific automation to have been deployed' ); assert.deepEqual( await testUtils.getActualJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'update'), 'returned metadata was not equal expected for update' ); // check if MD file was created and equals expectations expect(await testUtils.getActualDoc('testExisting_automation', 'automation')).to.equal( await testUtils.getExpectedFile( '9999999', 'automation', 'update-testExisting_automation', 'md' ) ); assert.equal( testUtils.getAPIHistoryLength(), 56, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update & runOnce an automation with --execute option', async () => { // WHEN handler.setOptions({ execute: true }); const deployed = await handler.deploy( 'testInstance/testBU', ['automation', 'verification'], ['testExisting_automation', 'testNew_automation', 'testNew_automation__s1.7'] ); // THEN assert.equal( process.exitCode, 0, 'deploy with --execute should not have thrown an error' ); // get results from cache const cached = cache.getCache(); assert.equal( cached.automation ? Object.keys(cached.automation).length : 0, 7, 'unexpected number of automations in cache' ); assert.equal( deployed['testInstance/testBU'].automation ? Object.keys(deployed['testInstance/testBU'].automation).length : 0, 2, 'two deployed automation expected' ); assert.equal( deployed['testInstance/testBU'].automation ? Object.keys(deployed['testInstance/testBU'].automation)[0] : null, 'testNew_automation', 'expected specific automation to have been deployed' ); assert.equal( deployed['testInstance/testBU'].automation ? Object.keys(deployed['testInstance/testBU'].automation)[1] : null, 'testExisting_automation', 'expected specific automation to have been deployed' ); // update assert.deepEqual( await testUtils.getActualJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'update'), 'returned metadata was not equal expected for update' ); // check if MD file was created and equals expectations expect(await testUtils.getActualDoc('testExisting_automation', 'automation')).to.equal( await testUtils.getExpectedFile( '9999999', 'automation', 'update-testExisting_automation', 'md' ) ); assert.equal( testUtils.getAPIHistoryLength(), 56, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('FixKeys ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should run fixKeys but not find fixable keys and hence stop', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false } }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // check which keys were fixed assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 0, 'expected to find no keys to be fixed' ); // get results from cache const result = cache.getCache(); assert.equal( result.automation ? Object.keys(result.automation).length : 0, 1, 'one automation expected' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 28, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key w/o re-retrieving, auto-schedule', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false } }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation_fixKey_schedule', 'testExisting_automation'] ); assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['automation'][0], 'testExisting_automation_fixedKey_scheduled', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_automation_fixedKey_scheduled', 'automation' ), await testUtils.getExpectedJson('9999999', 'automation', 'patch_fixKeys-schedule'), 'returned metadata was not equal expected for update automation' ); expect( await testUtils.getActualDoc( 'testExisting_automation_fixedKey_scheduled', 'automation' ) ).to.exist; // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 74, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key w/o re-retrieving, auto-schedule and then --execute', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false }, execute: true }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation_fixKey_schedule', 'testExisting_automation'] ); assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['automation'][0], 'testExisting_automation_fixedKey_scheduled', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_automation_fixedKey_scheduled', 'automation' ), await testUtils.getExpectedJson('9999999', 'automation', 'patch_fixKeys-schedule'), 'returned metadata was not equal expected for update automation' ); expect( await testUtils.getActualDoc( 'testExisting_automation_fixedKey_scheduled', 'automation' ) ).to.exist; // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 76, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key w/o re-retrieving, auto-schedule and then --schedule', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false }, schedule: true }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation_fixKey_schedule', 'testExisting_automation'] ); assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['automation'][0], 'testExisting_automation_fixedKey_scheduled', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_automation_fixedKey_scheduled', 'automation' ), await testUtils.getExpectedJson('9999999', 'automation', 'patch_fixKeys-schedule'), 'returned metadata was not equal expected for update automation' ); expect( await testUtils.getActualDoc( 'testExisting_automation_fixedKey_scheduled', 'automation' ) ).to.exist; // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 76, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key w/o re-retrieving, deploy paused', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false } }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation_fixKey_pause'] ); assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['automation'][0], 'testExisting_automation_fixedKey_paused', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_automation_fixedKey_paused', 'automation' ), await testUtils.getExpectedJson('9999999', 'automation', 'patch_fixKeys-pause'), 'returned metadata was not equal expected for update automation' ); expect( await testUtils.getActualDoc( 'testExisting_automation_fixedKey_paused', 'automation' ) ).to.exist; // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 69, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key w/o re-retrieving, deploy paused and then --execute', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false }, execute: true }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation_fixKey_pause', 'testExisting_automation'] ); assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['automation'][0], 'testExisting_automation_fixedKey_paused', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_automation_fixedKey_paused', 'automation' ), await testUtils.getExpectedJson('9999999', 'automation', 'patch_fixKeys-pause'), 'returned metadata was not equal expected for update automation' ); expect( await testUtils.getActualDoc( 'testExisting_automation_fixedKey_paused', 'automation' ) ).to.exist; // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 76, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key w/o re-retrieving, deploy paused and then --schedule', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false }, schedule: true }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['automation'], ['testExisting_automation_fixKey_pause', 'testExisting_automation'] ); assert.equal( resultFixKeys['testInstance/testBU']['automation'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['automation'][0], 'testExisting_automation_fixedKey_paused', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_automation_fixedKey_paused', 'automation' ), await testUtils.getExpectedJson('9999999', 'automation', 'patch_fixKeys-pause'), 'returned metadata was not equal expected for update automation' ); expect( await testUtils.getActualDoc( 'testExisting_automation_fixedKey_paused', 'automation' ) ).to.exist; // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 76, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a automation template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'automation', ['testExisting_automation'], 'testSourceMarket' ); assert.equal(process.exitCode, 0, 'retrieveAsTemplate should not have thrown an error'); // WHEN assert.equal( result.automation ? Object.keys(result.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/testBU', 'automation', ['testExisting_automation'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 30, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a automation template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['automation']); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/testBU', 'automation', ['testExisting_automation'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // WHEN assert.equal( result.automation ? Object.keys(result.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/testBU', 'automation', ['testExisting_automation'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'build'), 'returned deployment file was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 34, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a automation template via buildTemplate with --dependencies', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU'); assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); const expectedApiCallsRetrieve = 111; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsRetrieve, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); // preparation // set skipInteraction to true to skip re-retrieving question handler.setOptions({ dependencies: true, skipInteraction: true }); // GIVEN there is a template const templateResult = await handler.buildTemplate( 'testInstance/testBU', 'automation', ['testExisting_automation'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // WHEN // check type list assert.deepEqual( Object.keys(templateResult), [ 'automation', 'dataExtension', 'dataExtract', 'domainVerification', 'emailSend', 'fileTransfer', 'importFile', 'query', 'script', 'sendClassification', 'senderProfile', 'verification', ], 'did not create deployment packages for all relevant types' ); assert.equal( templateResult.automation ? Object.keys(templateResult.automation).length : 0, 1, 'only one automation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_automation', 'automation'), await testUtils.getExpectedJson('9999999', 'automation', 'template'), 'returned template was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsRetrieve, 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'automation', 'testExisting_automation' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN const fileList = await handler.getFilesToCommit('testInstance/testBU', 'automation', [ 'testExisting_automation', ]); // THEN assert.equal(process.exitCode, 0, 'getFilesToCommit should not have thrown an error'); assert.equal(fileList.length, 2, 'expected only 2 file paths'); assert.equal( fileList[0].split('\\').join('/'), 'retrieve/testInstance/testBU/automation/testExisting_automation.automation-meta.json', 'wrong JSON path' ); assert.equal( fileList[1].split('\\').join('/'), 'retrieve/testInstance/testBU/automation/testExisting_automation.automation-doc.md', 'wrong MD path' ); return; }); }); describe('Schedule ================', () => { it('Should schedule an automation by key', async () => { const scheduled = await handler.schedule( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( scheduled['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( scheduled['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should schedule an automation selected via --like', async () => { handler.setOptions({ like: { key: 'testExist%automation' } }); const scheduled = await handler.schedule('testInstance/testBU', ['automation']); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( scheduled['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( scheduled['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should not schedule executing an automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting%' } }); const scheduled = await handler.schedule( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); assert.equal(process.exitCode, 1, 'execute should have thrown an error'); assert.equal( Object.keys(scheduled).length, 0, 'automation was not supposed to be executed' ); return; }); }); describe('Execute ================', () => { it('Should execute --schedule an automation by key', async () => { handler.setOptions({ schedule: true }); const executedKeys = await handler.execute( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( executedKeys['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( executedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should execute --schedule an automation selected via --like', async () => { handler.setOptions({ like: { key: 'testExist%automation' }, schedule: true }); const executedKeys = await handler.execute('testInstance/testBU', ['automation']); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( executedKeys['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( executedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should not execute --schedule executing an automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting%' }, schedule: true }); const executedKeys = await handler.execute( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); assert.equal(process.exitCode, 1, 'execute should have thrown an error'); assert.equal( Object.keys(executedKeys).length, 0, 'automation was not supposed to be executed' ); return; }); it('Should runOnce an automation by key', async () => { const executedKeys = await handler.execute( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( executedKeys['testInstance/testBU']?.automation?.length, 1, 'automation was supposed to be executed' ); assert.equal( executedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should runOnce an automation selected via --like', async () => { handler.setOptions({ like: { key: 'testExist%automation' } }); const executedKeys = await handler.execute('testInstance/testBU', ['automation']); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( executedKeys['testInstance/testBU']?.automation?.length, 1, 'automation was supposed to be executed' ); assert.equal( executedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should not runOnce executing an automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting%' } }); const executedKeys = await handler.execute( 'testInstance/testBU', ['automation'], ['testExisting_automation'] ); assert.equal(process.exitCode, 1, 'execute should have thrown an error'); assert.equal( Object.keys(executedKeys).length, 0, 'automation was not supposed to be executed' ); return; }); }); describe('Pause ================', () => { it('Should pause a automation by key', async () => { const pausedKeys = await handler.pause( 'testInstance/testBU', ['automation'], ['testExisting_automation_pause'] ); assert.equal(process.exitCode, 0, 'pause should not have thrown an error'); assert.equal( pausedKeys['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( pausedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation_pause', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should pause a automation selected via --like', async () => { handler.setOptions({ like: { key: 'testExisting_a%n_pause' } }); const pausedKeys = await handler.pause('testInstance/testBU', ['automation']); assert.equal(process.exitCode, 0, 'pause should not have thrown an error'); assert.equal( pausedKeys['testInstance/testBU']?.automation?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( pausedKeys['testInstance/testBU']?.automation[0], 'testExisting_automation_pause', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should not pause automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting_a%n_pause' } }); const pausedKeys = await handler.pause( 'testInstance/testBU', ['automation'], ['testExisting_automation_pause'] ); assert.equal(process.exitCode, 1, 'pause should have thrown an error'); assert.equal( Object.keys(pausedKeys).length, 0, 'returned number of keys does not correspond to number of expected fixed keys' ); return; }); }); }); ================================================ FILE: test/type.dataExtension.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: dataExtension', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a dataExtension', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['dataExtension']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 8, 'unexpected number of dataExtension' ); assert.deepEqual( await testUtils.getActualJson('testExisting_dataExtension', 'dataExtension'), await testUtils.getExpectedJson('9999999', 'dataExtension', 'retrieve'), 'returned metadata was not equal expected' ); // check if MD file was created and equals expectations expect( await testUtils.getActualDoc('testExisting_dataExtension', 'dataExtension') ).to.equal( await testUtils.getExpectedFile('9999999', 'dataExtension', 'retrieve', 'md') ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a shared dataExtension', async () => { // WHEN await handler.retrieve('testInstance/_ParentBU_', ['dataExtension']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 1, 'only one dataExtension expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_dataExtensionShared', 'dataExtension', '_ParentBU_' ), await testUtils.getExpectedJson('1111111', 'dataExtension', 'retrieve'), 'returned metadata was not equal expected' ); // check if MD file was created and equals expectations expect( await testUtils.getActualDoc( 'testExisting_dataExtensionShared', 'dataExtension', '_ParentBU_' ) ).to.equal( await testUtils.getExpectedFile('1111111', 'dataExtension', 'retrieve', 'md') ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not fail if shared dataExtension cannot be retrieved', async () => { // WHEN await handler.retrieve('testInstance/_ParentBU_', ['dataExtension', 'query']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 1, 'only one dataExtension expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_dataExtensionShared', 'dataExtension', '_ParentBU_' ), await testUtils.getExpectedJson('1111111', 'dataExtension', 'retrieve'), 'returned metadata was not equal expected' ); // check if MD file was created and equals expectations expect( await testUtils.getActualDoc( 'testExisting_dataExtensionShared', 'dataExtension', '_ParentBU_' ) ).to.equal( await testUtils.getExpectedFile('1111111', 'dataExtension', 'retrieve', 'md') ); assert.equal( testUtils.getAPIHistoryLength(), 7, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & update a dataExtension including a field rename', async () => { // WHEN const deployResult = await handler.deploy('testInstance/testBU', ['dataExtension']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); assert.equal( deployResult['testInstance/testBU']?.dataExtension ? Object.keys(deployResult['testInstance/testBU']?.dataExtension).length : 0, 2, 'two dataExtensions to be deployed' ); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 10, 'unexpected number of dataExtensions' ); // insert assert.deepEqual( await testUtils.getActualJson('testNew_dataExtension', 'dataExtension'), await testUtils.getExpectedJson('9999999', 'dataExtension', 'create'), 'returned metadata was not equal expected for create' ); // update assert.deepEqual( await testUtils.getActualJson('testExisting_dataExtension', 'dataExtension'), await testUtils.getExpectedJson('9999999', 'dataExtension', 'update'), 'returned metadata was not equal expected for update' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create & update a shared dataExtension', async () => { // WHEN const deployResult = await handler.deploy('testInstance/_ParentBU_', ['dataExtension']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); assert.equal( deployResult['testInstance/_ParentBU_']?.dataExtension ? Object.keys(deployResult['testInstance/_ParentBU_']?.dataExtension).length : 0, 2, 'two dataExtensions to be deployed' ); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 2, 'two dataExtensions expected' ); // insert assert.deepEqual( await testUtils.getActualJson( 'testNew_dataExtensionShared', 'dataExtension', '_ParentBU_' ), await testUtils.getExpectedJson('1111111', 'dataExtension', 'create'), 'returned metadata was not equal expected for create' ); // update assert.deepEqual( await testUtils.getActualJson( 'testExisting_dataExtensionShared', 'dataExtension', '_ParentBU_' ), await testUtils.getExpectedJson('1111111', 'dataExtension', 'update'), 'returned metadata was not equal expected for update' ); assert.equal( testUtils.getAPIHistoryLength(), 7, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create & update a shared dataExtension with --fixShared & --skipInteraction', async () => { // WHEN handler.setOptions({ fixShared: 'testBU', skipInteraction: true, _runningTest: true }); const deployResult = await handler.deploy('testInstance/_ParentBU_', ['dataExtension']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); assert.equal( deployResult['testInstance/_ParentBU_']?.dataExtension ? Object.keys(deployResult['testInstance/_ParentBU_']?.dataExtension).length : 0, 2, 'two dataExtensions to be deployed' ); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 2, 'two dataExtensions expected' ); // insert assert.deepEqual( await testUtils.getActualJson( 'testNew_dataExtensionShared', 'dataExtension', '_ParentBU_' ), await testUtils.getExpectedJson('1111111', 'dataExtension', 'create'), 'returned metadata was not equal expected for create' ); // update assert.deepEqual( await testUtils.getActualJson( 'testExisting_dataExtensionShared', 'dataExtension', '_ParentBU_' ), await testUtils.getExpectedJson('1111111', 'dataExtension', 'update'), 'returned metadata was not equal expected for update' ); assert.equal( testUtils.getAPIHistoryLength(), 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a dataExtension template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'dataExtension', ['testExisting_dataExtension'], 'testSourceMarket' ); assert.equal(process.exitCode, 0, 'retrieveAsTemplate should not have thrown an error'); // WHEN assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 1, 'only one dataExtension expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_dataExtension', 'dataExtension' ), await testUtils.getExpectedJson('9999999', 'dataExtension', 'template'), 'returned template was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/testBU', 'dataExtension', ['testExisting_dataExtension'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_dataExtension', 'dataExtension'), await testUtils.getExpectedJson('9999999', 'dataExtension', 'build'), 'returned deployment file was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a dataExtension template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['dataExtension']); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/testBU', 'dataExtension', ['testExisting_dataExtension'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // WHEN assert.equal( result.dataExtension ? Object.keys(result.dataExtension).length : 0, 1, 'only one dataExtension expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_dataExtension', 'dataExtension' ), await testUtils.getExpectedJson('9999999', 'dataExtension', 'template'), 'returned template was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/testBU', 'dataExtension', ['testExisting_dataExtension'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_dataExtension', 'dataExtension'), await testUtils.getExpectedJson('9999999', 'dataExtension', 'build'), 'returned deployment file was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the dataExtension', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataExtension', 'testExisting_dataExtension' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN const fileList = await handler.getFilesToCommit( 'testInstance/testBU', 'dataExtension', ['testExisting_dataExtension'] ); // THEN assert.equal(process.exitCode, 0, 'getFilesToCommit should not have thrown an error'); assert.equal(fileList.length, 2, 'expected only 2 file paths (json, md)'); assert.equal( fileList[0].split('\\').join('/'), 'retrieve/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-meta.json', 'wrong JSON path' ); assert.equal( fileList[1].split('\\').join('/'), 'retrieve/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-doc.md', 'wrong MD path' ); return; }); }); }); ================================================ FILE: test/type.dataExtensionField.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: dataExtensionField', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Delete ================', () => { it('Should delete the dataExtensionField', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataExtensionField', 'testExisting_dataExtension.LastName' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should mass-delete the dataExtensionField across all dataExtensions', async () => { handler.setOptions({ skipInteraction: true }); // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataExtensionField', '*.LastName' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should mass-delete multiple dataExtensionFields across all dataExtensions', async () => { handler.setOptions({ skipInteraction: true }); // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataExtensionField', ['*.FirstName', '*.LastName'] ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.dataExtract.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: dataExtract', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a dataExtract', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['dataExtract']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtract ? Object.keys(result.dataExtract).length : 0, 1, 'only one dataExtract expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a dataExtract', async () => { // WHEN await handler.deploy('testInstance/testBU', ['dataExtract']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataExtract ? Object.keys(result.dataExtract).length : 0, 2, 'two dataExtracts expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'post'), 'returned new-JSON was not equal expected for insert dataExtract' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'patch'), 'returned existing-JSON was not equal expected for update dataExtract' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 13, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should change the key during update via --changeKeyValue '); }); describe('Templating ================', () => { it('Should create a dataExtract template via retrieveAsTemplate and build it', async () => { // buildTemplate const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'dataExtract', ['testExisting_dataExtract'], 'testSourceMarket' ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.dataExtract ? Object.keys(result.dataExtract).length : 0, 1, 'only one dataExtract expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'dataExtract', ['testExisting_dataExtract'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a dataExtract template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['dataExtract']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'dataExtract', ['testExisting_dataExtract'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.dataExtract ? Object.keys(result.dataExtract).length : 0, 1, 'only one dataExtract expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'dataExtract', ['testExisting_dataExtract'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_dataExtract', 'dataExtract'), await testUtils.getExpectedJson('9999999', 'dataExtract', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataExtract', 'testExisting_dataExtract' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.dataFilter.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: dataFilter', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a dataFilter', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['dataFilter']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataFilter ? Object.keys(result.dataFilter).length : 0, 1, 'unexpected number of items retrieved' ); assert.deepEqual( await testUtils.getActualJson('testExisting_dataFilter', 'dataFilter'), await testUtils.getExpectedJson('9999999', 'dataFilter', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a dataFilter by key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['dataFilter'], ['testExisting_dataFilter'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataFilter ? Object.keys(result.dataFilter).length : 0, 1, 'only one dataFilter expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_dataFilter', 'dataFilter'), await testUtils.getExpectedJson('9999999', 'dataFilter', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 7, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a dataFilter', async () => { // WHEN const deployed = await handler.deploy('testInstance/testBU', ['dataFilter']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.dataFilter ? Object.keys(result.dataFilter).length : 0, 2, 'unexpected number of dataFilters in cache' ); assert.equal( deployed?.['testInstance/testBU']?.dataFilter ? Object.keys(deployed['testInstance/testBU'].dataFilter).length : 0, 2, 'unexpected number of dataFilters deployed' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_dataFilter', 'dataFilter'), await testUtils.getExpectedJson('9999999', 'dataFilter', 'post'), 'returned new-JSON was not equal expected for insert dataFilter' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_dataFilter', 'dataFilter'), await testUtils.getExpectedJson('9999999', 'dataFilter', 'patch'), 'returned existing-JSON was not equal expected for update dataFilter' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a dataFilter template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['dataFilter']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'dataFilter', ['testExisting_dataFilter'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.dataFilter ? Object.keys(result.dataFilter).length : 0, 1, 'only one dataFilter expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_dataFilter', 'dataFilter'), await testUtils.getExpectedJson('9999999', 'dataFilter', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'dataFilter', ['testExisting_dataFilter'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_dataFilter', 'dataFilter'), await testUtils.getExpectedJson('9999999', 'dataFilter', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataFilter', 'testExisting_dataFilter' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.deliveryProfile.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: deliveryProfile', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a deliveryProfile', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['deliveryProfile']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.deliveryProfile ? Object.keys(result.deliveryProfile).length : 0, 1, 'only one deliveryProfile expected' ); assert.deepEqual( await testUtils.getActualJson('Default', 'deliveryProfile'), await testUtils.getExpectedJson('9999999', 'deliveryProfile', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 1, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.domainVerification.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: domainVerification', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a domainVerification', async () => { // WHEN const retrieve = await handler.retrieve('testInstance/testBU', { domainVerification: null, }); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache assert.equal( retrieve['testInstance/testBU'].domainVerification ? Object.keys(retrieve['testInstance/testBU'].domainVerification).length : 0, 5, 'Unexpected number of assets in retrieve response' ); const typeCache = cache.getCache()?.domainVerification; assert.equal( typeCache ? Object.keys(typeCache).length : 0, 5, 'unexpected number of domainVerifications' ); assert.deepEqual( await testUtils.getActualJson('mcdev.accenture.com', 'domainVerification'), await testUtils.getExpectedJson('9999999', 'domainVerification', 'get-sap'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 1, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert domainVerifications', async () => { // WHEN const deployed = await handler.deploy('testInstance/testBU', { domainVerification: [ 'joern.berkefeld@accenture.com', 'joern.berkefeld.New@accenture.com', ], }); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const cached = cache.getCache(); assert.equal( cached.domainVerification ? Object.keys(cached.domainVerification).length : 0, 6, 'unexpected number of domainVerifications in cache' ); assert.deepEqual( Object.keys(deployed['testInstance/testBU']?.domainVerification), ['joern.berkefeld.New@accenture.com', 'joern.berkefeld@accenture.com'], 'unexpected domainVerifications deployed' ); // check callouts const createCallout = testUtils.getRestCallout( 'post', '/messaging/v1/domainverification/' ); assert.deepEqual( createCallout, { domain: 'joern.berkefeld.New@accenture.com' }, 'unexecpted payload for create callout' ); const updateCallout = testUtils.getRestCallout( 'post', '/messaging/v1/domainverification/update' ); assert.deepEqual( updateCallout, [{ emailAddress: 'joern.berkefeld@accenture.com', isSendable: true }], 'unexecpted payload for update callout' ); // confirm created item assert.deepEqual( await testUtils.getActualJson( 'joern.berkefeld.New@accenture.com', 'domainVerification' ), await testUtils.getExpectedJson('9999999', 'domainVerification', 'create'), 'returned new-JSON was not equal expected for insert domainVerification' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'joern.berkefeld@accenture.com', 'domainVerification' ), await testUtils.getExpectedJson('9999999', 'domainVerification', 'update'), 'returned existing-JSON was not equal expected for update domainVerification' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey('testInstance/testBU', { domainVerification: ['joern.berkefeld@accenture.com'], }); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not delete the items with wrong domainType', async () => { // WHEN const isDeleted = await handler.deleteByKey('testInstance/testBU', { domainVerification: [ 'mcdev.accenture.com', 'adhoc.accenture.com', 'mcdev-transferrable.accenture.com', ], }); // THEN assert.equal(process.exitCode, 1, 'deleteByKey should have thrown an error'); assert.equal(isDeleted, false, 'deleteByKey should have returned false'); assert.equal( testUtils.getAPIHistoryLength(), 1, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.emailSend.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: emailSend', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a emailSend', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['emailSend']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.emailSend ? Object.keys(result.emailSend).length : 0, 1, 'only 1 emailSend expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_emailSend', 'emailSend'), await testUtils.getExpectedJson('9999999', 'emailSend', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a emailSend', async () => { // WHEN await handler.deploy('testInstance/testBU', ['emailSend']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.emailSend ? Object.keys(result.emailSend).length : 0, 2, '2 emailSends expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_emailSend', 'emailSend'), await testUtils.getExpectedJson('9999999', 'emailSend', 'post'), 'returned new-JSON was not equal expected for insert emailSend' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_emailSend', 'emailSend'), await testUtils.getExpectedJson('9999999', 'emailSend', 'patch'), 'returned existing-JSON was not equal expected for update emailSend' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a emailSend template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['emailSend']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'emailSend', ['testExisting_emailSend'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.emailSend ? Object.keys(result.emailSend).length : 0, 1, 'only one emailSend expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_emailSend', 'emailSend'), await testUtils.getExpectedJson('9999999', 'emailSend', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'emailSend', ['testExisting_emailSend'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_emailSend', 'emailSend'), await testUtils.getExpectedJson('9999999', 'emailSend', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'emailSend', 'testExisting_emailSend' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.event.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: event', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a event', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['event']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.event ? Object.keys(result.event).length : 0, 5, 'unexpected amount of events' ); assert.deepEqual( await testUtils.getActualJson('testExisting_event', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'get'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_event_automation', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'get-automation'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create an event & dataExtension via schema', async () => { // prepare await testUtils.copyFile( 'interaction/v1/eventDefinitions/post_withSchema-response.json', 'interaction/v1/eventDefinitions/post-response.json' ); await testUtils.copyFile( 'dataExtension/retrieve-createdViaEvent-response.xml', 'dataExtension/retrieve-response.xml' ); await testUtils.copyFile( 'dataExtension/update-afterCreatedViaEvent-response.xml', 'dataExtension/update-response.xml' ); await handler.deploy('testInstance/testBU', ['event'], ['testNew_event_withSchema']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.event ? Object.keys(result.event).length : 0, 6, 'unexpected number of events' ); // get callouts const createCallout = testUtils.getRestCallout( 'post', '/interaction/v1/eventDefinitions/' ); // confirm created item assert.deepEqual( createCallout, await testUtils.getExpectedJson('9999999', 'event', 'post_withSchema-callout'), 'create-payload JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testNew_event_withSchema', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'post_withSchema'), 'returned new-JSON was not equal expected for insert event' ); // confirm we changed the dataExtension key correctly const updateCalloutDE = testUtils.getSoapCallouts('Update', 'DataExtension'); expect(updateCalloutDE[0]).to.equal( await testUtils.getExpectedFile( '9999999', 'dataExtension', 'update-callout-afterCreatedViaEvent', 'xml' ) ); // confirm created dataExtension assert.deepEqual( await testUtils.getActualJson('testNew_event_withSchema', 'dataExtension'), await testUtils.getExpectedJson( '9999999', 'dataExtension', 'retrieve_event_withSchema' ), 'returned metadata was not equal expected' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 21, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create an event with pre-Existing dataExtension', async () => { // prepare await testUtils.copyFile( 'interaction/v1/eventDefinitions/post_withExistingDE-response.json', 'interaction/v1/eventDefinitions/post-response.json' ); await handler.deploy( 'testInstance/testBU', ['event'], ['testNew_event_withExistingDE'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.event ? Object.keys(result.event).length : 0, 6, 'unexpected number of events' ); // get callouts const createCallout = testUtils.getRestCallout( 'post', '/interaction/v1/eventDefinitions/' ); // confirm created item assert.deepEqual( createCallout, await testUtils.getExpectedJson('9999999', 'event', 'post_withExistingDE-callout'), 'create-payload JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testNew_event_withExistingDE', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'post_withExistingDE'), 'returned new-JSON was not equal expected for insert event' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update an event', async () => { await handler.deploy('testInstance/testBU', ['event'], ['testExisting_event']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.event ? Object.keys(result.event).length : 0, 5, 'unexpected number of events' ); // get callouts const updateCallout = testUtils.getRestCallout( 'put', '/interaction/v1/eventDefinitions/%' ); // confirm updated item assert.deepEqual( updateCallout, await testUtils.getExpectedJson('9999999', 'event', 'put-callout'), 'update-payload JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_event', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'put'), 'returned existing-JSON was not equal expected for update event' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('FixKeys ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should exit fixKeys because event is not supported intentionally', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false } }); const resultFixKeys = await handler.fixKeys('testInstance/testBU', ['event']); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // check which keys were fixed assert.equal( resultFixKeys['testInstance/testBU'], undefined, 'expected to find no keys to be fixed' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 0, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a event template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'event', ['testExisting_event'], 'testSourceMarket' ); // WHEN assert.equal(process.exitCode, 0, 'retrieveAsTemplate should not have thrown an error'); assert.equal( result.event ? Object.keys(result.event).length : 0, 1, 'only one event expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_event', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/testBU', 'event', ['testExisting_event'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_event', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a event template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['event']); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/testBU', 'event', ['testExisting_event'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.event ? Object.keys(result.event).length : 0, 1, 'only one event expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_event', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'template'), 'returned template JSON of buildTemplate was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/testBU', 'event', ['testExisting_event'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_event', 'event'), await testUtils.getExpectedJson('9999999', 'event', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'event', 'testExisting_event' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.fileLocation.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: fileLocation', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a fileLocation', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['fileLocation']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileLocation ? Object.keys(result.fileLocation).length : 0, 6, 'unexpected number of fileLocations' ); assert.deepEqual( await testUtils.getActualJson('Salesforce Objects %26 Reports', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-sor'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('ExactTarget Enhanced FTP', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-eftp'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_gcp', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-gcp'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_azure', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-azure'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_aws', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-aws'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_exsftp', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-exsftp'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve an old fileLocation by key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['fileLocation'], ['Salesforce Objects & Reports'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileLocation ? Object.keys(result.fileLocation).length : 0, 1, 'unexpected number of fileLocations' ); assert.deepEqual( await testUtils.getActualJson('Salesforce Objects %26 Reports', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-sor'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a new fileLocation by key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['fileLocation'], ['testExisting_fileLocation_azure'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileLocation ? Object.keys(result.fileLocation).length : 0, 1, 'unexpected number of fileLocations' ); assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_azure', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'get-azure'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should update fileLocations', async () => { // WHEN const deployed = await handler.deploy( 'testInstance/testBU', ['fileLocation'], ['testExisting_fileLocation_exsftp', 'testExisting_fileLocation_aws'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileLocation ? Object.keys(result.fileLocation).length : 0, 6, 'unexpected number of fileLocations in cache' ); assert.equal( deployed?.['testInstance/testBU']?.fileLocation ? Object.keys(deployed['testInstance/testBU'].fileLocation).length : 0, 2, 'unexpected number of fileLocations deployed' ); // confirm created item // TODO // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_exsftp', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'patch-exsftp'), 'returned JSON was not equal expected for insert fileLocation' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_fileLocation_aws', 'fileLocation'), await testUtils.getExpectedJson('9999999', 'fileLocation', 'patch-aws'), 'returned JSON was not equal expected for update fileLocation' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not update fileLocations', async () => { // WHEN const deployed = await handler.deploy( 'testInstance/testBU', ['fileLocation'], ['ExactTarget Enhanced FTP'] ); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileLocation ? Object.keys(result.fileLocation).length : 0, 6, 'unexpected number of fileLocations in cache' ); assert.equal( deployed?.['testInstance/testBU']?.fileLocation ? Object.keys(deployed['testInstance/testBU'].fileLocation).length : 0, 0, 'unexpected number of fileLocations deployed' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a fileLocation template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['fileLocation']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'fileLocation', ['testExisting_fileLocation_azure'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.fileLocation ? Object.keys(result.fileLocation).length : 0, 1, 'only one fileLocation expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_fileLocation_azure', 'fileLocation' ), await testUtils.getExpectedJson('9999999', 'fileLocation', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'fileLocation', ['testExisting_fileLocation_azure'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson( 'testTemplated_fileLocation_azure', 'fileLocation' ), await testUtils.getExpectedJson('9999999', 'fileLocation', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'fileLocation', 'testExisting_fileLocation_azure' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.fileTransfer.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: fileTransfer', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a fileTransfer', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['fileTransfer']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileTransfer ? Object.keys(result.fileTransfer).length : 0, 1, 'only one fileTransfer expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a fileTransfer', async () => { // WHEN await handler.deploy('testInstance/testBU', ['fileTransfer']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.fileTransfer ? Object.keys(result.fileTransfer).length : 0, 2, 'two fileTransfers expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'post'), 'returned JSON was not equal expected for insert fileTransfer' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'patch'), 'returned JSON was not equal expected for update fileTransfer' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a fileTransfer template via retrieveAsTemplate and build it', async () => { // buildTemplate const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'fileTransfer', ['testExisting_fileTransfer'], 'testSourceMarket' ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.fileTransfer ? Object.keys(result.fileTransfer).length : 0, 1, 'only one fileTransfer expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'fileTransfer', ['testExisting_fileTransfer'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a fileTransfer template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['fileTransfer']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'fileTransfer', ['testExisting_fileTransfer'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.fileTransfer ? Object.keys(result.fileTransfer).length : 0, 1, 'only one fileTransfer expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'fileTransfer', ['testExisting_fileTransfer'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_fileTransfer', 'fileTransfer'), await testUtils.getExpectedJson('9999999', 'fileTransfer', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'fileTransfer', 'testExisting_fileTransfer' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.filter.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: filter', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a filter', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['filter']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.filter ? Object.keys(result.filter).length : 0, 1, 'unexpected number of items retrieved' ); assert.deepEqual( await testUtils.getActualJson('testExisting_filter', 'filter'), await testUtils.getExpectedJson('9999999', 'filter', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a filter by key', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['filter'], ['testExisting_filter']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.filter ? Object.keys(result.filter).length : 0, 1, 'only one filter expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_filter', 'filter'), await testUtils.getExpectedJson('9999999', 'filter', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 15, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a filter', async () => { // WHEN const deployed = await handler.deploy('testInstance/testBU', ['filter']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.filter ? Object.keys(result.filter).length : 0, 2, 'unexpected number of filters in cache' ); assert.equal( deployed?.['testInstance/testBU']?.filter ? Object.keys(deployed['testInstance/testBU'].filter).length : 0, 2, 'unexpected number of filters deployed' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_filter', 'filter'), await testUtils.getExpectedJson('9999999', 'filter', 'post'), 'returned new-JSON was not equal expected for insert filter' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_filter', 'filter'), await testUtils.getExpectedJson('9999999', 'filter', 'patch'), 'returned existing-JSON was not equal expected for update filter' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 17, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a filter template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['filter']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'filter', ['testExisting_filter'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.filter ? Object.keys(result.filter).length : 0, 1, 'only one filter expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_filter', 'filter'), await testUtils.getExpectedJson('9999999', 'filter', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'filter', ['testExisting_filter'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_filter', 'filter'), await testUtils.getExpectedJson('9999999', 'filter', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'filter', 'testExisting_filter' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.folder.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; // const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; import { Util } from '../lib/util/util.js'; chai.use(chaiFiles); describe('type: folder', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve an asset whose folder name contains a slash and escape the slash in r__folder_Path', async () => { // GIVEN the SFMC folder "bla/blub" (child of Content Builder) and an asset in that folder await testUtils.copyFile( 'dataFolder/+retrieve-ContentTypeINasset,asset-shared,cloudpages-slashfolder-response.xml', 'dataFolder/retrieve-ContentTypeINasset,asset-shared,cloudpages-response.xml' ); await testUtils.copyFile( 'asset/v1/content/assets/query/+post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213-slashfolder.json', 'asset/v1/content/assets/query/post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213.json' ); const retrieve = await handler.retrieve('testInstance/testBU', ['asset-block']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); assert.equal( retrieve['testInstance/testBU'].asset ? Object.keys(retrieve['testInstance/testBU'].asset).length : 0, 5, 'five assets expected in retrieve response (4 existing + 1 new test_slash)' ); // Verify the retrieved asset has the escape char (∕) in r__folder_Path, not a real slash assert.equal( retrieve['testInstance/testBU'].asset?.test_slash?.r__folder_Path, 'Content Builder/bla' + Util.folderNameSlashEscapeChar + 'blub', 'r__folder_Path should use ∕ (U+2215) to escape the slash in the folder name' ); return; }); }); describe('Deploy ================', () => { it('Should create automation & dataExtension folders', async () => { // prepare testUtils.copyToDeploy('folder-deploy', 'folder'); await testUtils.copyFile( 'dataFolder/+retrieve-response.xml', 'dataFolder/retrieve-response.xml' ); await testUtils.copyFile( 'dataFolder/+retrieve-QAA-response.xml', 'dataFolder/retrieve-QAA-response.xml' ); const deployed = await handler.deploy('testInstance/testBU', ['folder']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const cached = cache.getCache(); assert.equal( cached.folder ? Object.keys(cached.folder).length : 0, 40, 'unexpected number of folders in cache' ); // check what was deployed assert.deepEqual( deployed['testInstance/testBU']?.folder ? Object.values(deployed['testInstance/testBU']?.folder).map((f) => f.Path) : null, [ 'Data Extensions/my', 'Data Extensions/testExisting_folder', 'Data Extensions/my/sub', 'Data Extensions/my/sub/path', 'Data Extensions/my/sub/path/subpath', 'my automations/my', 'my automations/my/sub', 'my automations/my/sub/path', 'my automations/my/sub/path/subpath', ], 'unexpected deployed folders' ); // get callouts const createRestCallouts = testUtils.getRestCallout('post', '/email/v1/category', true); // confirm created item assert.deepEqual( createRestCallouts, [ { parentCatId: 290937, name: 'my', catType: 'automations' }, { parentCatId: 862100, name: 'sub', catType: 'automations' }, { parentCatId: 862101, name: 'path', catType: 'automations' }, { parentCatId: 862102, name: 'subpath', catType: 'automations' }, ], 'create-payload JSON was not equal expected' ); const createSoapCallouts = testUtils.getSoapCallouts('Create', 'DataFolder'); const updateSoapCallouts = testUtils.getSoapCallouts('Update', 'DataFolder'); // confirm created item assert.deepEqual( createSoapCallouts, [ '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><CreateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI"><Objects xsi:type="DataFolder"><Name>my</Name><Description></Description><ContentType>dataextension</ContentType><IsActive>true</IsActive><IsEditable>true</IsEditable><AllowChildren>true</AllowChildren><ParentFolder><ID>2</ID></ParentFolder></Objects></CreateRequest></Body><Header><fueloauth xmlns="http://exacttarget.com">9999999</fueloauth></Header></Envelope>', '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><CreateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI"><Objects xsi:type="DataFolder"><Name>sub</Name><Description></Description><ContentType>dataextension</ContentType><IsActive>true</IsActive><IsEditable>true</IsEditable><AllowChildren>true</AllowChildren><ParentFolder><ID>862001</ID></ParentFolder></Objects></CreateRequest></Body><Header><fueloauth xmlns="http://exacttarget.com">9999999</fueloauth></Header></Envelope>', '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><CreateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI"><Objects xsi:type="DataFolder"><Name>path</Name><Description></Description><ContentType>dataextension</ContentType><IsActive>true</IsActive><IsEditable>true</IsEditable><AllowChildren>true</AllowChildren><ParentFolder><ID>862002</ID></ParentFolder></Objects></CreateRequest></Body><Header><fueloauth xmlns="http://exacttarget.com">9999999</fueloauth></Header></Envelope>', '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><CreateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI"><Objects xsi:type="DataFolder"><Name>subpath</Name><Description></Description><ContentType>dataextension</ContentType><IsActive>true</IsActive><IsEditable>true</IsEditable><AllowChildren>true</AllowChildren><ParentFolder><ID>862003</ID></ParentFolder></Objects></CreateRequest></Body><Header><fueloauth xmlns="http://exacttarget.com">9999999</fueloauth></Header></Envelope>', ], 'create-payload XL was not equal expected' ); // confirm updated item - this should have updated despite the folder name being different (changed case). The server compares folders case insensitively assert.deepEqual( updateSoapCallouts, [ '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><UpdateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI"><Objects xsi:type="DataFolder"><Name>testExisting_folder</Name><IsActive>true</IsActive><IsEditable>true</IsEditable><AllowChildren>true</AllowChildren><ParentFolder><ID>2</ID></ParentFolder><ID>66666</ID></Objects></UpdateRequest></Body><Header><fueloauth xmlns="http://exacttarget.com">9999999</fueloauth></Header></Envelope>', ], 'update-payload XL was not equal expected' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create folder when same path exists in another Business Unit', async () => { // prepare // Use folder deploy data with an asset folder path testUtils.copyToDeploy('folder-deploy-samepath', 'folder'); // Use a modified retrieve response that includes 'Content Builder/testFolder_samePath' // from a different BU (Client.ID=1111111). ContentType 'asset' is in folderTypesFromParent // so it will be cached even though it belongs to another BU - simulating the bug scenario await testUtils.copyFile( 'dataFolder/retrieve-samePathOtherBU-response.xml', 'dataFolder/retrieve-response.xml' ); const deployed = await handler.deploy('testInstance/testBU', ['folder']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // check what was deployed - 'Content Builder/testFolder_samePath' should be created // even though it exists in another BU (1111111) const deployedFolderPaths = deployed['testInstance/testBU']?.folder ? Object.values(deployed['testInstance/testBU']?.folder).map((f) => f.Path) : []; assert.include( deployedFolderPaths, 'Content Builder/testFolder_samePath', "'Content Builder/testFolder_samePath' should have been created in current BU, not skipped because it exists in another BU" ); const createRestCallouts = testUtils.getRestCallout( 'post', '/asset/v1/content/categories', true ); // 'Content Builder/testFolder_samePath' must be created in current BU via REST // (not skipped due to same path in other BU) assert.ok( createRestCallouts?.some( (c) => c.name === 'testFolder_samePath' && c.parentId === 89397 ), "'Content Builder/testFolder_samePath' folder creation callout not found - folder was incorrectly skipped" ); return; }); it('Should create a folder whose name contains a slash character (direct folder deploy)', async () => { // GIVEN a folder deploy file named Headers%2FFolders.folder-meta.json with Name "Headers/Folders" // (the % encoding represents the actual '/' in the SFMC folder name) testUtils.copyToDeploy('folder-deploy-slash', 'folder'); const deployed = await handler.deploy('testInstance/testBU', ['folder']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // Verify the deployed path uses the escape char (∕) not the real slash const deployedFolderPaths = deployed['testInstance/testBU']?.folder ? Object.values(deployed['testInstance/testBU']?.folder).map((f) => f.Path) : []; assert.include( deployedFolderPaths, 'Content Builder/Headers' + Util.folderNameSlashEscapeChar + 'Folders', 'deployed folder path should use escape char for the slash in folder name' ); // Verify that the REST Create callout uses the REAL slash character in the name field // (not the escape character), so that SFMC creates a folder named "Headers/Folders" const createRestCallouts = testUtils.getRestCallout( 'post', '/asset/v1/content/categories', true ); assert.ok( createRestCallouts?.some( (c) => c.name === 'Headers/Folders' && c.parentId === 89397 ), "REST create for 'Headers/Folders' should use the real slash in name, not the escape char" ); // Verify the escape char was NOT sent as the folder name assert.ok( !createRestCallouts?.some( (c) => c.name === 'Headers' + Util.folderNameSlashEscapeChar + 'Folders' ), 'REST create should NOT use the escape char in the name field' ); return; }); it('Should create a folder whose name contains a slash when triggered via r__folder_Path from an asset', async () => { // GIVEN an asset deploy with r__folder_Path pointing to a subfolder whose name contains a slash // The escape char (∕) in r__folder_Path separates the slash-in-name from path separators testUtils.copyToDeploy('asset-slashfolder-deploy', 'asset'); const deployed = await handler.deploy('testInstance/testBU', ['asset']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // Verify the asset was deployed assert.equal( deployed['testInstance/testBU']?.asset ? Object.keys(deployed['testInstance/testBU']?.asset).length : 0, 1, 'one asset should have been deployed' ); // Verify the auto-generated folder was created via REST with the REAL slash in the name field // (not the escape char), so SFMC creates a folder named "bla/blub" const createRestCallouts = testUtils.getRestCallout( 'post', '/asset/v1/content/categories', true ); assert.ok( createRestCallouts?.some((c) => c.name === 'bla/blub' && c.parentId === 89397), "REST create for 'Content Builder/bla∕blub' should send name 'bla/blub' with real slash" ); // Verify the escape char was NOT sent as the folder name assert.ok( !createRestCallouts?.some( (c) => c.name === 'bla' + Util.folderNameSlashEscapeChar + 'blub' ), 'REST create should NOT use the escape char in the name field' ); return; }); }); }); ================================================ FILE: test/type.importFile.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: importFile', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a importFile', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['importFile']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.importFile ? Object.keys(result.importFile).length : 0, 3, 'unexpected number of items retrieved' ); assert.deepEqual( await testUtils.getActualJson('testExisting_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'get'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_importFileSMS', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'get-sms'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_importFileDataImport', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'get-dataImport'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a importFile by key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['importFile'], ['testExisting_importFile'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.importFile ? Object.keys(result.importFile).length : 0, 1, 'only one importFile expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a importFile', async () => { // WHEN await handler.deploy('testInstance/testBU', ['importFile']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.importFile ? Object.keys(result.importFile).length : 0, 4, 'unexptected number of importFiles in cache' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'post'), 'returned new-JSON was not equal expected for insert importFile' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'patch'), 'returned existing-JSON was not equal expected for update importFile' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 18, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a importFile template via retrieveAsTemplate and build it', async () => { // buildTemplate const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'importFile', ['testExisting_importFile'], 'testSourceMarket' ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.importFile ? Object.keys(result.importFile).length : 0, 1, 'only one importFile expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'importFile', ['testExisting_importFile'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a importFile template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['importFile']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'importFile', ['testExisting_importFile'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.importFile ? Object.keys(result.importFile).length : 0, 1, 'only one importFile expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'importFile', ['testExisting_importFile'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_importFile', 'importFile'), await testUtils.getExpectedJson('9999999', 'importFile', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'importFile', 'testExisting_importFile' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.journey.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: journey', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a journey w/o keys', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['journey']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 6, 'unexpected number of journeys' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Multistep', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-multistep'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-transactionalEmail'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_journey_updatecontact_sharedDE', 'journey' ), await testUtils.getExpectedJson('9999999', 'journey', 'get-updatecontact-sharedDE'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 31, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve journeys with dataExtension type simultaneously (mcdev retrieve cred/bu -m journey dataExtension)', async () => { // WHEN - both types at once, no keys: unrelated DEs present alongside UPDATECONTACTDATA DEs await handler.retrieve('testInstance/testBU', ['journey', 'dataExtension']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 6, 'unexpected number of journeys (includes local-DE and shared-DE UPDATECONTACTDATA journeys)' ); // Verify UPDATECONTACTDATA activity with local DE is correctly resolved assert.deepEqual( await testUtils.getActualJson('testExisting_journey_updatecontact', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-updatecontact'), 'returned JSON was not equal expected for journey with local DE updatecontact activity' ); // Verify UPDATECONTACTDATA activity with shared DE is correctly resolved assert.deepEqual( await testUtils.getActualJson( 'testExisting_journey_updatecontact_sharedDE', 'journey' ), await testUtils.getExpectedJson('9999999', 'journey', 'get-updatecontact-sharedDE'), 'returned JSON was not equal expected for journey with shared DE updatecontact activity' ); assert.equal( testUtils.getAPIHistoryLength(), 34, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve only published journeys', async () => { handler.setOptions({ onlyPublished: true }); // WHEN await handler.retrieve('testInstance/testBU', ['journey']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'unexpected number of journeys' ); assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-transactionalEmail'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 24, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a Quicksend journey with key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['journey'], ['testExisting_journey_Quicksend'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 19, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a Multistep journey with key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['journey'], ['testExisting_journey_Multistep'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Multistep', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-multistep'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 19, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a journey containing an UPDATECONTACTDATA activity with key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['journey'], ['testExisting_journey_updatecontact'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_updatecontact', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-updatecontact'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 20, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a journey containing an UPDATECONTACTDATA activity referencing a shared DE with key', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['journey'], ['testExisting_journey_updatecontact_sharedDE'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_journey_updatecontact_sharedDE', 'journey' ), await testUtils.getExpectedJson('9999999', 'journey', 'get-updatecontact-sharedDE'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 20, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a Transactional Email journey with key', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['journey'], ['testExisting_temail']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-transactionalEmail'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 23, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a journey with id', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['journey'], ['id:3c3f4112-9b43-43ca-8a89-aa0375b2c1a2'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 19, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a journey with name', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['journey'], ['name:testExisting_journey_Quicksend'] ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only 1 journeys expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 20, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should NOT change the key during update with --changeKeyValue and instead fail due to missing support', async () => { // WHEN handler.setOptions({ changeKeyValue: 'updatedKey' }); await handler.deploy( 'testInstance/testBU', ['journey'], ['testExisting_journey_Quicksend'] ); // THEN assert.equal( process.exitCode, 1, 'deploy should have thrown an error due to lack of support' ); return; }); it('Should deploy --publish an already published transactional journey by first pausing it', async () => { await testUtils.copyFile( 'interaction/v1/interactions/key_testExisting_temail/put-response-paused.json', 'interaction/v1/interactions/key_testExisting_temail/put-response.json' ); // WHEN handler.setOptions({ skipStatusCheck: true, publish: true }); const deploy = await handler.deploy( 'testInstance/testBU', ['journey'], ['testExisting_temail'] ); // THEN assert.equal(process.exitCode, 0, 'deploy --publish should not have thrown an error'); // retrieve result assert.deepEqual( Object.keys(deploy['testInstance/testBU']?.journey), ['testExisting_temail'], 'should have published the right journey' ); const pauseCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/pause' ); const resumeCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/resume' ); // confirm callouts assert.deepEqual( pauseCallout, { definitionId: 'dsfdsafdsa-922c-4568-85a5-e5cc77efc3be', }, 'pauseCallout-payload JSON was not equal expected' ); assert.deepEqual( resumeCallout, { definitionId: 'dsfdsafdsa-922c-4568-85a5-e5cc77efc3be', }, 'resumeCallout-payload JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 60, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update and publish a transactional journey', async () => { // WHEN handler.setOptions({ skipStatusCheck: true, publish: true }); const deploy = await handler.deploy( 'testInstance/testBU', ['journey'], ['testExisting_temail_notPublished'] ); // THEN assert.equal(process.exitCode, 0, 'deploy --publish should not have thrown an error'); // retrieve result assert.deepEqual( Object.keys(deploy['testInstance/testBU']?.journey), ['testExisting_temail_notPublished'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/create' ); // confirm callouts assert.deepEqual( publishCallout, { definitionId: 'd4a900fe-3a8f-4cc5-9a49-81286e3e2cd2', }, 'publish-payload JSON was not equal expected' ); // confirm transactionalEmail was downloaded assert.deepEqual( await testUtils.getActualJson( 'testExisting_temail_notPublished', 'transactionalEmail' ), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 59, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create and publish a transactional journey', async () => { // WHEN handler.setOptions({ skipStatusCheck: true, publish: true }); const deploy = await handler.deploy( 'testInstance/testBU', ['journey'], ['testNew_temail_notPublished'] ); // THEN assert.equal(process.exitCode, 0, 'deploy --publish should not have thrown an error'); // retrieve result assert.deepEqual( Object.keys(deploy['testInstance/testBU']?.journey), ['testNew_temail_notPublished'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/create' ); // confirm callouts assert.deepEqual( publishCallout, { definitionId: '4c39662b-7c47-4df4-8bd6-65f01c313e8c', }, 'publish-payload JSON was not equal expected' ); // confirm transactionalEmail was downloaded assert.deepEqual( await testUtils.getActualJson('testNew_temail_notPublished', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'create-publish'), 'returned JSON was not equal expected' ); // confirm journey was downloaded assert.deepEqual( await testUtils.getActualJson('testNew_temail_notPublished', 'journey'), await testUtils.getExpectedJson( '9999999', 'journey', 'create-transactionaEmail-publish' ), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 59, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update & publish a multi-step journey by key (auto-picks latest version)', async () => { handler.setOptions({ skipStatusCheck: true, publish: true }); // WHEN const deploy = await handler.deploy( 'testInstance/testBU', ['journey'], ['testExisting_journey_Multistep'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( Object.keys(deploy['testInstance/testBU']?.journey), ['testExisting_journey_Multistep'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); // confirm event was downloaded assert.deepEqual( await testUtils.getActualJson( 'DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e', 'event' ), await testUtils.getExpectedJson('9999999', 'event', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 50, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update a journey with UPDATECONTACT activity', async () => { // WHEN await handler.deploy( 'testInstance/testBU', ['journey'], ['testExisting_journey_updatecontact'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_journey_updatecontact', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'put-updatecontact'), 'returned metadata was not equal expected for update journey with updatecontact activity' ); assert.equal( testUtils.getAPIHistoryLength(), 22, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should update a journey with UPDATECONTACT activity referencing a shared DE', async () => { // WHEN await handler.deploy( 'testInstance/testBU', ['journey'], ['testExisting_journey_updatecontact_sharedDE'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_journey_updatecontact_sharedDE', 'journey' ), await testUtils.getExpectedJson('9999999', 'journey', 'put-updatecontact-sharedDE'), 'returned metadata was not equal expected for update journey with shared DE updatecontact activity' ); assert.equal( testUtils.getAPIHistoryLength(), 22, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a journey template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['journey']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'journey', ['testExisting_journey_Quicksend'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.journey ? Object.keys(result.journey).length : 0, 1, 'only one journey expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'journey', ['testExisting_journey_Quicksend'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 31, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a journey template via buildTemplate with --dependencies', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['journey', 'asset']); assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); handler.setOptions({ dependencies: true, retrieve: true }); // GIVEN there is a template const templatedItems = await handler.buildTemplate( 'testInstance/testBU', 'journey', ['testExisting_journey_Quicksend', 'testExisting_journey_Multistep'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.deepEqual( Object.keys(templatedItems), [ 'asset', 'dataExtension', 'domainVerification', 'event', 'journey', 'sendClassification', 'senderProfile', ], 'expected specific types to be templated' ); // journey assert.deepEqual( templatedItems.journey.map((item) => item.key), ['{{{prefix}}}journey_Multistep', '{{{prefix}}}journey_Quicksend'], 'expected specific journeys to be templated' ); // event assert.deepEqual( templatedItems.event.map((item) => item.eventDefinitionKey), [ 'DEAudience-11be962d-064c-83d9-2804-7d1befc10325', 'DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e', ], 'expected specific events to be templated' ); // dataExtension assert.deepEqual( templatedItems.dataExtension.map((item) => item.CustomerKey), [ '{{{prefix}}}DomainExclusion', '{{{prefix}}}journey_Multistep', '{{{prefix}}}journey_Quicksend', ], 'expected specific dataExtensions to be templated' ); // domainVerification assert.deepEqual( templatedItems.domainVerification.map((item) => item.domain), ['joern.berkefeld+test@accenture.com', 'joern.berkefeld@accenture.com'], 'expected specific domainVerifications to be templated' ); // senderProfile assert.deepEqual( templatedItems.senderProfile.map((item) => item.CustomerKey), ['{{{prefix}}}senderProfile'], 'expected specific assets to be templated' ); // sendClassification assert.deepEqual( templatedItems.sendClassification.map((item) => item.CustomerKey), ['{{{prefix}}}sendClassification'], 'expected specific sendClassifications to be templated' ); // asset assert.deepEqual( templatedItems.asset.map((item) => item.customerKey), [ '{{{prefix}}}asset_htmlblock', '{{{prefix}}}htmlblock 3 spaces', '{{{prefix}}}htmlblock1', '{{{prefix}}}htmlblock2', ], 'expected specific assets to be templated' ); }); }); describe('Delete ================', () => { it('Should NOT delete the item due to missing version', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'journey', 'testExisting_journey_Multistep' ); // THEN assert.equal(process.exitCode, 1, 'delete should have thrown an error'); assert.equal(isDeleted, false, 'should not have deleted the item'); return; }); it('Should NOT delete the item due to unknown version', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'journey', 'testExisting_journey_Multistep/2' ); // THEN assert.equal(process.exitCode, 1, 'delete should have thrown an error'); assert.equal(isDeleted, false, 'should not have deleted the item'); return; }); it('Should delete the item with exact version', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'journey', 'testExisting_journey_Multistep/1' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); it('Should delete the item with all versions', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'journey', 'testExisting_journey_Multistep/*' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); it('Should delete 2 items with exact version', async () => { // WHEN const isDeleted = await handler.deleteByKey('testInstance/testBU', 'journey', [ 'testExisting_journey_Quicksend', 'testExisting_temail', 'testExisting_journey_Multistep/1', ]); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('ReplaceContentBlockByX ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { journey: null, }, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right journeys that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-name'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 37, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { journey: null, }, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right journeys that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-id'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 37, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { journey: null, }, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Quicksend'], 'should have found the right assets that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_journey_Quicksend', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-quicksend-rcb-key'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 37, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Publish ================', () => { it(`Should not publish a transactional journey by key that is already published but instead trigger a refresh`, async () => { handler.setOptions({ skipStatusCheck: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['testExisting_temail'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); assert.deepEqual( publish['testInstance/testBU']?.journey, ['testExisting_temail'], 'should not have published any journey but instead triggered a refresh' ); // get callouts const pauseCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/pause' ); const resumeCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/resume' ); const pauseResumeResponse = { definitionId: 'dsfdsafdsa-922c-4568-85a5-e5cc77efc3be', }; // confirm responses assert.deepEqual( pauseCallout, pauseResumeResponse, 'pause-payload JSON was not equal expected' ); assert.deepEqual( resumeCallout, pauseResumeResponse, 'resume-payload JSON was not equal expected' ); // confirm transactionalEmail was downloaded assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-transactionalEmail'), 'returned JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 38, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a transactional journey by key', async () => { handler.setOptions({ skipStatusCheck: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['testExisting_temail_notPublished'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( publish['testInstance/testBU']?.journey, ['testExisting_temail_notPublished'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/transactional/create' ); // confirm callouts assert.deepEqual( publishCallout, { definitionId: 'd4a900fe-3a8f-4cc5-9a49-81286e3e2cd2', }, 'publish-payload JSON was not equal expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_temail_notPublished', 'journey'), await testUtils.getExpectedJson('9999999', 'journey', 'get-published'), 'returned JSON was not equal expected' ); // confirm transactionalEmail was downloaded assert.deepEqual( await testUtils.getActualJson( 'testExisting_temail_notPublished', 'transactionalEmail' ), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 36, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a journey by key (auto-picks latest version)', async () => { handler.setOptions({ skipStatusCheck: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['testExisting_journey_Multistep'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( publish['testInstance/testBU']?.journey, ['testExisting_journey_Multistep'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); // confirm event was downloaded assert.deepEqual( await testUtils.getActualJson( 'DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e', 'event' ), await testUtils.getExpectedJson('9999999', 'event', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 31, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a journey by id w/ version', async () => { handler.setOptions({ skipStatusCheck: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f/1'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( publish['testInstance/testBU']?.journey, ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f/1'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); // confirm event was downloaded assert.deepEqual( await testUtils.getActualJson( 'DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e', 'event' ), await testUtils.getExpectedJson('9999999', 'event', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 31, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a journey by id but w/o version (auto-picks latest version)', async () => { handler.setOptions({ skipStatusCheck: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( publish['testInstance/testBU']?.journey, ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f'], 'should have published the right journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 31, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a journey by id w/ version with failing status check', async () => { await testUtils.copyFile( 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-failed.json', 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json' ); handler.setOptions({ skipStatusCheck: false, _runningTest: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f/1'] ); // THEN assert.equal(process.exitCode, 1, 'publish should have thrown an error'); // retrieve result assert.equal( publish['testInstance/testBU']?.journey.length, 0, 'should have not published the journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a journey by id w/ version with successful status check but with warnings', async () => { await testUtils.copyFile( 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-successWarnings.json', 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json' ); handler.setOptions({ skipStatusCheck: false, _runningTest: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f/1'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( publish['testInstance/testBU']?.journey, ['testExisting_journey_Multistep'], 'should have published the journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); // confirm event was downloaded assert.deepEqual( await testUtils.getActualJson( 'DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e', 'event' ), await testUtils.getExpectedJson('9999999', 'event', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 32, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should publish a journey by id w/ version with successful status check', async () => { await testUtils.copyFile( 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-success.json', 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json' ); handler.setOptions({ skipStatusCheck: false, _runningTest: true }); // WHEN const publish = await handler.publish( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f/1'] ); // THEN assert.equal(process.exitCode, 0, 'publish should not have thrown an error'); // retrieve result assert.deepEqual( publish['testInstance/testBU']?.journey, ['testExisting_journey_Multistep'], 'should have published the journey' ); // get callouts const publishCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/publishAsync/%' ); // confirm created item assert.deepEqual( publishCallout, await testUtils.getExpectedJson('9999999', 'journey', 'publish-callout'), 'publish-payload JSON was not equal expected' ); // confirm event was downloaded assert.deepEqual( await testUtils.getActualJson( 'DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e', 'event' ), await testUtils.getExpectedJson('9999999', 'event', 'get-published'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 32, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Validate ================', () => { it('Should not validate a transactional journey by key', async () => { handler.setOptions({ skipStatusCheck: true }); // WHEN const validate = await handler.validate( 'testInstance/testBU', ['journey'], ['testExisting_temail_notPublished'] ); // THEN assert.equal(process.exitCode, 0, 'validate should not have thrown an error'); // retrieve result assert.deepEqual( validate['testInstance/testBU']?.journey, [], 'should not have validated any journey' ); assert.equal( testUtils.getAPIHistoryLength(), 1, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should validate a multi-step journey but not the transactional journey by key', async () => { await testUtils.copyFile( 'interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-success.json', 'interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json' ); handler.setOptions({ skipStatusCheck: true }); // WHEN const validate = await handler.validate( 'testInstance/testBU', ['journey'], ['testExisting_temail_notPublished', 'testExisting_journey_Multistep'] ); // THEN assert.equal(process.exitCode, 0, 'validate should not have thrown an error'); // retrieve result assert.deepEqual( validate['testInstance/testBU']?.journey, ['testExisting_journey_Multistep'], 'should not have validated any journey' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should validate a journey by id but w/o version (auto-picks latest version)', async () => { await testUtils.copyFile( 'interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-success.json', 'interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json' ); // WHEN const validate = await handler.validate( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f'] ); // THEN assert.equal(process.exitCode, 0, 'validate should not have thrown an error'); // retrieve result assert.deepEqual( validate['testInstance/testBU']?.journey, ['testExisting_journey_Multistep'], 'should have validateed the right journey' ); // get callouts const validateCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/validateAsync/%' ); // confirm created item assert.deepEqual( validateCallout, await testUtils.getExpectedJson('9999999', 'journey', 'validate-callout'), 'validate-payload JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should validate a journey by id w/ version with failing status check', async () => { await testUtils.copyFile( 'interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-failed.json', 'interaction/v1/interactions/validateStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response.json' ); handler.setOptions({ _runningTest: true }); // WHEN const validate = await handler.validate( 'testInstance/testBU', ['journey'], ['id:0175b971-71a3-4d8e-98ac-48121f3fbf4f/1'] ); // THEN assert.equal(process.exitCode, 1, 'validate should have thrown an error'); // retrieve result assert.equal( validate['testInstance/testBU']?.journey.length, 0, 'should have not validated the journey' ); // get callouts const validateCallout = testUtils.getRestCallout( 'post', '/interaction/v1/interactions/validateAsync/%' ); // confirm created item assert.deepEqual( validateCallout, await testUtils.getExpectedJson('9999999', 'journey', 'validate-callout'), 'validate-payload JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Refresh ================', () => { it('Should refresh all active journeys'); it('Should refresh a specifc multi-step journey by key', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', { journey: ['testExisting_journey_Multistep'], }); // THEN assert.equal(process.exitCode, 0, 'refresh should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_journey_Multistep'], 'should have found the right journeys that need updating' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should refresh a specifc transactional send journey by key', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', { journey: ['testExisting_temail'], }); // THEN assert.equal(process.exitCode, 0, 'refresh should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_temail'], 'should have found the right journeys that need updating' ); assert.equal( testUtils.getAPIHistoryLength(), 37, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should refresh a specifc cross type journeys by key', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', { journey: ['testExisting_temail', 'testExisting_journey_Multistep'], }); // THEN assert.equal(process.exitCode, 0, 'refresh should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].journey, ['testExisting_temail', 'testExisting_journey_Multistep'], 'should have found the right journeys that need updating' ); assert.equal( testUtils.getAPIHistoryLength(), 42, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Audit ================', () => { it('Should show audit log of a transactional journey and version', async () => { const audit = await handler.audit('testInstance/testBU', { journey: ['testExisting_temail/2'], }); // THEN assert.equal(process.exitCode, 0, 'audit should not have thrown an error'); assert.deepEqual( audit['testInstance/testBU'].journey, ['testExisting_temail'], 'should have returned the right journeys' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should show audit log of a transactional journey with all its versions', async () => { const audit = await handler.audit('testInstance/testBU', { journey: ['testExisting_temail'], }); // THEN assert.equal(process.exitCode, 0, 'audit should not have thrown an error'); assert.deepEqual( audit['testInstance/testBU'].journey, ['testExisting_temail'], 'should have returned the right journeys' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not show audit log of a transactional journey with a too high version', async () => { const audit = await handler.audit('testInstance/testBU', { journey: ['testExisting_temail/99'], }); // THEN assert.equal(process.exitCode, 404, 'audit should have thrown an error'); assert.deepEqual( audit['testInstance/testBU'].journey, [], 'should have returned the right journeys' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should show audit log of a multi-step journey and version', async () => { const audit = await handler.audit('testInstance/testBU', { journey: ['testExisting_journey_Multistep/1'], }); // THEN assert.equal(process.exitCode, 0, 'audit should not have thrown an error'); assert.deepEqual( audit['testInstance/testBU'].journey, ['testExisting_journey_Multistep'], 'should have returned the right journeys' ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should show audit log of a multi-step journey with all its versions', async () => { const audit = await handler.audit('testInstance/testBU', { journey: ['testExisting_journey_Multistep'], }); // THEN assert.equal(process.exitCode, 0, 'audit should not have thrown an error'); assert.deepEqual( audit['testInstance/testBU'].journey, ['testExisting_journey_Multistep'], 'should have returned the right journeys' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should show audit log of a multi-step journey with all its versions via /*', async () => { const audit = await handler.audit('testInstance/testBU', { journey: ['testExisting_journey_Multistep'], }); // THEN assert.equal(process.exitCode, 0, 'audit should not have thrown an error'); assert.deepEqual( audit['testInstance/testBU'].journey, ['testExisting_journey_Multistep'], 'should have returned the right journeys' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.mobileKeyword.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: mobileKeyword', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a mobileKeyword', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['mobileKeyword']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.mobileKeyword ? Object.keys(result.mobileKeyword).length : 0, 1, 'only 1 mobileKeywords expected' ); assert.deepEqual( await testUtils.getActualJson( '4912312345678.TESTEXISTING_KEYWORD', 'mobileKeyword' ), await testUtils.getExpectedJson('9999999', 'mobileKeyword', 'get'), 'saved JSON was not equal expected' ); expect( await testUtils.getActualFile( '4912312345678.TESTEXISTING_KEYWORD', 'mobileKeyword', 'amp' ) ).to.equal(await testUtils.getExpectedFile('9999999', 'mobileKeyword', 'get', 'amp')); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create (but not update) a mobileKeyword', async () => { // WHEN await handler.deploy( 'testInstance/testBU', ['mobileKeyword'], ['4912312345678.TESTNEW_KEYWORD'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.mobileKeyword ? Object.keys(result.mobileKeyword).length : 0, 2, '2 mobileKeywords expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('4912312345678.TESTNEW_KEYWORD', 'mobileKeyword'), await testUtils.getExpectedJson('9999999', 'mobileKeyword', 'post-create'), 'returned JSON was not equal expected for insert mobileKeyword' ); expect( await testUtils.getActualFile( '4912312345678.TESTNEW_KEYWORD', 'mobileKeyword', 'amp' ) ).to.equal( await testUtils.getExpectedFile('9999999', 'mobileKeyword', 'post-create', 'amp') ); // confirm updated item // eslint-disable-next-line no-console console.log( 'Not testing UPDATE because the API only responds with an empty body unless there are errors in the request body' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not create a mobileKeyword with wrong type', async () => { // WHEN await handler.deploy( 'testInstance/testBU', ['mobileKeyword'], ['4912312345678.TESTNEW_KEYWORD_BLOCKED'] ); // THEN assert.equal(process.exitCode, 1, 'deploy should have thrown an error'); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a mobileKeyword template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'mobileKeyword', ['4912312345678.TESTEXISTING_KEYWORD'], 'testSourceMarket' ); // WHEN assert.equal(process.exitCode, 0, 'retrieveAsTemplate should not have thrown an error'); assert.equal( result.mobileKeyword ? Object.keys(result.mobileKeyword).length : 0, 1, 'only one item expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( '4912312345678.TESTEXISTING_KEYWORD', 'mobileKeyword' ), await testUtils.getExpectedJson('9999999', 'mobileKeyword', 'template'), 'returned template JSON was not equal expected' ); expect( await testUtils.getActualTemplateFile( '4912312345678.TESTEXISTING_KEYWORD', 'mobileKeyword', 'amp' ) ).to.equal( await testUtils.getExpectedFile('9999999', 'mobileKeyword', 'template', 'amp') ); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a mobileKeyword template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['mobileKeyword']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'mobileKeyword', ['4912312345678.TESTEXISTING_KEYWORD'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.mobileKeyword ? Object.keys(result.mobileKeyword).length : 0, 1, 'only one mobileKeyword expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( '4912312345678.TESTEXISTING_KEYWORD', 'mobileKeyword' ), await testUtils.getExpectedJson('9999999', 'mobileKeyword', 'template'), 'returned template JSON was not equal expected' ); expect( await testUtils.getActualTemplateFile( '4912312345678.TESTEXISTING_KEYWORD', 'mobileKeyword', 'amp' ) ).to.equal( await testUtils.getExpectedFile('9999999', 'mobileKeyword', 'template', 'amp') ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'mobileKeyword', ['4912312345678.TESTEXISTING_KEYWORD'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson( '4912312345678.TESTTEMPLATED_KEYWORD', 'mobileKeyword' ), await testUtils.getExpectedJson('9999999', 'mobileKeyword', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile( '4912312345678.TESTTEMPLATED_KEYWORD', 'mobileKeyword', 'amp' ) ).to.equal(await testUtils.getExpectedFile('9999999', 'mobileKeyword', 'build', 'amp')); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'mobileKeyword', '4912312345678.TESTEXISTING_KEYWORD' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN const fileList = await handler.getFilesToCommit( 'testInstance/testBU', 'mobileKeyword', ['4912312345678.TESTEXISTING_KEYWORD'] ); // THEN assert.equal(process.exitCode, 0, 'getFilesToCommit should not have thrown an error'); assert.equal(fileList.length, 2, 'expected only 2 file paths'); assert.equal( fileList[0].split('\\').join('/'), 'retrieve/testInstance/testBU/mobileKeyword/4912312345678.TESTEXISTING_KEYWORD.mobileKeyword-meta.json', 'wrong JSON path' ); assert.equal( fileList[1].split('\\').join('/'), 'retrieve/testInstance/testBU/mobileKeyword/4912312345678.TESTEXISTING_KEYWORD.mobileKeyword-meta.amp', 'wrong AMP path' ); return; }); }); }); ================================================ FILE: test/type.mobileMessage.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: mobileMessage', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a mobileMessage', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['mobileMessage']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.mobileMessage ? Object.keys(result.mobileMessage).length : 0, 1, 'only 1 mobileMessages expected' ); assert.deepEqual( await testUtils.getActualJson('NTIzOjc4OjA', 'mobileMessage'), await testUtils.getExpectedJson('9999999', 'mobileMessage', 'get'), 'saved JSON was not equal expected' ); expect(await testUtils.getActualFile('NTIzOjc4OjA', 'mobileMessage', 'amp')).to.equal( await testUtils.getExpectedFile('9999999', 'mobileMessage', 'get', 'amp') ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & update items', async () => { // WHEN await handler.deploy('testInstance/testBU', ['mobileMessage']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.mobileMessage ? Object.keys(result.mobileMessage).length : 0, 2, '2 mobileMessages expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('NTQ3Ojc4OjA', 'mobileMessage'), await testUtils.getExpectedJson('9999999', 'mobileMessage', 'post-create'), 'returned JSON was not equal expected for insert mobileMessage' ); expect(await testUtils.getActualFile('NTQ3Ojc4OjA', 'mobileMessage', 'amp')).to.equal( await testUtils.getExpectedFile('9999999', 'mobileMessage', 'post-create', 'amp') ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('NTIzOjc4OjA', 'mobileMessage'), await testUtils.getExpectedJson('9999999', 'mobileMessage', 'post-update'), // watch out - mobileMessage api wants put instead of patch for updates 'returned JSON was not equal expected for update mobileMessage' ); expect(await testUtils.getActualFile('NTIzOjc4OjA', 'mobileMessage', 'amp')).to.equal( await testUtils.getExpectedFile('9999999', 'mobileMessage', 'post-update', 'amp') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should NOT change the key during update with --changeKeyValue and instead fail due to missing support', async () => { // WHEN handler.setOptions({ changeKeyValue: 'updatedKey' }); await handler.deploy('testInstance/testBU', ['mobileMessage'], ['NTIzOjc4OjA']); // THEN assert.equal( process.exitCode, 1, 'deploy should have thrown an error due to lack of support' ); return; }); }); describe('Templating ================', () => { it('Should create a mobileMessage template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['mobileMessage']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'mobileMessage', ['NTIzOjc4OjA'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.mobileMessage ? Object.keys(result.mobileMessage).length : 0, 1, 'only one mobileMessage expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('NTIzOjc4OjA', 'mobileMessage'), await testUtils.getExpectedJson('9999999', 'mobileMessage', 'template'), 'returned template JSON was not equal expected' ); expect( await testUtils.getActualTemplateFile('NTIzOjc4OjA', 'mobileMessage', 'amp') ).to.equal( await testUtils.getExpectedFile('9999999', 'mobileMessage', 'template', 'amp') ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'mobileMessage', ['NTIzOjc4OjA'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('NTIzOjc4OjA', 'mobileMessage'), await testUtils.getExpectedJson('9999999', 'mobileMessage', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('NTIzOjc4OjA', 'mobileMessage', 'amp') ).to.equal(await testUtils.getExpectedFile('9999999', 'mobileMessage', 'build', 'amp')); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'mobileMessage', 'NTIzOjc4OjA' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN const fileList = await handler.getFilesToCommit( 'testInstance/testBU', 'mobileMessage', ['NTIzOjc4OjA'] ); // THEN assert.equal(process.exitCode, 0, 'getFilesToCommit should not have thrown an error'); assert.equal(fileList.length, 2, 'expected only 2 file paths'); assert.equal( fileList[0].split('\\').join('/'), 'retrieve/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.json', 'wrong JSON path' ); assert.equal( fileList[1].split('\\').join('/'), 'retrieve/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.amp', 'wrong AMP path' ); return; }); }); }); ================================================ FILE: test/type.query.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: query', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve all queries', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['query']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 5, 'only 5 queries expected' ); // normal test assert.deepEqual( await testUtils.getActualJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'get'), 'returned metadata with correct key was not equal expected' ); expect(await testUtils.getActualFile('testExisting_query', 'query', 'sql')).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'get', 'sql') ); // check if r__dataExtension_key was overwritten assert.deepEqual( await testUtils.getActualJson('testExisting_query2', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'get2'), 'returned metadata with wrong key was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should resolve shared dataExtensions in query when retrieved together with dataExtension', async () => { // WHEN // this test verifies the fix for: shared DEs not resolved if query+dataExtension is retrieved together await handler.retrieve('testInstance/testBU', ['dataExtension', 'query']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 5, 'only 5 queries expected' ); // verify that shared DE was resolved correctly in query (this is the key bug fix check) assert.deepEqual( await testUtils.getActualJson('testExisting_query_SharedDE', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'get_sharedDE'), 'returned metadata was not equal expected - shared DE should be resolved even when dataExtension is retrieved together with query' ); expect( await testUtils.getActualFile('testExisting_query_SharedDE', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'get_sharedDE', 'sql')); assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve one specific query by key', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['query'], ['testExisting_query']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'get'), 'returned metadata was not equal expected' ); expect(await testUtils.getActualFile('testExisting_query', 'query', 'sql')).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'get', 'sql') ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve one specific query via --like', async () => { // WHEN handler.setOptions({ like: { key: '%Existing_query' } }); await handler.retrieve('testInstance/testBU', ['query']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 5, '5 queries in cache expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'get'), 'returned metadata was not equal expected' ); expect(await testUtils.getActualFile('testExisting_query', 'query', 'sql')).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'get', 'sql') ); expect(await testUtils.getActualFile('testExisting_query2', 'query', 'sql')).to.not .exist; assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not retrieve any query via --like and key due to a mismatching filter', async () => { // WHEN handler.setOptions({ like: { key: 'NotExisting_query' } }); await handler.retrieve('testInstance/testBU', ['query']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 5, '5 queries in cache expected' ); expect(await testUtils.getActualFile('testExisting_query', 'query', 'sql')).to.not .exist; expect(await testUtils.getActualFile('testExisting_query2', 'query', 'sql')).to.not .exist; assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a query', async () => { // WHEN const resultDeploy = await handler.deploy( 'testInstance/testBU', ['query'], ['testNew_query', 'testExisting_query'] ); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); assert.equal( resultDeploy['testInstance/testBU']?.query ? Object.keys(resultDeploy['testInstance/testBU']?.query).length : 0, 2, 'two queries to be deployed' ); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 6, '6 queries expected in cache' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'post'), 'returned metadata was not equal expected for insert query' ); expect(await testUtils.getActualFile('testNew_query', 'query', 'sql')).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'post', 'sql') ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch'), 'returned metadata was not equal expected for insert query' ); expect(await testUtils.getActualFile('testExisting_query', 'query', 'sql')).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 7, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should deploy and execute with --execute', async () => { handler.setOptions({ execute: true }); // WHEN await handler.deploy( 'testInstance/testBU', ['query'], ['testExisting_query', 'testNew_query'] ); // THEN assert.equal( process.exitCode, 0, 'deploy with --execute should not have thrown an error' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch'), 'returned metadata was not equal expected for insert query' ); expect(await testUtils.getActualFile('testExisting_query', 'query', 'sql')).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('FixKeys ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should change the key during update with --changeKeyValue', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys'] ); handler.setOptions({ changeKeyValue: 'testExisting_query_fixedKeys', fromRetrieve: true, }); const deployed = await handler.deploy( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys'] ); // THEN assert.equal( process.exitCode, 0, 'deploy --changeKeyValue should not have thrown an error' ); const upsertCallout = testUtils.getRestCallout('patch', '/automation/v1/queries/%'); assert.equal( upsertCallout?.key, 'testExisting_query_fixedKeys', 'key in create callout was not as expected' ); assert.equal( Object.keys(deployed['testInstance/testBU'].query).length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( Object.keys(deployed['testInstance/testBU'].query)[0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should change the key during update with --changeKeyField', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys'] ); handler.setOptions({ changeKeyField: 'name', fromRetrieve: true }); const deployed = await handler.deploy( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys'] ); // THEN assert.equal( process.exitCode, 0, 'deploy --changeKeyValue should not have thrown an error' ); const upsertCallout = testUtils.getRestCallout('patch', '/automation/v1/queries/%'); assert.equal( upsertCallout?.key, 'testExisting_query_fixedKeys', 'key in create callout was not as expected' ); assert.equal( Object.keys(deployed['testInstance/testBU'].query).length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( Object.keys(deployed['testInstance/testBU'].query)[0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should change the key during update with --changeKeyField and --keySuffix', async () => { // WHEN await handler.retrieve( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeysSuffix'] ); handler.setOptions({ changeKeyField: 'name', keySuffix: '_DEV', fromRetrieve: true }); const deployed = await handler.deploy( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeysSuffix'] ); // THEN assert.equal( process.exitCode, 0, 'deploy --changeKeyValue --keySuffix should not have thrown an error' ); assert.equal( Object.keys(deployed['testInstance/testBU'].query).length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); const upsertCallout = testUtils.getRestCallout('patch', '/automation/v1/queries/%'); assert.equal( upsertCallout?.key, 'testExisting_query_fixedKeysSuff_DEV', 'key in create callout was not as expected' ); assert.equal( Object.keys(deployed['testInstance/testBU'].query)[0], 'testExisting_query_fixedKeysSuff_DEV', 'returned keys do not correspond to expected fixed keys' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeysSuff_DEV', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeysSuffix'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile( 'testExisting_query_fixedKeysSuff_DEV', 'query', 'sql' ) ).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeysSuffix', 'sql') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should change the key during create with and --keySuffix', async () => { handler.setOptions({ keySuffix: '_DEV' }); const deployed = await handler.deploy( 'testInstance/_ParentBU_', ['query'], ['testNew_query'] ); // THEN assert.equal(process.exitCode, 0, 'deploy --keySuffix should not have thrown an error'); assert.equal( Object.keys(deployed['testInstance/_ParentBU_'].query).length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( Object.keys(deployed['testInstance/_ParentBU_'].query)[0], 'testNew_query_DEV', 'returned keys do not correspond to expected fixed keys' ); const createCallout = testUtils.getRestCallout('post', '/automation/v1/queries/'); assert.equal( createCallout?.key, 'testNew_query_DEV', 'key in create callout was not as expected' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testNew_query_DEV', 'query', '_ParentBU_'), await testUtils.getExpectedJson('1111111', 'query', 'patch_keySuffix'), 'returned metadata was not equal expected for update query' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should run fixKeys but not find fixable keys and hence stop', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false } }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['query'], ['testExisting_query'] ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // check which keys were fixed assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 0, 'expected to find no keys to be fixed' ); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, 1, 'one query expected' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key WITHOUT re-retrieving dependent types', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false } }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys', 'testExisting_query'] ); assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['query'][0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key with --keySuffix WITHOUT re-retrieving dependent types', async () => { // WHEN handler.setOptions({ keySuffix: '_DEV', skipInteraction: { fixKeysReretrieve: false }, }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeysSuffix', 'testExisting_query'] ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); const upsertCallout = testUtils.getRestCallout('patch', '/automation/v1/queries/%'); assert.equal( upsertCallout?.key, 'testExisting_query_fixedKeysSuff_DEV', 'key in create callout was not as expected' ); assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['query'][0], 'testExisting_query_fixedKeysSuff_DEV', 'returned keys do not correspond to expected fixed keys' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeysSuff_DEV', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeysSuffix'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile( 'testExisting_query_fixedKeysSuff_DEV', 'query', 'sql' ) ).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeysSuffix', 'sql') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key WITHOUT re-retrieving dependent types and then --execute', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: false }, execute: true }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys', 'testExisting_query'] ); assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['query'][0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal( process.exitCode, 0, 'fixKeys with --execute should not have thrown an error' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key AND re-retrieve dependent types', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: true } }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys', 'testExisting_query'] ); assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['query'][0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 48, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys by key AND re-retrieve dependent types and then --execute', async () => { // WHEN handler.setOptions({ skipInteraction: { fixKeysReretrieve: true }, execute: true }); const resultFixKeys = await handler.fixKeys( 'testInstance/testBU', ['query'], ['testExisting_query_fixKeys', 'testExisting_query'] ); assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['query'][0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal( process.exitCode, 0, 'fixKeys with --execute should not have thrown an error' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 50, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should fixKeys via --like WITHOUT re-retrieving dependent types', async () => { // WHEN handler.setOptions({ like: { key: 'testExisting_query_f%' }, skipInteraction: { fixKeysReretrieve: false }, }); const resultFixKeys = await handler.fixKeys('testInstance/testBU', ['query']); assert.equal( resultFixKeys['testInstance/testBU']['query'].length, 2, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( resultFixKeys['testInstance/testBU']['query'][0], 'testExisting_query_fixedKeys', 'returned keys do not correspond to expected fixed keys' ); // THEN assert.equal(process.exitCode, 0, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for update query' ); expect( await testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql')); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a query template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'query', ['testExisting_query'], 'testSourceMarket' ); // WHEN assert.equal(process.exitCode, 0, 'retrieveAsTemplate should not have thrown an error'); assert.equal( result.query ? Object.keys(result.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // THEN await handler.buildDefinition( 'testInstance/testBU', 'query', ['testExisting_query'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should warn about shared dataExtension in _ParentBU_ when running buildTemplate with --dependencies on child BU', async () => { // Retrieve shared DEs from _ParentBU_ to disk first await handler.retrieve('testInstance/_ParentBU_', ['dataExtension']); assert.equal( process.exitCode, 0, '_ParentBU_ retrieve should not have thrown an error' ); const expectedApiCallsParentBURetrieve = 4; assert.equal( testUtils.getAPIHistoryLength(), expectedApiCallsParentBURetrieve, 'Unexpected number of requests for _ParentBU_ dataExtension retrieve' ); // Retrieve query from child BU (testBU) await handler.retrieve('testInstance/testBU', ['query']); assert.equal( process.exitCode, 0, 'testBU query retrieve should not have thrown an error' ); const expectedApiCallsTestBURetrieve = 5; assert.equal( testUtils.getAPIHistoryLength() - expectedApiCallsParentBURetrieve, expectedApiCallsTestBURetrieve, 'Unexpected number of requests for testBU query retrieve' ); // Run buildTemplate with --dependencies: shared DE must show a warning, not be included in result handler.setOptions({ dependencies: true, skipInteraction: true }); const templateResult = await handler.buildTemplate( 'testInstance/testBU', 'query', ['testExisting_query_SharedDE'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // Verify query was templated assert.equal( templateResult.query ? templateResult.query.length : 0, 1, 'expected one query to be templated' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query_SharedDE', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template_sharedDE'), 'returned query template JSON was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query_SharedDE', 'query', 'sql') ).to.equal( await testUtils.getExpectedFile('9999999', 'query', 'template_sharedDE', 'sql') ); // Verify shared DE was NOT included in template result (only a warning should be shown) assert.equal( templateResult.dataExtension ? templateResult.dataExtension.length : 0, 0, 'shared DE should not be included in the child BU template result - only a warning should be shown' ); return; }); it('Should create a query template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['query']); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/testBU', 'query', ['testExisting_query'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.query ? Object.keys(result.query).length : 0, 1, 'only one query expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'template'), 'returned template JSON of buildTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'template', 'sql')); // THEN await handler.buildDefinition( 'testInstance/testBU', 'query', ['testExisting_query'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_query', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_query', 'query', 'sql') ).to.equal(await testUtils.getExpectedFile('9999999', 'query', 'build', 'sql')); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'query', 'testExisting_query' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN const fileList = await handler.getFilesToCommit('testInstance/testBU', 'query', [ 'testExisting_query', ]); // THEN assert.equal(process.exitCode, 0, 'getFilesToCommit should not have thrown an error'); assert.equal(fileList.length, 2, 'expected only 2 file paths'); assert.equal( fileList[0].split('\\').join('/'), 'retrieve/testInstance/testBU/query/testExisting_query.query-meta.json', 'wrong JSON path' ); assert.equal( fileList[1].split('\\').join('/'), 'retrieve/testInstance/testBU/query/testExisting_query.query-meta.sql', 'wrong JSON path' ); return; }); }); describe('Execute ================', () => { it('Should start a query by key', async () => { const executedKeys = await handler.execute( 'testInstance/testBU', ['query'], ['testExisting_query'] ); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( executedKeys['testInstance/testBU']?.query?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( executedKeys['testInstance/testBU']?.query[0], 'testExisting_query', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should start a query selected via --like', async () => { handler.setOptions({ like: { key: 'testExist%query' } }); const executedKeys = await handler.execute('testInstance/testBU', ['query']); assert.equal(process.exitCode, 0, 'execute should not have thrown an error'); assert.equal( executedKeys['testInstance/testBU']?.query?.length, 1, 'returned number of keys does not correspond to number of expected fixed keys' ); assert.equal( executedKeys['testInstance/testBU']?.query[0], 'testExisting_query', 'returned keys do not correspond to expected fixed keys' ); return; }); it('Should not start executing a query because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting%' } }); const executedKeys = await handler.execute( 'testInstance/testBU', ['query'], ['testExisting_query'] ); assert.equal(process.exitCode, 1, 'execute should have thrown an error'); assert.equal( Object.keys(executedKeys).length, 0, 'query was not supposed to be executed' ); return; }); }); }); ================================================ FILE: test/type.script.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: script', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve all scripts', async () => { // WHEN const retrieve = await handler.retrieve('testInstance/testBU', ['script']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.equal( retrieve['testInstance/testBU'].script ? Object.keys(retrieve['testInstance/testBU'].script).length : 0, 5, 'only 5 scripts expected in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 5, 'only 5 scripts expected' ); // normal test assert.deepEqual( await testUtils.getActualJson('testExisting_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get'), 'returned metadata with correct key was not equal expected' ); expect(await testUtils.getActualFile('testExisting_script', 'script', 'html')).to.not .exist; expect(await testUtils.getActualFile('testExisting_script', 'script', 'ssjs')).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs') ); // test with no script tag assert.deepEqual( await testUtils.getActualJson('testExisting_script_noScriptTag', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get_noScriptTag'), 'returned metadata was not equal expected' ); expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_noScriptTag', 'html') ); expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'ssjs') ).to.not.exist; // test with ampscript assert.deepEqual( await testUtils.getActualJson('testExisting_script_ampscript', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get_ampscript'), 'returned metadata was not equal expected' ); expect( await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_ampscript', 'html') ); expect(await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'ssjs')) .to.not.exist; // test with mixed code (ampscript inside of ssjs) assert.deepEqual( await testUtils.getActualJson('testExisting_script_ampincluded', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get_ampincluded'), 'returned metadata was not equal expected' ); expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'ssjs') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_ampincluded', 'html') ); // test with mixed code (ssjs and ampscript side-by-side) assert.deepEqual( await testUtils.getActualJson('testExisting_script_mixed', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get_mixed'), 'returned metadata was not equal expected' ); expect( await testUtils.getActualFile('testExisting_script_mixed', 'script', 'html') ).to.equal(await testUtils.getExpectedFile('9999999', 'script', 'get_mixed', 'html')); expect(await testUtils.getActualFile('testExisting_script_mixed', 'script', 'ssjs')).to .not.exist; assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve one specific script by key', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['script'], ['testExisting_script']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 1, 'only one script expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get'), 'returned metadata was not equal expected' ); expect(await testUtils.getActualFile('testExisting_script', 'script', 'html')).to.not .exist; expect(await testUtils.getActualFile('testExisting_script', 'script', 'ssjs')).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs') ); expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'json') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'ssjs') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'html') ).to.not.exist; assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve one specific script via --like', async () => { // WHEN handler.setOptions({ like: { key: '%Existing_script' } }); await handler.retrieve('testInstance/testBU', ['script']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 5, '5 scripts in cache expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'get'), 'returned metadata was not equal expected' ); expect(await testUtils.getActualFile('testExisting_script', 'script', 'ssjs')).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs') ); expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'json') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'ssjs') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'html') ).to.not.exist; assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not retrieve any script via --like and key due to a mismatching filter', async () => { // WHEN handler.setOptions({ like: { key: 'NotExisting_script' } }); await handler.retrieve('testInstance/testBU', ['script']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 5, '5 scripts in cache expected' ); expect(await testUtils.getActualFile('testExisting_script', 'script', 'ssjs')).to.not .exist; assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a script', async () => { // WHEN await handler.deploy('testInstance/testBU', ['script']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 6, '6 scripts expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'post'), 'returned metadata was not equal expected for insert script' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'patch'), 'returned metadata was not equal expected for insert script' ); expect(await testUtils.getActualFile('testExisting_script', 'script', 'html')).to.not .exist; expect(await testUtils.getActualFile('testExisting_script', 'script', 'ssjs')).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'patch', 'ssjs') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a script template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'script', ['testExisting_script'], 'testSourceMarket' ); // WHEN assert.equal(process.exitCode, 0, 'retrieveAsTemplate should not have thrown an error'); assert.equal( result.script ? Object.keys(result.script).length : 0, 1, 'only one script expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'template'), 'returned template JSON of retrieveAsTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_script', 'script', 'ssjs') ).to.equal(await testUtils.getExpectedFile('9999999', 'script', 'template', 'ssjs')); // THEN await handler.buildDefinition( 'testInstance/testBU', 'script', ['testExisting_script'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_script', 'script', 'ssjs') ).to.equal(await testUtils.getExpectedFile('9999999', 'script', 'build', 'ssjs')); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a script template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['script']); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/testBU', 'script', ['testExisting_script'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.script ? Object.keys(result.script).length : 0, 1, 'only one script expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'template'), 'returned template JSON of buildTemplate was not equal expected' ); expect( await testUtils.getActualTemplateFile('testExisting_script', 'script', 'ssjs') ).to.equal(await testUtils.getExpectedFile('9999999', 'script', 'template', 'ssjs')); // THEN await handler.buildDefinition( 'testInstance/testBU', 'script', ['testExisting_script'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_script', 'script'), await testUtils.getExpectedJson('9999999', 'script', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_script', 'script', 'ssjs') ).to.equal(await testUtils.getExpectedFile('9999999', 'script', 'build', 'ssjs')); assert.equal( testUtils.getAPIHistoryLength(), 2, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a script template via buildTemplate with --dependencies', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['script', 'asset']); assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); handler.setOptions({ dependencies: true, skipInteraction: true }); // GIVEN there is a template const templatedItems = await handler.buildTemplate( 'testInstance/testBU', 'script', ['testExisting_script_ampscript'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.deepEqual( Object.keys(templatedItems), ['asset', 'script'], 'expected specific types to be templated' ); // script assert.deepEqual( templatedItems.script.map((item) => item.key), ['{{{prefix}}}script_ampscript'], 'expected specific scripts to be templated' ); // asset assert.deepEqual( templatedItems.asset.map((item) => item.customerKey), [ '{{{prefix}}}asset_htmlblock', '{{{prefix}}}htmlblock 3 spaces', '{{{prefix}}}htmlblock1', '{{{prefix}}}htmlblock2', ], 'expected specific assets to be templated' ); }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'script', 'testExisting_script' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN const fileList = await handler.getFilesToCommit('testInstance/testBU', 'script', [ 'testExisting_script', ]); // THEN assert.equal(process.exitCode, 0, 'getFilesToCommit should not have thrown an error'); assert.equal(fileList.length, 3, 'expected only 3 file paths (html, json, ssjs)'); assert.equal( fileList[0].split('\\').join('/'), 'retrieve/testInstance/testBU/script/testExisting_script.script-meta.json', 'wrong JSON path' ); assert.equal( fileList[1].split('\\').join('/'), 'retrieve/testInstance/testBU/script/testExisting_script.script-meta.ssjs', 'wrong SSJS path' ); assert.equal( fileList[2].split('\\').join('/'), 'retrieve/testInstance/testBU/script/testExisting_script.script-meta.html', 'wrong HTML path' ); return; }); }); describe('Execute ================', () => {}); describe('ReplaceContentBlockByX ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { script: null, }, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].script, [ 'testExisting_script_ampscript', 'testExisting_script_ampincluded', 'testExisting_script_mixed', ], 'should have found the right scripts that need updating' ); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 5, 'only 5 scripts expected' ); // check if conversions happened expect( await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'html') ).to.equal( await testUtils.getExpectedFile( '9999999', 'script', 'get_ampscript-rcb-name', 'html' ) ); expect(await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'ssjs')) .to.not.exist; expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'html') ).to.equal( await testUtils.getExpectedFile( '9999999', 'script', 'get_ampincluded-rcb-name', 'html' ) ); expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'ssjs') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_mixed', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_mixed-rcb-name', 'html') ); expect(await testUtils.getActualFile('testExisting_script_mixed', 'script', 'ssjs')).to .not.exist; assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { script: null, }, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].script, ['testExisting_script_ampscript', 'testExisting_script_mixed'], 'should have found the right scripts that need updating' ); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 5, 'only 5 scripts expected' ); // check if conversions happened expect( await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_ampscript-rcb-id', 'html') ); expect(await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'ssjs')) .to.not.exist; expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'html') ).to.equal( await testUtils.getExpectedFile( '9999999', 'script', 'get_ampincluded-rcb-id', 'html' ) ); expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'ssjs') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_mixed', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_mixed-rcb-id', 'html') ); expect(await testUtils.getActualFile('testExisting_script_mixed', 'script', 'ssjs')).to .not.exist; assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { script: null, }, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].script, ['testExisting_script_ampscript', 'testExisting_script_ampincluded'], 'should have found the right scripts that need updating' ); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, 5, 'only 5 scripts expected' ); // check if conversions happened expect( await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'html') ).to.equal( await testUtils.getExpectedFile( '9999999', 'script', 'get_ampscript-rcb-key', 'html' ) ); expect(await testUtils.getActualFile('testExisting_script_ampscript', 'script', 'ssjs')) .to.not.exist; expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'html') ).to.equal( await testUtils.getExpectedFile( '9999999', 'script', 'get_ampincluded-rcb-key', 'html' ) ); expect( await testUtils.getActualFile('testExisting_script_ampincluded', 'script', 'ssjs') ).to.not.exist; expect( await testUtils.getActualFile('testExisting_script_mixed', 'script', 'html') ).to.equal( await testUtils.getExpectedFile('9999999', 'script', 'get_mixed-rcb-key', 'html') ); expect(await testUtils.getActualFile('testExisting_script_mixed', 'script', 'ssjs')).to .not.exist; assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.sendClassification.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: sendClassification', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a sendClassification', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['sendClassification']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.sendClassification ? Object.keys(result.sendClassification).length : 0, 3, 'only 3 sendClassifications expected' ); assert.deepEqual( await testUtils.getActualJson( 'testExisting_sendClassification', 'sendClassification' ), await testUtils.getExpectedJson('9999999', 'sendClassification', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a sendClassification', async () => { // WHEN await handler.deploy('testInstance/testBU', ['sendClassification']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.sendClassification ? Object.keys(result.sendClassification).length : 0, 4, 'two sendClassifications expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_sendClassification', 'sendClassification'), await testUtils.getExpectedJson('9999999', 'sendClassification', 'post'), 'returned new-JSON was not equal expected for insert sendClassification' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson( 'testExisting_sendClassification', 'sendClassification' ), await testUtils.getExpectedJson('9999999', 'sendClassification', 'patch'), 'returned existing-JSON was not equal expected for update sendClassification' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 7, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a sendClassification template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['sendClassification']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'sendClassification', ['testExisting_sendClassification'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.sendClassification ? Object.keys(result.sendClassification).length : 0, 1, 'only one sendClassification expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_sendClassification', 'sendClassification' ), await testUtils.getExpectedJson('9999999', 'sendClassification', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'sendClassification', ['testExisting_sendClassification'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson( 'testTemplated_sendClassification', 'sendClassification' ), await testUtils.getExpectedJson('9999999', 'sendClassification', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'sendClassification', 'testExisting_sendClassification' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); }); ================================================ FILE: test/type.senderProfile.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: senderProfile', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a senderProfile', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['senderProfile']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.senderProfile ? Object.keys(result.senderProfile).length : 0, 3, '3 senderProfiles expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_senderProfile', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a senderProfile', async () => { // WHEN await handler.deploy('testInstance/testBU', ['senderProfile']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.senderProfile ? Object.keys(result.senderProfile).length : 0, 4, '4 senderProfiles expected' ); // check callouts const createCallout = testUtils.getRestCallout( 'post', '/messaging/v1/domainverification/' ); assert.deepEqual( createCallout, { domain: 'joern.berkefeld.New@accenture.com' }, 'unexecpted payload for create callout' ); // confirm created domainVerification item assert.deepEqual( await testUtils.getActualJson( 'joern.berkefeld.New@accenture.com', 'domainVerification' ), await testUtils.getExpectedJson('9999999', 'domainVerification', 'create'), 'returned new-JSON was not equal expected for insert domainVerification' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_senderProfile', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'post'), 'returned new-JSON was not equal expected for insert senderProfile' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_senderProfile', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'patch'), 'returned existing-JSON was not equal expected for update senderProfile' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a senderProfile template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['senderProfile']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'senderProfile', ['testExisting_senderProfile'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.senderProfile ? Object.keys(result.senderProfile).length : 0, 1, 'only one senderProfile expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_senderProfile', 'senderProfile' ), await testUtils.getExpectedJson('9999999', 'senderProfile', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'senderProfile', ['testExisting_senderProfile'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_senderProfile', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a senderProfile template via buildTemplate with --dependencies', async () => { // download first before we test buildTemplate handler.setOptions({ dependencies: true, retrieve: true }); assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // GIVEN there is a template const templatedItems = await handler.buildTemplate( 'testInstance/testBU', 'senderProfile', ['Default', 'testExisting_senderProfile', 'testExisting_senderProfile_rcb'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.deepEqual( Object.keys(templatedItems), ['asset', 'domainVerification', 'senderProfile'], 'expected specific types to be templated' ); // asset assert.deepEqual( templatedItems.asset.map((item) => item.customerKey), [ '{{{prefix}}}asset_htmlblock', '{{{prefix}}}htmlblock 3 spaces', '{{{prefix}}}htmlblock1', '{{{prefix}}}htmlblock2', ], 'expected specific assets to be templated' ); // domainVerification assert.deepEqual( templatedItems.domainVerification.map((item) => item.domain), ['joern.berkefeld+test@accenture.com', 'joern.berkefeld@accenture.com'], 'expected specific domainVerifications to be templated' ); // senderProfile assert.deepEqual( templatedItems.senderProfile.map((item) => item.CustomerKey), ['Default', '{{{prefix}}}senderProfile', '{{{prefix}}}senderProfile_rcb'], 'expected specific senderProfiles to be templated' ); }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'senderProfile', 'testExisting_senderProfile' ); // THEN assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); describe('ReplaceContentBlockByX ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { senderProfile: null, }, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_senderProfile_rcb', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-name'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { senderProfile: null, }, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right senderProfiles that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_senderProfile_rcb', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-id'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { senderProfile: null, }, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].senderProfile, ['testExisting_senderProfile_rcb'], 'should have found the right assets that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_senderProfile_rcb', 'senderProfile'), await testUtils.getExpectedJson('9999999', 'senderProfile', 'get-rcb-key'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.transactionalEmail.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: transactionalEmail', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a transactionalEmail', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['transactionalEmail']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.transactionalEmail ? Object.keys(result.transactionalEmail).length : 0, 3, 'unexpected number of transactionalEmail' ); assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a transactionalEmail', async () => { // WHEN await handler.deploy('testInstance/testBU', ['transactionalEmail']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.transactionalEmail ? Object.keys(result.transactionalEmail).length : 0, 4, 'unexpected number of transactionalEmails' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_temail', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'post'), 'returned JSON was not equal expected for insert transactionalEmail' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_temail', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'patch'), 'returned JSON was not equal expected for update transactionalEmail' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should NOT change the key during update with --changeKeyValue and instead fail due to missing support', async () => { // WHEN handler.setOptions({ changeKeyValue: 'updatedKey' }); await handler.deploy( 'testInstance/testBU', ['transactionalEmail'], ['testExisting_temail'] ); // THEN assert.equal( process.exitCode, 1, 'deploy should have thrown an error due to lack of support' ); return; }); }); describe('Templating ================', () => { // it.skip('Should create a transactionalEmail template via retrieveAsTemplate and build it'); it('Should create a transactionalEmail template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['transactionalEmail']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'transactionalEmail', ['testExisting_temail'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.transactionalEmail ? Object.keys(result.transactionalEmail).length : 0, 1, 'only one transactionalEmail expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_temail', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'transactionalEmail', ['testExisting_temail'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_temail', 'transactionalEmail'), await testUtils.getExpectedJson('9999999', 'transactionalEmail', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'transactionalEmail', 'testExisting_temail' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); }); ================================================ FILE: test/type.transactionalPush.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: transactionalPush', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a transactionalPush', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['transactionalPush']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.transactionalPush ? Object.keys(result.transactionalPush).length : 0, 1, 'only one transactionalPush expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_tpush', 'transactionalPush'), await testUtils.getExpectedJson('9999999', 'transactionalPush', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a transactionalPush', async () => { // WHEN await handler.deploy('testInstance/testBU', ['transactionalPush']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.transactionalPush ? Object.keys(result.transactionalPush).length : 0, 2, 'two transactionalPushs expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_tpush', 'transactionalPush'), await testUtils.getExpectedJson('9999999', 'transactionalPush', 'post'), 'returned JSON was not equal expected for insert transactionalPush' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_tpush', 'transactionalPush'), await testUtils.getExpectedJson('9999999', 'transactionalPush', 'patch'), 'returned JSON was not equal expected for update transactionalPush' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should NOT change the key during update with --changeKeyValue and instead fail due to missing support', async () => { // WHEN handler.setOptions({ changeKeyValue: 'updatedKey' }); await handler.deploy( 'testInstance/testBU', ['transactionalPush'], ['testExisting_tpush'] ); // THEN assert.equal( process.exitCode, 1, 'deploy should have thrown an error due to lack of support' ); return; }); }); describe('Templating ================', () => { // it.skip('Should create a transactionalPush template via retrieveAsTemplate and build it'); it('Should create a transactionalPush template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['transactionalPush']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'transactionalPush', ['testExisting_tpush'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.transactionalPush ? Object.keys(result.transactionalPush).length : 0, 1, 'only one transactionalPush expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_tpush', 'transactionalPush'), await testUtils.getExpectedJson('9999999', 'transactionalPush', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'transactionalPush', ['testExisting_tpush'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_tpush', 'transactionalPush'), await testUtils.getExpectedJson('9999999', 'transactionalPush', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { // TODO: add this test it('Should delete the item'); // , async () => { // // WHEN // const isDeleted = await handler.deleteByKey('testInstance/testBU', 'mobileKeyword', 'testExisting_keyword'); // // THEN // assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); // assert.equal(isDeleted, true, 'should have deleted the item'); // return; // }); }); }); ================================================ FILE: test/type.transactionalSMS.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: transactionalSMS', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a transactionalSMS', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['transactionalSMS']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.transactionalSMS ? Object.keys(result.transactionalSMS).length : 0, 1, 'only one transactionalSMS expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_tsms', 'transactionalSMS'), await testUtils.getExpectedJson('9999999', 'transactionalSMS', 'get'), 'returned JSON was not equal expected' ); expect( await testUtils.getActualFile('testExisting_tsms', 'transactionalSMS', 'amp') ).to.equal( await testUtils.getExpectedFile('9999999', 'transactionalSMS', 'get', 'amp') ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a transactionalSMS', async () => { // WHEN await handler.deploy('testInstance/testBU', ['transactionalSMS']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.transactionalSMS ? Object.keys(result.transactionalSMS).length : 0, 2, 'two transactionalSMSs expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_tsms', 'transactionalSMS'), await testUtils.getExpectedJson('9999999', 'transactionalSMS', 'post'), 'returned JSON was not equal expected for insert transactionalSMS' ); expect( await testUtils.getActualFile('testNew_tsms', 'transactionalSMS', 'amp') ).to.equal( await testUtils.getExpectedFile('9999999', 'transactionalSMS', 'post', 'amp') ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_tsms', 'transactionalSMS'), await testUtils.getExpectedJson('9999999', 'transactionalSMS', 'patch'), 'returned JSON was not equal expected for update transactionalSMS' ); expect( await testUtils.getActualFile('testExisting_tsms', 'transactionalSMS', 'amp') ).to.equal( await testUtils.getExpectedFile('9999999', 'transactionalSMS', 'patch', 'amp') ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should NOT change the key during update with --changeKeyValue and instead fail due to missing support', async () => { // WHEN handler.setOptions({ changeKeyValue: 'updatedKey' }); await handler.deploy( 'testInstance/testBU', ['transactionalSMS'], ['testExisting_tsms'] ); // THEN assert.equal( process.exitCode, 1, 'deploy should have thrown an error due to lack of support' ); return; }); }); describe('Templating ================', () => { // it.skip('Should create a transactionalSMS template via retrieveAsTemplate and build it'); it('Should create a transactionalSMS template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['transactionalSMS']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'transactionalSMS', ['testExisting_tsms'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.transactionalSMS ? Object.keys(result.transactionalSMS).length : 0, 1, 'only one transactionalSMS expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_tsms', 'transactionalSMS'), await testUtils.getExpectedJson('9999999', 'transactionalSMS', 'template'), 'returned template JSON was not equal expected' ); expect( await testUtils.getActualTemplateFile( 'testExisting_tsms', 'transactionalSMS', 'amp' ) ).to.equal( await testUtils.getExpectedFile('9999999', 'transactionalSMS', 'template', 'amp') ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'transactionalSMS', ['testExisting_tsms'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_tsms', 'transactionalSMS'), await testUtils.getExpectedJson('9999999', 'transactionalSMS', 'build'), 'returned deployment JSON was not equal expected' ); expect( await testUtils.getActualDeployFile('testTemplated_tsms', 'transactionalSMS', 'amp') ).to.equal( await testUtils.getExpectedFile('9999999', 'transactionalSMS', 'build', 'amp') ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { // TODO: add this test it('Should delete the item'); // , async () => { // // WHEN // const isDeleted = await handler.deleteByKey('testInstance/testBU', 'mobileKeyword', 'testExisting_keyword'); // // THEN // assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); // assert.equal(isDeleted, true, 'should have deleted the item'); // return; // }); }); describe('CI/CD ================', () => { // TODO: add this test it('Should return a list of files based on their type and key'); // , async () => { // // WHEN // const fileList = await handler.getFilesToCommit( // 'testInstance/testBU', // 'mobileKeyword', // ['testExisting_keyword'] // ); // // THEN // assert.equal( // process.exitCode, // false, // 'getFilesToCommit should not have thrown an error' // ); // assert.equal(fileList.length, 2, 'expected only 2 file paths'); // assert.equal( // fileList[0].split('\\').join('/'), // 'retrieve/testInstance/testBU/mobileKeyword/testExisting_keyword.mobileKeyword-meta.json', // 'wrong JSON path' // ); // assert.equal( // fileList[1].split('\\').join('/'), // 'retrieve/testInstance/testBU/mobileKeyword/testExisting_keyword.mobileKeyword-meta.amp', // 'wrong AMP path' // ); // return; // }); }); }); ================================================ FILE: test/type.triggeredSend.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: triggeredSend', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a triggeredSend', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['triggeredSend']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.triggeredSend ? Object.keys(result.triggeredSend).length : 0, 2, 'only 2 triggeredSend expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_triggeredSend', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a triggeredSend', async () => { // WHEN await handler.deploy('testInstance/testBU', ['triggeredSend']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.triggeredSend ? Object.keys(result.triggeredSend).length : 0, 3, 'two triggeredSends expected' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_triggeredSend', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'post'), 'returned JSON was not equal expected for insert triggeredSend' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_triggeredSend', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'patch'), 'returned JSON was not equal expected for update triggeredSend' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a triggeredSend template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['triggeredSend']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'triggeredSend', ['testExisting_triggeredSend'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.triggeredSend ? Object.keys(result.triggeredSend).length : 0, 1, 'only one triggeredSend expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_triggeredSend', 'triggeredSend' ), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'triggeredSend', ['testExisting_triggeredSend'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_triggeredSend', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 10, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should create a script template via buildTemplate with --dependencies', async () => { // download first before we test buildTemplate handler.setOptions({ dependencies: true, retrieve: true }); // GIVEN there is a template const templatedItems = await handler.buildTemplate( 'testInstance/testBU', 'triggeredSend', ['testExisting_triggeredSend', 'testExisting_triggeredSend_rcb'], ['testSourceMarket'] ); // WHEN assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.deepEqual( Object.keys(templatedItems), [ 'asset', 'domainVerification', 'sendClassification', 'senderProfile', 'triggeredSend', ], 'expected specific types to be templated' ); // triggeredSend assert.deepEqual( templatedItems.triggeredSend.map((item) => item.CustomerKey), ['{{{prefix}}}triggeredSend', '{{{prefix}}}triggeredSend_rcb'], 'expected specific triggeredSends to be templated' ); // sendClassification assert.deepEqual( templatedItems.sendClassification.map((item) => item.CustomerKey), ['{{{prefix}}}sendClassification'], 'expected specific sendClassifications to be templated' ); // senderProfile assert.deepEqual( templatedItems.senderProfile.map((item) => item.CustomerKey), ['{{{prefix}}}senderProfile', '{{{prefix}}}senderProfile_rcb'], 'expected specific senderProfiles to be templated' ); // domainVerification assert.deepEqual( templatedItems.domainVerification.map((item) => item.domain), ['joern.berkefeld+test@accenture.com', 'joern.berkefeld@accenture.com'], 'expected specific domainVerification to be templated' ); // asset assert.deepEqual( templatedItems.asset.map((item) => item.customerKey), [ '{{{prefix}}}asset_htmlblock', '{{{prefix}}}htmlblock 3 spaces', '{{{prefix}}}htmlblock1', '{{{prefix}}}htmlblock2', ], 'expected specific assets to be templated' ); }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'triggeredSend', 'testExisting_triggeredSend' ); // THEN assert.equal(process.exitCode, 0, 'delete should not have thrown an error'); assert.equal(isDeleted, true, 'should have deleted the item'); return; }); }); describe('Refresh ================', () => { it('Should refresh all active triggeredSend', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', { triggeredSend: null, }); // THEN assert.equal(process.exitCode, 0, 'refresh should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].triggeredSend, ['testExisting_triggeredSend', 'testExisting_triggeredSend_rcb'], 'should have found the right triggeredSends that need updating' ); assert.equal( testUtils.getAPIHistoryLength(), 15, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should refresh a specifc triggeredSend by key', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', { triggeredSend: ['testExisting_triggeredSend'], }); // THEN assert.equal(process.exitCode, 0, 'refresh should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].triggeredSend, ['testExisting_triggeredSend'], 'should have found the right triggeredSends that need updating' ); assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should refresh 2 triggeredSend by key', async () => { // WHEN const replace = await handler.refresh('testInstance/testBU', { triggeredSend: ['testExisting_triggeredSend', 'testExisting_triggeredSend_rcb'], }); // THEN assert.equal(process.exitCode, 0, 'refresh should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].triggeredSend, ['testExisting_triggeredSend', 'testExisting_triggeredSend_rcb'], 'should have found the right triggeredSends that need updating' ); assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Start (Execute) ================', () => { it('Should start a triggeredSend by key'); }); describe('Pause ================', () => { it('Should pause a triggeredSend by key'); }); describe('ReplaceContentBlockByX ================', () => { it('Should replace references with ContentBlockByName w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { triggeredSend: null, }, 'name' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].triggeredSend, ['testExisting_triggeredSend_rcb'], 'should have found the right triggeredSends that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_triggeredSend_rcb', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'get-rcb-name'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockById w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { triggeredSend: null, }, 'id' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].triggeredSend, ['testExisting_triggeredSend_rcb'], 'should have found the right triggeredSends that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_triggeredSend_rcb', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'get-rcb-id'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should replace references with ContentBlockByKey w/o deploy', async () => { handler.setOptions({ skipDeploy: true }); // WHEN const replace = await handler.replaceCbReference( 'testInstance/testBU', { triggeredSend: null, }, 'key' ); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // retrieve result assert.deepEqual( replace['testInstance/testBU'].triggeredSend, ['testExisting_triggeredSend_rcb'], 'should have found the right assets that need updating' ); // check if conversions happened assert.deepEqual( await testUtils.getActualJson('testExisting_triggeredSend_rcb', 'triggeredSend'), await testUtils.getExpectedJson('9999999', 'triggeredSend', 'get-rcb-key'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.triggeredSendSummary.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: triggeredSendSummary', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a triggeredSendSummary', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['triggeredSendSummary']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.triggeredSendSummary ? Object.keys(result.triggeredSendSummary).length : 0, 1, 'only 1 triggeredSendSummary expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_triggeredSend', 'triggeredSendSummary'), await testUtils.getExpectedJson('9999999', 'triggeredSendSummary', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 3, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.user.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; const expect = chai.expect; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); const file = chaiFiles.file; import File from '../lib/util/file.js'; describe('type: user', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a user', async () => { // WHEN await handler.retrieve('testInstance/_ParentBU_', ['user']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, 3, 'only three users expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_user', 'user', '_ParentBU_'), await testUtils.getExpectedJson('1111111', 'user', 'retrieve'), 'returned metadata was not equal expected' ); // check if MD file was created and equals expectations // ! this test needs to update the lastLoginDate counter because it changes with every passing day const expectedFile = await testUtils.getExpectedFile( '1111111', 'user', 'retrieve', 'md' ); const regexFindDaysSinceLogin = /\| (\d*) (seconds|minutes|days|weeks|months|years){1} \|/g; // fetch expected time since last login const expectedDaysSinceLogin = expectedFile.match(regexFindDaysSinceLogin); // load actual file and replace days since last login with expected value const actualFile = ( await File.readFile(`./docs/user/testInstance.users.md`, { encoding: 'utf8', }) ).replaceAll(regexFindDaysSinceLogin, expectedDaysSinceLogin[0]); expect(actualFile).to.equal(expectedFile); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should retrieve a specific user but not run document', async () => { // WHEN await handler.retrieve('testInstance/_ParentBU_', ['user'], ['testExisting_user']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // because user is single-document-type we would not want to find an md file when we retrieve specific keys. only the generic retrieve updates it expect(file(`./docs/user/testInstance.users.md`)).to.not.exist; assert.equal( testUtils.getAPIHistoryLength(), 4, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a user', async () => { // WHEN const expectedCache = [ 'testExisting_user', 'testExisting_user_inactive', '45372cbb-06e0-438e-88d8-008981f7a18b', 'testNew_user', ]; await handler.deploy('testInstance/_ParentBU_', ['user'], expectedCache); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, 4, 'four users expected' ); // confirm if result.user only includes values from expectedCache assert.deepEqual( Object.keys(result.user), expectedCache, 'returned user keys were not equal expected' ); // insert assert.deepEqual( await testUtils.getActualJson('testNew_user', 'user', '_ParentBU_'), await testUtils.getExpectedJson('1111111', 'user', 'create'), 'returned metadata was not equal expected for create' ); // update assert.deepEqual( await testUtils.getActualJson('testExisting_user', 'user', '_ParentBU_'), await testUtils.getExpectedJson('1111111', 'user', 'update'), 'returned metadata was not equal expected for update' ); // because user is single-document-type we would not want to find an md file getting created by deploy. only retrieve updates it expect(file(`./docs/user/testInstance.users.md`)).to.not.exist; assert.equal( testUtils.getAPIHistoryLength(), 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); it('Should not deploy user with Marketing Cloud role', async () => { // WHEN const expectedCache = [ 'testExisting_user', 'testExisting_user_inactive', '45372cbb-06e0-438e-88d8-008981f7a18b', ]; await handler.deploy('testInstance/_ParentBU_', ['user'], ['testBlocked_user']); // THEN assert.equal(process.exitCode, 1, 'Deployment should have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, 3, 'three users expected' ); // confirm if result.user only includes values from expectedCache assert.deepEqual( Object.keys(result.user), expectedCache, 'returned user keys were not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 5, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { // it('Should create a user template via retrieveAsTemplate and build it', async () => {}); it('Should create a user template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/_ParentBU_', ['user']); // GIVEN there is a template const result = await handler.buildTemplate( 'testInstance/_ParentBU_', 'user', ['testExisting_user'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); // WHEN assert.equal( result.user ? Object.keys(result.user).length : 0, 1, 'only one user expected' ); assert.deepEqual( await testUtils.getActualTemplateJson('testExisting_user', 'user'), await testUtils.getExpectedJson('1111111', 'user', 'template'), 'returned template was not equal expected' ); // THEN await handler.buildDefinition( 'testInstance/_ParentBU_', 'user', ['testExisting_user'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson('testTemplated_user', 'user', '_ParentBU_'), await testUtils.getExpectedJson('1111111', 'user', 'build'), 'returned deployment file was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 6, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); }); ================================================ FILE: test/type.verification.test.js ================================================ import * as chai from 'chai'; const assert = chai.assert; import chaiFiles from 'chai-files'; import cache from '../lib/util/cache.js'; import * as testUtils from './utils.js'; import handler from '../lib/index.js'; chai.use(chaiFiles); describe('type: verification', () => { beforeEach(() => { testUtils.mockSetup(); }); afterEach(() => { testUtils.mockReset(); }); describe('Retrieve ================', () => { it('Should retrieve a verification', async () => { // WHEN const retrieved = await handler.retrieve('testInstance/testBU', ['verification']); // THEN assert.equal(process.exitCode, 0, 'retrieve should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.verification ? Object.keys(result.verification).length : 0, 1, 'only one verification expected' ); assert.equal( retrieved['testInstance/testBU']?.verification ? Object.keys(retrieved['testInstance/testBU']?.verification).length : 0, 1, 'one verifications to be retrieved' ); assert.deepEqual( await testUtils.getActualJson('testExisting_automation__s1.7', 'verification'), await testUtils.getExpectedJson('9999999', 'verification', 'get'), 'returned JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Deploy ================', () => { beforeEach(() => { testUtils.mockSetup(true); }); it('Should create & upsert a verification', async () => { // WHEN const deployed = await handler.deploy('testInstance/testBU', ['verification']); // THEN assert.equal(process.exitCode, 0, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.verification ? Object.keys(result.verification).length : 0, 2, 'two verifications expected' ); assert.equal( deployed['testInstance/testBU']?.verification ? Object.keys(deployed['testInstance/testBU']?.verification).length : 0, 2, 'two verifications to be deployed' ); // confirm created item assert.deepEqual( await testUtils.getActualJson('testNew_automation__s1.7', 'verification'), await testUtils.getExpectedJson('9999999', 'verification', 'post'), 'returned new-JSON was not equal expected for insert verification' ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_automation__s1.7', 'verification'), await testUtils.getExpectedJson('9999999', 'verification', 'patch'), 'returned existing-JSON was not equal expected for update verification' ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Templating ================', () => { it('Should create a verification template via buildTemplate and build it', async () => { // download first before we test buildTemplate await handler.retrieve('testInstance/testBU', ['verification']); // buildTemplate const result = await handler.buildTemplate( 'testInstance/testBU', 'verification', ['testExisting_automation__s1.7'], ['testSourceMarket'] ); assert.equal(process.exitCode, 0, 'buildTemplate should not have thrown an error'); assert.equal( result.verification ? Object.keys(result.verification).length : 0, 1, 'only one verification expected' ); assert.deepEqual( await testUtils.getActualTemplateJson( 'testExisting_automation__s1.7', 'verification' ), await testUtils.getExpectedJson('9999999', 'verification', 'template'), 'returned template JSON was not equal expected' ); // buildDefinition await handler.buildDefinition( 'testInstance/testBU', 'verification', ['testExisting_automation__s1.7'], ['testTargetMarket'] ); assert.equal(process.exitCode, 0, 'buildDefinition should not have thrown an error'); assert.deepEqual( await testUtils.getActualDeployJson( 'testTemplated_automation__s1.7', 'verification' ), await testUtils.getExpectedJson('9999999', 'verification', 'build'), 'returned deployment JSON was not equal expected' ); assert.equal( testUtils.getAPIHistoryLength(), 14, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); describe('Delete ================', () => { it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'verification', 'testExisting_39f6a488-20eb-4ba0-b0b9' ); // THEN assert.equal( process.exitCode, 0, 'deleteByKey should have thrown an error due to lack of support' ); assert.equal(isDeleted, true, 'deleteByKey should have returned true for success'); return; }); }); }); ================================================ FILE: test/utils.js ================================================ import File from '../lib/util/file.js'; import path from 'node:path'; import MockAdapter from 'axios-mock-adapter'; import { axiosInstance } from '../node_modules/sfmc-sdk/lib/util.js'; import handler from '../lib/index.js'; import auth from '../lib/util/auth.js'; import { Util } from '../lib/util/util.js'; import cache from '../lib/util/cache.js'; import ReplaceContentBlockReference from '../lib/util/replaceContentBlockReference.js'; import MetadataTypes from '../lib/MetadataTypeInfo.js'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // for some reason doesnt realize below reference import fsmock from 'mock-fs'; let apimock; import { handleSOAPRequest, handleRESTRequest, soapUrl, restUrl, tWarn, } from './resourceFactory.js'; const authResources = File.readJsonSync(path.join(__dirname, './resources/auth.json')); const loadingFile = 'loading expected file:///' + __dirname.split(path.sep).join('/'); /** * gets file from Retrieve folder * * @param {string} from source path (starting in bu folder) * @param {string} to target path (starting in bu folder) * @param {string} [mid] used when we need to test on ParentBU * @returns {Promise.<{status:'ok'|'skipped'|'failed', statusMessage:string, file:string}>} - */ export async function copyFile(from, to, mid = '9999999') { return File.copyFileSimple(`./test/resources/${mid}/${from}`, `./test/resources/${mid}/${to}`); } /** * gets file from Retrieve folder * * @param {string} from source path (starting in bu folder) * @param {string} to target path (starting in bu folder) * @param {string} [mid] used when we need to test on ParentBU * @param {string} [buName] used when we need to test on ParentBU * @returns {void} - */ export function copyToDeploy(from, to, mid = '9999999', buName = 'testBU') { console.log(`Copying ${from} to deploy folder`); // eslint-disable-line no-console File.copySync(`./test/resources/${mid}/${from}`, `./deploy/testInstance/${buName}/${to}`); } /** * gets file from Retrieve folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string>} file in string form */ export function getActualJson(customerKey, type, buName = 'testBU') { return File.readJSON( `./retrieve/testInstance/${buName}/${type}/${customerKey}.${type}-meta.json` ); } /** * gets file from Retrieve folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string>} file path */ export function getActualDoc(customerKey, type, buName = 'testBU') { return File.readFile( `./retrieve/testInstance/${buName}/${type}/${customerKey}.${type}-doc.md`, 'utf8' ); } /** * gets file from Retrieve folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} ext file extension * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string | null>} file in string form, null if not found */ export async function getActualFile(customerKey, type, ext, buName = 'testBU') { const path = `./retrieve/testInstance/${buName}/${type}/${customerKey}.${type}-meta.${ext}`; try { return await File.readFile(path, 'utf8'); } catch { console.log(`File not found: ${path}`); // eslint-disable-line no-console return null; } } /** * gets file from Deploy folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string>} file in JSON form */ export function getActualDeployJson(customerKey, type, buName = 'testBU') { return File.readJSON( `./deploy/testInstance/${buName}/${type}/${customerKey}.${type}-meta.json` ); } /** * gets file from Deploy folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} ext file extension * @param {string} [buName] used when we need to test on ParentBU * @returns {Promise.<string>} file in string form */ export function getActualDeployFile(customerKey, type, ext, buName = 'testBU') { return File.readFile( `./deploy/testInstance/${buName}/${type}/${customerKey}.${type}-meta.${ext}`, 'utf8' ); } /** * gets file from Template folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @returns {Promise.<string>} file in JSON form */ export function getActualTemplateJson(customerKey, type) { return File.readJSON(`./template/${type}/${customerKey}.${type}-meta.json`); } /** * gets file from Template folder * * @param {string} customerKey of metadata * @param {string} type of metadata * @param {string} ext file extension * @returns {Promise.<string>} file in string form */ export function getActualTemplateFile(customerKey, type, ext) { return File.readFile(`./template/${type}/${customerKey}.${type}-meta.${ext}`, 'utf8'); } /** * gets file from resources folder which should be used for comparison * * @param {string} mid of Business Unit * @param {string} type of metadata * @param {string} action of SOAP request * @returns {Promise.<string>} file in JSON form */ export function getExpectedJson(mid, type, action) { const path = `/resources/${mid}/${type}/${action}-expected.json`; console.log(loadingFile + path); // eslint-disable-line no-console return File.readJSON(`./test` + path); } /** * gets file from resources folder which should be used for comparison * * @param {string} mid of Business Unit * @param {string} type of metadata * @param {string} action of SOAP request * @param {string} ext file extension * @returns {Promise.<string>} file in string form */ export function getExpectedFile(mid, type, action, ext) { const path = `/resources/${mid}/${type}/${action}-expected.${ext}`; console.log(loadingFile + path); // eslint-disable-line no-console return File.readFile(`./test` + path, 'utf8'); } /** * setup mocks for API and FS * * @param {boolean} [isDeploy] if true, will mock deploy folder * @returns {void} */ export function mockSetup(isDeploy) { cache.clearCache(); // clear local caches for (const type of Object.keys(MetadataTypes)) { if (MetadataTypes[type].cache) { // we rarely use a local cache in types which also needs to be reset MetadataTypes[type].cache = {}; } } // no need to execute this again if we ran it a 2nd time for deploy - already done in standard setup if (!isDeploy) { // reset all options to default const resetOptions = {}; // get known options and make sure none are set for (const option in handler.knownOptions) { resetOptions[option] = undefined; } // test config resetOptions.debug = true; resetOptions.noLogFile = true; handler.setOptions(resetOptions); } File.prettierConfig = null; apimock = new MockAdapter(axiosInstance, { onNoMatch: 'throwException' }); // set access_token to mid to allow for autorouting of mock to correct resources apimock.onPost(authResources.success.url).reply((config) => { authResources.success.response.access_token = JSON.parse(config.data).account_id; return [authResources.success.status, authResources.success.response]; }); apimock.onPost(soapUrl).reply((config) => handleSOAPRequest(config)); apimock .onAny(new RegExp(`^${escapeRegExp(restUrl)}`)) .reply((config) => handleRESTRequest(config)); const fsMockConf = { '.beautyamp.json': fsmock.load( path.resolve(__dirname, '../boilerplate/files/.beautyamp.json') ), '.prettierrc': fsmock.load(path.resolve(__dirname, '../boilerplate/files/.prettierrc')), 'eslint.config.js': fsmock.load( path.resolve(__dirname, '../boilerplate/files/eslint.config.js') ), '.mcdevrc.json': fsmock.load(path.resolve(__dirname, 'mockRoot/.mcdevrc.json')), '.mcdev-auth.json': fsmock.load(path.resolve(__dirname, 'mockRoot/.mcdev-auth.json')), '.mcdev-validations.js': fsmock.load( path.resolve(__dirname, 'mockRoot/.mcdev-validations.js') ), 'boilerplate/config.json': fsmock.load( path.resolve(__dirname, '../boilerplate/config.json') ), test: fsmock.load(path.resolve(__dirname)), // the following node_modules are required for prettier's SQL parser to work 'node_modules/prettier': fsmock.load(path.resolve(__dirname, '../node_modules/prettier')), 'node_modules/prettier-plugin-sql': fsmock.load( path.resolve(__dirname, '../node_modules/prettier-plugin-sql') ), 'node_modules/beauty-amp-core2': fsmock.load( path.resolve(__dirname, '../node_modules/beauty-amp-core2') ), 'node_modules/node-sql-parser': fsmock.load( path.resolve(__dirname, '../node_modules/node-sql-parser') ), 'node_modules/big-integer': fsmock.load( path.resolve(__dirname, '../node_modules/big-integer') ), 'node_modules/sql-formatter': fsmock.load( path.resolve(__dirname, '../node_modules/sql-formatter') ), 'node_modules/jsox': fsmock.load(path.resolve(__dirname, '../node_modules/jsox')), 'node_modules/nearley': fsmock.load(path.resolve(__dirname, '../node_modules/nearley')), }; if (isDeploy) { // load files we manually prepared for a direct test of `deploy` command fsMockConf.deploy = fsmock.load(path.resolve(__dirname, 'mockRoot/deploy')); } fsmock(fsMockConf); // ! reset exitCode or else tests could influence each other; do this in mockSetup to to ensure correct starting value process.exitCode = 0; } /** * resets mocks for API and FS * * @returns {void} */ export function mockReset() { // remove all options that might have been set by previous tests for (const key in Util.OPTIONS) { if (Object.prototype.hasOwnProperty.call(Util.OPTIONS, key)) { delete Util.OPTIONS[key]; } } // avoid spillover from other tests ReplaceContentBlockReference.resetCacheMap(); // reset sfmc login auth.clearSessions(); fsmock.restore(); apimock.restore(); } /** * helper to return amount of api callouts * * @param {boolean} [includeToken] if true, will include token calls in count * @returns {object} of API history */ export function getAPIHistoryLength(includeToken) { const historyArr = Object.values(apimock.history).flat(); if (includeToken) { return historyArr.length; } return historyArr.filter((item) => item.url !== '/v2/token').length; } /** * helper to return api history * * @returns {object} of API history */ export function getAPIHistory() { return apimock.history; } /** * * @param {'patch'|'delete'|'post'|'get'|'put'} method http method * @param {string} url url without domain, end on % if you want to search with startsWith() * @param {boolean} returnAll useful for post requests that often have multiple callouts with the same url * @returns {object} json payload of the request */ export function getRestCallout(method, url, returnAll = false) { if (!apimock.history[method]?.length) { console.log(`${tWarn} No history for method ${method}.`); // eslint-disable-line no-console const methods = Object.keys(apimock.history) .filter((el) => apimock.history[el]?.length) .join(', '); console.error(`Available methods: ${methods}`); // eslint-disable-line no-console return null; } const subset = apimock.history[method]; /** * helper for filter/find * * @param {any} item history item * @returns {boolean} if item matches */ function findCallout(item) { return url.endsWith('%') ? item.url.startsWith(url.slice(0, -1)) : item.url === url; } const myCallout = returnAll ? subset.filter(findCallout) : subset.find(findCallout); if (!myCallout) { console.error(`${tWarn} No callout found for ${method} ${url}`); // eslint-disable-line no-console const urls = [...new Set(subset.map((el) => el.url))].join('\n- '); const methods = Object.keys(apimock.history) .filter((el) => apimock.history[el]?.length) .join(', '); console.error(`Available methods: ${methods}`); // eslint-disable-line no-console console.error(`Available unique urls in method ${method}:\n- ${urls}`); // eslint-disable-line no-console return null; } return returnAll ? myCallout.map((el) => JSON.parse(el.data)) : JSON.parse(myCallout.data); } /** * * @param {'Schedule'|'Retrieve'|'Create'|'Update'|'Delete'|'Describe'|'Execute'} requestAction soap request types * @param {string} [objectType] optionall filter requests by object * @returns {object[]} json payload of the requests */ export function getSoapCallouts(requestAction, objectType) { const method = 'post'; const url = '/Service.asmx'; const subset = apimock.history[method]; const myCallout = subset // find soap requests .filter((item) => item.url === url) // find soap requestst of the correct request type .filter((item) => item.headers.SOAPAction === requestAction) // find soap requestst of the correct request type .filter((item) => !objectType || item.data.includes('<ObjectType') ? item.data.split('<ObjectType>')[1].split('</ObjectType>')[0] === objectType : item.data.includes('<Objects xsi:type="') ? item.data.split('<Objects xsi:type="')[1].split('">')[0] === objectType : false ) .map((item) => item.data); if (!myCallout) { console.error(`${tWarn} No callout found for ${requestAction} ${objectType || ''}`); // eslint-disable-line no-console return null; } return myCallout; } /** * helper to return most important fields for each api call * * @returns {object} of API history */ export function getAPIHistoryDebug() { const historyArr = Object.values(apimock.history) .flat() .map((item) => { const log = { method: item.method, url: item.url }; if (item.data) { log.body = item.data; } return log; }); return historyArr; } /** * helper to return most important fields for each api call * * @returns {void} of API history */ export function logAPIHistoryDebug() { console.log(getAPIHistoryDebug()); // eslint-disable-line no-console } /** * escapes string for regex * * @param {string} str to escape * @returns {string} escaped string */ function escapeRegExp(str) { return str.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`); // $& means the whole matched string } ================================================ FILE: tsconfig.json ================================================ { // Change this to match your project "include": ["lib/**/*.js", "types/**/*.js", "test/**/*.js"], "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext", "checkJs": true, "skipLibCheck": true, "target": "es2023", // Tells TypeScript to read JS files, as // normally they are ignored as source files "allowJs": true, // Generate d.ts files "declaration": true, // This compiler run should // only output d.ts files "emitDeclarationOnly": true, // Types should go into this directory. // Removing this would place the .d.ts files // next to the .js files "outDir": "@types", // go to js file when using IDE functions like // "Go to Definition" in VSCode "declarationMap": true } } ================================================ FILE: tsconfig.npmScripts.json ================================================ { "include": ["lib/**/*.js", "types/**/*.js", "test/**/*.js"], "exclude": ["node_modules"], "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext", "target": "es2023", "checkJs": true, "skipLibCheck": true, "noEmit": true } } ================================================ FILE: tsconfig.precommit.json ================================================ { // Change this to match your project "include": ["lib/**/*.js"], "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext", "target": "es2023", "checkJs": true, "skipLibCheck": true, // Tells TypeScript to read JS files, as // normally they are ignored as source files "allowJs": true, // Generate d.ts files "declaration": true, // This compiler run should // only output d.ts files "emitDeclarationOnly": true, // Types should go into this directory. // Removing this would place the .d.ts files // next to the .js files "outDir": "@types", // go to js file when using IDE functions like // "Go to Definition" in VSCode "declarationMap": true } } ================================================ FILE: types/mcdev.d.js ================================================ /** * @typedef {object} BuObject * @property {string} [clientId] installed package client id * @property {string} [clientSecret] installed package client secret * @property {string} [tenant] subdomain part of Authentication Base Uri * @property {number} [eid] Enterprise ID = MID of the parent BU * @property {number} [mid] MID of the BU to work with * @property {string} [businessUnit] name of the BU to interact with * @property {string} [credential] name of the credential to interact with */ /** * @typedef {Object.<string, string>} TemplateMap * @typedef {'asset'|'asset-archive'|'asset-asset'|'asset-audio'|'asset-block'|'asset-code'|'asset-document'|'asset-image'|'asset-message'|'asset-other'|'asset-rawimage'|'asset-template'|'asset-textfile'|'asset-video'|'attributeGroup'|'attributeSet'|'automation'|'campaign'|'contentArea'|'dataExtension'|'dataExtensionField'|'dataExtensionTemplate'|'dataExtract'|'dataExtractType'|'discovery'|'deliveryProfile'|'email'|'emailSend'|'event'|'fileLocation'|'fileTransfer'|'filter'|'folder'|'importFile'|'journey'|'list'|'mobileCode'|'mobileKeyword'|'mobileMessage'|'query'|'role'|'script'|'sendClassification'|'senderProfile'|'transactionalEmail'|'transactionalPush'|'transactionalSMS'|'triggeredSend'|'user'|'verification'} SupportedMetadataTypes * @typedef {Object.<string, string[] | null>} TypeKeyCombo object-key=SupportedMetadataTypes, value=array of external keys */ /** * @typedef {Object.<any, any>} MetadataTypeItem generic metadata item * @typedef {Object.<string, MetadataTypeItem>} MetadataTypeMap key=customer key * @typedef {Object.<string, MetadataTypeMap>} MultiMetadataTypeMap key=Supported MetadataType * @typedef {Object.<string, MetadataTypeItem[]>} MultiMetadataTypeList key=Supported MetadataType * @typedef {{metadata: MetadataTypeMap, type: string}} MetadataTypeMapObj * @typedef {{metadata: MetadataTypeItem, type: string}} MetadataTypeItemObj * @typedef {Object.<number, MultiMetadataTypeMap>} Cache key=MID * @typedef {{before: MetadataTypeItem, after: MetadataTypeItem}} MetadataTypeItemDiff used during update */ /** * @typedef {object} CodeExtractItem * @property {MetadataTypeItem} json metadata of one item w/o code * @property {CodeExtract[]} codeArr list of code snippets in this item * @property {string[]} subFolder mostly set to null, otherwise list of subfolders */ /** * @typedef {object} CodeExtract * @property {string[]} subFolder mostly set to null, otherwise subfolders path split into elements * @property {string} fileName name of file w/o extension * @property {string} fileExt file extension * @property {string} content file content * @property {'base64'} [encoding] optional for binary files */ /** * @typedef {object} QueryItem * @property {string} name name * @property {string} key key * @property {string} description - * @property {string} [targetId] Object ID of DE (removed before save) * @property {string} targetKey key of target data extension * @property {string} r__dataExtension_key key of target data extension * @property {string} createdDate e.g. "2020-09-14T01:42:03.017" * @property {string} modifiedDate e.g. "2020-09-14T01:42:03.017" * @property {'Overwrite'|'Update'|'Append'} targetUpdateTypeName defines how the query writes into the target data extension * @property {number} [targetUpdateTypeId] 0|1|2, mapped to targetUpdateTypeName via this.definition.targetUpdateTypeMapping * @property {string} [targetDescription] Description DE (removed before save) * @property {boolean} isFrozen looks like this is always set to false * @property {string} [queryText] contains SQL query with line breaks converted to '\n'. The content is extracted during retrieval and written into a separate *.sql file * @property {string} [categoryId] holds folder ID, replaced with r__folder_Path during retrieve * @property {string} r__folder_Path folder path in which this DE is saved * @property {string} [queryDefinitionId] Object ID of query * @typedef {Object.<string, QueryItem>} QueryMap */ /** * @typedef {object} ScriptItem * @property {string} name name * @property {string} key key * @property {string} description - * @property {string} createdDate e.g. "2020-09-14T01:42:03.017" * @property {string} modifiedDate e.g. "2020-09-14T01:42:03.017" * @property {string} [script] contains script with line breaks converted to '\n'. The content is extracted during retrieval and written into a separate *.ssjs file * @property {string} [categoryId] holds folder ID, replaced with r__folder_Path during retrieve * @property {string} r__folder_Path folder path in which this DE is saved * @typedef {Object.<string, ScriptItem>} ScriptMap */ /** * @typedef {Object.<string, any>} AssetItem * @typedef {Object.<string, AssetItem>} AssetMap * @typedef {'archive'|'asset'|'audio'|'block'|'code'|'document'|'image'|'message'|'other'|'rawimage'|'template'|'textfile'|'video'} AssetSubType */ /** * @typedef {object} DataExtensionFieldItem * @property {string} [ObjectID] id * @property {string} [CustomerKey] key in format [DEkey].[FieldName] * @property {object} [DataExtension] - * @property {string} DataExtension.CustomerKey key of DE * @property {string} Name name of field * @property {string} [Name_new] custom attribute that is only used when trying to rename a field from Name to Name_new * @property {string} DefaultValue empty string for not set * @property {true|false} IsRequired - * @property {true|false} [IsNullable] opposite of IsRequired * @property {true|false} IsPrimaryKey - * @property {number} Ordinal 1, 2, 3, ... * @property {'Text'|'Number'|'Date'|'Boolean'|'Decimal'|'EmailAddress'|'Phone'|'Locale'} FieldType can only be set on create * @property {number|string} MaxLength field length * @property {string} Scale the number of places after the decimal that the field can hold; example: "0","1", ... */ /** * @typedef {Object.<string, DataExtensionFieldItem>} DataExtensionFieldMap key: name of field, value: DataExtensionFieldItem */ /** * @typedef {object} DataExtensionItem * @property {string} CustomerKey key * @property {string} Name name * @property {string} Description - * @property {string} [CreatedDate] iso format * @property {string} [ModifiedDate] iso format * @property {true|false} IsSendable - * @property {true|false} IsTestable - * @property {object} SendableDataExtensionField - * @property {string} SendableDataExtensionField.Name - * @property {object} SendableSubscriberField - * @property {string} SendableSubscriberField.Name - * @property {DataExtensionFieldItem[]} Fields list of DE fields * @property {'dataextension'|'salesforcedataextension'|'synchronizeddataextension'|'shared_dataextension'|'shared_salesforcedataextension'} r__folder_ContentType retrieved from associated folder * @property {string} r__folder_Path folder path in which this DE is saved * @property {string} [CategoryID] holds folder ID, replaced with r__folder_Path during retrieve * @property {string} [r__dataExtensionTemplate_name] name of optionally associated DE template * @property {object} [Template] - * @property {string} [Template.CustomerKey] key of optionally associated DE teplate * @property {string} RetainUntil empty string or US date + 12:00:00 AM * @property {string} c__retainUntil YYYY-MM-DD * @property {'none'|'allRecordsAndDataextension'|'allRecords'|'individialRecords'} [c__retentionPolicy] readable name of retention policy * @property {number} [DataRetentionPeriodLength] number of days/weeks/months/years before retention kicks in * @property {number} [DataRetentionPeriodUnitOfMeasure] 3:Days, 4:Weeks, 5:Months, 6:Years * @property {string} [c__dataRetentionPeriodUnitOfMeasure] 3:Days, 4:Weeks, 5:Months, 6:Years * @property {boolean} [RowBasedRetention] true for retention policy individialRecords * @property {boolean} ResetRetentionPeriodOnImport ? * @property {boolean} [DeleteAtEndOfRetentionPeriod] true for retention policy allRecords */ /** * @typedef {Object.<string, DataExtensionItem>} DataExtensionMap */ /** * @typedef {object} UserDocument * @property {'User'|'Installed Package'|'Inactivated User'} TYPE - * @property {string} [ID] equal to UserID; optional in update/create calls * @property {string} UserID equal to ID; required in update/create calls * @property {number} [AccountUserID] user.AccountUserID * @property {number} c__AccountUserID copy of AccountUserID * @property {string} CustomerKey user.CustomerKey * @property {string} Name user.Name * @property {string} Email user.Email * @property {string} NotificationEmailAddress user.NotificationEmailAddress * @property {boolean} ActiveFlag user.ActiveFlag === true ? '✓' : '-' * @property {boolean} IsAPIUser user.IsAPIUser === true ? '✓' : '-' * @property {boolean} MustChangePassword user.MustChangePassword === true ? '✓' : '-' * @property {number} DefaultBusinessUnit default MID; BUName after we resolved it * @property {number[]} c__AssociatedBusinessUnits associatedBus * @property {object} [Roles] (API only) * @property {object[]} [Roles.Role] roles (API only) * @property {string[]} c__RoleNamesGlobal roles * @property {string[]} UserPermissions userPermissions * @property {string} LastSuccessfulLogin this.timeSinceDate(user.LastSuccessfulLogin) * @property {string} CreatedDate user.CreatedDate * @property {string} ModifiedDate user.ModifiedDate * @property {object} Client - * @property {number} [Client.ID] EID e.g:7281698 * @property {number} [Client.ModifiedBy] AccountUserID of user who last modified this user * @property {'User'|'Installed Package'} c__type - * @property {boolean} [IsLocked] (API only) * @property {boolean} [Unlock] used to unlock a user that has IsLocked === true * @property {boolean} c__IsLocked_readOnly copy of IsLocked * @property {string} c__TimeZoneName name of timezone * @property {object} [TimeZone] (API only) * @property {string} [TimeZone.Name] (API only) * @property {string} [TimeZone.ID] (API only) * @property {string} [Password] only used to set the password. cannot be retrieved * @property {'en-US'|'fr-CA'|'fr-FR'|'de-DE'|'it-IT'|'ja-JP'|'pt-BR'|'es-419'|'es-ES'} c__LocaleCode fr-CA, en-US, ... * @property {object} [Locale] (API only) * @property {'en-US'|'fr-CA'|'fr-FR'|'de-DE'|'it-IT'|'ja-JP'|'pt-BR'|'es-419'|'es-ES'} [Locale.LocaleCode] (API only) * @property {object} [SsoIdentity] - * @property {Array|object} [SsoIdentities] - */ /** * @typedef {{before:UserDocument,after:UserDocument}} UserDocumentDiff * @typedef {Object.<string, UserDocument>} UserDocumentMap key=customer key */ /** * @typedef {object} UserDocumentDocumentHelper * @property {string} ActiveFlagDocs docs: user.ActiveFlag === true ? '✓' : '-' * @property {string} IsAPIUserDocs docs: user.IsAPIUser === true ? '✓' : '-' * @property {string} MustChangePasswordDocs docs: user.MustChangePassword === true ? '✓' : '-' * @property {string} DefaultBusinessUnitDocs docs: default MID; BUName after we resolved it * @property {string} RolesDocs docs: list of roles as concatenated string * @property {string} AssociatedBusDocs docs: list of associated BUs as concatenated string * @property {string | number} ModifiedBy docs: user name who last modified this user * @property {string} TimeZoneName docs: name of timezone * @property {string} IsLockedDocs docs: if the user cannot login * @typedef {UserDocument & UserDocumentDocumentHelper} UserDocumentDocument */ /** * @typedef {object} AccountUserConfiguration * @property {object} Client wrapper * @property {number} Client.ID EID e.g:7281698 * @property {string} [PartnerKey] empty string * @property {number | string} ID User ID e.g:717133502 * @property {string} [ObjectID] empty string * @property {number} [Delete] 0,1 * @property {BusinessUnitAssignmentConfiguration} BusinessUnitAssignmentConfiguration - * @typedef {object} BusinessUnitAssignmentConfiguration * @property {object} BusinessUnitIds wrapper * @property {number[]|number} BusinessUnitIds.BusinessUnitId e.g:[518003624] * @property {boolean} IsDelete assign BU if false, remove assignment if true */ /** * @typedef {object} AutomationActivity * @property {string} r__key key of associated activity * @property {string} [name] name (not key) of associated activity * @property {string} [timeZone] used by wait activity if a specific time of day was set * @property {number} [objectTypeId] Id of assoicated activity type; see this.definition.activityTypeMapping * @property {string} [activityObjectId] Object Id of assoicated metadata item * @property {number} [displayOrder] order within step; starts with 1 or higher number * @property {string} r__type see this.definition.activityTypeMapping */ /** * @typedef {object} AutomationStep * @property {string} name description * @property {string} [annotation] equals AutomationStep.name * @property {number} [step] step iterator; starts with 1 * @property {number} [stepNumber] step iterator, automatically set during deployment * @property {AutomationActivity[]} activities - */ /** * @typedef {object} AutomationSchedule REST format * @property {string} id legacy id of schedule * @property {number} typeId equals schedule.scheduleTypeId; upsert endpoint requires scheduleTypeId. retrieve endpoint returns typeId * @property {number} [scheduleTypeId] equals schedule.typeId; upsert endpoint requires scheduleTypeId. retrieve endpoint returns typeId * @property {string} startDate example: '2021-05-07T09:00:00' * @property {string} endDate example: '2021-05-07T09:00:00' * @property {string} icalRecur example: 'FREQ=DAILY;UNTIL=20790606T160000;INTERVAL=1' * @property {string} [iCalRecur] same as icalRecur but returned by legacy-API; example: 'FREQ=DAILY;UNTIL=20790606T160000;INTERVAL=1' * @property {string} timezoneName example: 'W. Europe Standard Time'; see this.definition.timeZoneMapping * @property {string} [timeZone] same as timezoneName but returned by legacy-API; example: 'W. Europe Standard Time'; see this.definition.timeZoneMapping * @property {string} [description] kept in legacy API only, exact description of what this schedule does * @property {number} [timezoneId] see this.definition.timeZoneMapping * @property {number} [timeZoneId] same as timezoneId but returned by legacy-API; see this.definition.timeZoneMapping * @property {number} [rangeTypeId] ? * @property {any} [pattern] ? * @property {any} [scheduledTime] ? * @property {string} [scheduledStatus] ? */ /** * @typedef {object} AutomationScheduleSoap SOAP format * @property {string} [RecurrenceType] 'Minutely'|'Hourly'|'Daily'|'Weekly'|'Monthly'|'Yearly' * @property {object} Recurrence - * @property {object} [Recurrence.$] {'xsi:type': keyStem + 'lyRecurrence'} * @property {'ByYear'} [Recurrence.YearlyRecurrencePatternType] * currently not supported by tool * * @property {'ByMonth'} [Recurrence.MonthlyRecurrencePatternType] * currently not supported by tool * * @property {'ByWeek'} [Recurrence.WeeklyRecurrencePatternType] * currently not supported by tool * * @property {'ByDay'} [Recurrence.DailyRecurrencePatternType] - * @property {'Interval'} [Recurrence.MinutelyRecurrencePatternType] - * @property {'Interval'} [Recurrence.HourlyRecurrencePatternType] - * @property {number} [Recurrence.YearInterval] 1..n * currently not supported by tool * * @property {number} [Recurrence.MonthInterval] 1..n * currently not supported by tool * * @property {number} [Recurrence.WeekInterval] 1..n * currently not supported by tool * * @property {number} [Recurrence.DayInterval] 1..n * @property {number} [Recurrence.HourInterval] 1..n * @property {number} [Recurrence.MinuteInterval] 1..n * @property {number} [_interval] internal variable for CLI output only * @property {object} TimeZone - * @property {number} TimeZone.ID AutomationSchedule.timezoneId * @property {true} [TimeZone.IDSpecified] always true * @property {string} [_timezoneString] internal variable for CLI output only * @property {string} StartDateTime AutomationSchedule.startDate * @property {string} [_StartDateTime] AutomationSchedule.startDate; internal variable for CLI output only * @property {string} [EndDateTime] AutomationSchedule.endDate * @property {'EndOn'|'EndAfter'} RecurrenceRangeType set to 'EndOn' if AutomationSchedule.icalRecur contains 'UNTIL'; otherwise to 'EndAfter' * @property {number} [Occurrences] only exists if RecurrenceRangeType=='EndAfter' */ /** * @typedef {object} AutomationItem * @property {string} id Object Id * @property {string} [legacyId] legacy Object Id - used for handling notifications * @property {string} [ObjectID] Object Id as returned by SOAP API * @property {string} [programId] legacy id * @property {string} key key (Rest API) * @property {string} [CustomerKey] key (SOAP API) * @property {string} [name] name (Rest API) * @property {string} [Name] name (SOAP API) * @property {any} [notifications] notifications * @property {string} [description] - * @property {'scheduled'|'triggered'|'automationtriggered'} [type] Starting Source = Schedule / File Drop * @property {'scheduled'|'triggered'|'automationtriggered'} [automationType] Starting Source = Schedule / File Drop; from legacy api * @property {'Scheduled'|'Running'|'Ready'|'Building'|'PausedSchedule'|'InactiveTrigger'} [status] automation status * @property {number} [statusId] automation status * @property {AutomationSchedule} [schedule] only existing if type=scheduled * @property {object} [fileTrigger] only existing if type=triggered * @property {string} fileTrigger.fileNamingPattern file name with placeholders * @property {number} fileTrigger.fileNamePatternTypeId - * @property {string} fileTrigger.folderLocationText where to look for the fileNamingPattern * @property {boolean} fileTrigger.isPublished ? * @property {boolean} fileTrigger.queueFiles ? * @property {boolean} fileTrigger.triggerActive - * @property {object} [automationTrigger] only existing if type=automationtriggered * @property {object} [startSource] - * @property {AutomationSchedule} [startSource.schedule] rewritten to AutomationItem.schedule * @property {object} [startSource.fileDrop] rewritten to AutomationItem.fileTrigger * @property {string} startSource.fileDrop.fileNamePattern file name with placeholders * @property {number} startSource.fileDrop.fileNamePatternTypeId - * @property {string} startSource.fileDrop.folderLocation - * @property {boolean} startSource.fileDrop.queueFiles - * @property {number} startSource.typeId - * @property {AutomationStep[]} [steps] - * @property {string} [r__folder_Path] folder path * @property {string} [categoryId] holds folder ID, replaced with r__folder_Path during retrieve * @property {string} [createdName] user name of person who created this automation * @property {string} [createdDate] iso format * @property {string} [modifiedName] user name of person who last modified this automation * @property {string} [modifiedDate] iso format * @property {string} [pausedName] user name of person who paused this automation * @property {string} [pausedDate] iso format */ /** * @typedef {object} VerificationItem * @property {string} dataVerificationDefinitionId ID / Key * @property {'IsEqualTo'|'IsLessThan'|'IsGreaterThan'|'IsOutsideRange'|'IsInsideRange'|'IsNotEqualTo'|'IsNotLessThan'|'IsNotGreaterThan'|'IsNotOutsideRange'|'IsNotInsideRange'} verificationType key * @property {number} value1 used for all verificationTypes; lower value for IsOutsideRange, IsInsideRange, IsNotOutsideRange, IsNotInsideRange * @property {number} value2 only used for IsOutsideRange, IsInsideRange, IsNotOutsideRange, IsNotInsideRange; otherwise set to 0 * @property {boolean} shouldStopOnFailure flag to stop automation if verification fails * @property {boolean} shouldEmailOnFailure flag to send email if verification fails * @property {string} notificationEmailAddress email address to send notification to; empty string if shouldEmailOnFailure=false * @property {string} notificationEmailMessage email message to send; empty string if shouldEmailOnFailure=false * @property {number} createdBy user id of creator * @property {string} [targetObjectId] ObjectID of target data extension * @property {string} r__dataExtension_key key of target data extension * @property {string} c__automation_step custom key for verifications based on automation, step and activity number */ /** * @typedef {Object.<string, AutomationItem>} AutomationMap * @typedef {{metadata:AutomationMap,type:string}} AutomationMapObj * @typedef {{metadata:object | AutomationItem,type:string}} AutomationItemObj * @typedef {object} McdevDeltaPkgItem * @property {string} file relative path to file * @property {number} changes changed lines * @property {number} insertions added lines * @property {number} deletions deleted lines * @property {boolean} binary is a binary file * @property {boolean} moved git thinks this file was moved * @property {string} [fromPath] git thinks this relative path is where the file was before * @property {string} type metadata type * @property {string} externalKey key * @property {string} name name * @property {'move'|'add/update'|'delete'} gitAction what git recognized as an action * @property {string} _credential mcdev credential name * @property {string} _businessUnit mcdev business unit name inside of _credential * @typedef {import('simple-git').DiffResultTextFile & McdevDeltaPkgItem} DeltaPkgItem */ /** * @typedef {import('sfmc-sdk/util').RestError} RestError * @typedef {import('sfmc-sdk/util').SOAPError} SOAPError * @typedef {SOAPError & RestError} SDKError */ /** * @typedef {object} SkipInteraction signals what to insert automatically for things usually asked via wizard * @property {string} [client_id] client id of installed package * @property {string} [client_secret] client secret of installed package * @property {string} [auth_url] tenant specific auth url of installed package * @property {number} [account_id] MID of the Parent Business Unit * @property {string} [credentialName] how you would like the credential to be named * @property {string} [gitRemoteUrl] URL of Git remote server * @property {boolean} [fixKeysReretrieve] will trigger re-downloading latest versions of dependent types after fixing keys * @property {string} [gitPush] used by mcdev init to directly push to a remote * @property {string} [developmentBu] used by mcdev init to directly push to a remote * @property {string} [downloadBUs] used by mcdev init to directly push to a remote */ /** * @typedef {object} FilterItem * @property {number} categoryId folder id * @property {string} [createdDate] - * @property {string} customerKey key * @property {string} destinationObjectId DE/List ID * @property {1|2|3|4} destinationTypeId 1:SubscriberList, 2:DataExtension, 3:GroupWizard, 4:BehavioralData * @property {string} filterActivityId ? * @property {string} filterDefinitionId ObjectID of filterDefinition * @property {string} modifiedDate - * @property {string} name name * @property {string} [description] - * @property {string} sourceObjectId DE/List ID * @property {null} resultGroupFolderId required for upsert; unknown purpose; set to null * @property {null} resultGroupName required for upsert; unknown purpose; set to null * @property {null} sourceId required for upsert; unknown purpose; set to null * @property {1|2|3|4} sourceTypeId 1:SubscriberList, 2:DataExtension, 3:GroupWizard, 4:BehavioralData * @property {1|2|3|4} [filterDefinitionSourceTypeId] seems to be a duplicate of sourceTypeId? * @property {string} [resultDEDescription] description of destination DE * @property {string} [resultDEName] name of destination DE * @property {string} [resultDEKey] key of destination DE * @property {number} statusId ? * @property {string} [r__dataFilter_key] relationship to filterDefinition * @property {string} [r__source_dataExtension_key] relationship to dataExtension source * @property {string} [r__destination_dataExtension_key] relationship to dataExtension destination * @property {string} [r__folder_Path] relationship to folder * @typedef {Object.<string, FilterItem>} FilterMap */ /** * /automation/v1/filterdefinitions/<id> (not used) * * @typedef {object} AutomationFilterDefinitionItem * @property {string} id object id * @property {string} key external key * @property {string} createdDate - * @property {number} createdBy user id * @property {string} createdName - * @property {string} [description] (omitted by API if empty) * @property {string} modifiedDate - * @property {number} modifiedBy user id * @property {string} modifiedName - * @property {string} name name * @property {string} categoryId folder id * @property {string} filterDefinitionXml from REST API defines the filter in XML form * @property {1|2} derivedFromType 1:list/profile attributes/measures, 2: dataExtension * @property {boolean} isSendable ? */ /** * /email/v1/filters/filterdefinition/<id> * * @typedef {object} DataFilterItem * @property {string} id object id * @property {string} key external key * @property {string} createdDate date * @property {number} createdBy user id * @property {string} createdName name * @property {string} [description] (omitted by API if empty) * @property {string} lastUpdated date * @property {number} lastUpdatedBy user id * @property {string} lastUpdatedName name * @property {string} name name * @property {string} categoryId folder id * @property {string} filterDefinitionXml from REST API defines the filter in XML form * @property {1|2} derivedFromType 1:list/profile attributes/measures, 2: dataExtension * @property {string} derivedFromObjectId Id of DataExtension - present if derivedFromType=2 * @property {'DataExtension'|'SubscriberAttributes'} derivedFromObjectTypeName - * @property {string} [derivedFromObjectName] name of DataExtension * @property {boolean} isSendable ? * @property {object} [c__filterDefinition] copied from SOAP API, defines the filter in readable form * @property {FilterConditionSet} c__filterDefinition.ConditionSet - * @property {string} [r__source_list_PathName] relationship to list source (if derivedFromType=1) * @property {string} [r__source_dataExtension_key] relationship to dataExtension source (if derivedFromType=2) */ /** * @typedef {object} FilterConditionSet * @property {FilterCondition | FilterCondition[]} Condition - * @property {FilterConditionSet} ConditionSet - */ /** * @typedef {object} FilterCondition * @property {'IsEmpty'|'IsNotEmpty'|'Equals'} Operator comparison operator (actually \@_Operator) * @property {string} [ID] object id of field (actually \@_ID) * @property {string} [Value] filter value to compare against * @property {string} [r__dataExtensionField_name] name of field */ /** * @typedef {Object.<string, DataFilterItem>} DataFilterMap */ /** * @typedef {object} AuthObject * @property {string} client_id client_id client_id for sfmc-sdk auth * @property {string} client_secret client_secret for sfmc-sdk auth * @property {number} account_id mid of business unit to auth against * @property {string} auth_url authentication base url */ /** * @typedef {object} SoapRequestParams * @property {string} [continueRequest] request id * @property {object} [options] additional options (CallsInConversation, Client, ConversationID, Priority, RequestType, SaveOptions, ScheduledTime, SendResponseTo, SequenceCode) * @property {*} [clientIDs] ? * @property {SoapSDKFilter} [filter] simple or complex complex * @property {boolean} [QueryAllAccounts] all BUs or just one */ /** * @typedef {object} SoapFilterSimple * @property {string} property field * @property {'equals'|'notEquals'|'isNull'|'isNotNull'|'greaterThan'|'lessThan'|'greaterThanOrEqual'|'lessThanOrEqual'|'between'|'IN'|'in'|'like'} simpleOperator various options * @property {string | number | boolean | string[] | number[]} [value] field value */ /** * @typedef {object} SoapFilterComplex * @property {SoapSDKFilter} leftOperand string for simple or a new filter-object for complex * @property {'AND'|'OR'} logicalOperator various options * @property {SoapSDKFilter} rightOperand string for simple or a new filter-object for complex; omit for isNull and isNotNull */ /** * @typedef {object} SoapSDKFilterSimple * @property {SoapFilterSimple["property"]} leftOperand string for simple or a new filter-object for complex * @property {SoapFilterSimple["simpleOperator"]} operator various options * @property {SoapFilterSimple["value"]} [rightOperand] string for simple or a new filter-object for complex; omit for isNull and isNotNull */ /** * @typedef {object} SoapSDKFilterComplex * @property {SoapFilterComplex["leftOperand"]} leftOperand string for simple or a new filter-object for complex * @property {SoapFilterComplex["logicalOperator"]} operator various options * @property {SoapFilterComplex["rightOperand"]} rightOperand string for simple or a new filter-object for complex; omit for isNull and isNotNull */ /** * @typedef {SoapSDKFilterSimple | SoapSDKFilterComplex} SoapSDKFilter */ /** * @typedef {object} AssetRequestParams * @property {string} [continueRequest] request id * @property {object} [options] additional options (CallsInConversation, Client, ConversationID, Priority, RequestType, SaveOptions, ScheduledTime, SendResponseTo, SequenceCode) * @property {*} [clientIDs] ? complex * @property {object} [page] pagination * @property {string[]} [fields] list of fields we want returned * @property {{property:string, direction: 'ASC'|'DESC'}[]} [sort] pagination * @property {AssetFilter | AssetFilterSimple} [query] simple or complex filter */ /** * @typedef {object} AssetFilter * @property {AssetFilter | AssetFilterSimple} leftOperand string for simple or a new filter-object for complex * @property {'AND'|'OR'} logicalOperator various options * @property {SoapSDKFilter | AssetFilterSimple} [rightOperand] string for simple or a new filter-object for complex; omit for isNull and isNotNull */ /** * @typedef {object} AssetFilterSimple * @property {string} property field * @property {'equal'|'notEquals'|'isNull'|'isNotNull'|'greaterThan'|'lessThan'|'greaterThanOrEqual'|'lessThanOrEqual'|'between'|'IN'|'in'|'like'} simpleOperator various options * @property {string | number | boolean | Array} value field value */ /** * @typedef {object} Mcdevrc * @property {object} credentials list of credentials * @property {object} options configure options for mcdev * @property {object} directories configure directories for mcdev to read/write to * @property {string} directories.businessUnits "businessUnits/" * @property {string} directories.deploy "deploy/" * @property {string} directories.docs "docs/" * @property {string} directories.retrieve "retrieve/" * @property {string} directories.template "template/" * @property {string} directories.templateBuilds ["retrieve/", "deploy/"] * @property {Object.<string, object>} markets templating variables grouped by markets * @property {object} marketList combination of markets and BUs for streamlined deployments * @property {object} metaDataTypes templating variables grouped by markets * @property {string[]} metaDataTypes.retrieve define what types shall be downloaded by default during retrieve * @property {string[]} metaDataTypes.createDeltaPkg defines what types shall be passed to build() as part of running cdp * @property {string[]} metaDataTypes.documentOnRetrieve which types should be parsed & documented after retrieve * @property {string} version mcdev version that last updated the config file */ /** * @typedef {'error'|'verbose'|'info'|'debug'} LoggerLevel * @typedef {object} McdevLogger * @property {LoggerLevel} [level] (msg) print info message * @property {(msg:string)=>void} error (msg) print error message; wrapper around winstonLogger.error that also sets error code to 1 * @property {(ex:SDKError,message?:string)=>void} errorStack print error with trace message * @typedef {import('winston').Logger & McdevLogger} Logger */ /** * @typedef {{id: number, key: string, name: string}} AssetItemSimple * @typedef {Object.<string, AssetItemSimple>} AssetItemSimpleMap * @typedef {Object.<number, AssetItemSimple>} AssetItemIdSimpleMap * @typedef {'id'|'key'|'name'} ContentBlockConversionTypes */ /** * @typedef {object} ExplainType * @property {string} name readable name of type * @property {string} apiName api parameter name for type * @property {string} description more info on what this type is about * @property {boolean | string[]} retrieveByDefault is it retrieved by default OR list of subtypes that are retrieved by default * @property {object} supports supported features * @property {boolean} supports.retrieve can you download this type * @property {boolean} supports.create can you create new records of this type * @property {boolean} supports.update can you update records of this type * @property {boolean} supports.delete can you delete records of this type * @property {boolean} supports.changeKey can you change the key of existing records of this type * @property {boolean} supports.buildTemplate can you apply templating on downloaded records of this type * @property {boolean} supports.retrieveAsTemplate can you retrieve & template in one step */ /** * @typedef {object} ListItem * @property {object} [Client] wrapper * @property {number} Client.ID owning BU's MID * @property {string} [PartnerKey] not used * @property {string} [CreatedDate] "2021-06-21T11:54:57.103" * @property {string} [ModifiedDate] "2021-06-21T11:54:57.103" * @property {number} [ID] unique identifier per BU * @property {string} [ObjectID] not used * @property {string} [CustomerKey] unique identifer per BU * @property {string} [Path] customn field that tracks the exact directory path of the current folder including its own name * @property {object} [ParentFolder] wrapper * @property {number} ParentFolder.ID folder id of parent folder; 0 if current folder is already on top level * @property {string} [ParentFolder.ObjectID] not used * @property {string} [ParentFolder.Path] customn field that tracks the exact directory path of the current folder including its own name * @property {string} Name folder name * @property {string} [Description] deprecated option to describe the folder content * @property {string} ContentType e.g. "shared_data"; see folder-subtypes for complete list * @property {boolean} IsActive ? * @property {boolean} IsEditable option to disable renaming/moving this folder via GUI * @property {boolean} AllowChildren option to prevent creating subfolders via GUI * @property {boolean} [_generated] helper flag for Deployer class to signal if the folder was auto-generated or manually placed * * @typedef {Object.<number, ListItem>} ListIdMap key=id * @typedef {Object.<string, ListItem>} ListMap key=customer key */ /** * @typedef {object} ReferenceObject returned by /data/v1/integration/member/salesforce/object/<OBJECT NAME>/referenceobjects * @property {string} displayname label * @property {string} referenceObjectName api name of salesforce object * @property {string} relationshipName name of lookup/MD field on related object ending on __r (way to return fields from other object) * @property {string} relationshipIdName name of lookup/MD field on related object ending on __c (returning id) * @property {boolean} isPolymorphic if this lookup can point to multiple objects or not * * @typedef {object} SfObjectPicklist returned by /legacy/v1/beta/integration/member/salesforce/object/<OBJECT NAME> * @property {boolean} active - * @property {boolean} defaultValue - * @property {string} label what you see in the GUI * @property {string} value whats stored in the DB */ /** * @typedef {object} SfObjectField returned by /legacy/v1/beta/integration/member/salesforce/object/<OBJECT NAME> * @property {string} label "Annual Revenue" * @property {string} name "AnnualRevenue" * @property {'currency'|'string'|'int'|'picklist'|'textarea'|'boolean'|'date'|'datetime'|'email'} datatype type * @property {number} length 0-4000 * @property {boolean} nillable == not required * @property {boolean} custom is it a custom field * @property {boolean} updateable always true? * @property {boolean} createable always true? * @property {boolean} defaultedoncreate - * @property {boolean} externalid - * @property {boolean} idlookup - * @property {number} precision - * @property {number} scale - * @property {'Currency'|'Text'|'Number'|'Picklist'|'Text Area (long)'|'Checkbox'|'Date'|'Date/Time'|'Email'} displaydatatype "Currency" * @property {string} objectname "Lead", * @property {string} relationname "", * @property {boolean} isnamefield - * @property {SfObjectPicklist[]} [picklist] list of values */ /** * @typedef {object} configurationArguments * @property {string} applicationExtensionKey SalesforceObjectTriggerV2 * @property {string} version 3.0 * @property {'Created'|'Updated'|'CreatedUpdated'} salesforceTriggerCriteria what record event in SF triggers this * @property {object} eventDataConfig what objects are used by this event * @property {eventDataConfigObject[]} eventDataConfig.objects list of sf objects with the fields that are used * @property {Conditions} primaryObjectFilterCriteria TODO * @property {Conditions} relatedObjectFilterCriteria TODO * @property {object} [additionalObjectFilterCriteria] seems to only exist on journey but not on event and also not on every journey * @property {object} contactKey defines how this event links to the all contacts list * @property {string} contactKey.relationshipIdName Id / the __c field * @property {string} contactKey.relationshipName Common / the __r field * @property {boolean} contactKey.isPolymorphic false * @property {string} contactKey.referenceObjectName Common * @property {string} [contactKey.fieldName] if relationshipIdName points to a __c field then this tends to be set to "Id" * @property {object} passThroughArgument TODO * @property {object} passThroughArgument.fields TODO * @property {string} passThroughArgument.fields.ContactKey CampaignMember:Common:Id * @property {object} passThroughArgument.fields.Email CampaignMember:Common:Email; not affected by changing which field is to be used for email in the journey * @property {string} [passThroughArgument.fields.HasOptedOutOfEmail] Contact:HasOptedOutOfEmail * @property {string} primaryObjectFilterSummary primaryObjectFilterCriteria in simplified string-form * @property {string} relatedObjectFilterSummary relatedObjectFilterCriteria in simplified string-form * @property {string[]} eventDataSummary eventDataConfig in simplified string-form * @property {'Created;'|'Updated;'|'Created;Updated;'} evaluationCriteriaSummary salesforceTriggerCriteria plus semi-colon * @property {'CampaignMember'|'Contact'} contactPersonType if objectAPIName==CampaignMember then this is also CampaignMember; otherwise it's Contact * @property {string} objectAPIName the SF object on which the salesforceTriggerCriteria is listening on * @property {string} whoToInject "objectAPIName (Contact / Lead / Contacts and Leads)" * @property {string} criteria empty string for SF events * @property {number} schemaVersionId set to 0 for SF events */ /** * @typedef {object} eventDataConfigObject part of configurationArguments * @property {string} dePrefix CampaignMember:Campaign: * @property {boolean} isPolymorphic ? * @property {string} referenceObject field on parent object containing the id; ends on __c for custom fields; same as referenceObject for standard fields; can be "Contacts and Leads" * @property {string} relationshipName field on parent object acting as lookup; ends on __r for custom fields; same as referenceObject for standard fields; can be "Common" * @property {string} [relationshipIdName] ? * @property {string[]} fields list of field names that are used by this journey */ /** * @typedef {object} Conditions part of configurationArguments * @property {'AND'|'OR'} operand - * @property {(Conditions | FieldCondition)[]} conditions list of conditions */ /** * @typedef {object} FieldCondition part of configurationArguments * @property {number} _length is 0 for booleans, otherwise field length * @property {'currency'|'string'|'int'|'picklist'|'textarea'|'boolean'|'date'|'datetime'|'email'} datatype type * @property {string} fieldName field API name; "TR1__Email__c" * @property {string} folderId "CampaignMember-CampaignMember" * @property {string} id "CampaignMember-CampaignMember-TR1__Email__c" * @property {boolean} isPolymorphic ? * @property {string} name likely the field label; "Email" * @property {'equals'|'EQUALS'|'WASSET'} operator condition comparator * @property {string} [value] value to compare the field with if operator is sth like "equals"; booleans are stored as upper-camel-case string! * @property {number} precision ? * @property {string} referenceObjectName "Contacts and Leads" * @property {string} relationshipIdName "CommonId"; can be an empty string * @property {string} relationshipName "Common"; can be an empty string * @property {number} scale ? * @property {string} text seems to be equal to name-attribute?; "Email" */ /** * * @callback validationRuleFix * @returns {boolean|null} true = test passed; false = test failed & fixed; null = test failed & item removed to fix * * @callback validationRuleTest * @returns {boolean} true = test passed; false = test failed * * @typedef {object} validationRule * @property {string} failedMsg error message to display in case of a failed test * @property {validationRuleTest} passed test to run * @property {validationRuleFix} [fix] test to run * * @typedef {Object.<string, validationRule>} validationRuleList key=rule name */ /** * @typedef {object} DomainVerificationItem * @property {number} [enterpriseId] EID * @property {number} [memberId] MID * @property {string} [domain] domain or email address used in retrieve and create * @property {string} [emailAddress] email address used in update call for isSendable field * @property {'Verified'|'Pending'} [status] returned by retrieve * @property {'SAP'|'UserDomain'|'PrivateDomain'|'RegisteredDomain'} [domainType] returned by retrieve and required for update call * @property {boolean} isSendable automatically true upon creation. can be changed to false via update * @property {string} [emailSendTime] e.g. ""2023-06-19T11:11:17.32"" * @property {string} [notificationEmail] for bulk-creation only: email address to send notifications to when done * @property {string[]} [addresses] for bulk-creation only: list of email addresses to verify * @property {string} [deTable] for bulk-creation only: instead of an array in addresses, specify the name of a DE * @property {string} [deColumn] for bulk-creation only: instead of an array in addresses, specify the name of a DE column/field here */ /** * @typedef {object} BuildFilter * @property {BuildFilterKeys} [include] include key filters * @property {BuildFilterKeys} [exclude] exclude key filters */ /** * @typedef {object} BuildFilterKeys * @property {Object.<"*"|SupportedMetadataTypes, string[]>} [key] object with keys representing metadata types ("*" for all types, or specific type names) and values being arrays of string patterns to match against */ export default {};