mcdev 5.0.2 → 5.2.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/.coverage-comment-template.svelte +177 -161
- package/.eslintrc.json +4 -4
- package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +2 -2
- package/.github/dependabot.yml +8 -0
- package/.github/workflows/coverage-base-update.yml +6 -2
- package/.github/workflows/coverage-develop-branch.yml +7 -8
- package/.github/workflows/coverage-main-branch.yml +7 -8
- package/.github/workflows/coverage.yml +7 -4
- package/.husky/post-checkout +4 -2
- package/.husky/post-merge +1 -0
- package/.vscode/extensions.json +4 -0
- package/docs/dist/documentation.md +756 -294
- package/lib/Deployer.js +28 -28
- package/lib/MetadataTypeDefinitions.js +1 -1
- package/lib/MetadataTypeInfo.js +1 -1
- package/lib/Retriever.js +1 -1
- package/lib/cli.js +184 -6
- package/lib/index.js +493 -22
- package/lib/metadataTypes/Asset.js +10 -11
- package/lib/metadataTypes/AttributeGroup.js +76 -2
- package/lib/metadataTypes/AttributeSet.js +260 -0
- package/lib/metadataTypes/Automation.js +771 -247
- package/lib/metadataTypes/DataExtension.js +7 -7
- package/lib/metadataTypes/DataExtensionField.js +1 -1
- package/lib/metadataTypes/Event.js +2 -3
- package/lib/metadataTypes/Folder.js +1 -1
- package/lib/metadataTypes/Journey.js +5 -6
- package/lib/metadataTypes/MetadataType.js +187 -60
- package/lib/metadataTypes/MobileKeyword.js +8 -8
- package/lib/metadataTypes/MobileMessage.js +5 -5
- package/lib/metadataTypes/Query.js +47 -5
- package/lib/metadataTypes/Script.js +3 -3
- package/lib/metadataTypes/TransactionalSMS.js +5 -5
- package/lib/metadataTypes/TriggeredSend.js +25 -50
- package/lib/metadataTypes/User.js +7 -4
- package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
- package/lib/metadataTypes/definitions/AttributeGroup.definition.js +117 -106
- package/lib/metadataTypes/definitions/{SetDefinition.definition.js → AttributeSet.definition.js} +54 -27
- package/lib/metadataTypes/definitions/Automation.definition.js +74 -21
- package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -0
- package/lib/metadataTypes/definitions/DataExtract.definition.js +1 -0
- package/lib/metadataTypes/definitions/EmailSend.definition.js +1 -0
- package/lib/metadataTypes/definitions/Event.definition.js +1 -0
- package/lib/metadataTypes/definitions/Filter.definition.js +1 -0
- package/lib/metadataTypes/definitions/ImportFile.definition.js +37 -6
- package/lib/metadataTypes/definitions/MobileKeyword.definition.js +1 -0
- package/lib/metadataTypes/definitions/Query.definition.js +1 -0
- package/lib/metadataTypes/definitions/Role.definition.js +1 -0
- package/lib/metadataTypes/definitions/TriggeredSend.definition.js +2 -0
- package/lib/metadataTypes/definitions/User.definition.js +1 -0
- package/lib/util/cache.js +9 -4
- package/lib/util/cli.js +40 -0
- package/lib/util/devops.js +13 -11
- package/lib/util/file.js +2 -2
- package/lib/util/init.js +84 -0
- package/lib/util/util.js +268 -137
- package/package.json +11 -11
- package/test/general.test.js +26 -0
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +52 -0
- package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +45 -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/{testExistingQuery.query-meta.json → testExisting_query.query-meta.json} +2 -2
- 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/query/{testNewQuery.query-meta.json → testNew_query.query-meta.json} +2 -2
- 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/triggeredSend/testExisting_triggeredSend.triggeredSend-meta.json +29 -0
- package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testNew_triggeredSend.triggeredSend-meta.json +29 -0
- package/test/resourceFactory.js +132 -24
- 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/user/retrieve-expected.md +4 -2
- package/test/resources/9999999/attributeGroup/retrieve-expected.json +25 -0
- package/test/resources/9999999/attributeSet/retrieve-expected.json +748 -0
- package/test/resources/9999999/automation/build-expected.json +57 -0
- package/test/resources/9999999/automation/create-expected.json +45 -0
- package/test/resources/9999999/automation/create-testNew_automation-expected.md +28 -0
- package/test/resources/9999999/automation/delete-response.xml +40 -0
- 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 +57 -0
- package/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +30 -0
- 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 +57 -0
- package/test/resources/9999999/automation/update-expected.json +45 -0
- package/test/resources/9999999/automation/update-testExisting_automation-expected.md +28 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +85 -0
- package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/patch-response.json +85 -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 +85 -0
- package/test/resources/9999999/automation/v1/automations/post-response.json +86 -0
- package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/get-response.json +38 -0
- package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/patch-response.json +38 -0
- package/test/resources/9999999/automation/v1/dataextracts/get-response.json +20 -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/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/get-response.json +18 -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/get-response.json +15 -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 +38 -0
- 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/actions/start/post-response.txt +1 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +2 -2
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +2 -2
- 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 +22 -5
- package/test/resources/9999999/automation/v1/queries/post-response.json +2 -2
- 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 +27 -0
- package/test/resources/9999999/automation/v1/scripts/post-response.json +10 -0
- package/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml +52 -0
- package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml +98 -0
- package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml +99 -0
- 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=automations-response.xml +48 -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=queryactivity-response.xml +48 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml +48 -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 +45 -0
- package/test/resources/9999999/email/retrieve-response.xml +203 -0
- package/test/resources/9999999/emailSendDefinition/retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml +85 -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 +585 -0
- package/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json +19807 -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/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/get-response.json +21 -0
- package/test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/post-response.json +0 -0
- package/test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json +30 -0
- package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation-response.xml +30 -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-CustomerKey=testNew_automation-response.xml +30 -0
- package/test/resources/9999999/program/retrieve-Name=testExisting_automation-response.xml +31 -0
- package/test/resources/9999999/program/retrieve-response.xml +50 -0
- package/test/resources/9999999/query/build-expected.json +2 -2
- package/test/resources/9999999/query/get-expected.json +2 -2
- package/test/resources/9999999/query/get2-expected.json +2 -2
- package/test/resources/9999999/query/patch-expected.json +2 -2
- 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/query/post-expected.json +2 -2
- package/test/resources/9999999/query/template-expected.json +2 -2
- 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/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/type.attributeGroup.test.js +55 -0
- package/test/type.attributeSet.test.js +55 -0
- package/test/type.automation.test.js +886 -0
- package/test/type.dataExtension.test.js +3 -1
- package/test/type.dataExtract.test.js +187 -0
- package/test/type.fileTransfer.test.js +185 -0
- package/test/type.importFile.test.js +186 -0
- package/test/type.mobileKeyword.test.js +0 -1
- package/test/type.query.test.js +497 -33
- package/test/type.script.test.js +367 -0
- package/test/type.triggeredSend.test.js +152 -0
- package/test/type.user.test.js +37 -11
- package/test/utils.js +10 -6
- package/.coverage-comment-template.md +0 -20
- package/lib/metadataTypes/SetDefinition.js +0 -37
- /package/test/mockRoot/deploy/testInstance/testBU/query/{testExistingQuery.query-meta.sql → testExisting_query.query-meta.sql} +0 -0
- /package/test/mockRoot/deploy/testInstance/testBU/query/{testNewQuery.query-meta.sql → testNew_query.query-meta.sql} +0 -0
- /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/queryDefinition/{retrieve-response.xml → retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml} +0 -0
package/lib/Deployer.js
CHANGED
|
@@ -44,17 +44,17 @@ class Deployer {
|
|
|
44
44
|
* @param {string} businessUnit references credentials from properties.json
|
|
45
45
|
* @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit deployment to given metadata type
|
|
46
46
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
47
|
-
* @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder
|
|
48
47
|
* @returns {Promise.<Object.<string,TYPE.MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type)
|
|
49
48
|
*/
|
|
50
|
-
static async deploy(businessUnit, selectedTypesArr, keyArr
|
|
49
|
+
static async deploy(businessUnit, selectedTypesArr, keyArr) {
|
|
51
50
|
Util.logger.info('mcdev:: Deploy');
|
|
52
51
|
const buMultiMetadataTypeMap = {};
|
|
53
52
|
const properties = await config.getProperties();
|
|
54
53
|
if (!(await config.checkProperties(properties))) {
|
|
55
54
|
return null;
|
|
56
55
|
}
|
|
57
|
-
|
|
56
|
+
const deployDirBak = properties.directories.deploy;
|
|
57
|
+
if (Util.OPTIONS.fromRetrieve) {
|
|
58
58
|
properties.directories.deploy = properties.directories.retrieve;
|
|
59
59
|
}
|
|
60
60
|
if (Array.isArray(selectedTypesArr)) {
|
|
@@ -66,7 +66,7 @@ class Deployer {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
if (
|
|
69
|
-
fromRetrieve &&
|
|
69
|
+
Util.OPTIONS.fromRetrieve &&
|
|
70
70
|
(!selectedTypesArr ||
|
|
71
71
|
!Array.isArray(selectedTypesArr) ||
|
|
72
72
|
!selectedTypesArr.length ||
|
|
@@ -97,13 +97,12 @@ class Deployer {
|
|
|
97
97
|
bu,
|
|
98
98
|
properties,
|
|
99
99
|
selectedTypesArr,
|
|
100
|
-
keyArr
|
|
101
|
-
fromRetrieve
|
|
100
|
+
keyArr
|
|
102
101
|
);
|
|
103
102
|
buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap;
|
|
104
103
|
counter_credBu++;
|
|
105
104
|
Util.logger.info('');
|
|
106
|
-
Util.
|
|
105
|
+
Util.startLogger(true);
|
|
107
106
|
}
|
|
108
107
|
} else {
|
|
109
108
|
// anything but "*" passed in
|
|
@@ -137,7 +136,7 @@ class Deployer {
|
|
|
137
136
|
return;
|
|
138
137
|
}
|
|
139
138
|
// valid credential given and -all- BUs targeted
|
|
140
|
-
Util.logger.info(
|
|
139
|
+
Util.logger.info(`:: Deploying all BUs for ${cred}`);
|
|
141
140
|
let counter_credBu = 0;
|
|
142
141
|
// for (const bu in properties.credentials[cred].businessUnits) {
|
|
143
142
|
const deployFolders = await File.readDirectories(
|
|
@@ -151,15 +150,14 @@ class Deployer {
|
|
|
151
150
|
buPath,
|
|
152
151
|
properties,
|
|
153
152
|
selectedTypesArr,
|
|
154
|
-
keyArr
|
|
155
|
-
fromRetrieve
|
|
153
|
+
keyArr
|
|
156
154
|
);
|
|
157
155
|
buMultiMetadataTypeMap[cred + '/' + buPath] = multiMetadataTypeMap;
|
|
158
156
|
counter_credBu++;
|
|
159
157
|
Util.logger.info('');
|
|
160
|
-
Util.
|
|
158
|
+
Util.startLogger(true);
|
|
161
159
|
}
|
|
162
|
-
Util.logger.info(
|
|
160
|
+
Util.logger.info(` :: ${counter_credBu} BUs for ${cred}\n`);
|
|
163
161
|
} else {
|
|
164
162
|
// either bad credential or specific BU or no BU given
|
|
165
163
|
const multiMetadataTypeMap = await this._deployBU(
|
|
@@ -167,30 +165,31 @@ class Deployer {
|
|
|
167
165
|
bu,
|
|
168
166
|
properties,
|
|
169
167
|
selectedTypesArr,
|
|
170
|
-
keyArr
|
|
171
|
-
fromRetrieve
|
|
168
|
+
keyArr
|
|
172
169
|
);
|
|
173
170
|
counter_credBu++;
|
|
174
171
|
buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap;
|
|
175
172
|
}
|
|
176
173
|
}
|
|
174
|
+
if (Util.OPTIONS.fromRetrieve) {
|
|
175
|
+
properties.directories.deploy = deployDirBak;
|
|
176
|
+
}
|
|
177
177
|
if (counter_credBu !== 0) {
|
|
178
|
-
Util.logger.info(
|
|
178
|
+
Util.logger.info(`:: Deployed ${counter_credBu} BUs\n`);
|
|
179
179
|
}
|
|
180
180
|
return buMultiMetadataTypeMap;
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
|
-
* helper for {@link deploy}
|
|
183
|
+
* helper for {@link Deployer.deploy}
|
|
184
184
|
*
|
|
185
185
|
* @param {string} cred name of Credential
|
|
186
186
|
* @param {string} bu name of BU
|
|
187
187
|
* @param {TYPE.Mcdevrc} properties General configuration to be used in retrieve
|
|
188
188
|
* @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type
|
|
189
189
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
190
|
-
* @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder
|
|
191
190
|
* @returns {Promise.<TYPE.MultiMetadataTypeMap>} ensure that BUs are worked on sequentially
|
|
192
191
|
*/
|
|
193
|
-
static async _deployBU(cred, bu, properties, typeArr, keyArr
|
|
192
|
+
static async _deployBU(cred, bu, properties, typeArr, keyArr) {
|
|
194
193
|
const buPath = `${cred}/${bu}`;
|
|
195
194
|
Util.logger.info(`:: Deploying to ${buPath}`);
|
|
196
195
|
const buObject = await Cli.getCredentialObject(properties, buPath, null, true);
|
|
@@ -201,7 +200,7 @@ class Deployer {
|
|
|
201
200
|
const deployer = new Deployer(properties, buObject);
|
|
202
201
|
try {
|
|
203
202
|
// await is required or the calls end up conflicting
|
|
204
|
-
multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr
|
|
203
|
+
multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr);
|
|
205
204
|
} catch (ex) {
|
|
206
205
|
Util.logger.errorStack(ex, 'mcdev.deploy failed');
|
|
207
206
|
}
|
|
@@ -214,11 +213,9 @@ class Deployer {
|
|
|
214
213
|
*
|
|
215
214
|
* @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type (can include subtype)
|
|
216
215
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
217
|
-
* @param {boolean} [fromRetrieve] if true, no folders will be updated/created
|
|
218
|
-
* @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets
|
|
219
216
|
* @returns {Promise.<TYPE.MultiMetadataTypeMap>} Promise of all deployed metadata
|
|
220
217
|
*/
|
|
221
|
-
async _deploy(typeArr, keyArr
|
|
218
|
+
async _deploy(typeArr, keyArr) {
|
|
222
219
|
if (await File.pathExists(this.deployDir)) {
|
|
223
220
|
/** @type {TYPE.MultiMetadataTypeMap} */
|
|
224
221
|
this.metadata = Deployer.readBUMetadata(this.deployDir, typeArr);
|
|
@@ -252,7 +249,7 @@ class Deployer {
|
|
|
252
249
|
}
|
|
253
250
|
}
|
|
254
251
|
|
|
255
|
-
if (!fromRetrieve) {
|
|
252
|
+
if (!Util.OPTIONS.fromRetrieve) {
|
|
256
253
|
await Deployer.createFolderDefinitions(
|
|
257
254
|
this.deployDir,
|
|
258
255
|
this.metadata,
|
|
@@ -292,13 +289,16 @@ class Deployer {
|
|
|
292
289
|
// TODO rewrite to allow deploying only a specific sub-type; currently, subtypes are ignored when executing deploy
|
|
293
290
|
const type = metadataType;
|
|
294
291
|
if (this.metadata[type]) {
|
|
295
|
-
Util.logger.info(
|
|
292
|
+
Util.logger.info(
|
|
293
|
+
'Deploying: ' +
|
|
294
|
+
metadataType +
|
|
295
|
+
(Util.OPTIONS.fromRetrieve ? ' (from retrieve folder)' : '')
|
|
296
|
+
);
|
|
296
297
|
|
|
297
298
|
const result = await MetadataTypeInfo[type].deploy(
|
|
298
299
|
this.metadata[type],
|
|
299
300
|
this.deployDir,
|
|
300
|
-
this.retrieveDir
|
|
301
|
-
isRefresh
|
|
301
|
+
this.retrieveDir
|
|
302
302
|
);
|
|
303
303
|
multiMetadataTypeMap[type] = result;
|
|
304
304
|
cache.mergeMetadata(type, result);
|
|
@@ -312,7 +312,7 @@ class Deployer {
|
|
|
312
312
|
*
|
|
313
313
|
* @param {string} deployDir root directory of metadata.
|
|
314
314
|
* @param {string[]} [typeArr] limit deployment to given metadata type
|
|
315
|
-
* @param {boolean} [listBadKeys
|
|
315
|
+
* @param {boolean} [listBadKeys] do not print errors, used for badKeys()
|
|
316
316
|
* @returns {TYPE.MultiMetadataTypeMap} Metadata of BU in local directory
|
|
317
317
|
*/
|
|
318
318
|
static readBUMetadata(deployDir, typeArr, listBadKeys) {
|
|
@@ -387,7 +387,7 @@ class Deployer {
|
|
|
387
387
|
const allFolders = Object.keys(metadata[metadataType])
|
|
388
388
|
.filter(
|
|
389
389
|
// filter out root folders (which would not have a slash in their path)
|
|
390
|
-
(key) => metadata[metadataType][key].r__folder_Path
|
|
390
|
+
(key) => metadata[metadataType][key].r__folder_Path?.includes('/')
|
|
391
391
|
)
|
|
392
392
|
.filter(
|
|
393
393
|
// filter out dataExtension folders other than standard & shared (--> synchronized / salesforce are not allowed)
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const MetadataTypeDefinitions = {
|
|
7
7
|
asset: require('./metadataTypes/definitions/Asset.definition'),
|
|
8
8
|
attributeGroup: require('./metadataTypes/definitions/AttributeGroup.definition'),
|
|
9
|
+
attributeSet: require('./metadataTypes/definitions/AttributeSet.definition'),
|
|
9
10
|
automation: require('./metadataTypes/definitions/Automation.definition'),
|
|
10
11
|
campaign: require('./metadataTypes/definitions/Campaign.definition'),
|
|
11
12
|
contentArea: require('./metadataTypes/definitions/ContentArea.definition'),
|
|
@@ -32,7 +33,6 @@ const MetadataTypeDefinitions = {
|
|
|
32
33
|
role: require('./metadataTypes/definitions/Role.definition'),
|
|
33
34
|
script: require('./metadataTypes/definitions/Script.definition'),
|
|
34
35
|
sendClassification: require('./metadataTypes/definitions/SendClassification.definition'),
|
|
35
|
-
setDefinition: require('./metadataTypes/definitions/SetDefinition.definition'),
|
|
36
36
|
transactionalEmail: require('./metadataTypes/definitions/TransactionalEmail.definition'),
|
|
37
37
|
transactionalPush: require('./metadataTypes/definitions/TransactionalPush.definition'),
|
|
38
38
|
transactionalSMS: require('./metadataTypes/definitions/TransactionalSMS.definition'),
|
package/lib/MetadataTypeInfo.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const MetadataTypeInfo = {
|
|
7
7
|
asset: require('./metadataTypes/Asset'),
|
|
8
8
|
attributeGroup: require('./metadataTypes/AttributeGroup'),
|
|
9
|
+
attributeSet: require('./metadataTypes/AttributeSet'),
|
|
9
10
|
automation: require('./metadataTypes/Automation'),
|
|
10
11
|
campaign: require('./metadataTypes/Campaign'),
|
|
11
12
|
contentArea: require('./metadataTypes/ContentArea'),
|
|
@@ -32,7 +33,6 @@ const MetadataTypeInfo = {
|
|
|
32
33
|
role: require('./metadataTypes/Role'),
|
|
33
34
|
script: require('./metadataTypes/Script'),
|
|
34
35
|
sendClassification: require('./metadataTypes/SendClassification'),
|
|
35
|
-
setDefinition: require('./metadataTypes/SetDefinition'),
|
|
36
36
|
transactionalEmail: require('./metadataTypes/TransactionalEmail'),
|
|
37
37
|
transactionalPush: require('./metadataTypes/TransactionalPush'),
|
|
38
38
|
transactionalSMS: require('./metadataTypes/TransactionalSMS'),
|
package/lib/Retriever.js
CHANGED
|
@@ -189,7 +189,7 @@ class Retriever {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/**
|
|
192
|
-
* helper for {@link retrieve} to get all dependencies of the given types
|
|
192
|
+
* helper for {@link Retriever.retrieve} to get all dependencies of the given types
|
|
193
193
|
*
|
|
194
194
|
* @param {TYPE.SupportedMetadataTypes[]} metadataTypes list of metadata types to retrieve; can include subtypes!
|
|
195
195
|
* @returns {TYPE.SupportedMetadataTypes[]} unique list dependent metadata types
|
package/lib/cli.js
CHANGED
|
@@ -31,6 +31,12 @@ yargs
|
|
|
31
31
|
.positional('KEY', {
|
|
32
32
|
type: 'string',
|
|
33
33
|
describe: 'metadata keys that shall be exclusively downloaded',
|
|
34
|
+
})
|
|
35
|
+
.option('like', {
|
|
36
|
+
type: 'string',
|
|
37
|
+
group: 'Options for retrieve:',
|
|
38
|
+
describe:
|
|
39
|
+
'filter metadata components (can include % as wildcard or _ for a single character)',
|
|
34
40
|
});
|
|
35
41
|
},
|
|
36
42
|
handler: (argv) => {
|
|
@@ -59,22 +65,38 @@ yargs
|
|
|
59
65
|
})
|
|
60
66
|
.option('changeKeyField', {
|
|
61
67
|
type: 'string',
|
|
68
|
+
group: 'Options for deploy:',
|
|
62
69
|
describe:
|
|
63
70
|
'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.',
|
|
64
71
|
})
|
|
65
72
|
.option('changeKeyValue', {
|
|
66
73
|
type: 'string',
|
|
74
|
+
group: 'Options for deploy:',
|
|
67
75
|
describe:
|
|
68
76
|
'allows updating the key of the metadata to the provided value. Only available if a single type and key is deployed',
|
|
69
77
|
})
|
|
70
78
|
.option('fromRetrieve', {
|
|
71
79
|
type: 'boolean',
|
|
80
|
+
group: 'Options for deploy:',
|
|
72
81
|
describe: 'optionally deploy from retrieve folder',
|
|
73
82
|
})
|
|
74
83
|
.option('refresh', {
|
|
75
84
|
type: 'boolean',
|
|
85
|
+
group: 'Options for deploy:',
|
|
76
86
|
describe:
|
|
77
87
|
'optional for asset-message: runs refresh command for related triggeredSends after deploy',
|
|
88
|
+
})
|
|
89
|
+
.option('execute', {
|
|
90
|
+
type: 'boolean',
|
|
91
|
+
group: 'Options for deploy:',
|
|
92
|
+
describe:
|
|
93
|
+
'optional: executes item after deploy; this will run the item once immediately',
|
|
94
|
+
})
|
|
95
|
+
.option('schedule', {
|
|
96
|
+
type: 'boolean',
|
|
97
|
+
group: 'Options for deploy:',
|
|
98
|
+
describe:
|
|
99
|
+
'optionally start existing schedule instead of running item once immediately (only works for automations)',
|
|
78
100
|
});
|
|
79
101
|
},
|
|
80
102
|
handler: (argv) => {
|
|
@@ -307,6 +329,7 @@ yargs
|
|
|
307
329
|
builder: (yargs) => {
|
|
308
330
|
yargs.option('json', {
|
|
309
331
|
type: 'boolean',
|
|
332
|
+
group: 'Options for explainTypes:',
|
|
310
333
|
describe: 'optionaly return info in json format',
|
|
311
334
|
});
|
|
312
335
|
},
|
|
@@ -316,7 +339,7 @@ yargs
|
|
|
316
339
|
},
|
|
317
340
|
})
|
|
318
341
|
.command({
|
|
319
|
-
command: 'createDeltaPkg [range]
|
|
342
|
+
command: 'createDeltaPkg [range]',
|
|
320
343
|
aliases: ['cdp'],
|
|
321
344
|
desc: 'Copies commit-based file delta into deploy folder',
|
|
322
345
|
builder: (yargs) => {
|
|
@@ -327,11 +350,13 @@ yargs
|
|
|
327
350
|
})
|
|
328
351
|
.option('filter', {
|
|
329
352
|
type: 'string',
|
|
353
|
+
group: 'Options for createDeltaPkg:',
|
|
330
354
|
describe:
|
|
331
355
|
'Disable templating & instead filter by the specified BU path (comma separated), can include subtype, will be prefixed with "retrieve/"',
|
|
332
356
|
})
|
|
333
357
|
.option('commitHistory', {
|
|
334
358
|
type: 'number',
|
|
359
|
+
group: 'Options for createDeltaPkg:',
|
|
335
360
|
describe: 'Number of commits to look back for changes (supersedes config)',
|
|
336
361
|
});
|
|
337
362
|
},
|
|
@@ -389,6 +414,147 @@ yargs
|
|
|
389
414
|
Mcdev.refresh(argv.BU, argv.TYPE, csvToArray(argv.KEY));
|
|
390
415
|
},
|
|
391
416
|
})
|
|
417
|
+
.command({
|
|
418
|
+
command: 'execute <BU> <TYPE> [KEY]',
|
|
419
|
+
aliases: ['exec', 'start'],
|
|
420
|
+
desc: 'executes the entity (query/journey/automation etc.)',
|
|
421
|
+
builder: (yargs) => {
|
|
422
|
+
yargs
|
|
423
|
+
.positional('BU', {
|
|
424
|
+
type: 'string',
|
|
425
|
+
describe: 'the business unit where to start an item',
|
|
426
|
+
})
|
|
427
|
+
.positional('TYPE', {
|
|
428
|
+
type: 'string',
|
|
429
|
+
describe: 'metadata type',
|
|
430
|
+
})
|
|
431
|
+
.positional('KEY', {
|
|
432
|
+
type: 'string',
|
|
433
|
+
describe: 'key(s) of the metadata component(s)',
|
|
434
|
+
})
|
|
435
|
+
.option('like', {
|
|
436
|
+
type: 'string',
|
|
437
|
+
group: 'Options for execute:',
|
|
438
|
+
describe:
|
|
439
|
+
'filter metadata components (can include % as wildcard or _ for a single character)',
|
|
440
|
+
})
|
|
441
|
+
.option('schedule', {
|
|
442
|
+
type: 'boolean',
|
|
443
|
+
group: 'Options for execute:',
|
|
444
|
+
describe:
|
|
445
|
+
'optionally start existing schedule instead of running item once immediately (only works for automations)',
|
|
446
|
+
});
|
|
447
|
+
},
|
|
448
|
+
handler: (argv) => {
|
|
449
|
+
Mcdev.setOptions(argv);
|
|
450
|
+
// ! do not allow multiple types to be passed in here via csvToArray
|
|
451
|
+
Mcdev.execute(argv.BU, argv.TYPE, csvToArray(argv.KEY));
|
|
452
|
+
},
|
|
453
|
+
})
|
|
454
|
+
.command({
|
|
455
|
+
command: 'schedule <BU> <TYPE> [KEY]',
|
|
456
|
+
aliases: ['sched'],
|
|
457
|
+
desc: 'starts the predefined schedule of the item (shortcut for running execute --schedule)',
|
|
458
|
+
builder: (yargs) => {
|
|
459
|
+
yargs
|
|
460
|
+
.positional('BU', {
|
|
461
|
+
type: 'string',
|
|
462
|
+
describe: 'the business unit where to start an item',
|
|
463
|
+
})
|
|
464
|
+
.positional('TYPE', {
|
|
465
|
+
type: 'string',
|
|
466
|
+
describe: 'metadata type',
|
|
467
|
+
})
|
|
468
|
+
.positional('KEY', {
|
|
469
|
+
type: 'string',
|
|
470
|
+
describe: 'key(s) of the metadata component(s)',
|
|
471
|
+
})
|
|
472
|
+
.option('like', {
|
|
473
|
+
type: 'string',
|
|
474
|
+
group: 'Options for execute:',
|
|
475
|
+
describe:
|
|
476
|
+
'filter metadata components (can include % as wildcard or _ for a single character)',
|
|
477
|
+
});
|
|
478
|
+
},
|
|
479
|
+
handler: (argv) => {
|
|
480
|
+
Mcdev.setOptions(argv);
|
|
481
|
+
// ! do not allow multiple types to be passed in here via csvToArray
|
|
482
|
+
Mcdev.schedule(argv.BU, argv.TYPE, csvToArray(argv.KEY));
|
|
483
|
+
},
|
|
484
|
+
})
|
|
485
|
+
.command({
|
|
486
|
+
command: 'pause <BU> <TYPE> [KEY]',
|
|
487
|
+
aliases: ['p', 'stop'],
|
|
488
|
+
desc: 'pauses the entity (automation etc.)',
|
|
489
|
+
builder: (yargs) => {
|
|
490
|
+
yargs
|
|
491
|
+
.positional('BU', {
|
|
492
|
+
type: 'string',
|
|
493
|
+
describe: 'the business unit where to start an item',
|
|
494
|
+
})
|
|
495
|
+
.positional('TYPE', {
|
|
496
|
+
type: 'string',
|
|
497
|
+
describe: 'metadata type',
|
|
498
|
+
})
|
|
499
|
+
.positional('KEY', {
|
|
500
|
+
type: 'string',
|
|
501
|
+
describe: 'key(s) of the metadata component(s)',
|
|
502
|
+
})
|
|
503
|
+
.option('like', {
|
|
504
|
+
type: 'string',
|
|
505
|
+
group: 'Options for pause:',
|
|
506
|
+
describe:
|
|
507
|
+
'filter metadata components (can include % as wildcard or _ for a single character)',
|
|
508
|
+
});
|
|
509
|
+
},
|
|
510
|
+
handler: (argv) => {
|
|
511
|
+
Mcdev.setOptions(argv);
|
|
512
|
+
// ! do not allow multiple types to be passed in here via csvToArray
|
|
513
|
+
Mcdev.pause(argv.BU, argv.TYPE, csvToArray(argv.KEY));
|
|
514
|
+
},
|
|
515
|
+
})
|
|
516
|
+
.command({
|
|
517
|
+
command: 'fixKeys <BU> <TYPE> [KEY]',
|
|
518
|
+
aliases: ['fx'],
|
|
519
|
+
desc: 'changes the key of the items to match the name',
|
|
520
|
+
builder: (yargs) => {
|
|
521
|
+
yargs
|
|
522
|
+
.positional('BU', {
|
|
523
|
+
type: 'string',
|
|
524
|
+
describe: 'the business unit where to fix keys',
|
|
525
|
+
})
|
|
526
|
+
.positional('TYPE', {
|
|
527
|
+
type: 'string',
|
|
528
|
+
describe: 'metadata type',
|
|
529
|
+
})
|
|
530
|
+
.positional('KEY', {
|
|
531
|
+
type: 'string',
|
|
532
|
+
describe: 'key(s) of the metadata component(s)',
|
|
533
|
+
})
|
|
534
|
+
.option('like', {
|
|
535
|
+
type: 'string',
|
|
536
|
+
group: 'Options for fixKeys:',
|
|
537
|
+
describe:
|
|
538
|
+
'filter metadata components (can include % as wildcard or _ for a single character)',
|
|
539
|
+
})
|
|
540
|
+
.option('execute', {
|
|
541
|
+
type: 'boolean',
|
|
542
|
+
group: 'Options for fixKeys:',
|
|
543
|
+
describe:
|
|
544
|
+
'optional: executes item after deploy; this will run the item once immediately',
|
|
545
|
+
})
|
|
546
|
+
.option('schedule', {
|
|
547
|
+
type: 'boolean',
|
|
548
|
+
group: 'Options for fixKeys:',
|
|
549
|
+
describe:
|
|
550
|
+
'optionally start existing schedule instead of running item once immediately (only works for automations)',
|
|
551
|
+
});
|
|
552
|
+
},
|
|
553
|
+
handler: (argv) => {
|
|
554
|
+
Mcdev.setOptions(argv);
|
|
555
|
+
Mcdev.fixKeys(argv.BU, argv.TYPE, csvToArray(argv.KEY));
|
|
556
|
+
},
|
|
557
|
+
})
|
|
392
558
|
.command({
|
|
393
559
|
command: 'upgrade',
|
|
394
560
|
aliases: ['up'],
|
|
@@ -410,6 +576,14 @@ yargs
|
|
|
410
576
|
type: 'boolean',
|
|
411
577
|
description: 'Only output errors to CLI',
|
|
412
578
|
})
|
|
579
|
+
.option('noLogColors', {
|
|
580
|
+
type: 'boolean',
|
|
581
|
+
description: 'do not use color codes in CLI log output',
|
|
582
|
+
})
|
|
583
|
+
.option('noLogFile', {
|
|
584
|
+
type: 'boolean',
|
|
585
|
+
description: 'Only output log to CLI but not to files',
|
|
586
|
+
})
|
|
413
587
|
.option('skipInteraction', {
|
|
414
588
|
alias: ['yes', 'y'],
|
|
415
589
|
description: 'Interactive questions where possible and go with defaults instead',
|
|
@@ -438,9 +612,13 @@ function csvToArray(csv) {
|
|
|
438
612
|
return !csv
|
|
439
613
|
? null
|
|
440
614
|
: csv.includes(',')
|
|
441
|
-
? csv
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
615
|
+
? csv
|
|
616
|
+
.split(',')
|
|
617
|
+
.map((item) =>
|
|
618
|
+
// allow whitespace in comma-separated lists
|
|
619
|
+
item.trim()
|
|
620
|
+
)
|
|
621
|
+
// make sure trailing commas are ignored
|
|
622
|
+
.filter(Boolean)
|
|
623
|
+
: [csv.trim()].filter(Boolean);
|
|
446
624
|
}
|