mcdev 4.3.0 → 4.3.2
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/.fork/custom-commands.json +14 -0
- package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
- package/boilerplate/gitignore-template +1 -0
- package/docs/dist/documentation.md +2 -40
- package/lib/Retriever.js +22 -19
- package/lib/metadataTypes/AccountUser.js +42 -13
- package/lib/metadataTypes/Asset.js +37 -42
- package/lib/metadataTypes/Automation.js +1 -1
- package/lib/metadataTypes/DataExtensionField.js +5 -3
- package/lib/metadataTypes/EmailSendDefinition.js +84 -44
- package/lib/metadataTypes/Interaction.js +74 -9
- package/lib/metadataTypes/List.js +17 -15
- package/lib/metadataTypes/MetadataType.js +1 -1
- package/lib/metadataTypes/TriggeredSendDefinition.js +6 -5
- package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +52 -31
- package/lib/metadataTypes/definitions/Interaction.definition.js +1 -1
- package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +2 -2
- package/lib/metadataTypes/definitions/TransactionalPush.definition.js +2 -2
- package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +2 -2
- package/lib/util/auth.js +8 -3
- package/lib/util/devops.js +8 -4
- package/lib/util/util.js +51 -9
- package/package.json +2 -1
- package/test/interaction.test.js +2 -2
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/resourceFactory.js +20 -9
- 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/triggeredSendDefinition/retrieve-response.xml +68 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "Create PR to develop branch",
|
|
4
|
+
"target": "ref",
|
|
5
|
+
"refTargets": [
|
|
6
|
+
"localbranch",
|
|
7
|
+
"remotebranch"
|
|
8
|
+
],
|
|
9
|
+
"action": {
|
|
10
|
+
"type": "url",
|
|
11
|
+
"url": "https://github.com/Accenture/sfmc-devtools/compare/develop...$shortname?expand=1"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -736,10 +736,7 @@ MessageSendActivity MetadataType
|
|
|
736
736
|
* [AccountUser](#AccountUser) ⇐ [<code>MetadataType</code>](#MetadataType)
|
|
737
737
|
* [.retrieve(retrieveDir, _, [__], [key])](#AccountUser.retrieve) ⇒ <code>Promise.<TYPE.MetadataTypeMapObj></code>
|
|
738
738
|
* [.retrieveChangelog()](#AccountUser.retrieveChangelog) ⇒ <code>Promise.<TYPE.MetadataTypeMapObj></code>
|
|
739
|
-
* [.timeSinceDate(date)](#AccountUser.timeSinceDate) ⇒ <code>number</code>
|
|
740
|
-
* [.getBuName(id)](#AccountUser.getBuName) ⇒ <code>string</code>
|
|
741
739
|
* [.document([metadata])](#AccountUser.document) ⇒ <code>Promise.<void></code>
|
|
742
|
-
* [._generateDocMd(users, type, columnsToPrint)](#AccountUser._generateDocMd) ⇒ <code>string</code>
|
|
743
740
|
* [.postRetrieveTasks(metadata)](#AccountUser.postRetrieveTasks) ⇒ <code>TYPE.MetadataTypeItem</code>
|
|
744
741
|
* [.parseMetadata(metadata)](#AccountUser.parseMetadata) ⇒ <code>TYPE.MetadataTypeItem</code>
|
|
745
742
|
|
|
@@ -765,28 +762,6 @@ Retrieves SOAP based metadata of metadata type into local filesystem. executes c
|
|
|
765
762
|
|
|
766
763
|
**Kind**: static method of [<code>AccountUser</code>](#AccountUser)
|
|
767
764
|
**Returns**: <code>Promise.<TYPE.MetadataTypeMapObj></code> - Promise of metadata
|
|
768
|
-
<a name="AccountUser.timeSinceDate"></a>
|
|
769
|
-
|
|
770
|
-
### AccountUser.timeSinceDate(date) ⇒ <code>number</code>
|
|
771
|
-
**Kind**: static method of [<code>AccountUser</code>](#AccountUser)
|
|
772
|
-
**Returns**: <code>number</code> - time difference
|
|
773
|
-
|
|
774
|
-
| Param | Type | Description |
|
|
775
|
-
| --- | --- | --- |
|
|
776
|
-
| date | <code>string</code> | first date |
|
|
777
|
-
|
|
778
|
-
<a name="AccountUser.getBuName"></a>
|
|
779
|
-
|
|
780
|
-
### AccountUser.getBuName(id) ⇒ <code>string</code>
|
|
781
|
-
helper to print bu names
|
|
782
|
-
|
|
783
|
-
**Kind**: static method of [<code>AccountUser</code>](#AccountUser)
|
|
784
|
-
**Returns**: <code>string</code> - "bu name (bu id)""
|
|
785
|
-
|
|
786
|
-
| Param | Type | Description |
|
|
787
|
-
| --- | --- | --- |
|
|
788
|
-
| id | <code>number</code> | bu id |
|
|
789
|
-
|
|
790
765
|
<a name="AccountUser.document"></a>
|
|
791
766
|
|
|
792
767
|
### AccountUser.document([metadata]) ⇒ <code>Promise.<void></code>
|
|
@@ -799,18 +774,6 @@ Creates markdown documentation of all roles
|
|
|
799
774
|
| --- | --- | --- |
|
|
800
775
|
| [metadata] | <code>TYPE.MetadataTypeMap</code> | user list |
|
|
801
776
|
|
|
802
|
-
<a name="AccountUser._generateDocMd"></a>
|
|
803
|
-
|
|
804
|
-
### AccountUser.\_generateDocMd(users, type, columnsToPrint) ⇒ <code>string</code>
|
|
805
|
-
**Kind**: static method of [<code>AccountUser</code>](#AccountUser)
|
|
806
|
-
**Returns**: <code>string</code> - markdown
|
|
807
|
-
|
|
808
|
-
| Param | Type | Description |
|
|
809
|
-
| --- | --- | --- |
|
|
810
|
-
| users | <code>Array.<object></code> | list of users and installed package |
|
|
811
|
-
| type | <code>'Installed Package'</code> \| <code>'User'</code> | choose what sub type to print |
|
|
812
|
-
| columnsToPrint | <code>Array.<Array></code> | helper array |
|
|
813
|
-
|
|
814
777
|
<a name="AccountUser.postRetrieveTasks"></a>
|
|
815
778
|
|
|
816
779
|
### AccountUser.postRetrieveTasks(metadata) ⇒ <code>TYPE.MetadataTypeItem</code>
|
|
@@ -849,7 +812,7 @@ FileTransfer MetadataType
|
|
|
849
812
|
* [.retrieveAsTemplate(templateDir, name, templateVariables, [selectedSubType])](#Asset.retrieveAsTemplate) ⇒ <code>Promise.<{metadata: TYPE.AssetItem, type: string}></code>
|
|
850
813
|
* [.create(metadata)](#Asset.create) ⇒ <code>Promise</code>
|
|
851
814
|
* [.update(metadata)](#Asset.update) ⇒ <code>Promise</code>
|
|
852
|
-
* [.requestSubType(subType,
|
|
815
|
+
* [.requestSubType(subType, [retrieveDir], [templateName], [templateVariables], key)](#Asset.requestSubType) ⇒ <code>Promise</code>
|
|
853
816
|
* [.requestAndSaveExtended(items, subType, retrieveDir, [templateVariables])](#Asset.requestAndSaveExtended) ⇒ <code>Promise</code>
|
|
854
817
|
* [._retrieveExtendedFile(metadata, subType, retrieveDir)](#Asset._retrieveExtendedFile) ⇒ <code>Promise.<void></code>
|
|
855
818
|
* [._readExtendedFileFromFS(metadata, subType, deployDir, [pathOnly])](#Asset._readExtendedFileFromFS) ⇒ <code>Promise.<string></code>
|
|
@@ -939,7 +902,7 @@ Updates a single asset
|
|
|
939
902
|
|
|
940
903
|
<a name="Asset.requestSubType"></a>
|
|
941
904
|
|
|
942
|
-
### Asset.requestSubType(subType,
|
|
905
|
+
### Asset.requestSubType(subType, [retrieveDir], [templateName], [templateVariables], key) ⇒ <code>Promise</code>
|
|
943
906
|
Retrieves Metadata of a specific asset type
|
|
944
907
|
|
|
945
908
|
**Kind**: static method of [<code>Asset</code>](#Asset)
|
|
@@ -948,7 +911,6 @@ Retrieves Metadata of a specific asset type
|
|
|
948
911
|
| Param | Type | Description |
|
|
949
912
|
| --- | --- | --- |
|
|
950
913
|
| subType | <code>TYPE.AssetSubType</code> | group of similar assets to put in a folder (ie. images) |
|
|
951
|
-
| subTypeArray | <code>Array.<TYPE.AssetSubType></code> | list of all asset types within this subtype |
|
|
952
914
|
| [retrieveDir] | <code>string</code> | target directory for saving assets |
|
|
953
915
|
| [templateName] | <code>string</code> | name of the metadata file |
|
|
954
916
|
| [templateVariables] | <code>TYPE.TemplateMap</code> | variables to be replaced in the metadata |
|
package/lib/Retriever.js
CHANGED
|
@@ -62,29 +62,33 @@ class Retriever {
|
|
|
62
62
|
// ensure we know which real dependencies we have to ensure we cache those completely
|
|
63
63
|
const dependencies = this._getTypeDependencies(metadataTypes);
|
|
64
64
|
const deployOrder = Util.getMetadataHierachy(metadataTypes);
|
|
65
|
-
for (const
|
|
66
|
-
const
|
|
67
|
-
const subTypeArr = deployOrder[metadataType];
|
|
65
|
+
for (const type in deployOrder) {
|
|
66
|
+
const subTypeArr = deployOrder[type];
|
|
68
67
|
// if types were added by getMetadataHierachy() for caching, make sure the key-list is set to [null] for them which will retrieve all
|
|
69
|
-
typeKeyMap[
|
|
68
|
+
typeKeyMap[type] = typeKeyMap[type] || [null];
|
|
70
69
|
// add client to metadata process class instead of passing every time
|
|
71
70
|
MetadataTypeInfo[type].client = auth.getSDK(this.buObject);
|
|
72
71
|
MetadataTypeInfo[type].properties = this.properties;
|
|
73
72
|
MetadataTypeInfo[type].buObject = this.buObject;
|
|
74
73
|
try {
|
|
75
74
|
let result;
|
|
76
|
-
if (
|
|
75
|
+
if (
|
|
76
|
+
!metadataTypes.includes(type) &&
|
|
77
|
+
(!Array.isArray(subTypeArr) ||
|
|
78
|
+
(Array.isArray(subTypeArr) &&
|
|
79
|
+
!metadataTypes.includes(`${type}-${subTypeArr?.[0]}`)))
|
|
80
|
+
) {
|
|
77
81
|
// type not in list of types to retrieve, but is a dependency of one of them
|
|
78
82
|
if (changelogOnly && type !== 'folder') {
|
|
79
83
|
// no extra caching needed for list view except for folders
|
|
80
84
|
continue;
|
|
81
85
|
}
|
|
82
|
-
Util.logger.info(`Caching dependent Metadata: ${
|
|
86
|
+
Util.logger.info(`Caching dependent Metadata: ${type}`);
|
|
83
87
|
Util.logSubtypes(subTypeArr);
|
|
84
88
|
result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr);
|
|
85
89
|
} else if (templateVariables) {
|
|
86
90
|
// type is in list of types to retrieve and we have template variables
|
|
87
|
-
Util.logger.info(`Retrieving as Template: ${
|
|
91
|
+
Util.logger.info(`Retrieving as Template: ${type}`);
|
|
88
92
|
if (subTypeArr?.length > 1) {
|
|
89
93
|
Util.logger.warn(
|
|
90
94
|
`retrieveAsTemplate only works with one subtype, ignoring all but first subtype from your list: ${subTypeArr.join(
|
|
@@ -93,7 +97,7 @@ class Retriever {
|
|
|
93
97
|
);
|
|
94
98
|
}
|
|
95
99
|
result = await Promise.all(
|
|
96
|
-
typeKeyMap[
|
|
100
|
+
typeKeyMap[type].map((name) =>
|
|
97
101
|
MetadataTypeInfo[type].retrieveAsTemplate(
|
|
98
102
|
this.templateDir,
|
|
99
103
|
name,
|
|
@@ -106,12 +110,11 @@ class Retriever {
|
|
|
106
110
|
// type is in list of types to retrieve and we don't have template variables
|
|
107
111
|
let cacheResult = null;
|
|
108
112
|
if (
|
|
109
|
-
(typeKeyMap[
|
|
110
|
-
|
|
111
|
-
(dependencies.includes(type) || dependencies.includes(metadataType))
|
|
113
|
+
(typeKeyMap[type].length > 1 || typeKeyMap[type][0] !== null) &&
|
|
114
|
+
(dependencies.includes(type) || dependencies.includes(type))
|
|
112
115
|
) {
|
|
113
116
|
// if we have a key-list and the type is a dependency, we need to cache the whole type
|
|
114
|
-
Util.logger.info(`Caching dependent Metadata: ${
|
|
117
|
+
Util.logger.info(`Caching dependent Metadata: ${type}`);
|
|
115
118
|
Util.logSubtypes(subTypeArr);
|
|
116
119
|
cacheResult = await MetadataTypeInfo[type].retrieveForCache(
|
|
117
120
|
null,
|
|
@@ -119,15 +122,15 @@ class Retriever {
|
|
|
119
122
|
);
|
|
120
123
|
}
|
|
121
124
|
Util.logger.info(
|
|
122
|
-
`Retrieving: ${
|
|
123
|
-
(typeKeyMap[
|
|
125
|
+
`Retrieving: ${type}` +
|
|
126
|
+
(typeKeyMap[type][0] === null
|
|
124
127
|
? ''
|
|
125
|
-
: Util.getKeysString(typeKeyMap[
|
|
128
|
+
: Util.getKeysString(typeKeyMap[type]))
|
|
126
129
|
);
|
|
127
130
|
result = await (changelogOnly
|
|
128
131
|
? MetadataTypeInfo[type].retrieveChangelog(null, subTypeArr)
|
|
129
132
|
: Promise.all(
|
|
130
|
-
typeKeyMap[
|
|
133
|
+
typeKeyMap[type].map((key) =>
|
|
131
134
|
MetadataTypeInfo[type].retrieve(
|
|
132
135
|
this.savePath,
|
|
133
136
|
null,
|
|
@@ -154,14 +157,14 @@ class Retriever {
|
|
|
154
157
|
cache.mergeMetadata(type, result_i.metadata);
|
|
155
158
|
}
|
|
156
159
|
}
|
|
157
|
-
if (metadataTypes.includes(type) || metadataTypes.includes(
|
|
160
|
+
if (metadataTypes.includes(type) || metadataTypes.includes(type)) {
|
|
158
161
|
retrieveChangelog[type] = result
|
|
159
162
|
.filter((el) => !!el)
|
|
160
163
|
.map((element) => element.metadata);
|
|
161
164
|
}
|
|
162
165
|
} else {
|
|
163
166
|
cache.setMetadata(type, result.metadata);
|
|
164
|
-
if (metadataTypes.includes(type) || metadataTypes.includes(
|
|
167
|
+
if (metadataTypes.includes(type) || metadataTypes.includes(type)) {
|
|
165
168
|
retrieveChangelog[type] = result.metadata;
|
|
166
169
|
}
|
|
167
170
|
}
|
|
@@ -175,7 +178,7 @@ class Retriever {
|
|
|
175
178
|
Util.logger.error(ex.message);
|
|
176
179
|
break;
|
|
177
180
|
} else {
|
|
178
|
-
Util.logger.errorStack(ex, ` - Retrieving ${
|
|
181
|
+
Util.logger.errorStack(ex, ` - Retrieving ${type} failed`);
|
|
179
182
|
}
|
|
180
183
|
}
|
|
181
184
|
}
|
|
@@ -60,10 +60,17 @@ class AccountUser extends MetadataType {
|
|
|
60
60
|
for (const item of resultsBatch) {
|
|
61
61
|
this.userIdBuMap[item.AccountUser.AccountUserID] =
|
|
62
62
|
this.userIdBuMap[item.AccountUser.AccountUserID] || [];
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
// push to array if not already in array
|
|
64
|
+
if (
|
|
65
|
+
!this.userIdBuMap[item.AccountUser.AccountUserID].some(
|
|
66
|
+
(bu) => bu.ID === item.Account.ID
|
|
67
|
+
)
|
|
68
|
+
) {
|
|
69
|
+
this.userIdBuMap[item.AccountUser.AccountUserID].push({
|
|
70
|
+
ID: item.Account.ID,
|
|
71
|
+
Name: item.Account.Name,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
67
74
|
}
|
|
68
75
|
// get actual user details
|
|
69
76
|
/** @type {TYPE.SoapRequestParams} */
|
|
@@ -114,10 +121,11 @@ class AccountUser extends MetadataType {
|
|
|
114
121
|
}
|
|
115
122
|
/**
|
|
116
123
|
*
|
|
124
|
+
* @private
|
|
117
125
|
* @param {string} date first date
|
|
118
126
|
* @returns {number} time difference
|
|
119
127
|
*/
|
|
120
|
-
static
|
|
128
|
+
static _timeSinceDate(date) {
|
|
121
129
|
const interval = 'days';
|
|
122
130
|
const second = 1000,
|
|
123
131
|
minute = second * 60,
|
|
@@ -172,13 +180,28 @@ class AccountUser extends MetadataType {
|
|
|
172
180
|
/**
|
|
173
181
|
* helper to print bu names
|
|
174
182
|
*
|
|
183
|
+
* @private
|
|
175
184
|
* @param {number} id bu id
|
|
176
185
|
* @returns {string} "bu name (bu id)""
|
|
177
186
|
*/
|
|
178
|
-
static
|
|
187
|
+
static _getBuName(id) {
|
|
179
188
|
const name = this.buObject.eid == id ? '_ParentBU_' : this.buIdName[id];
|
|
180
189
|
return `<nobr>${name} (${id})</nobr>`;
|
|
181
190
|
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* helper that gets BU names from config
|
|
194
|
+
*
|
|
195
|
+
* @private
|
|
196
|
+
*/
|
|
197
|
+
static _getBuNames() {
|
|
198
|
+
this.buIdName = {};
|
|
199
|
+
for (const cred in this.properties.credentials) {
|
|
200
|
+
for (const buName in this.properties.credentials[cred].businessUnits) {
|
|
201
|
+
this.buIdName[this.properties.credentials[cred].businessUnits[buName]] = buName;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
182
205
|
/**
|
|
183
206
|
* Creates markdown documentation of all roles
|
|
184
207
|
*
|
|
@@ -209,7 +232,7 @@ class AccountUser extends MetadataType {
|
|
|
209
232
|
}
|
|
210
233
|
}
|
|
211
234
|
// init map of BU Ids > BU Name
|
|
212
|
-
this.
|
|
235
|
+
this._getBuNames();
|
|
213
236
|
|
|
214
237
|
// initialize permission object
|
|
215
238
|
this.allPermissions = {};
|
|
@@ -244,14 +267,19 @@ class AccountUser extends MetadataType {
|
|
|
244
267
|
}
|
|
245
268
|
let associatedBus = '';
|
|
246
269
|
if (user.AssociatedBusinessUnits__c) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
270
|
+
user.AssociatedBusinessUnits__c.push({
|
|
271
|
+
ID: user.DefaultBusinessUnit,
|
|
272
|
+
});
|
|
273
|
+
// ensure associatedBus have no duplicates
|
|
274
|
+
associatedBus = [
|
|
275
|
+
...new Set(
|
|
276
|
+
user.AssociatedBusinessUnits__c.map((item) => this._getBuName(item.ID))
|
|
277
|
+
),
|
|
278
|
+
]
|
|
251
279
|
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))
|
|
252
280
|
.join(',<br> ');
|
|
253
281
|
}
|
|
254
|
-
const defaultBUName = this.
|
|
282
|
+
const defaultBUName = this._getBuName(user.DefaultBusinessUnit);
|
|
255
283
|
users.push({
|
|
256
284
|
TYPE: user.type__c,
|
|
257
285
|
UserID: user.UserID,
|
|
@@ -267,7 +295,7 @@ class AccountUser extends MetadataType {
|
|
|
267
295
|
AssociatedBusinessUnits__c: associatedBus,
|
|
268
296
|
Roles: roles,
|
|
269
297
|
UserPermissions: userPermissions,
|
|
270
|
-
LastSuccessfulLogin: this.
|
|
298
|
+
LastSuccessfulLogin: this._timeSinceDate(user.LastSuccessfulLogin),
|
|
271
299
|
CreatedDate: user.CreatedDate.split('T').join(' '),
|
|
272
300
|
ModifiedDate: user.ModifiedDate.split('T').join(' '),
|
|
273
301
|
});
|
|
@@ -325,6 +353,7 @@ class AccountUser extends MetadataType {
|
|
|
325
353
|
}
|
|
326
354
|
/**
|
|
327
355
|
*
|
|
356
|
+
* @private
|
|
328
357
|
* @param {object[]} users list of users and installed package
|
|
329
358
|
* @param {'Installed Package'|'User'} type choose what sub type to print
|
|
330
359
|
* @param {Array[]} columnsToPrint helper array
|
|
@@ -31,16 +31,7 @@ class Asset extends MetadataType {
|
|
|
31
31
|
for (const subType of subTypeArr) {
|
|
32
32
|
// each subtype contains multiple different specific types (images contains jpg and png for example)
|
|
33
33
|
// we use await here to limit the risk of too many concurrent api requests at time
|
|
34
|
-
items.push(
|
|
35
|
-
...(await this.requestSubType(
|
|
36
|
-
subType,
|
|
37
|
-
this.definition.extendedSubTypes[subType],
|
|
38
|
-
retrieveDir,
|
|
39
|
-
null,
|
|
40
|
-
null,
|
|
41
|
-
key
|
|
42
|
-
))
|
|
43
|
-
);
|
|
34
|
+
items.push(...(await this.requestSubType(subType, retrieveDir, null, null, key)));
|
|
44
35
|
}
|
|
45
36
|
const metadata = this.parseResponseBody({ items: items });
|
|
46
37
|
if (retrieveDir) {
|
|
@@ -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';
|
|
@@ -338,22 +317,30 @@ class Asset extends MetadataType {
|
|
|
338
317
|
} catch (ex) {
|
|
339
318
|
failed.push({ item: item, error: ex });
|
|
340
319
|
}
|
|
320
|
+
// even if the extended file failed, still save the metadata
|
|
341
321
|
metadata[item.customerKey] = item;
|
|
342
322
|
}
|
|
343
323
|
// this is a complex type which stores data in the asset itself
|
|
344
324
|
else if (!completed.includes(item.id)) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
325
|
+
try {
|
|
326
|
+
const extendedItem = await this.client.rest.get(
|
|
327
|
+
'asset/v1/content/assets/' + item.id
|
|
328
|
+
);
|
|
329
|
+
// only save the metadata if we have extended content
|
|
330
|
+
metadata[item.customerKey] = extendedItem;
|
|
331
|
+
} catch (ex) {
|
|
332
|
+
failed.push({ item: item, error: ex });
|
|
333
|
+
}
|
|
349
334
|
}
|
|
350
335
|
completed.push(item.id);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
336
|
+
if (metadata[item.customerKey]) {
|
|
337
|
+
await this.saveResults(
|
|
338
|
+
metadata,
|
|
339
|
+
retrieveDir,
|
|
340
|
+
'asset-' + subType,
|
|
341
|
+
templateVariables
|
|
342
|
+
);
|
|
343
|
+
}
|
|
357
344
|
// update the current value in your application..
|
|
358
345
|
extendedBar.increment();
|
|
359
346
|
})
|
|
@@ -367,7 +354,7 @@ class Asset extends MetadataType {
|
|
|
367
354
|
} catch (ex) {
|
|
368
355
|
extendedBar.stop();
|
|
369
356
|
Asset._resetLogLevel(loggerLevelBak, failed);
|
|
370
|
-
// timeouts should be retried, others can be
|
|
357
|
+
// timeouts should be retried, others can be exited
|
|
371
358
|
if (ex.code !== 'ETIMEDOUT') {
|
|
372
359
|
throw ex;
|
|
373
360
|
}
|
|
@@ -415,11 +402,17 @@ class Asset extends MetadataType {
|
|
|
415
402
|
);
|
|
416
403
|
for (const fail of failed) {
|
|
417
404
|
Util.logger.warn(
|
|
418
|
-
` -
|
|
405
|
+
` - "${fail.item.name}" (${fail.item.customerKey}): ${fail.error.message} (${
|
|
406
|
+
fail.error.code
|
|
407
|
+
})${
|
|
408
|
+
fail.error.endpoint
|
|
409
|
+
? Util.getGrayMsg(
|
|
410
|
+
' - ' +
|
|
411
|
+
fail.error.endpoint.split('rest.marketingcloudapis.com')[1]
|
|
412
|
+
)
|
|
413
|
+
: ''
|
|
414
|
+
}`
|
|
419
415
|
);
|
|
420
|
-
Util.logger.debug(`-- Error: ${fail.error.message}`);
|
|
421
|
-
Util.logger.debug(`-- AssetType: ${fail.item.assetType.name}`);
|
|
422
|
-
Util.logger.debug(`-- fileProperties: ${JSON.stringify(fail.item.fileProperties)}`);
|
|
423
416
|
}
|
|
424
417
|
Util.logger.info(
|
|
425
418
|
' - You will still find a JSON file for each of these in the download directory.'
|
|
@@ -977,6 +970,7 @@ class Asset extends MetadataType {
|
|
|
977
970
|
|
|
978
971
|
break;
|
|
979
972
|
}
|
|
973
|
+
case 'template': // template-template
|
|
980
974
|
case 'buttonblock': // block - Button Block
|
|
981
975
|
case 'freeformblock': // block
|
|
982
976
|
case 'htmlblock': // block
|
|
@@ -1198,6 +1192,7 @@ class Asset extends MetadataType {
|
|
|
1198
1192
|
subFolder: [customerKey],
|
|
1199
1193
|
};
|
|
1200
1194
|
}
|
|
1195
|
+
case 'template': // template-template
|
|
1201
1196
|
case 'buttonblock': // block - Button Block
|
|
1202
1197
|
case 'freeformblock': // block
|
|
1203
1198
|
case 'htmlblock': // block
|
|
@@ -63,7 +63,7 @@ class Automation extends MetadataType {
|
|
|
63
63
|
}
|
|
64
64
|
// if we do get here, we should log the error and continue instead of failing to download all automations
|
|
65
65
|
Util.logger.error(
|
|
66
|
-
`
|
|
66
|
+
` ☇ skipping Automation ${a.ObjectID}: ${ex.message} ${ex.code}`
|
|
67
67
|
);
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
@@ -242,9 +242,11 @@ class DataExtensionField extends MetadataType {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
Util.logger.info(
|
|
245
|
-
|
|
246
|
-
deployColumns.length
|
|
247
|
-
|
|
245
|
+
Util.getGrayMsg(
|
|
246
|
+
` - Found ${deployColumns.length} added/updated Fields for ${deKey}${
|
|
247
|
+
deployColumns.length ? ': ' : ''
|
|
248
|
+
}` + deployColumns.map((item) => item.Name).join(', ')
|
|
249
|
+
)
|
|
248
250
|
);
|
|
249
251
|
return existingFieldByName;
|
|
250
252
|
}
|