mcdev 5.1.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +4 -4
- package/.fork/custom-commands.json +12 -0
- package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
- package/.github/PULL_REQUEST_TEMPLATE/pr_template_release.md +19 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +2 -2
- package/.github/workflows/coverage-develop-branch.yml +0 -2
- package/.github/workflows/coverage-main-branch.yml +0 -2
- package/.github/workflows/coverage.yml +0 -2
- package/.husky/post-checkout +1 -0
- package/.husky/post-merge +1 -0
- package/.vscode/extensions.json +4 -0
- package/docs/dist/documentation.md +1034 -296
- package/lib/Deployer.js +25 -25
- package/lib/MetadataTypeDefinitions.js +2 -1
- package/lib/MetadataTypeInfo.js +2 -1
- package/lib/Retriever.js +1 -1
- package/lib/cli.js +165 -10
- package/lib/index.js +398 -95
- package/lib/metadataTypes/Asset.js +10 -11
- package/lib/metadataTypes/AttributeGroup.js +76 -2
- package/lib/metadataTypes/AttributeSet.js +367 -0
- package/lib/metadataTypes/Automation.js +483 -137
- package/lib/metadataTypes/DataExtension.js +465 -68
- package/lib/metadataTypes/DataExtensionField.js +31 -14
- package/lib/metadataTypes/Event.js +2 -3
- package/lib/metadataTypes/Folder.js +1 -1
- package/lib/metadataTypes/Journey.js +13 -7
- package/lib/metadataTypes/MetadataType.js +212 -54
- package/lib/metadataTypes/MobileKeyword.js +9 -9
- package/lib/metadataTypes/MobileMessage.js +5 -5
- package/lib/metadataTypes/Query.js +26 -10
- package/lib/metadataTypes/Script.js +3 -3
- package/lib/metadataTypes/TransactionalEmail.js +94 -17
- package/lib/metadataTypes/TransactionalMessage.js +3 -2
- package/lib/metadataTypes/TransactionalSMS.js +5 -5
- package/lib/metadataTypes/TriggeredSend.js +25 -50
- package/lib/metadataTypes/User.js +7 -4
- package/lib/metadataTypes/Verification.js +230 -0
- package/lib/metadataTypes/definitions/AttributeGroup.definition.js +119 -108
- package/lib/metadataTypes/definitions/{SetDefinition.definition.js → AttributeSet.definition.js} +123 -43
- package/lib/metadataTypes/definitions/Automation.definition.js +23 -15
- package/lib/metadataTypes/definitions/ImportFile.definition.js +36 -6
- package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +19 -1
- package/lib/metadataTypes/definitions/TriggeredSend.definition.js +1 -0
- package/lib/metadataTypes/definitions/Verification.definition.js +88 -0
- package/lib/util/cache.js +9 -4
- package/lib/util/cli.js +40 -0
- package/lib/util/file.js +2 -2
- package/lib/util/init.js +84 -0
- package/lib/util/util.js +121 -13
- package/package.json +13 -13
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testExisting_dataExtensionShared.dataExtension-meta.json +59 -0
- package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testNew_dataExtensionShared.dataExtension-meta.json +23 -0
- package/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +1 -2
- package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +9 -6
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-meta.json +1 -0
- package/test/mockRoot/deploy/testInstance/testBU/dataExtract/testExisting_dataExtract.dataExtract-meta.json +35 -0
- package/test/mockRoot/deploy/testInstance/testBU/dataExtract/testNew_dataExtract.dataExtract-meta.json +35 -0
- package/test/mockRoot/deploy/testInstance/testBU/fileTransfer/testExisting_fileTransfer.fileTransfer-meta.json +17 -0
- package/test/mockRoot/deploy/testInstance/testBU/fileTransfer/testNew_fileTransfer.fileTransfer-meta.json +17 -0
- package/test/mockRoot/deploy/testInstance/testBU/importFile/testExisting_importFile.importFile-meta.json +29 -0
- package/test/mockRoot/deploy/testInstance/testBU/importFile/testNew_importFile.importFile-meta.json +29 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql +6 -0
- package/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json +6 -0
- package/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs +1 -0
- package/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json +6 -0
- package/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs +1 -0
- package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +3 -4
- package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testNew_temail.transactionalEmail-meta.json +1 -6
- package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testExisting_triggeredSend.triggeredSend-meta.json +29 -0
- package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testNew_triggeredSend.triggeredSend-meta.json +29 -0
- package/test/mockRoot/deploy/testInstance/testBU/verification/testExisting_39f6a488-20eb-4ba0-b0b9.verification-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/testBU/verification/testNew_39f6a488-20eb-4ba0-b0b9.verification-meta.json +11 -0
- package/test/resourceFactory.js +77 -12
- package/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml +27 -0
- package/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml +156 -0
- package/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +87 -0
- package/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml +156 -0
- package/test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +27 -0
- package/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml +60 -0
- package/test/resources/1111111/data/v1/customobjectdata/key/testExisting_dataExtensionShared/rowset/get-response.json +13 -0
- package/test/resources/1111111/dataExtension/create-expected.json +23 -0
- package/test/resources/1111111/dataExtension/create-response.xml +59 -0
- package/test/resources/1111111/dataExtension/retrieve-expected.json +55 -0
- package/test/resources/1111111/dataExtension/retrieve-expected.md +18 -0
- package/test/resources/1111111/dataExtension/retrieve-response.xml +27 -1
- package/test/resources/1111111/dataExtension/update-expected.json +55 -0
- package/test/resources/1111111/dataExtension/update-response.xml +57 -0
- package/test/resources/1111111/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtensionShared].[TriggerUpdate_randomNumber_]-response.xml +45 -0
- package/test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml +98 -0
- package/test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionSharedORDataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml +98 -0
- package/test/resources/1111111/dataExtensionField/retrieve-response.xml +98 -0
- package/test/resources/1111111/dataExtensionTemplate/retrieve-response.xml +303 -0
- package/test/resources/1111111/dataFolder/retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml +387 -0
- package/test/resources/1111111/dataFolder/retrieve-response.xml +353 -9
- package/test/resources/1111111/user/retrieve-expected.md +4 -2
- package/test/resources/9999999/attributeGroup/retrieve-expected.json +25 -0
- package/test/resources/9999999/attributeSet/retrieve-expected.json +143 -0
- package/test/resources/9999999/automation/build-expected.json +5 -2
- package/test/resources/9999999/automation/create-expected.json +11 -8
- package/test/resources/9999999/automation/create-testNew_automation-expected.md +5 -4
- package/test/resources/9999999/automation/patch_fixKeys-pause-expected.json +44 -0
- package/test/resources/9999999/automation/patch_fixKeys-schedule-expected.json +44 -0
- package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +42 -0
- package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_pause-response.xml +42 -0
- package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_schedule-response.xml +42 -0
- package/test/resources/9999999/automation/perform-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +42 -0
- package/test/resources/9999999/automation/retrieve-expected.json +5 -2
- package/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +3 -2
- package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +52 -0
- package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml +38 -0
- package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-fixKey_pause-response.xml +52 -0
- package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-fixKey_schedule-response.xml +52 -0
- package/test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +52 -0
- package/test/resources/9999999/automation/template-expected.json +5 -2
- package/test/resources/9999999/automation/update-expected.json +1 -2
- package/test/resources/9999999/automation/update-testExisting_automation-expected.md +2 -2
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +7 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/get-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/patch-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/get-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/patch-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +1 -1
- package/test/resources/9999999/automation/v1/automations/post-response.json +27 -19
- package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/patch-response.json +38 -0
- package/test/resources/9999999/automation/v1/dataextracts/post-response.json +38 -0
- package/test/resources/9999999/automation/v1/dataextracttypes/get-response.json +50 -0
- package/test/resources/9999999/automation/v1/dataverifications/post-response.json +12 -0
- package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/delete-response.json +0 -0
- package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/get-response.json +12 -0
- package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/patch-response.json +12 -0
- package/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/patch-response.json +18 -0
- package/test/resources/9999999/automation/v1/filetransfers/post-response.json +18 -0
- package/test/resources/9999999/automation/v1/ftplocations/get-response.json +18 -0
- package/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/patch-response.json +31 -0
- package/test/resources/9999999/automation/v1/imports/get-response.json +1 -1
- package/test/resources/9999999/automation/v1/imports/post-response.json +30 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt +1 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json +17 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json +18 -0
- package/test/resources/9999999/automation/v1/queries/get-response.json +18 -1
- package/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json +10 -0
- package/test/resources/9999999/automation/v1/scripts/get-response.json +12 -2
- package/test/resources/9999999/automation/v1/scripts/post-response.json +10 -0
- package/test/resources/9999999/dataExtension/build-expected.json +16 -0
- package/test/resources/9999999/dataExtension/delete-response.xml +42 -0
- package/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml +52 -0
- package/test/resources/9999999/dataExtension/retrieve-expected.json +16 -0
- package/test/resources/9999999/dataExtension/retrieve-expected.md +3 -1
- package/test/resources/9999999/dataExtension/template-expected.json +16 -0
- package/test/resources/9999999/dataExtension/update-expected.json +17 -1
- package/test/resources/9999999/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtension].[LastName]-response.xml +44 -0
- package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml +133 -0
- package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml +99 -0
- package/test/resources/9999999/dataExtensionField/retrieve-response.xml +36 -1
- package/test/resources/9999999/dataExtract/build-expected.json +35 -0
- package/test/resources/9999999/dataExtract/get-expected.json +39 -0
- package/test/resources/9999999/dataExtract/patch-expected.json +37 -0
- package/test/resources/9999999/dataExtract/post-expected.json +37 -0
- package/test/resources/9999999/dataExtract/template-expected.json +35 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentType=contextual_suppression_listORContentType=publicationORContentType=suppression_listORContentType=mysubsORContentType=list-response.xml +136 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml +48 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml +117 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentType=triggered_send_journeybuilderORContentType=triggered_sendORContentType=hidden-response.xml +276 -0
- package/test/resources/9999999/dataFolder/retrieve-response.xml +23 -0
- package/test/resources/9999999/email/retrieve-response.xml +203 -0
- package/test/resources/9999999/fileTransfer/build-expected.json +15 -0
- package/test/resources/9999999/fileTransfer/get-expected.json +17 -0
- package/test/resources/9999999/fileTransfer/patch-expected.json +17 -0
- package/test/resources/9999999/fileTransfer/post-expected.json +17 -0
- package/test/resources/9999999/fileTransfer/template-expected.json +15 -0
- package/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json +628 -0
- package/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json +20194 -0
- package/test/resources/9999999/importFile/build-expected.json +27 -0
- package/test/resources/9999999/importFile/get-expected.json +29 -0
- package/test/resources/9999999/importFile/patch-expected.json +29 -0
- package/test/resources/9999999/importFile/post-expected.json +29 -0
- package/test/resources/9999999/importFile/template-expected.json +27 -0
- package/test/resources/9999999/interaction/v1/interactions/233d4413-922c-4568-85a5-e5cc77efc3be/delete-response.json +1 -0
- package/test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json +1 -1
- package/test/resources/9999999/messaging/v1/email/definitions/post-response.json +1 -1
- package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/delete-response.json +6 -0
- package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_pause-response.xml +32 -0
- package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_schedule-response.xml +32 -0
- package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_paused-response.xml +32 -0
- package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_scheduled-response.xml +32 -0
- package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml +30 -0
- package/test/resources/9999999/program/retrieve-response.xml +21 -3
- package/test/resources/9999999/query/patch_fixKeys-expected.json +11 -0
- package/test/resources/9999999/query/patch_fixKeys-expected.sql +6 -0
- package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml +30 -0
- package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixedKeysANDStatus=Active-response.xml +30 -0
- package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml +30 -0
- package/test/resources/9999999/script/build-expected.json +6 -0
- package/test/resources/9999999/script/build-expected.ssjs +1 -0
- package/test/resources/9999999/script/get-expected.json +8 -0
- package/test/resources/9999999/script/get-expected.ssjs +1 -0
- package/test/resources/9999999/script/get_noScriptTag-expected.html +1 -0
- package/test/resources/9999999/script/get_noScriptTag-expected.json +8 -0
- package/test/resources/9999999/script/patch-expected.json +8 -0
- package/test/resources/9999999/script/patch-expected.ssjs +1 -0
- package/test/resources/9999999/script/post-expected.json +8 -0
- package/test/resources/9999999/script/post-expected.ssjs +1 -0
- package/test/resources/9999999/script/template-expected.json +6 -0
- package/test/resources/9999999/script/template-expected.ssjs +1 -0
- package/test/resources/9999999/transactionalEmail/build-expected.json +3 -7
- package/test/resources/9999999/transactionalEmail/get-expected.json +3 -7
- package/test/resources/9999999/transactionalEmail/patch-expected.json +3 -7
- package/test/resources/9999999/transactionalEmail/post-expected.json +3 -7
- package/test/resources/9999999/transactionalEmail/template-expected.json +3 -7
- package/test/resources/9999999/triggeredSend/build-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/get-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/patch-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/post-expected.json +29 -0
- package/test/resources/9999999/triggeredSend/template-expected.json +29 -0
- package/test/resources/9999999/triggeredSendDefinition/create-response.xml +75 -0
- package/test/resources/9999999/triggeredSendDefinition/delete-response.xml +36 -0
- package/test/resources/9999999/triggeredSendDefinition/{retrieve-response.xml → retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml} +4 -4
- package/test/resources/9999999/triggeredSendDefinition/update-response.xml +74 -0
- package/test/resources/9999999/verification/build-expected.json +11 -0
- package/test/resources/9999999/verification/get-expected.json +11 -0
- package/test/resources/9999999/verification/patch-expected.json +11 -0
- package/test/resources/9999999/verification/post-expected.json +11 -0
- package/test/resources/9999999/verification/template-expected.json +11 -0
- package/test/type.attributeGroup.test.js +55 -0
- package/test/type.attributeSet.test.js +55 -0
- package/test/type.automation.test.js +650 -17
- package/test/type.dataExtension.test.js +205 -46
- package/test/type.dataExtract.test.js +194 -0
- package/test/type.fileTransfer.test.js +192 -0
- package/test/type.importFile.test.js +193 -0
- package/test/type.journey.test.js +38 -11
- package/test/type.mobileKeyword.test.js +6 -5
- package/test/type.mobileMessage.test.js +6 -4
- package/test/type.query.test.js +470 -17
- package/test/type.script.test.js +372 -0
- package/test/type.transactionalEmail.test.js +12 -11
- package/test/type.transactionalPush.test.js +2 -4
- package/test/type.transactionalSMS.test.js +2 -4
- package/test/type.triggeredSend.test.js +154 -0
- package/test/type.user.test.js +22 -10
- package/test/type.verification.test.js +173 -0
- package/test/utils.js +11 -2
- package/types/mcdev.d.js +14 -0
- package/lib/metadataTypes/SetDefinition.js +0 -37
- /package/test/resources/1111111/accountUser/{retrieve-response.xml → retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml} +0 -0
- /package/test/resources/1111111/accountUserAccount/{retrieve-response.xml → retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml} +0 -0
- /package/test/resources/1111111/businessUnit/{retrieve-response.xml → retrieve-ID=1111111-response.xml} +0 -0
- /package/test/resources/1111111/list/{retrieve-response.xml → retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml} +0 -0
- /package/test/resources/1111111/role/{retrieve-response.xml → retrieve-IsPrivate=false-response.xml} +0 -0
- /package/test/resources/9999999/emailSendDefinition/{retrieve-response.xml → retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml} +0 -0
- /package/test/resources/9999999/queryDefinition/{retrieve-response.xml → retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml} +0 -0
|
@@ -35,7 +35,7 @@ class MetadataType {
|
|
|
35
35
|
* Returns file contents mapped to their filename without '.json' ending
|
|
36
36
|
*
|
|
37
37
|
* @param {string} dir directory that contains '.json' files to be read
|
|
38
|
-
* @param {boolean} [listBadKeys
|
|
38
|
+
* @param {boolean} [listBadKeys] do not print errors, used for badKeys()
|
|
39
39
|
* @returns {TYPE.MetadataTypeMap} fileName => fileContent map
|
|
40
40
|
*/
|
|
41
41
|
static getJsonFromFS(dir, listBadKeys) {
|
|
@@ -108,11 +108,10 @@ class MetadataType {
|
|
|
108
108
|
* @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField
|
|
109
109
|
* @param {string} deployDir directory where deploy metadata are saved
|
|
110
110
|
* @param {string} retrieveDir directory where metadata after deploy should be saved
|
|
111
|
-
* @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets
|
|
112
111
|
* @returns {Promise.<TYPE.MetadataTypeMap>} Promise of keyField => metadata map
|
|
113
112
|
*/
|
|
114
|
-
static async deploy(metadata, deployDir, retrieveDir
|
|
115
|
-
const upsertResults = await this.upsert(metadata, deployDir
|
|
113
|
+
static async deploy(metadata, deployDir, retrieveDir) {
|
|
114
|
+
const upsertResults = await this.upsert(metadata, deployDir);
|
|
116
115
|
const savedMetadata = await this.saveResults(upsertResults, retrieveDir, null);
|
|
117
116
|
if (
|
|
118
117
|
this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) &&
|
|
@@ -131,22 +130,22 @@ class MetadataType {
|
|
|
131
130
|
* @param {TYPE.MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create
|
|
132
131
|
* @param {TYPE.MetadataTypeMap} originalMetadata metadata to be updated (contains additioanl fields)
|
|
133
132
|
* @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates
|
|
134
|
-
* @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets
|
|
135
133
|
* @returns {void}
|
|
136
134
|
*/
|
|
137
|
-
static postDeployTasks(upsertResults, originalMetadata, createdUpdated
|
|
135
|
+
static postDeployTasks(upsertResults, originalMetadata, createdUpdated) {}
|
|
138
136
|
|
|
139
137
|
/**
|
|
140
|
-
* helper for {@link createREST}
|
|
138
|
+
* helper for {@link MetadataType.createREST}
|
|
141
139
|
*
|
|
142
140
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
143
141
|
* @param {object} apiResponse varies depending on the API call
|
|
142
|
+
* @param {TYPE.MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped
|
|
144
143
|
* @returns {void}
|
|
145
144
|
*/
|
|
146
|
-
static postCreateTasks(metadataEntry, apiResponse) {}
|
|
145
|
+
static postCreateTasks(metadataEntry, apiResponse, metadataEntryWithAllFields) {}
|
|
147
146
|
|
|
148
147
|
/**
|
|
149
|
-
* helper for {@link updateREST}
|
|
148
|
+
* helper for {@link MetadataType.updateREST}
|
|
150
149
|
*
|
|
151
150
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
152
151
|
* @param {object} apiResponse varies depending on the API call
|
|
@@ -155,7 +154,7 @@ class MetadataType {
|
|
|
155
154
|
static postUpdateTasks(metadataEntry, apiResponse) {}
|
|
156
155
|
|
|
157
156
|
/**
|
|
158
|
-
* helper for {@link createREST} when legacy API endpoints as these do not return the created item but only their new id
|
|
157
|
+
* helper for {@link MetadataType.createREST} when legacy API endpoints as these do not return the created item but only their new id
|
|
159
158
|
*
|
|
160
159
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
161
160
|
* @param {object} apiResponse varies depending on the API call
|
|
@@ -267,11 +266,10 @@ class MetadataType {
|
|
|
267
266
|
*
|
|
268
267
|
* @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true
|
|
269
268
|
* @param {string[]} [subTypeArr] optionally limit to a single subtype
|
|
270
|
-
* @param {string} [key] customer key of single item to retrieve
|
|
271
269
|
* @returns {Promise.<TYPE.MetadataTypeMapObj>} metadata
|
|
272
270
|
*/
|
|
273
|
-
static async retrieveForCache(additionalFields, subTypeArr
|
|
274
|
-
return this.retrieve(null, additionalFields, subTypeArr
|
|
271
|
+
static async retrieveForCache(additionalFields, subTypeArr) {
|
|
272
|
+
return this.retrieve(null, additionalFields, subTypeArr);
|
|
275
273
|
}
|
|
276
274
|
/**
|
|
277
275
|
* Gets metadata cache with limited fields and does not store value to disk
|
|
@@ -463,7 +461,18 @@ class MetadataType {
|
|
|
463
461
|
Util.logger.error(
|
|
464
462
|
` ☇ skipping ${this.definition.type}: execute is not supported yet for ${this.definition.type}`
|
|
465
463
|
);
|
|
466
|
-
return;
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Abstract pause method that needs to be implemented in child metadata type
|
|
468
|
+
*
|
|
469
|
+
* @returns {void}
|
|
470
|
+
*/
|
|
471
|
+
static pause() {
|
|
472
|
+
Util.logger.error(
|
|
473
|
+
` ☇ skipping ${this.definition.type}: pause is not supported yet for ${this.definition.type}`
|
|
474
|
+
);
|
|
475
|
+
return [];
|
|
467
476
|
}
|
|
468
477
|
|
|
469
478
|
/**
|
|
@@ -537,10 +546,9 @@ class MetadataType {
|
|
|
537
546
|
*
|
|
538
547
|
* @param {TYPE.MetadataTypeMap} metadataMap metadata mapped by their keyField
|
|
539
548
|
* @param {string} deployDir directory where deploy metadata are saved
|
|
540
|
-
* @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets
|
|
541
549
|
* @returns {Promise.<TYPE.MetadataTypeMap>} keyField => metadata map
|
|
542
550
|
*/
|
|
543
|
-
static async upsert(metadataMap, deployDir
|
|
551
|
+
static async upsert(metadataMap, deployDir) {
|
|
544
552
|
const orignalMetadataMap = JSON.parse(JSON.stringify(metadataMap));
|
|
545
553
|
const metadataToUpdate = [];
|
|
546
554
|
const metadataToCreate = [];
|
|
@@ -632,12 +640,10 @@ class MetadataType {
|
|
|
632
640
|
const metadataResults = createResults.concat(updateResults).filter(Boolean);
|
|
633
641
|
upsertResults = this.parseResponseBody(metadataResults);
|
|
634
642
|
}
|
|
635
|
-
await this.postDeployTasks(
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
isRefresh
|
|
640
|
-
);
|
|
643
|
+
await this.postDeployTasks(upsertResults, orignalMetadataMap, {
|
|
644
|
+
created: createResults.length,
|
|
645
|
+
updated: updateResults.length,
|
|
646
|
+
});
|
|
641
647
|
return upsertResults;
|
|
642
648
|
}
|
|
643
649
|
|
|
@@ -802,11 +808,12 @@ class MetadataType {
|
|
|
802
808
|
* @returns {Promise.<object> | null} Promise of API response or null in case of an error
|
|
803
809
|
*/
|
|
804
810
|
static async createREST(metadataEntry, uri) {
|
|
811
|
+
const metadataClone = JSON.parse(JSON.stringify(metadataEntry));
|
|
805
812
|
this.removeNotCreateableFields(metadataEntry);
|
|
806
813
|
try {
|
|
807
814
|
// set to empty object in case API returned nothing to be able to update it in helper classes
|
|
808
815
|
const response = (await this.client.rest.post(uri, metadataEntry)) || {};
|
|
809
|
-
await this.postCreateTasks(metadataEntry, response);
|
|
816
|
+
await this.postCreateTasks(metadataEntry, response, metadataClone);
|
|
810
817
|
Util.logger.info(
|
|
811
818
|
` - created ${this.definition.type}: ${
|
|
812
819
|
metadataEntry[this.definition.keyField] ||
|
|
@@ -815,7 +822,7 @@ class MetadataType {
|
|
|
815
822
|
);
|
|
816
823
|
return response;
|
|
817
824
|
} catch (ex) {
|
|
818
|
-
const parsedErrors = this.
|
|
825
|
+
const parsedErrors = this.getErrorsREST(ex);
|
|
819
826
|
Util.logger.error(
|
|
820
827
|
` ☇ error creating ${this.definition.type} ${
|
|
821
828
|
metadataEntry[this.definition.keyField] ||
|
|
@@ -845,7 +852,7 @@ class MetadataType {
|
|
|
845
852
|
this.removeNotCreateableFields(metadataEntry);
|
|
846
853
|
try {
|
|
847
854
|
const response = await this.client.soap.create(
|
|
848
|
-
|
|
855
|
+
Util.capitalizeFirstLetter(soapType),
|
|
849
856
|
metadataEntry,
|
|
850
857
|
null
|
|
851
858
|
);
|
|
@@ -869,7 +876,7 @@ class MetadataType {
|
|
|
869
876
|
*
|
|
870
877
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
871
878
|
* @param {string} uri rest endpoint for PATCH
|
|
872
|
-
* @param {'patch'|'post'|'put'} [httpMethod
|
|
879
|
+
* @param {'patch'|'post'|'put'} [httpMethod] defaults to 'patch'; some update requests require PUT instead of PATCH
|
|
873
880
|
* @returns {Promise.<object> | null} Promise of API response or null in case of an error
|
|
874
881
|
*/
|
|
875
882
|
static async updateREST(metadataEntry, uri, httpMethod = 'patch') {
|
|
@@ -878,7 +885,7 @@ class MetadataType {
|
|
|
878
885
|
// set to empty object in case API returned nothing to be able to update it in helper classes
|
|
879
886
|
const response = (await this.client.rest[httpMethod](uri, metadataEntry)) || {};
|
|
880
887
|
await this._postChangeKeyTasks(metadataEntry);
|
|
881
|
-
this.
|
|
888
|
+
this.getErrorsREST(response);
|
|
882
889
|
await this.postUpdateTasks(metadataEntry, response);
|
|
883
890
|
// some times, e.g. automation dont return a key in their update response and hence we need to fall back to name
|
|
884
891
|
Util.logger.info(
|
|
@@ -889,7 +896,7 @@ class MetadataType {
|
|
|
889
896
|
);
|
|
890
897
|
return response;
|
|
891
898
|
} catch (ex) {
|
|
892
|
-
const parsedErrors = this.
|
|
899
|
+
const parsedErrors = this.getErrorsREST(ex);
|
|
893
900
|
Util.logger.error(
|
|
894
901
|
` ☇ error updating ${this.definition.type} ${
|
|
895
902
|
metadataEntry[this.definition.keyField] ||
|
|
@@ -904,7 +911,7 @@ class MetadataType {
|
|
|
904
911
|
}
|
|
905
912
|
|
|
906
913
|
/**
|
|
907
|
-
* helper for {@link updateREST} and {@link updateSOAP} that removes old files after the key was changed
|
|
914
|
+
* helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed
|
|
908
915
|
*
|
|
909
916
|
* @private
|
|
910
917
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
@@ -950,7 +957,7 @@ class MetadataType {
|
|
|
950
957
|
this.removeNotUpdateableFields(metadataEntry);
|
|
951
958
|
try {
|
|
952
959
|
const response = await this.client.soap.update(
|
|
953
|
-
|
|
960
|
+
Util.capitalizeFirstLetter(soapType),
|
|
954
961
|
metadataEntry,
|
|
955
962
|
null
|
|
956
963
|
);
|
|
@@ -985,15 +992,20 @@ class MetadataType {
|
|
|
985
992
|
}
|
|
986
993
|
}
|
|
987
994
|
/**
|
|
988
|
-
* helper for {@link _handleSOAPErrors}
|
|
995
|
+
* helper for {@link MetadataType._handleSOAPErrors}
|
|
989
996
|
*
|
|
990
997
|
* @param {Error} ex error that occured
|
|
991
998
|
* @returns {string} error message
|
|
992
999
|
*/
|
|
993
1000
|
static getSOAPErrorMsg(ex) {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1001
|
+
if (ex?.json?.Results?.length) {
|
|
1002
|
+
if (ex?.json?.Results[0].StatusMessage) {
|
|
1003
|
+
return `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})`;
|
|
1004
|
+
} else if (ex?.json?.Results[0].Result.StatusMessage) {
|
|
1005
|
+
return `${ex.json.Results[0].Result.StatusMessage} (Code ${ex.json.Results[0].Result.ErrorCode})`;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
return ex.message;
|
|
997
1009
|
}
|
|
998
1010
|
/**
|
|
999
1011
|
* Retrieves SOAP via generic fuel-soap wrapper based metadata of metadata type into local filesystem. executes callback with retrieved metadata
|
|
@@ -1010,7 +1022,11 @@ class MetadataType {
|
|
|
1010
1022
|
const soapType = this.definition.soapType || this.definition.type;
|
|
1011
1023
|
let response;
|
|
1012
1024
|
try {
|
|
1013
|
-
response = await this.client.soap.retrieveBulk(
|
|
1025
|
+
response = await this.client.soap.retrieveBulk(
|
|
1026
|
+
Util.capitalizeFirstLetter(soapType),
|
|
1027
|
+
fields,
|
|
1028
|
+
requestParams
|
|
1029
|
+
);
|
|
1014
1030
|
} catch (ex) {
|
|
1015
1031
|
this._handleSOAPErrors(ex, 'retrieving');
|
|
1016
1032
|
return {};
|
|
@@ -1045,6 +1061,7 @@ class MetadataType {
|
|
|
1045
1061
|
const results = this.parseResponseBody(response, singleRetrieve);
|
|
1046
1062
|
// get extended metadata if applicable
|
|
1047
1063
|
if (this.definition.hasExtended) {
|
|
1064
|
+
Util.logger.debug(' - retrieving extended metadata');
|
|
1048
1065
|
const extended = await this.client.rest.getCollection(
|
|
1049
1066
|
Object.keys(results).map((key) => uri + results[key][this.definition.idField])
|
|
1050
1067
|
);
|
|
@@ -1073,29 +1090,117 @@ class MetadataType {
|
|
|
1073
1090
|
type: this.definition.type,
|
|
1074
1091
|
};
|
|
1075
1092
|
}
|
|
1093
|
+
/**
|
|
1094
|
+
*
|
|
1095
|
+
* @param {object[]} urlArray {uri: string, id: string} combo of URL and ID/key of metadata
|
|
1096
|
+
* @param {number} [concurrentRequests] optionally set a different amount of concurrent requests
|
|
1097
|
+
* @param {boolean} [logAmountOfUrls] if true, prints an info message about to-be loaded amount of metadata
|
|
1098
|
+
* @returns {Promise.<{metadata: (TYPE.MetadataTypeMap | TYPE.MetadataTypeItem), type: string}>} Promise of item map (single item for templated result)
|
|
1099
|
+
*/
|
|
1100
|
+
static async retrieveRESTcollection(urlArray, concurrentRequests = 10, logAmountOfUrls = true) {
|
|
1101
|
+
if (logAmountOfUrls) {
|
|
1102
|
+
Util.logger.info(
|
|
1103
|
+
Util.getGrayMsg(
|
|
1104
|
+
` - ${urlArray?.length} ${this.definition.type}${
|
|
1105
|
+
urlArray?.length === 1 ? '' : 's'
|
|
1106
|
+
} found. Retrieving details...`
|
|
1107
|
+
)
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
const rateLimit = pLimit(concurrentRequests);
|
|
1111
|
+
|
|
1112
|
+
const metadataArr = urlArray.length
|
|
1113
|
+
? await Promise.all(
|
|
1114
|
+
urlArray.map(async (item) =>
|
|
1115
|
+
rateLimit(async () => {
|
|
1116
|
+
try {
|
|
1117
|
+
return await this.client.rest.get(item.uri);
|
|
1118
|
+
} catch (ex) {
|
|
1119
|
+
return this.handleRESTErrors(ex, item.id);
|
|
1120
|
+
}
|
|
1121
|
+
})
|
|
1122
|
+
)
|
|
1123
|
+
)
|
|
1124
|
+
: [];
|
|
1125
|
+
const results = {};
|
|
1126
|
+
for (const item of metadataArr) {
|
|
1127
|
+
const key = item[this.definition.keyField];
|
|
1128
|
+
results[key] = item;
|
|
1129
|
+
}
|
|
1130
|
+
return {
|
|
1131
|
+
metadata: results,
|
|
1132
|
+
type: this.definition.type,
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* helper for {@link this.retrieveRESTcollection}
|
|
1138
|
+
*
|
|
1139
|
+
* @param {Error} ex exception
|
|
1140
|
+
* @param {string} id id or key of item
|
|
1141
|
+
* @returns {null} -
|
|
1142
|
+
*/
|
|
1143
|
+
static handleRESTErrors(ex, id) {
|
|
1144
|
+
// if the ID is too short, the system will throw the 400 error
|
|
1145
|
+
Util.logger.debug(` ☇ skipping ${this.definition.type} ${id}: ${ex.message} ${ex.code}`);
|
|
1146
|
+
|
|
1147
|
+
return null;
|
|
1148
|
+
}
|
|
1076
1149
|
/**
|
|
1077
1150
|
* Used to execute a query/automation etc.
|
|
1078
1151
|
*
|
|
1079
1152
|
* @param {string} uri REST endpoint where the POST request should be sent
|
|
1080
1153
|
* @param {string} key item key
|
|
1081
|
-
* @returns {Promise.<string>}
|
|
1154
|
+
* @returns {Promise.<{key:string, response:string}>} metadata key and API response (OK or error)
|
|
1082
1155
|
*/
|
|
1083
1156
|
static async executeREST(uri, key) {
|
|
1084
1157
|
try {
|
|
1085
1158
|
const response = await this.client.rest.post(uri, {}); // payload is empty for this request
|
|
1086
1159
|
if (response === 'OK') {
|
|
1087
|
-
Util.logger.info(`
|
|
1160
|
+
Util.logger.info(` - executed ${this.definition.type}: ${key}`);
|
|
1088
1161
|
} else {
|
|
1089
1162
|
throw new Error(response);
|
|
1090
1163
|
}
|
|
1091
|
-
return response;
|
|
1164
|
+
return { key, response };
|
|
1092
1165
|
} catch (ex) {
|
|
1093
1166
|
Util.logger.error(`Failed to execute ${this.definition.type} ${key}: ${ex.message}`);
|
|
1094
1167
|
}
|
|
1095
1168
|
}
|
|
1096
1169
|
|
|
1097
1170
|
/**
|
|
1098
|
-
*
|
|
1171
|
+
* Used to execute a query/automation etc.
|
|
1172
|
+
*
|
|
1173
|
+
* @param {TYPE.MetadataTypeItem} [metadataEntry] single metadata entry
|
|
1174
|
+
* @returns {Promise.<{key:string, response:object}>} metadata key and API response
|
|
1175
|
+
*/
|
|
1176
|
+
static async executeSOAP(metadataEntry) {
|
|
1177
|
+
const soapType = this.definition.soapType || this.definition.type;
|
|
1178
|
+
try {
|
|
1179
|
+
const response = await this.client.soap.perform(
|
|
1180
|
+
Util.capitalizeFirstLetter(soapType),
|
|
1181
|
+
'start',
|
|
1182
|
+
{
|
|
1183
|
+
ObjectID: metadataEntry[this.definition.idField],
|
|
1184
|
+
}
|
|
1185
|
+
);
|
|
1186
|
+
if (response?.OverallStatus === 'OK') {
|
|
1187
|
+
Util.logger.info(
|
|
1188
|
+
` - executed ${this.definition.type}: ${
|
|
1189
|
+
metadataEntry[this.definition.keyField]
|
|
1190
|
+
}`
|
|
1191
|
+
);
|
|
1192
|
+
} else {
|
|
1193
|
+
throw new Error(response?.OverallStatus);
|
|
1194
|
+
}
|
|
1195
|
+
return { key: metadataEntry[this.definition.keyField], response };
|
|
1196
|
+
} catch (ex) {
|
|
1197
|
+
this._handleSOAPErrors(ex, 'executing', metadataEntry);
|
|
1198
|
+
return null;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
/**
|
|
1203
|
+
* helper for {@link MetadataType.retrieveREST} and {@link MetadataType.retrieveSOAP}
|
|
1099
1204
|
*
|
|
1100
1205
|
* @param {string|number} [singleRetrieve] key of single item to filter by
|
|
1101
1206
|
* @param {TYPE.MetadataTypeMap} metadataMap saved metadata
|
|
@@ -1298,7 +1403,7 @@ class MetadataType {
|
|
|
1298
1403
|
*
|
|
1299
1404
|
* @static
|
|
1300
1405
|
* @param {TYPE.MetadataTypeItem} metadataEntry metadata entry
|
|
1301
|
-
* @param {boolean} [include
|
|
1406
|
+
* @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude
|
|
1302
1407
|
* @returns {boolean} true: skip saving == filtered; false: continue with saving
|
|
1303
1408
|
* @memberof MetadataType
|
|
1304
1409
|
*/
|
|
@@ -1343,7 +1448,7 @@ class MetadataType {
|
|
|
1343
1448
|
*
|
|
1344
1449
|
* @static
|
|
1345
1450
|
* @param {object} metadataEntry metadata entry
|
|
1346
|
-
* @param {boolean} [include
|
|
1451
|
+
* @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude
|
|
1347
1452
|
* @returns {boolean} true: filtered == do NOT save; false: not filtered == do save
|
|
1348
1453
|
* @memberof MetadataType
|
|
1349
1454
|
*/
|
|
@@ -1575,6 +1680,10 @@ class MetadataType {
|
|
|
1575
1680
|
}
|
|
1576
1681
|
}
|
|
1577
1682
|
|
|
1683
|
+
if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey])) {
|
|
1684
|
+
Util.logger.debug(`Filtered ${originalKey} because of --like option`);
|
|
1685
|
+
continue;
|
|
1686
|
+
}
|
|
1578
1687
|
// we dont store Id on local disk, but we need it for caching logic,
|
|
1579
1688
|
// so its in retrieve but not in save. Here we put into the clone so that the original
|
|
1580
1689
|
// object used for caching doesnt have the Id removed.
|
|
@@ -1621,7 +1730,7 @@ class MetadataType {
|
|
|
1621
1730
|
return savedResults;
|
|
1622
1731
|
}
|
|
1623
1732
|
/**
|
|
1624
|
-
* helper for {@link buildDefinitionForNested}
|
|
1733
|
+
* helper for {@link MetadataType.buildDefinitionForNested}
|
|
1625
1734
|
* searches extracted file for template variable names and applies the market values
|
|
1626
1735
|
*
|
|
1627
1736
|
* @param {string} code code from extracted code
|
|
@@ -1633,7 +1742,7 @@ class MetadataType {
|
|
|
1633
1742
|
return Mustache.render(code, templateVariables, {}, ['{{{', '}}}']);
|
|
1634
1743
|
}
|
|
1635
1744
|
/**
|
|
1636
|
-
* helper for {@link buildTemplateForNested}
|
|
1745
|
+
* helper for {@link MetadataType.buildTemplateForNested}
|
|
1637
1746
|
* searches extracted file for template variable values and applies the market variable names
|
|
1638
1747
|
*
|
|
1639
1748
|
* @param {string} code code from extracted code
|
|
@@ -1645,7 +1754,7 @@ class MetadataType {
|
|
|
1645
1754
|
return Util.replaceByObject(code, templateVariables);
|
|
1646
1755
|
}
|
|
1647
1756
|
/**
|
|
1648
|
-
* helper for {@link buildDefinition}
|
|
1757
|
+
* helper for {@link MetadataType.buildDefinition}
|
|
1649
1758
|
* handles extracted code if any are found for complex types (e.g script, asset, query)
|
|
1650
1759
|
*
|
|
1651
1760
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
@@ -1666,7 +1775,7 @@ class MetadataType {
|
|
|
1666
1775
|
return null;
|
|
1667
1776
|
}
|
|
1668
1777
|
/**
|
|
1669
|
-
* helper for {@link buildTemplate}
|
|
1778
|
+
* helper for {@link MetadataType.buildTemplate}
|
|
1670
1779
|
* handles extracted code if any are found for complex types
|
|
1671
1780
|
*
|
|
1672
1781
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
@@ -1812,7 +1921,7 @@ class MetadataType {
|
|
|
1812
1921
|
* @param {object} ex response payload from REST API
|
|
1813
1922
|
* @returns {string[] | void} formatted Error Message
|
|
1814
1923
|
*/
|
|
1815
|
-
static
|
|
1924
|
+
static getErrorsREST(ex) {
|
|
1816
1925
|
const errors = [];
|
|
1817
1926
|
if (ex?.response?.status >= 400 && ex?.response?.status < 600) {
|
|
1818
1927
|
if (ex.response.data.errors) {
|
|
@@ -1835,11 +1944,13 @@ class MetadataType {
|
|
|
1835
1944
|
}
|
|
1836
1945
|
} else if (ex.response.data.message) {
|
|
1837
1946
|
errors.push(ex.response.data.message);
|
|
1838
|
-
} else {
|
|
1947
|
+
} else if (ex.response.data) {
|
|
1839
1948
|
errors.push(`Undefined Errors: ${JSON.stringify(ex.response.data)}`);
|
|
1949
|
+
Util.logger.debug(JSON.stringify(ex.response.data));
|
|
1950
|
+
} else {
|
|
1951
|
+
errors.push(`${ex.response.status} ${ex.response.statusText}`);
|
|
1840
1952
|
}
|
|
1841
1953
|
Util.logger.debug(JSON.stringify(ex.config));
|
|
1842
|
-
Util.logger.debug(JSON.stringify(ex.response.data));
|
|
1843
1954
|
}
|
|
1844
1955
|
return errors;
|
|
1845
1956
|
}
|
|
@@ -1902,11 +2013,7 @@ class MetadataType {
|
|
|
1902
2013
|
metadata[overrideKeyField || this.definition.keyField] = customerKey;
|
|
1903
2014
|
const soapType = this.definition.soapType || this.definition.type;
|
|
1904
2015
|
try {
|
|
1905
|
-
await this.client.soap.delete(
|
|
1906
|
-
soapType.charAt(0).toUpperCase() + soapType.slice(1),
|
|
1907
|
-
metadata,
|
|
1908
|
-
null
|
|
1909
|
-
);
|
|
2016
|
+
await this.client.soap.delete(Util.capitalizeFirstLetter(soapType), metadata, null);
|
|
1910
2017
|
if (!handleOutside) {
|
|
1911
2018
|
Util.logger.info(` - deleted ${this.definition.type}: ${customerKey}`);
|
|
1912
2019
|
}
|
|
@@ -1959,7 +2066,7 @@ class MetadataType {
|
|
|
1959
2066
|
* Returns metadata of a business unit that is saved locally
|
|
1960
2067
|
*
|
|
1961
2068
|
* @param {string} readDir root directory of metadata.
|
|
1962
|
-
* @param {boolean} [listBadKeys
|
|
2069
|
+
* @param {boolean} [listBadKeys] do not print errors, used for badKeys()
|
|
1963
2070
|
* @param {object} [buMetadata] Metadata of BU in local directory
|
|
1964
2071
|
* @returns {object} Metadata of BU in local directory
|
|
1965
2072
|
*/
|
|
@@ -1997,6 +2104,57 @@ class MetadataType {
|
|
|
1997
2104
|
const fileList = keyArr.map((key) => File.normalizePath([path, key + typeExtension]));
|
|
1998
2105
|
return fileList;
|
|
1999
2106
|
}
|
|
2107
|
+
|
|
2108
|
+
/**
|
|
2109
|
+
*
|
|
2110
|
+
* @param {TYPE.MetadataTypeMap} metadataMap metadata mapped by their keyField
|
|
2111
|
+
* @returns {string[]} list of keys
|
|
2112
|
+
*/
|
|
2113
|
+
static getKeysForFixing(metadataMap) {
|
|
2114
|
+
const keysForDeploy = [];
|
|
2115
|
+
if (Object.keys(metadataMap).length) {
|
|
2116
|
+
Util.logger.info(
|
|
2117
|
+
`Searching for ${this.definition.type} keys among downloaded items that need fixing:`
|
|
2118
|
+
);
|
|
2119
|
+
for (const item of Object.values(metadataMap)) {
|
|
2120
|
+
if (item[this.definition.nameField].length > this.definition.maxKeyLength) {
|
|
2121
|
+
Util.logger.warn(
|
|
2122
|
+
`Name of the item ${
|
|
2123
|
+
item[this.definition.keyField]
|
|
2124
|
+
} is too long for a key. Consider renaming your item. Key will be equal first ${
|
|
2125
|
+
this.definition.maxKeyLength
|
|
2126
|
+
} characters of the name`
|
|
2127
|
+
);
|
|
2128
|
+
item[this.definition.nameField] = item[this.definition.nameField].slice(
|
|
2129
|
+
0,
|
|
2130
|
+
this.definition.maxKeyLength
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
if (
|
|
2135
|
+
item[this.definition.nameField] != item[this.definition.keyField] &&
|
|
2136
|
+
!this.definition.keyIsFixed
|
|
2137
|
+
) {
|
|
2138
|
+
keysForDeploy.push(item[this.definition.keyField]);
|
|
2139
|
+
Util.logger.info(
|
|
2140
|
+
` - added ${this.definition.type} to fixKey queue: ${
|
|
2141
|
+
item[this.definition.keyField]
|
|
2142
|
+
}`
|
|
2143
|
+
);
|
|
2144
|
+
} else {
|
|
2145
|
+
Util.logger.info(
|
|
2146
|
+
Util.getGrayMsg(
|
|
2147
|
+
` ☇ skipping ${this.definition.type} ${
|
|
2148
|
+
item[this.definition.keyField]
|
|
2149
|
+
}: key does not need to be updated`
|
|
2150
|
+
)
|
|
2151
|
+
);
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
Util.logger.info(`Found ${keysForDeploy.length} ${this.definition.type} keys to fix`);
|
|
2155
|
+
}
|
|
2156
|
+
return keysForDeploy;
|
|
2157
|
+
}
|
|
2000
2158
|
}
|
|
2001
2159
|
|
|
2002
2160
|
MetadataType.definition = {
|
|
@@ -96,7 +96,7 @@ class MobileKeyword extends MetadataType {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* helper for {@link parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword
|
|
99
|
+
* helper for {@link MobileKeyword.parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword
|
|
100
100
|
*
|
|
101
101
|
* @private
|
|
102
102
|
* @param {TYPE.MetadataType} metadata single item
|
|
@@ -106,7 +106,7 @@ class MobileKeyword extends MetadataType {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
|
-
* helper for {@link preDeployTasks} and {@link createOrUpdate} to ensure we have code & keyword properly set
|
|
109
|
+
* helper for {@link MobileKeyword.preDeployTasks} and {@link MobileKeyword.createOrUpdate} to ensure we have code & keyword properly set
|
|
110
110
|
*
|
|
111
111
|
* @private
|
|
112
112
|
* @param {TYPE.MetadataType} metadata single item
|
|
@@ -192,7 +192,7 @@ class MobileKeyword extends MetadataType {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
/**
|
|
195
|
-
* helper for {@link retrieve} and {@link retrieveAsTemplate}
|
|
195
|
+
* helper for {@link MobileKeyword.retrieve} and {@link MobileKeyword.retrieveAsTemplate}
|
|
196
196
|
*
|
|
197
197
|
* @private
|
|
198
198
|
* @param {string} key customer key of single item to retrieve / name of the metadata file
|
|
@@ -281,7 +281,7 @@ class MobileKeyword extends MetadataType {
|
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
/**
|
|
284
|
-
* helper for {@link
|
|
284
|
+
* helper for {@link MobileKeyword.postRetrieveTasks} and {@link MobileKeyword._buildForNested}
|
|
285
285
|
*
|
|
286
286
|
* @param {string} metadataScript the code of the file
|
|
287
287
|
* @returns {{fileExt:string,code:string}} returns found extension and file content
|
|
@@ -349,7 +349,7 @@ class MobileKeyword extends MetadataType {
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
/**
|
|
352
|
-
* helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested}
|
|
352
|
+
* helper for {@link MobileKeyword.buildTemplateForNested} / {@link MobileKeyword.buildDefinitionForNested}
|
|
353
353
|
* handles extracted code if any are found for complex types
|
|
354
354
|
*
|
|
355
355
|
* @param {string} templateDir Directory where metadata templates are stored
|
|
@@ -445,7 +445,7 @@ class MobileKeyword extends MetadataType {
|
|
|
445
445
|
return metadata;
|
|
446
446
|
}
|
|
447
447
|
/**
|
|
448
|
-
* helper for {@link createREST}
|
|
448
|
+
* helper for {@link MetadataType.createREST}
|
|
449
449
|
*
|
|
450
450
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
451
451
|
* @param {object} apiResponse varies depending on the API call
|
|
@@ -455,7 +455,7 @@ class MobileKeyword extends MetadataType {
|
|
|
455
455
|
await super.postDeployTasks_legacyApi(metadataEntry, apiResponse);
|
|
456
456
|
}
|
|
457
457
|
/**
|
|
458
|
-
* helper for {@link updateREST}
|
|
458
|
+
* helper for {@link MetadataType.updateREST}
|
|
459
459
|
*
|
|
460
460
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
461
461
|
* @param {object} apiResponse varies depending on the API call
|
|
@@ -466,7 +466,7 @@ class MobileKeyword extends MetadataType {
|
|
|
466
466
|
}
|
|
467
467
|
|
|
468
468
|
/**
|
|
469
|
-
* helper for {@link preDeployTasks} that loads extracted code content back into JSON
|
|
469
|
+
* helper for {@link MobileKeyword.preDeployTasks} that loads extracted code content back into JSON
|
|
470
470
|
*
|
|
471
471
|
* @param {TYPE.MetadataTypeItem} metadata a single definition
|
|
472
472
|
* @param {string} deployDir directory of deploy files
|
|
@@ -501,7 +501,7 @@ class MobileKeyword extends MetadataType {
|
|
|
501
501
|
*/
|
|
502
502
|
static async deleteByKey(key) {
|
|
503
503
|
// get id from cache
|
|
504
|
-
const { metadata } = await this.retrieveForCache(key);
|
|
504
|
+
const { metadata } = await this.retrieveForCache(undefined, undefined, key);
|
|
505
505
|
if (!metadata[key]) {
|
|
506
506
|
Util.logger.error(`Could not find ${this.definition.type} with key ${key}.`);
|
|
507
507
|
return false;
|
|
@@ -83,7 +83,7 @@ class MobileMessage extends MetadataType {
|
|
|
83
83
|
return super.createREST(metadata, '/legacy/v1/beta/mobile/message/');
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
|
-
* helper for {@link preDeployTasks} that loads extracted code content back into JSON
|
|
86
|
+
* helper for {@link MobileMessage.preDeployTasks} that loads extracted code content back into JSON
|
|
87
87
|
*
|
|
88
88
|
* @param {TYPE.MetadataTypeItem} metadata a single definition
|
|
89
89
|
* @param {string} deployDir directory of deploy files
|
|
@@ -110,7 +110,7 @@ class MobileMessage extends MetadataType {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
|
-
* helper for {@link
|
|
113
|
+
* helper for {@link MobileMessage.postRetrieveTasks} and {@link MobileMessage._buildForNested}
|
|
114
114
|
*
|
|
115
115
|
* @param {string} code the code of the file
|
|
116
116
|
* @returns {{fileExt:string,code:string}} returns found extension and file content
|
|
@@ -304,7 +304,7 @@ class MobileMessage extends MetadataType {
|
|
|
304
304
|
return metadata;
|
|
305
305
|
}
|
|
306
306
|
/**
|
|
307
|
-
* helper for {@link createREST}
|
|
307
|
+
* helper for {@link MetadataType.createREST}
|
|
308
308
|
*
|
|
309
309
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
310
310
|
* @param {object} apiResponse varies depending on the API call
|
|
@@ -314,7 +314,7 @@ class MobileMessage extends MetadataType {
|
|
|
314
314
|
await super.postDeployTasks_legacyApi(metadataEntry, apiResponse);
|
|
315
315
|
}
|
|
316
316
|
/**
|
|
317
|
-
* helper for {@link updateREST}
|
|
317
|
+
* helper for {@link MetadataType.updateREST}
|
|
318
318
|
*
|
|
319
319
|
* @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
|
|
320
320
|
* @param {object} apiResponse varies depending on the API call
|
|
@@ -380,7 +380,7 @@ class MobileMessage extends MetadataType {
|
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
/**
|
|
383
|
-
* helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested}
|
|
383
|
+
* helper for {@link MobileMessage.buildTemplateForNested} / {@link MobileMessage.buildDefinitionForNested}
|
|
384
384
|
* handles extracted code if any are found for complex types
|
|
385
385
|
*
|
|
386
386
|
* @param {string} templateDir Directory where metadata templates are stored
|