mcdev 4.2.1 → 4.3.1
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/.github/ISSUE_TEMPLATE/bug.yml +3 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +1 -2
- package/.github/pr-labeler.yml +3 -0
- package/.github/workflows/close_issues_on_merge.yml +18 -0
- package/.github/workflows/pr-labeler.yml +19 -0
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/docs/dist/documentation.md +702 -284
- package/lib/Deployer.js +21 -15
- package/lib/Retriever.js +41 -34
- package/lib/cli.js +36 -6
- package/lib/index.js +56 -10
- package/lib/metadataTypes/AccountUser.js +17 -23
- package/lib/metadataTypes/Asset.js +36 -48
- package/lib/metadataTypes/AttributeGroup.js +1 -2
- package/lib/metadataTypes/Automation.js +75 -37
- package/lib/metadataTypes/Campaign.js +4 -3
- package/lib/metadataTypes/ContentArea.js +2 -3
- package/lib/metadataTypes/DataExtension.js +56 -47
- package/lib/metadataTypes/DataExtensionField.js +9 -12
- package/lib/metadataTypes/DataExtensionTemplate.js +2 -3
- package/lib/metadataTypes/DataExtract.js +1 -2
- package/lib/metadataTypes/DataExtractType.js +1 -2
- package/lib/metadataTypes/Discovery.js +3 -4
- package/lib/metadataTypes/Email.js +20 -6
- package/lib/metadataTypes/EmailSendDefinition.js +40 -39
- package/lib/metadataTypes/EventDefinition.js +29 -2
- package/lib/metadataTypes/FileTransfer.js +1 -2
- package/lib/metadataTypes/Filter.js +1 -2
- package/lib/metadataTypes/Folder.js +12 -14
- package/lib/metadataTypes/FtpLocation.js +1 -2
- package/lib/metadataTypes/ImportFile.js +1 -2
- package/lib/metadataTypes/Interaction.js +743 -12
- package/lib/metadataTypes/List.js +36 -33
- package/lib/metadataTypes/MetadataType.js +170 -124
- package/lib/metadataTypes/MobileCode.js +1 -2
- package/lib/metadataTypes/MobileKeyword.js +1 -2
- package/lib/metadataTypes/Query.js +15 -6
- package/lib/metadataTypes/Role.js +10 -11
- package/lib/metadataTypes/Script.js +2 -5
- package/lib/metadataTypes/SetDefinition.js +1 -2
- package/lib/metadataTypes/TransactionalMessage.js +25 -32
- package/lib/metadataTypes/TransactionalSMS.js +3 -4
- package/lib/metadataTypes/TriggeredSendDefinition.js +232 -56
- package/lib/metadataTypes/definitions/Asset.definition.js +1 -1
- package/lib/metadataTypes/definitions/Automation.definition.js +1 -1
- package/lib/metadataTypes/definitions/DataExtension.definition.js +10 -1
- package/lib/metadataTypes/definitions/Email.definition.js +1 -1
- package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +1 -1
- package/lib/metadataTypes/definitions/EventDefinition.definition.js +40 -1
- package/lib/metadataTypes/definitions/Folder.definition.js +31 -0
- package/lib/metadataTypes/definitions/ImportFile.definition.js +1 -1
- package/lib/metadataTypes/definitions/Interaction.definition.js +47 -26
- package/lib/metadataTypes/definitions/List.definition.js +1 -1
- package/lib/metadataTypes/definitions/Query.definition.js +1 -1
- package/lib/metadataTypes/definitions/Script.definition.js +1 -1
- package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +4 -3
- package/lib/metadataTypes/definitions/TransactionalPush.definition.js +4 -3
- package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +4 -3
- package/lib/metadataTypes/definitions/TriggeredSendDefinition.definition.js +10 -2
- package/lib/util/auth.js +15 -2
- package/lib/util/cli.js +4 -1
- package/lib/util/file.js +7 -3
- package/lib/util/init.js +62 -0
- package/lib/util/util.js +173 -11
- package/package.json +23 -9
- package/test/dataExtension.test.js +10 -10
- package/test/interaction.test.js +123 -0
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/mockRoot/deploy/testInstance/testBU/interaction/testExisting_interaction.interaction-meta.json +266 -0
- package/test/mockRoot/deploy/testInstance/testBU/interaction/testNew_interaction.interaction-meta.json +266 -0
- package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +0 -3
- package/test/query.test.js +8 -8
- package/test/resourceFactory.js +30 -14
- package/test/resources/1111111/dataExtension/retrieve-response.xml +26 -0
- package/test/resources/9999999/data/v1/customobjectdata/key/childBU_dataextension_test/rowset/get-response.json +13 -0
- package/test/resources/9999999/dataFolder/retrieve-response.xml +22 -0
- package/test/resources/9999999/eventDefinition/get-expected.json +34 -0
- package/test/resources/9999999/interaction/build-expected.json +260 -0
- package/test/resources/9999999/interaction/get-expected.json +264 -0
- package/test/resources/9999999/interaction/post-expected.json +264 -0
- package/test/resources/9999999/interaction/put-expected.json +264 -0
- package/test/resources/9999999/interaction/template-expected.json +260 -0
- package/test/resources/9999999/interaction/v1/EventDefinitions/get-response.json +43 -0
- package/test/resources/9999999/interaction/v1/interactions/get-response.json +222 -3
- package/test/resources/9999999/interaction/v1/interactions/key_0b76dccf-594c-b6dc-1acf-10c4493dcb84/get-response.json +219 -0
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_interaction/get-response.json +280 -0
- package/test/resources/9999999/interaction/v1/interactions/post-response.json +280 -0
- package/test/resources/9999999/interaction/v1/interactions/put-response.json +280 -0
- package/test/resources/9999999/messaging/v1/email/definitions/post-response.json +1 -1
- package/test/resources/9999999/query/post-expected.sql +1 -1
- package/test/resources/9999999/transactionalEmail/post-expected.json +1 -1
- package/test/resources/9999999/triggeredSendDefinition/retrieve-response.xml +68 -0
- package/test/transactionalEmail.test.js +7 -7
- package/test/transactionalPush.test.js +7 -7
- package/test/transactionalSMS.test.js +7 -7
- package/test/utils.js +50 -0
- package/types/mcdev.d.js +1 -0
|
@@ -19,34 +19,25 @@ class Asset extends MetadataType {
|
|
|
19
19
|
*
|
|
20
20
|
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
21
21
|
* @param {void} _ -
|
|
22
|
-
* @param {
|
|
23
|
-
* @param {TYPE.AssetSubType} [selectedSubType] optionally limit to a single subtype
|
|
22
|
+
* @param {TYPE.AssetSubType[]} [subTypeArr] optionally limit to a single subtype
|
|
24
23
|
* @param {string} [key] customer key
|
|
25
24
|
* @returns {Promise.<{metadata: TYPE.AssetMap, type: string}>} Promise
|
|
26
25
|
*/
|
|
27
|
-
static async retrieve(retrieveDir, _,
|
|
26
|
+
static async retrieve(retrieveDir, _, subTypeArr, key) {
|
|
28
27
|
const items = [];
|
|
29
|
-
|
|
28
|
+
subTypeArr = subTypeArr || this._getSubTypes();
|
|
30
29
|
await File.initPrettier();
|
|
31
30
|
// loop through subtypes and return results of each subType for caching (saving is handled per subtype)
|
|
32
|
-
for (const subType of
|
|
31
|
+
for (const subType of subTypeArr) {
|
|
33
32
|
// each subtype contains multiple different specific types (images contains jpg and png for example)
|
|
34
33
|
// we use await here to limit the risk of too many concurrent api requests at time
|
|
35
|
-
items.push(
|
|
36
|
-
...(await this.requestSubType(
|
|
37
|
-
subType,
|
|
38
|
-
this.definition.extendedSubTypes[subType],
|
|
39
|
-
retrieveDir,
|
|
40
|
-
null,
|
|
41
|
-
null,
|
|
42
|
-
key
|
|
43
|
-
))
|
|
44
|
-
);
|
|
34
|
+
items.push(...(await this.requestSubType(subType, retrieveDir, null, null, key)));
|
|
45
35
|
}
|
|
46
36
|
const metadata = this.parseResponseBody({ items: items });
|
|
47
37
|
if (retrieveDir) {
|
|
48
38
|
Util.logger.info(
|
|
49
|
-
`Downloaded: ${this.definition.type} (${Object.keys(metadata).length})`
|
|
39
|
+
`Downloaded: ${this.definition.type} (${Object.keys(metadata).length})` +
|
|
40
|
+
Util.getKeysString(key)
|
|
50
41
|
);
|
|
51
42
|
}
|
|
52
43
|
return { metadata: metadata, type: this.definition.type };
|
|
@@ -55,12 +46,12 @@ class Asset extends MetadataType {
|
|
|
55
46
|
/**
|
|
56
47
|
* Retrieves asset metadata for caching
|
|
57
48
|
*
|
|
58
|
-
* @param {void} _
|
|
59
|
-
* @param {string} [
|
|
49
|
+
* @param {void} _ unused
|
|
50
|
+
* @param {string[]} [subTypeArr] optionally limit to a single subtype
|
|
60
51
|
* @returns {Promise.<{metadata: TYPE.AssetMap, type: string}>} Promise
|
|
61
52
|
*/
|
|
62
|
-
static retrieveForCache(_,
|
|
63
|
-
return this.retrieve(null, null,
|
|
53
|
+
static retrieveForCache(_, subTypeArr) {
|
|
54
|
+
return this.retrieve(null, null, subTypeArr);
|
|
64
55
|
}
|
|
65
56
|
|
|
66
57
|
/**
|
|
@@ -81,13 +72,7 @@ class Asset extends MetadataType {
|
|
|
81
72
|
// each subtype contains multiple different specific types (images contains jpg and png for example)
|
|
82
73
|
// we use await here to limit the risk of too many concurrent api requests at time
|
|
83
74
|
items.push(
|
|
84
|
-
...(await this.requestSubType(
|
|
85
|
-
subType,
|
|
86
|
-
this.definition.extendedSubTypes[subType],
|
|
87
|
-
templateDir,
|
|
88
|
-
name,
|
|
89
|
-
templateVariables
|
|
90
|
-
))
|
|
75
|
+
...(await this.requestSubType(subType, templateDir, name, templateVariables))
|
|
91
76
|
);
|
|
92
77
|
}
|
|
93
78
|
const metadata = this.parseResponseBody({ items: items });
|
|
@@ -146,27 +131,21 @@ class Asset extends MetadataType {
|
|
|
146
131
|
* Retrieves Metadata of a specific asset type
|
|
147
132
|
*
|
|
148
133
|
* @param {TYPE.AssetSubType} subType group of similar assets to put in a folder (ie. images)
|
|
149
|
-
* @param {TYPE.AssetSubType[]} subTypeArray list of all asset types within this subtype
|
|
150
134
|
* @param {string} [retrieveDir] target directory for saving assets
|
|
151
135
|
* @param {string} [templateName] name of the metadata file
|
|
152
136
|
* @param {TYPE.TemplateMap} [templateVariables] variables to be replaced in the metadata
|
|
153
137
|
* @param {string} key customer key to filter by
|
|
154
138
|
* @returns {Promise} Promise
|
|
155
139
|
*/
|
|
156
|
-
static async requestSubType(
|
|
157
|
-
subType,
|
|
158
|
-
subTypeArray,
|
|
159
|
-
retrieveDir,
|
|
160
|
-
templateName,
|
|
161
|
-
templateVariables,
|
|
162
|
-
key
|
|
163
|
-
) {
|
|
140
|
+
static async requestSubType(subType, retrieveDir, templateName, templateVariables, key) {
|
|
164
141
|
if (retrieveDir) {
|
|
165
142
|
Util.logger.info(`- Retrieving Subtype: ${subType}`);
|
|
166
143
|
} else {
|
|
167
144
|
Util.logger.info(` - Caching Subtype: ${subType}`);
|
|
168
145
|
}
|
|
169
|
-
|
|
146
|
+
/** @type {TYPE.AssetSubType[]} */
|
|
147
|
+
const extendedSubTypeArr = this.definition.extendedSubTypes[subType];
|
|
148
|
+
const subtypeIds = extendedSubTypeArr?.map(
|
|
170
149
|
(subTypeItemName) => Asset.definition.typeMapping[subTypeItemName]
|
|
171
150
|
);
|
|
172
151
|
const uri = '/asset/v1/content/assets/query';
|
|
@@ -507,10 +486,9 @@ class Asset extends MetadataType {
|
|
|
507
486
|
*
|
|
508
487
|
* @param {TYPE.AssetItem} metadata a single asset
|
|
509
488
|
* @param {string} deployDir directory of deploy files
|
|
510
|
-
* @param {TYPE.BuObject} buObject buObject properties for auth
|
|
511
489
|
* @returns {Promise.<TYPE.AssetItem>} Promise
|
|
512
490
|
*/
|
|
513
|
-
static async preDeployTasks(metadata, deployDir
|
|
491
|
+
static async preDeployTasks(metadata, deployDir) {
|
|
514
492
|
// additonalattributes fail where the value is "" so we need to remove them from deploy
|
|
515
493
|
if (metadata?.data?.email?.attributes?.length > 0) {
|
|
516
494
|
metadata.data.email.attributes = metadata.data.email.attributes.filter(
|
|
@@ -519,10 +497,7 @@ class Asset extends MetadataType {
|
|
|
519
497
|
}
|
|
520
498
|
|
|
521
499
|
// folder
|
|
522
|
-
metadata
|
|
523
|
-
id: cache.searchForField('folder', metadata.r__folder_Path, 'Path', 'ID'),
|
|
524
|
-
};
|
|
525
|
-
delete metadata.r__folder_Path;
|
|
500
|
+
this.setFolderId(metadata);
|
|
526
501
|
|
|
527
502
|
// restore asset type id which is needed for deploy
|
|
528
503
|
metadata.assetType.id = this.definition.typeMapping[metadata.assetType.name];
|
|
@@ -538,13 +513,13 @@ class Asset extends MetadataType {
|
|
|
538
513
|
|
|
539
514
|
// only execute #3 if we are deploying / copying from one BU to another, not while using mcdev as a developer tool
|
|
540
515
|
if (
|
|
541
|
-
buObject.mid &&
|
|
542
|
-
metadata.memberId !== buObject.mid &&
|
|
543
|
-
!metadata[this.definition.keyField].endsWith(buObject.mid)
|
|
516
|
+
this.buObject.mid &&
|
|
517
|
+
metadata.memberId !== this.buObject.mid &&
|
|
518
|
+
!metadata[this.definition.keyField].endsWith(this.buObject.mid)
|
|
544
519
|
) {
|
|
545
520
|
// #3 make sure customer key is unique by suffixing it with target MID (unless we are deploying to the same MID)
|
|
546
521
|
// check if this suffixed with the source MID
|
|
547
|
-
const suffix = '-' + buObject.mid;
|
|
522
|
+
const suffix = '-' + this.buObject.mid;
|
|
548
523
|
// for customer key max is 36 chars
|
|
549
524
|
metadata[this.definition.keyField] =
|
|
550
525
|
metadata[this.definition.keyField].slice(0, Math.max(0, 36 - suffix.length)) +
|
|
@@ -610,7 +585,7 @@ class Asset extends MetadataType {
|
|
|
610
585
|
*
|
|
611
586
|
* @private
|
|
612
587
|
* @param {TYPE.AssetItem} metadata a single asset
|
|
613
|
-
* @returns {TYPE.AssetSubType} subtype
|
|
588
|
+
* @returns {TYPE.AssetSubType | void} subtype
|
|
614
589
|
*/
|
|
615
590
|
static _getSubtype(metadata) {
|
|
616
591
|
for (const sub in this.definition.extendedSubTypes) {
|
|
@@ -790,6 +765,17 @@ class Asset extends MetadataType {
|
|
|
790
765
|
);
|
|
791
766
|
}
|
|
792
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Asset-specific script that retrieves the folder ID from cache and updates the given metadata with it before deploy
|
|
770
|
+
*
|
|
771
|
+
* @param {TYPE.MetadataTypeItem} metadata a single item
|
|
772
|
+
*/
|
|
773
|
+
static setFolderId(metadata) {
|
|
774
|
+
metadata.category = {
|
|
775
|
+
id: cache.searchForField('folder', metadata.r__folder_Path, 'Path', 'ID'),
|
|
776
|
+
};
|
|
777
|
+
delete metadata.r__folder_Path;
|
|
778
|
+
}
|
|
793
779
|
|
|
794
780
|
/**
|
|
795
781
|
* helper for {@link preDeployTasks} that loads extracted code content back into JSON
|
|
@@ -970,6 +956,7 @@ class Asset extends MetadataType {
|
|
|
970
956
|
|
|
971
957
|
break;
|
|
972
958
|
}
|
|
959
|
+
case 'template': // template-template
|
|
973
960
|
case 'buttonblock': // block - Button Block
|
|
974
961
|
case 'freeformblock': // block
|
|
975
962
|
case 'htmlblock': // block
|
|
@@ -1191,6 +1178,7 @@ class Asset extends MetadataType {
|
|
|
1191
1178
|
subFolder: [customerKey],
|
|
1192
1179
|
};
|
|
1193
1180
|
}
|
|
1181
|
+
case 'template': // template-template
|
|
1194
1182
|
case 'buttonblock': // block - Button Block
|
|
1195
1183
|
case 'freeformblock': // block
|
|
1196
1184
|
case 'htmlblock': // block
|
|
@@ -15,11 +15,10 @@ class AttributeGroup extends MetadataType {
|
|
|
15
15
|
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
16
16
|
* @param {void} [_] unused parameter
|
|
17
17
|
* @param {void} [__] unused parameter
|
|
18
|
-
* @param {void} [___] unused parameter
|
|
19
18
|
* @param {string} [key] customer key of single item to retrieve
|
|
20
19
|
* @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
|
|
21
20
|
*/
|
|
22
|
-
static retrieve(retrieveDir, _, __,
|
|
21
|
+
static retrieve(retrieveDir, _, __, key) {
|
|
23
22
|
return super.retrieveREST(
|
|
24
23
|
retrieveDir,
|
|
25
24
|
'/hub/v1/contacts/schema/attributeGroups',
|
|
@@ -19,11 +19,10 @@ class Automation extends MetadataType {
|
|
|
19
19
|
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
20
20
|
* @param {void} [_] unused parameter
|
|
21
21
|
* @param {void} [__] unused parameter
|
|
22
|
-
* @param {void} [___] unused parameter
|
|
23
22
|
* @param {string} [key] customer key of single item to retrieve
|
|
24
23
|
* @returns {Promise.<TYPE.AutomationMapObj>} Promise of metadata
|
|
25
24
|
*/
|
|
26
|
-
static async retrieve(retrieveDir, _, __,
|
|
25
|
+
static async retrieve(retrieveDir, _, __, key) {
|
|
27
26
|
/** @type {TYPE.SoapRequestParams} */
|
|
28
27
|
let requestParams = null;
|
|
29
28
|
if (key) {
|
|
@@ -36,12 +35,39 @@ class Automation extends MetadataType {
|
|
|
36
35
|
};
|
|
37
36
|
}
|
|
38
37
|
const results = await this.client.soap.retrieveBulk('Program', ['ObjectID'], requestParams);
|
|
39
|
-
|
|
38
|
+
if (results.Results?.length) {
|
|
39
|
+
// empty results will come back without "Results" defined
|
|
40
|
+
Util.logger.info(
|
|
41
|
+
Util.getGrayMsg(
|
|
42
|
+
` - ${results.Results?.length} Automations found. Retrieving details...`
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
40
46
|
const details = results.Results
|
|
41
47
|
? await Promise.all(
|
|
42
|
-
results.Results.map((a) =>
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
results.Results.map(async (a) => {
|
|
49
|
+
try {
|
|
50
|
+
return await this.client.rest.get(
|
|
51
|
+
'/automation/v1/automations/' + a.ObjectID
|
|
52
|
+
);
|
|
53
|
+
} catch (ex) {
|
|
54
|
+
try {
|
|
55
|
+
if (ex.message == 'socket hang up') {
|
|
56
|
+
// one more retry; it's a rare case but retrying again should solve the issue gracefully
|
|
57
|
+
return await this.client.rest.get(
|
|
58
|
+
'/automation/v1/automations/' + a.ObjectID
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
// no extra action needed, handled below
|
|
63
|
+
}
|
|
64
|
+
// if we do get here, we should log the error and continue instead of failing to download all automations
|
|
65
|
+
Util.logger.error(
|
|
66
|
+
` ☇ skipping Automation ${a.ObjectID}: ${ex.message} ${ex.code}`
|
|
67
|
+
);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
})
|
|
45
71
|
)
|
|
46
72
|
: [];
|
|
47
73
|
const parsed = this.parseResponseBody({ items: details });
|
|
@@ -49,10 +75,11 @@ class Automation extends MetadataType {
|
|
|
49
75
|
// * retrieveDir is mandatory in this method as it is not used for caching (there is a seperate method for that)
|
|
50
76
|
const savedMetadata = await this.saveResults(parsed, retrieveDir, null, null);
|
|
51
77
|
Util.logger.info(
|
|
52
|
-
`Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})`
|
|
78
|
+
`Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` +
|
|
79
|
+
Util.getKeysString(key)
|
|
53
80
|
);
|
|
54
81
|
if (this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)) {
|
|
55
|
-
await this.document(
|
|
82
|
+
await this.document(savedMetadata);
|
|
56
83
|
}
|
|
57
84
|
return { metadata: savedMetadata, type: this.definition.type };
|
|
58
85
|
}
|
|
@@ -245,28 +272,9 @@ class Automation extends MetadataType {
|
|
|
245
272
|
*/
|
|
246
273
|
static async preDeployTasks(metadata) {
|
|
247
274
|
if (this.validateDeployMetadata(metadata)) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
metadata.r__folder_Path,
|
|
252
|
-
'Path',
|
|
253
|
-
'ID'
|
|
254
|
-
);
|
|
255
|
-
if (metadata.r__folder_Path !== 'my automations') {
|
|
256
|
-
Util.logger.warn(
|
|
257
|
-
` - Automation '${
|
|
258
|
-
metadata[this.definition.nameField]
|
|
259
|
-
}' is located in subfolder ${
|
|
260
|
-
metadata.r__folder_Path
|
|
261
|
-
}. Please note that creating automation folders is not supported via API and hence you will have to create it manually in the GUI if you choose to deploy this automation.`
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
delete metadata.r__folder_Path;
|
|
265
|
-
} catch {
|
|
266
|
-
throw new Error(
|
|
267
|
-
`Folder '${metadata.r__folder_Path}' was not found on the server. Please create this manually in the GUI. Automation-folders cannot be deployed automatically.`
|
|
268
|
-
);
|
|
269
|
-
}
|
|
275
|
+
// folder
|
|
276
|
+
this.setFolderId(metadata);
|
|
277
|
+
|
|
270
278
|
if (metadata.type === 'scheduled' && metadata?.schedule?.startDate) {
|
|
271
279
|
// Starting Source == 'Schedule'
|
|
272
280
|
|
|
@@ -493,13 +501,44 @@ class Automation extends MetadataType {
|
|
|
493
501
|
}
|
|
494
502
|
}
|
|
495
503
|
|
|
504
|
+
/**
|
|
505
|
+
* automation-specific script that retrieves the folder ID from cache and updates the given metadata with it before deploy
|
|
506
|
+
*
|
|
507
|
+
* @param {TYPE.MetadataTypeItem} metadata a single item
|
|
508
|
+
*/
|
|
509
|
+
static setFolderId(metadata) {
|
|
510
|
+
try {
|
|
511
|
+
metadata.categoryId = cache.searchForField(
|
|
512
|
+
'folder',
|
|
513
|
+
metadata.r__folder_Path,
|
|
514
|
+
'Path',
|
|
515
|
+
'ID'
|
|
516
|
+
);
|
|
517
|
+
if (metadata.r__folder_Path !== 'my automations') {
|
|
518
|
+
Util.logger.warn(
|
|
519
|
+
` - Automation '${
|
|
520
|
+
metadata[this.definition.nameField]
|
|
521
|
+
}' is located in subfolder ${
|
|
522
|
+
metadata.r__folder_Path
|
|
523
|
+
}. Please note that creating automation folders is not supported via API and hence you will have to create it manually in the GUI if you choose to deploy this automation.`
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
delete metadata.r__folder_Path;
|
|
527
|
+
} catch {
|
|
528
|
+
throw new Error(
|
|
529
|
+
`Folder '${metadata.r__folder_Path}' was not found on the server. Please create this manually in the GUI. Automation-folders cannot be deployed automatically.`
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
496
534
|
/**
|
|
497
535
|
* parses retrieved Metadata before saving
|
|
498
536
|
*
|
|
499
537
|
* @param {TYPE.AutomationItem} metadata a single automation definition
|
|
500
|
-
* @returns {TYPE.AutomationItem} parsed item
|
|
538
|
+
* @returns {TYPE.AutomationItem | void} parsed item
|
|
501
539
|
*/
|
|
502
540
|
static parseMetadata(metadata) {
|
|
541
|
+
// folder
|
|
503
542
|
this.setFolderPath(metadata);
|
|
504
543
|
// automations are often skipped due to lack of support.
|
|
505
544
|
try {
|
|
@@ -895,26 +934,25 @@ class Automation extends MetadataType {
|
|
|
895
934
|
/**
|
|
896
935
|
* Parses metadata into a readable Markdown/HTML format then saves it
|
|
897
936
|
*
|
|
898
|
-
* @param {TYPE.BuObject} buObject properties for auth
|
|
899
937
|
* @param {TYPE.AutomationMap} [metadata] a list of dataExtension definitions
|
|
900
938
|
* @returns {Promise.<void>} -
|
|
901
939
|
*/
|
|
902
|
-
static async document(
|
|
940
|
+
static async document(metadata) {
|
|
903
941
|
if (['md', 'both'].includes(this.properties.options.documentType)) {
|
|
904
942
|
if (!metadata) {
|
|
905
943
|
metadata = this.readBUMetadataForType(
|
|
906
944
|
File.normalizePath([
|
|
907
945
|
this.properties.directories.retrieve,
|
|
908
|
-
buObject.credential,
|
|
909
|
-
buObject.businessUnit,
|
|
946
|
+
this.buObject.credential,
|
|
947
|
+
this.buObject.businessUnit,
|
|
910
948
|
]),
|
|
911
949
|
true
|
|
912
950
|
).automation;
|
|
913
951
|
}
|
|
914
952
|
const docPath = File.normalizePath([
|
|
915
953
|
this.properties.directories.retrieve,
|
|
916
|
-
buObject.credential,
|
|
917
|
-
buObject.businessUnit,
|
|
954
|
+
this.buObject.credential,
|
|
955
|
+
this.buObject.businessUnit,
|
|
918
956
|
this.definition.type,
|
|
919
957
|
]);
|
|
920
958
|
if (!metadata || !Object.keys(metadata).length) {
|
|
@@ -17,11 +17,10 @@ class Campaign extends MetadataType {
|
|
|
17
17
|
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
18
18
|
* @param {void} [_] unused parameter
|
|
19
19
|
* @param {void} [__] unused parameter
|
|
20
|
-
* @param {void} [___] unused parameter
|
|
21
20
|
* @param {string} [key] customer key of single item to retrieve
|
|
22
21
|
* @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise
|
|
23
22
|
*/
|
|
24
|
-
static async retrieve(retrieveDir, _, __,
|
|
23
|
+
static async retrieve(retrieveDir, _, __, key) {
|
|
25
24
|
const res = await super.retrieveREST(retrieveDir, '/hub/v1/campaigns', null, null, key);
|
|
26
25
|
// get assignments
|
|
27
26
|
|
|
@@ -30,7 +29,9 @@ class Campaign extends MetadataType {
|
|
|
30
29
|
this.getAssetTags(retrieveDir, res.metadata[key].id, key)
|
|
31
30
|
)
|
|
32
31
|
);
|
|
33
|
-
Util.logger.info(
|
|
32
|
+
Util.logger.info(
|
|
33
|
+
`Downloaded: campaignAssets (${campaignAssets.flat().length})` + Util.getKeysString(key)
|
|
34
|
+
);
|
|
34
35
|
|
|
35
36
|
return res;
|
|
36
37
|
}
|
|
@@ -17,11 +17,10 @@ class ContentArea extends MetadataType {
|
|
|
17
17
|
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
18
18
|
* @param {void} [_] unused parameter
|
|
19
19
|
* @param {void} [__] unused parameter
|
|
20
|
-
* @param {void} [___] unused parameter
|
|
21
20
|
* @param {string} [key] customer key of single item to retrieve
|
|
22
21
|
* @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
|
|
23
22
|
*/
|
|
24
|
-
static retrieve(retrieveDir, _, __,
|
|
23
|
+
static retrieve(retrieveDir, _, __, key) {
|
|
25
24
|
Util.logger.warn(
|
|
26
25
|
' - Classic Content Areas are deprecated and will be discontinued by SFMC in the near future. Ensure that you migrate any existing Content Areas to Content Builder as soon as possible.'
|
|
27
26
|
);
|
|
@@ -37,7 +36,7 @@ class ContentArea extends MetadataType {
|
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
38
|
// !dont activate `await File.initPrettier('html');` as we only want to retrieve for migration and formatting might mess with the outcome
|
|
40
|
-
return super.retrieveSOAP(retrieveDir,
|
|
39
|
+
return super.retrieveSOAP(retrieveDir, requestParams);
|
|
41
40
|
}
|
|
42
41
|
/**
|
|
43
42
|
* manages post retrieve steps
|