mcdev 8.0.0 → 8.0.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/.github/ISSUE_TEMPLATE/bug.yml +2 -0
- package/.github/workflows/coverage-base-update.yml +2 -2
- package/.github/workflows/coverage.yml +1 -1
- package/@types/lib/index.d.ts +1 -0
- package/@types/lib/index.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Asset.d.ts +1 -0
- package/@types/lib/metadataTypes/Asset.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Automation.d.ts +1 -0
- package/@types/lib/metadataTypes/Automation.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DataExtension.d.ts +1 -0
- package/@types/lib/metadataTypes/DataExtension.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DataExtract.d.ts +1 -0
- package/@types/lib/metadataTypes/DataExtract.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Event.d.ts +2 -0
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
- package/@types/lib/metadataTypes/FileTransfer.d.ts +1 -0
- package/@types/lib/metadataTypes/FileTransfer.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Folder.d.ts.map +1 -1
- package/@types/lib/metadataTypes/ImportFile.d.ts +1 -0
- package/@types/lib/metadataTypes/ImportFile.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MetadataType.d.ts +3 -1
- package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MobileKeyword.d.ts +1 -0
- package/@types/lib/metadataTypes/MobileKeyword.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Query.d.ts +1 -0
- package/@types/lib/metadataTypes/Query.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Script.d.ts +1 -0
- package/@types/lib/metadataTypes/Script.d.ts.map +1 -1
- package/@types/lib/util/cache.d.ts +9 -0
- package/@types/lib/util/cache.d.ts.map +1 -1
- package/@types/lib/util/file.d.ts.map +1 -1
- package/@types/lib/util/util.d.ts +8 -1
- package/@types/lib/util/util.d.ts.map +1 -1
- package/lib/index.js +2 -3
- package/lib/metadataTypes/Asset.js +29 -7
- package/lib/metadataTypes/Automation.js +2 -0
- package/lib/metadataTypes/DataExtension.js +2 -0
- package/lib/metadataTypes/DataExtract.js +2 -0
- package/lib/metadataTypes/Event.js +21 -13
- package/lib/metadataTypes/FileTransfer.js +2 -0
- package/lib/metadataTypes/Folder.js +39 -37
- package/lib/metadataTypes/ImportFile.js +2 -0
- package/lib/metadataTypes/Journey.js +2 -1
- package/lib/metadataTypes/MetadataType.js +20 -15
- package/lib/metadataTypes/MobileKeyword.js +2 -0
- package/lib/metadataTypes/Query.js +2 -0
- package/lib/metadataTypes/Script.js +2 -0
- package/lib/util/cache.js +22 -3
- package/lib/util/file.js +10 -1
- package/lib/util/util.js +26 -12
- package/package.json +10 -10
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/resources/9999999/asset/test_coderesource_js-retrieve-expected.json +2 -4
- package/test/resources/9999999/asset/test_coderesource_json-retrieve-expected.json +2 -4
- package/test/resources/9999999/asset/test_coderesource_xml-retrieve-expected.json +2 -4
- package/test/resources/9999999/asset/test_interactivecontent-retrieve-expected.json +2 -4
- package/test/resources/9999999/asset/test_landingpage-retrieve-expected.json +2 -4
- package/test/resources/9999999/asset/test_microsite-retrieve-expected.json +2 -4
- package/test/resources/9999999/asset/v1/content/assets/9451/get-response.json +3 -3
- package/test/resources/9999999/asset/v1/content/assets/9456/get-response.json +3 -3
- package/test/resources/9999999/asset/v1/content/assets/9458/get-response.json +3 -3
- package/test/resources/9999999/asset/v1/content/assets/9460/get-response.json +3 -3
- package/test/resources/9999999/asset/v1/content/assets/9463/get-response.json +3 -3
- package/test/resources/9999999/asset/v1/content/assets/9465/get-response.json +3 -3
|
@@ -1493,12 +1493,14 @@ class DataExtension extends MetadataType {
|
|
|
1493
1493
|
/**
|
|
1494
1494
|
* Retrieves dataExtension metadata in template format.
|
|
1495
1495
|
*
|
|
1496
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
1496
1497
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
1497
1498
|
* @param {string} name name of the metadata item
|
|
1498
1499
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
1499
1500
|
* @returns {Promise.<{metadata: DataExtensionItem, type: string}>} Promise of items
|
|
1500
1501
|
*/
|
|
1501
1502
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
1503
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
1502
1504
|
/** @type {SoapRequestParams} */
|
|
1503
1505
|
const options = {
|
|
1504
1506
|
filter: {
|
|
@@ -50,12 +50,14 @@ class DataExtract extends MetadataType {
|
|
|
50
50
|
/**
|
|
51
51
|
* Retrieve a specific dataExtract Definition by Name
|
|
52
52
|
*
|
|
53
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
53
54
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
54
55
|
* @param {string} name name of the metadata file
|
|
55
56
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
56
57
|
* @returns {Promise.<MetadataTypeItemObj>} Promise of metadata
|
|
57
58
|
*/
|
|
58
59
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
60
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
59
61
|
const res = await this.client.rest.get(
|
|
60
62
|
'/automation/v1/dataextracts/?$filter=name%20eq%20' + encodeURIComponent(name)
|
|
61
63
|
);
|
|
@@ -33,6 +33,7 @@ import pLimit from 'p-limit';
|
|
|
33
33
|
*/
|
|
34
34
|
class Event extends MetadataType {
|
|
35
35
|
static reCacheDataExtensions = [];
|
|
36
|
+
static createdKeys = [];
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* Retrieves Metadata of Event Definition.
|
|
@@ -81,12 +82,14 @@ class Event extends MetadataType {
|
|
|
81
82
|
/**
|
|
82
83
|
* Retrieve a specific Event Definition by Name
|
|
83
84
|
*
|
|
85
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
84
86
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
85
87
|
* @param {string} name name of the metadata file
|
|
86
88
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
87
89
|
* @returns {Promise.<MetadataTypeItemObj>} Promise of metadata
|
|
88
90
|
*/
|
|
89
91
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
92
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
90
93
|
const res = await this.client.rest.get(
|
|
91
94
|
'/interaction/v1/eventDefinitions?name=' + encodeURIComponent(name)
|
|
92
95
|
);
|
|
@@ -158,7 +161,10 @@ class Event extends MetadataType {
|
|
|
158
161
|
*/
|
|
159
162
|
static async deploy(metadata, deployDir, retrieveDir) {
|
|
160
163
|
Util.logBeta(this.definition.type);
|
|
161
|
-
|
|
164
|
+
const metadataMap = await super.deploy(metadata, deployDir, retrieveDir);
|
|
165
|
+
|
|
166
|
+
this.createdKeys.length = 0; // reset createdKeys after deploy to ensure it's not used in future retrieves
|
|
167
|
+
return metadataMap;
|
|
162
168
|
}
|
|
163
169
|
|
|
164
170
|
/**
|
|
@@ -168,6 +174,7 @@ class Event extends MetadataType {
|
|
|
168
174
|
* @returns {Promise} Promise
|
|
169
175
|
*/
|
|
170
176
|
static create(metadata) {
|
|
177
|
+
this.createdKeys.push(metadata[this.definition.keyField]);
|
|
171
178
|
return super.createREST(metadata, '/interaction/v1/eventDefinitions/');
|
|
172
179
|
}
|
|
173
180
|
|
|
@@ -215,8 +222,7 @@ class Event extends MetadataType {
|
|
|
215
222
|
break;
|
|
216
223
|
}
|
|
217
224
|
case 'SalesforceObjectTriggerV2': {
|
|
218
|
-
metadata.iconUrl ||=
|
|
219
|
-
'/events/js/salesforce-event/events/NetworkMember/images/SF-Event-Icon.svg';
|
|
225
|
+
metadata.iconUrl ||= '/events/js/salesforce-event/images/SF-Event-Icon.svg';
|
|
220
226
|
break;
|
|
221
227
|
}
|
|
222
228
|
case 'AutomationAudience': {
|
|
@@ -601,16 +607,18 @@ class Event extends MetadataType {
|
|
|
601
607
|
if (metadata.mode === 'Production') {
|
|
602
608
|
delete metadata.mode;
|
|
603
609
|
}
|
|
604
|
-
if (
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
Util.
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
610
|
+
if (!this.createdKeys.includes(metadata[this.definition.keyField])) {
|
|
611
|
+
if (metadata.interactionCount === 0 && metadata.publishedInteractionCount === 0) {
|
|
612
|
+
Util.logger.warn(
|
|
613
|
+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): is not used and could therefore be deleted. Associated Journeys: ${metadata.interactionCount}. Active Journeys: ${metadata.publishedInteractionCount}.`
|
|
614
|
+
);
|
|
615
|
+
} else if (metadata.publishedInteractionCount === 0) {
|
|
616
|
+
Util.logger.info(
|
|
617
|
+
Util.getGrayMsg(
|
|
618
|
+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${metadata[this.definition.keyField]}): is currently inactive. Associated Journeys: ${metadata.interactionCount}. Active Journeys: ${metadata.publishedInteractionCount}.`
|
|
619
|
+
)
|
|
620
|
+
);
|
|
621
|
+
}
|
|
614
622
|
}
|
|
615
623
|
|
|
616
624
|
try {
|
|
@@ -50,12 +50,14 @@ class FileTransfer extends MetadataType {
|
|
|
50
50
|
/**
|
|
51
51
|
* Retrieve a specific File Transfer Definition by Name
|
|
52
52
|
*
|
|
53
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
53
54
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
54
55
|
* @param {string} name name of the metadata file
|
|
55
56
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
56
57
|
* @returns {Promise.<MetadataTypeItemObj>} Promise
|
|
57
58
|
*/
|
|
58
59
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
60
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
59
61
|
const res = await this.client.rest.get(
|
|
60
62
|
'/automation/v1/filetransfers/?$filter=name%20eq%20' + encodeURIComponent(name)
|
|
61
63
|
);
|
|
@@ -101,17 +101,21 @@ class Folder extends MetadataType {
|
|
|
101
101
|
idMap[id].Path = idMap[id].Name;
|
|
102
102
|
}
|
|
103
103
|
} else {
|
|
104
|
-
Util.logger.
|
|
105
|
-
|
|
104
|
+
Util.logger.info(
|
|
105
|
+
Util.getGrayMsg(
|
|
106
|
+
` ☇ skipping folder ${idMap[id].Name} (${id}, type: ${idMap[id].ContentType}): Cannot find parent folder (${idMap[id].ParentFolder.ID})`
|
|
107
|
+
)
|
|
106
108
|
);
|
|
109
|
+
delete idMap[id];
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
// All folders except the artificial root have ParentFolder attribute. If they dont something else is wrong
|
|
110
113
|
else if (idMap[id].Name !== '<ROOT>') {
|
|
111
114
|
idMap[id].Path = '';
|
|
112
115
|
Util.logger.warn(
|
|
113
|
-
`
|
|
116
|
+
` ☇ skipping folder ${idMap[id].Name} (${id}, type: ${idMap[id].ContentType}): Does not have a parent folder`
|
|
114
117
|
);
|
|
118
|
+
delete idMap[id];
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
|
|
@@ -220,25 +224,11 @@ class Folder extends MetadataType {
|
|
|
220
224
|
let existingId;
|
|
221
225
|
try {
|
|
222
226
|
// perform a secondary check based on path
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
deployableMetadata.Path
|
|
226
|
-
'Path',
|
|
227
|
-
'ID',
|
|
228
|
-
undefined,
|
|
229
|
-
true
|
|
230
|
-
);
|
|
231
|
-
const cachedVersion = cache.getByKey(
|
|
232
|
-
'folder',
|
|
233
|
-
cache.searchForField(
|
|
234
|
-
'folder',
|
|
235
|
-
deployableMetadata.Path,
|
|
236
|
-
'Path',
|
|
237
|
-
this.definition.keyField,
|
|
238
|
-
undefined,
|
|
239
|
-
true
|
|
240
|
-
)
|
|
227
|
+
|
|
228
|
+
const cachedVersion = cache.getFolderByPath(
|
|
229
|
+
deployableMetadata.Path
|
|
241
230
|
);
|
|
231
|
+
existingId = cachedVersion?.ID;
|
|
242
232
|
if (
|
|
243
233
|
existingId &&
|
|
244
234
|
!this.hasChangedGeneric(
|
|
@@ -374,6 +364,7 @@ class Folder extends MetadataType {
|
|
|
374
364
|
return {};
|
|
375
365
|
}
|
|
376
366
|
const path = metadataEntry.Path;
|
|
367
|
+
let apiTypeSoap = false;
|
|
377
368
|
try {
|
|
378
369
|
if (this.definition.deployFolderTypesEmailRest.includes(metadataEntry.ContentType)) {
|
|
379
370
|
// * The SOAP endpoint for creating folders does not support folders for automations nor journeys. The Rest endpoint on the other hand errors out on certain characters in the folder names that are actually valid. We therefore only use Rest for the folder types that are not supported by SOAP.
|
|
@@ -448,6 +439,7 @@ class Folder extends MetadataType {
|
|
|
448
439
|
throw new Error(JSON.stringify(response));
|
|
449
440
|
}
|
|
450
441
|
} else {
|
|
442
|
+
apiTypeSoap = true;
|
|
451
443
|
const response = await super.createSOAP(metadataEntry, true);
|
|
452
444
|
if (response) {
|
|
453
445
|
// set the client ID to ensure we can find the newly created folders as parents for folders created afterwards inside of it
|
|
@@ -464,14 +456,18 @@ class Folder extends MetadataType {
|
|
|
464
456
|
}
|
|
465
457
|
}
|
|
466
458
|
} catch (ex) {
|
|
467
|
-
if (
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
)
|
|
459
|
+
if (apiTypeSoap) {
|
|
460
|
+
this._handleSOAPErrors(ex, 'creating', metadataEntry, false, 'Name');
|
|
461
|
+
} else {
|
|
462
|
+
if (ex?.results) {
|
|
463
|
+
Util.logger.error(
|
|
464
|
+
`${this.definition.type}-${metadataEntry.ContentType}.create:: error creating: '${path}'. ${ex.results[0].StatusMessage}`
|
|
465
|
+
);
|
|
466
|
+
} else if (ex) {
|
|
467
|
+
Util.logger.error(
|
|
468
|
+
`${this.definition.type}-${metadataEntry.ContentType}.create:: error creating: '${path}'. ${ex.message}`
|
|
469
|
+
);
|
|
470
|
+
}
|
|
475
471
|
}
|
|
476
472
|
}
|
|
477
473
|
}
|
|
@@ -490,6 +486,7 @@ class Folder extends MetadataType {
|
|
|
490
486
|
return {};
|
|
491
487
|
}
|
|
492
488
|
const path = metadataEntry.Path;
|
|
489
|
+
let apiTypeSoap = false;
|
|
493
490
|
try {
|
|
494
491
|
let response;
|
|
495
492
|
if (this.definition.deployFolderTypesAssetRest.includes(metadataEntry.ContentType)) {
|
|
@@ -531,6 +528,7 @@ class Folder extends MetadataType {
|
|
|
531
528
|
throw new Error(JSON.stringify(response));
|
|
532
529
|
}
|
|
533
530
|
} else {
|
|
531
|
+
apiTypeSoap = true;
|
|
534
532
|
response = await super.updateSOAP(metadataEntry, true);
|
|
535
533
|
if (response.Results?.[0]?.StatusCode === 'OK') {
|
|
536
534
|
response.Results[0].Object = metadataEntry;
|
|
@@ -541,14 +539,18 @@ class Folder extends MetadataType {
|
|
|
541
539
|
}
|
|
542
540
|
}
|
|
543
541
|
} catch (ex) {
|
|
544
|
-
if (
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
)
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
)
|
|
542
|
+
if (apiTypeSoap) {
|
|
543
|
+
this._handleSOAPErrors(ex, 'updating', metadataEntry, false, 'Name');
|
|
544
|
+
} else {
|
|
545
|
+
if (ex?.results) {
|
|
546
|
+
Util.logger.error(
|
|
547
|
+
`${this.definition.type}-${metadataEntry.ContentType}.update:: error updating: '${path}'. ${ex.results[0].StatusMessage}`
|
|
548
|
+
);
|
|
549
|
+
} else if (ex) {
|
|
550
|
+
Util.logger.error(
|
|
551
|
+
`${this.definition.type}-${metadataEntry.ContentType}.update:: error updating: '${path}'. ${ex.message}`
|
|
552
|
+
);
|
|
553
|
+
}
|
|
552
554
|
}
|
|
553
555
|
}
|
|
554
556
|
}
|
|
@@ -133,12 +133,14 @@ class ImportFile extends MetadataType {
|
|
|
133
133
|
/**
|
|
134
134
|
* Retrieve a specific Import Definition by Name
|
|
135
135
|
*
|
|
136
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
136
137
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
137
138
|
* @param {string} name name of the metadata file
|
|
138
139
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
139
140
|
* @returns {Promise.<MetadataTypeItemObj>} Promise
|
|
140
141
|
*/
|
|
141
142
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
143
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
142
144
|
// using '?$filter=name%20eq%20' + encodeURIComponent(name) would also work but that just retrieves more data for no reason
|
|
143
145
|
const cache = await this.retrieveForCache(null, null, 'name:' + name);
|
|
144
146
|
const metadataArr = Object.values(cache?.metadata);
|
|
@@ -182,7 +182,8 @@ class Journey extends MetadataType {
|
|
|
182
182
|
// if the interaction does not exist, the API returns an error code which would otherwise bring execution to a hold
|
|
183
183
|
if (
|
|
184
184
|
[
|
|
185
|
-
'Interaction matching key not found.',
|
|
185
|
+
'Interaction matching key not found.', // might be outdated
|
|
186
|
+
'Interaction matching criteria not found.', // seen in 2025-05
|
|
186
187
|
'Must provide a valid ID or Key parameter',
|
|
187
188
|
].includes(ex.message) ||
|
|
188
189
|
(key && ex.code === 'ERR_BAD_REQUEST')
|
|
@@ -299,7 +299,7 @@ class MetadataType {
|
|
|
299
299
|
* @returns {Promise.<MetadataTypeMapObj>} metadata
|
|
300
300
|
*/
|
|
301
301
|
static async retrieve(retrieveDir, additionalFields, subTypeArr, key) {
|
|
302
|
-
Util.
|
|
302
|
+
Util.logNotSupported(this.definition, 'retrieve');
|
|
303
303
|
return { metadata: {}, type: this.definition.type };
|
|
304
304
|
}
|
|
305
305
|
|
|
@@ -329,6 +329,7 @@ class MetadataType {
|
|
|
329
329
|
/**
|
|
330
330
|
* Gets metadata cache with limited fields and does not store value to disk
|
|
331
331
|
*
|
|
332
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
332
333
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
333
334
|
* @param {string} name name of the metadata file
|
|
334
335
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
@@ -336,7 +337,8 @@ class MetadataType {
|
|
|
336
337
|
* @returns {Promise.<MetadataTypeItemObj>} metadata
|
|
337
338
|
*/
|
|
338
339
|
static async retrieveAsTemplate(templateDir, name, templateVariables, subType) {
|
|
339
|
-
Util.
|
|
340
|
+
Util.logNotSupported(this.definition, 'retrieveAsTemplate');
|
|
341
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
340
342
|
return { metadata: null, type: this.definition.type };
|
|
341
343
|
}
|
|
342
344
|
|
|
@@ -499,7 +501,7 @@ class MetadataType {
|
|
|
499
501
|
* @returns {Promise.<object> | null} Promise of API response or null in case of an error
|
|
500
502
|
*/
|
|
501
503
|
static async create(metadata, deployDir) {
|
|
502
|
-
Util.
|
|
504
|
+
Util.logNotSupported(this.definition, 'create', metadata);
|
|
503
505
|
return;
|
|
504
506
|
}
|
|
505
507
|
|
|
@@ -511,7 +513,7 @@ class MetadataType {
|
|
|
511
513
|
* @returns {Promise.<object> | null} Promise of API response or null in case of an error
|
|
512
514
|
*/
|
|
513
515
|
static async update(metadata, metadataBefore) {
|
|
514
|
-
Util.
|
|
516
|
+
Util.logNotSupported(this.definition, 'update', metadata);
|
|
515
517
|
return;
|
|
516
518
|
}
|
|
517
519
|
|
|
@@ -524,7 +526,7 @@ class MetadataType {
|
|
|
524
526
|
* @returns {Promise.<string[]>} Returns list of keys that were refreshed
|
|
525
527
|
*/
|
|
526
528
|
static async refresh(keyArr, checkKey = true, upsertResults) {
|
|
527
|
-
Util.
|
|
529
|
+
Util.logNotSupported(this.definition, 'refresh');
|
|
528
530
|
return [];
|
|
529
531
|
}
|
|
530
532
|
|
|
@@ -630,7 +632,7 @@ class MetadataType {
|
|
|
630
632
|
* @returns {Promise.<MetadataTypeItem | CodeExtractItem>} key of the item that was updated
|
|
631
633
|
*/
|
|
632
634
|
static async replaceCbReference(item, retrieveDir, findAssetKeys) {
|
|
633
|
-
Util.
|
|
635
|
+
Util.logNotSupported(this.definition, 'replaceCbReference');
|
|
634
636
|
return [];
|
|
635
637
|
}
|
|
636
638
|
|
|
@@ -642,7 +644,7 @@ class MetadataType {
|
|
|
642
644
|
* @returns {Promise.<string[]>} Returns list of keys that were executed
|
|
643
645
|
*/
|
|
644
646
|
static async execute(keyArr, cache) {
|
|
645
|
-
Util.
|
|
647
|
+
Util.logNotSupported(this.definition, 'execute');
|
|
646
648
|
return [];
|
|
647
649
|
}
|
|
648
650
|
|
|
@@ -654,7 +656,7 @@ class MetadataType {
|
|
|
654
656
|
* @returns {Promise.<string[]>} Returns list of keys that were executed
|
|
655
657
|
*/
|
|
656
658
|
static async schedule(keyArr, cache) {
|
|
657
|
-
Util.
|
|
659
|
+
Util.logNotSupported(this.definition, 'schedule');
|
|
658
660
|
return [];
|
|
659
661
|
}
|
|
660
662
|
|
|
@@ -666,7 +668,7 @@ class MetadataType {
|
|
|
666
668
|
* @returns {Promise.<string[]>} Returns list of keys that were paused
|
|
667
669
|
*/
|
|
668
670
|
static async pause(keyArr, cache) {
|
|
669
|
-
Util.
|
|
671
|
+
Util.logNotSupported(this.definition, 'pause');
|
|
670
672
|
return [];
|
|
671
673
|
}
|
|
672
674
|
|
|
@@ -677,7 +679,7 @@ class MetadataType {
|
|
|
677
679
|
* @returns {Promise.<string[]>} Returns list of keys that were stopped
|
|
678
680
|
*/
|
|
679
681
|
static async stop(keyArr) {
|
|
680
|
-
Util.
|
|
682
|
+
Util.logNotSupported(this.definition, 'stop');
|
|
681
683
|
return [];
|
|
682
684
|
}
|
|
683
685
|
|
|
@@ -1354,13 +1356,16 @@ class MetadataType {
|
|
|
1354
1356
|
* @param {'creating'|'updating'|'retrieving'|'executing'|'pausing'} msg what to print in the log
|
|
1355
1357
|
* @param {MetadataTypeItem} [metadataEntry] single metadata entry
|
|
1356
1358
|
* @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method
|
|
1359
|
+
* @param {string} [nameAttribute] name attribute to use in the error message instead of keyField
|
|
1357
1360
|
*/
|
|
1358
|
-
static _handleSOAPErrors(ex, msg, metadataEntry, handleOutside) {
|
|
1361
|
+
static _handleSOAPErrors(ex, msg, metadataEntry, handleOutside, nameAttribute) {
|
|
1359
1362
|
if (handleOutside) {
|
|
1360
1363
|
throw ex;
|
|
1361
1364
|
} else {
|
|
1362
1365
|
const errorMsg = this.getSOAPErrorMsg(ex);
|
|
1363
|
-
const name = metadataEntry
|
|
1366
|
+
const name = metadataEntry
|
|
1367
|
+
? ` '${metadataEntry[nameAttribute || this.definition.keyField]}'`
|
|
1368
|
+
: '';
|
|
1364
1369
|
Util.logger.error(` ☇ error ${msg} ${this.definition.type}${name}: ${errorMsg}`);
|
|
1365
1370
|
}
|
|
1366
1371
|
}
|
|
@@ -2464,7 +2469,7 @@ class MetadataType {
|
|
|
2464
2469
|
*/
|
|
2465
2470
|
static document(metadata, isDeploy) {
|
|
2466
2471
|
if (!isDeploy) {
|
|
2467
|
-
Util.
|
|
2472
|
+
Util.logNotSupported(this.definition, 'document');
|
|
2468
2473
|
}
|
|
2469
2474
|
}
|
|
2470
2475
|
|
|
@@ -2475,7 +2480,7 @@ class MetadataType {
|
|
|
2475
2480
|
* @returns {Promise.<{key:string, name:string}>} key, name and path of metadata; null if not found
|
|
2476
2481
|
*/
|
|
2477
2482
|
static async resolveId(id) {
|
|
2478
|
-
Util.
|
|
2483
|
+
Util.logNotSupported(this.definition, 'resolveId');
|
|
2479
2484
|
return;
|
|
2480
2485
|
}
|
|
2481
2486
|
|
|
@@ -2486,7 +2491,7 @@ class MetadataType {
|
|
|
2486
2491
|
* @returns {Promise.<boolean>} deletion success status
|
|
2487
2492
|
*/
|
|
2488
2493
|
static async deleteByKey(customerKey) {
|
|
2489
|
-
Util.
|
|
2494
|
+
Util.logNotSupported(this.definition, 'delete');
|
|
2490
2495
|
return false;
|
|
2491
2496
|
}
|
|
2492
2497
|
|
|
@@ -137,12 +137,14 @@ class MobileKeyword extends MetadataType {
|
|
|
137
137
|
/**
|
|
138
138
|
* retrieve an item and create a template from it
|
|
139
139
|
*
|
|
140
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
140
141
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
141
142
|
* @param {string} key name of the metadata file
|
|
142
143
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
143
144
|
* @returns {Promise.<MetadataTypeItemObj>} Promise of metadata
|
|
144
145
|
*/
|
|
145
146
|
static async retrieveAsTemplate(templateDir, key, templateVariables) {
|
|
147
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
146
148
|
try {
|
|
147
149
|
let queryParams;
|
|
148
150
|
[key, queryParams] = this.#getRetrieveKeyAndUrl(key);
|
|
@@ -127,12 +127,14 @@ class Query extends MetadataType {
|
|
|
127
127
|
/**
|
|
128
128
|
* Retrieve a specific Query by Name
|
|
129
129
|
*
|
|
130
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
130
131
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
131
132
|
* @param {string} name name of the metadata file
|
|
132
133
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
133
134
|
* @returns {Promise.<{metadata: Query, type: string}>} Promise of metadata
|
|
134
135
|
*/
|
|
135
136
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
137
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
136
138
|
await File.initPrettier('sql');
|
|
137
139
|
return super.retrieveREST(
|
|
138
140
|
templateDir,
|
|
@@ -57,12 +57,14 @@ class Script extends MetadataType {
|
|
|
57
57
|
/**
|
|
58
58
|
* Retrieve a specific Script by Name
|
|
59
59
|
*
|
|
60
|
+
* @deprecated Use `retrieve` followed by `build` instead. `retrieveAsTemplate` will be removed in a future version.
|
|
60
61
|
* @param {string} templateDir Directory where retrieved metadata directory will be saved
|
|
61
62
|
* @param {string} name name of the metadata file
|
|
62
63
|
* @param {TemplateMap} templateVariables variables to be replaced in the metadata
|
|
63
64
|
* @returns {Promise.<{metadata: ScriptItem, type: string}>} Promise
|
|
64
65
|
*/
|
|
65
66
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
67
|
+
Util.logDeprecated('retrieveAsTemplate', `'retrieve' followed by 'build'`);
|
|
66
68
|
await File.initPrettier('ssjs');
|
|
67
69
|
return super.retrieveREST(
|
|
68
70
|
templateDir,
|
package/lib/util/cache.js
CHANGED
|
@@ -186,26 +186,45 @@ export default {
|
|
|
186
186
|
* @returns {number} folder ID
|
|
187
187
|
*/
|
|
188
188
|
getFolderId(r__folder_Path, overrideMID, allowOtherBu = true) {
|
|
189
|
+
const folder = this.getFolderByPath(r__folder_Path, overrideMID, allowOtherBu);
|
|
190
|
+
return folder?.ID;
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* helper for setFolderId
|
|
195
|
+
*
|
|
196
|
+
* @param {string} r__folder_Path folder path value
|
|
197
|
+
* @param {number} [overrideMID] ignore currentMID and use alternative (for example parent MID)
|
|
198
|
+
* @param {boolean} allowOtherBu getting folder from other BU; FALSE for folder parent search
|
|
199
|
+
* @returns {object} folder item
|
|
200
|
+
*/
|
|
201
|
+
getFolderByPath(r__folder_Path, overrideMID, allowOtherBu = true) {
|
|
189
202
|
if (!r__folder_Path) {
|
|
190
203
|
throw new Error('r__folder_Path not set');
|
|
191
204
|
}
|
|
205
|
+
|
|
192
206
|
/** @type {ListMap} */
|
|
193
207
|
const folderMap = dataStore[overrideMID || currentMID]?.['folder'];
|
|
194
208
|
if (!folderMap) {
|
|
195
209
|
throw new Error('No folders found in cache');
|
|
196
210
|
}
|
|
211
|
+
const folderPath_lower = r__folder_Path.toLowerCase();
|
|
197
212
|
const potentialFolders = [];
|
|
198
213
|
for (const folder of Object.values(folderMap)) {
|
|
199
|
-
if (folder
|
|
214
|
+
if (!folder?.Path) {
|
|
215
|
+
continue; // skip folders without Path
|
|
216
|
+
}
|
|
217
|
+
if (folder.Path.toLowerCase() === folderPath_lower) {
|
|
200
218
|
if (folder?.Client?.ID === (overrideMID || currentMID)) {
|
|
201
|
-
return folder
|
|
219
|
+
return folder;
|
|
202
220
|
} else if (allowOtherBu) {
|
|
203
221
|
potentialFolders.push(folder);
|
|
204
222
|
}
|
|
205
223
|
}
|
|
206
224
|
}
|
|
225
|
+
|
|
207
226
|
if (potentialFolders.length >= 1) {
|
|
208
|
-
return potentialFolders[0]
|
|
227
|
+
return potentialFolders[0];
|
|
209
228
|
} else {
|
|
210
229
|
throw new Error(`No folders found with path ${r__folder_Path}`);
|
|
211
230
|
}
|
package/lib/util/file.js
CHANGED
|
@@ -571,6 +571,15 @@ const File = {
|
|
|
571
571
|
* @returns {Promise.<boolean>} success of config load
|
|
572
572
|
*/
|
|
573
573
|
async initPrettier(filetype = 'html') {
|
|
574
|
+
if (Util.OPTIONS.format === false) {
|
|
575
|
+
// auto-formatting was disabled via CLI option
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
const properties = await config.getProperties();
|
|
579
|
+
if (Util.OPTIONS.format !== true && properties.options.formatOnSave === false) {
|
|
580
|
+
// auto-formatting was disabled via config file
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
574
583
|
if (FileFs.prettierConfig === null || FileFs.prettierConfigFileType !== filetype) {
|
|
575
584
|
// run this if no config was yet found or if the filetype previously used to initialize it differs (because it results in a potentially different config!)
|
|
576
585
|
FileFs.prettierConfigFileType = filetype;
|
|
@@ -591,7 +600,7 @@ const File = {
|
|
|
591
600
|
return true;
|
|
592
601
|
} catch (ex) {
|
|
593
602
|
FileFs.prettierConfig = false;
|
|
594
|
-
Util.logger.error('Cannot apply auto-formatting to your code:' + ex.message);
|
|
603
|
+
Util.logger.error('Cannot apply auto-formatting to your code: ' + ex.message);
|
|
595
604
|
return false;
|
|
596
605
|
}
|
|
597
606
|
} else {
|
package/lib/util/util.js
CHANGED
|
@@ -904,6 +904,32 @@ export const Util = {
|
|
|
904
904
|
` - 🚧 ${type} support is currently still in beta. Please report any issues here: https://github.com/Accenture/sfmc-devtools/issues/new/choose`
|
|
905
905
|
);
|
|
906
906
|
},
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* outputs a warning that the given method is deprecated
|
|
910
|
+
*
|
|
911
|
+
* @param {string} method name of the method
|
|
912
|
+
* @param {string} [useInstead] optionally specify which method to use instead
|
|
913
|
+
*/
|
|
914
|
+
logDeprecated(method, useInstead = '') {
|
|
915
|
+
Util.logger.warn(
|
|
916
|
+
` 💥 '${method}' is deprecated and will be sunset in a future version. ${useInstead ? `Please use ${useInstead} instead.` : ''}`
|
|
917
|
+
);
|
|
918
|
+
},
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* helper for MetadataType class to issue a similar error message for unsupported methods
|
|
922
|
+
*
|
|
923
|
+
* @param {any} definition type definition object
|
|
924
|
+
* @param {string} method name of the method thats not supported
|
|
925
|
+
* @param {MetadataTypeItem} [item] metadata item
|
|
926
|
+
*/
|
|
927
|
+
logNotSupported: function (definition, method, item) {
|
|
928
|
+
Util.logger.error(
|
|
929
|
+
` ☇ skipping ${item ? Util.getTypeKeyName(definition, item) : definition.type}: ${method} is not supported for ${definition.type}`
|
|
930
|
+
);
|
|
931
|
+
},
|
|
932
|
+
|
|
907
933
|
// defined colors for logging things in different colors
|
|
908
934
|
color: {
|
|
909
935
|
reset: '\x1B[0m',
|
|
@@ -1317,18 +1343,6 @@ export const Util = {
|
|
|
1317
1343
|
return acc;
|
|
1318
1344
|
}, {});
|
|
1319
1345
|
},
|
|
1320
|
-
/**
|
|
1321
|
-
* helper for MetadataType class to issue a similar error message for unsupported methods
|
|
1322
|
-
*
|
|
1323
|
-
* @param {any} definition type definition object
|
|
1324
|
-
* @param {string} method name of the method thats not supported
|
|
1325
|
-
* @param {MetadataTypeItem} [item] metadata item
|
|
1326
|
-
*/
|
|
1327
|
-
notSupportedError: function (definition, method, item) {
|
|
1328
|
-
Util.logger.error(
|
|
1329
|
-
` ☇ skipping ${item ? Util.getTypeKeyName(definition, item) : definition.type}: ${method} is not supported yet for ${definition.type}`
|
|
1330
|
-
);
|
|
1331
|
-
},
|
|
1332
1346
|
};
|
|
1333
1347
|
|
|
1334
1348
|
Util.startLogger(false, true);
|