mcdev 7.5.0 → 7.6.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 +2 -0
- package/@types/lib/index.d.ts +12 -8
- package/@types/lib/index.d.ts.map +1 -1
- package/@types/lib/metadataTypes/AttributeSet.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Automation.d.ts +14 -0
- package/@types/lib/metadataTypes/Automation.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DataExtension.d.ts +3 -1
- package/@types/lib/metadataTypes/DataExtension.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Event.d.ts +2 -2
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Journey.d.ts +17 -0
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MetadataType.d.ts +8 -4
- package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Query.d.ts +7 -0
- package/@types/lib/metadataTypes/Query.d.ts.map +1 -1
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts +1 -0
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts.map +1 -1
- package/@types/lib/metadataTypes/TriggeredSend.d.ts +0 -8
- package/@types/lib/metadataTypes/TriggeredSend.d.ts.map +1 -1
- package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +1 -0
- package/@types/lib/metadataTypes/definitions/TransactionalEmail.definition.d.ts +1 -0
- package/@types/lib/util/replaceContentBlockReference.d.ts.map +1 -1
- package/@types/lib/util/util.d.ts.map +1 -1
- package/@types/types/mcdev.d.d.ts +20 -8
- package/@types/types/mcdev.d.d.ts.map +1 -1
- package/lib/cli.js +13 -2
- package/lib/index.js +46 -45
- package/lib/metadataTypes/Automation.js +28 -0
- package/lib/metadataTypes/Event.js +4 -1
- package/lib/metadataTypes/Journey.js +472 -94
- package/lib/metadataTypes/MetadataType.js +12 -6
- package/lib/metadataTypes/TriggeredSend.js +46 -15
- package/lib/metadataTypes/definitions/Automation.definition.js +1 -0
- package/lib/metadataTypes/definitions/Journey.definition.js +1 -0
- package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +1 -0
- package/package.json +15 -15
- package/test/general.test.js +5 -5
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/resources/9999999/dataFolder/retrieve-ContentTypeINcontextual_suppression_list,hidden,list,mysubs,publication,suppression_list,triggered_send,triggered_send_journeybuilder-response.xml +385 -0
- package/test/resources/9999999/interaction/v1/interactions/0175b971-71a3-4d8e-98ac-48121f3fbf4f/get-response.json +461 -0
- package/test/resources/9999999/interaction/v1/interactions/dsfdsafdsa-922c-4568-85a5-e5cc77efc3be/delete-response.txt +1 -0
- package/test/resources/9999999/interaction/v1/interactions/transactional/pause/post-response.json +3 -0
- package/test/resources/9999999/interaction/v1/interactions/transactional/resume/post-response.json +3 -0
- package/test/resources/9999999/triggeredSendDefinition/retrieve-CustomerKey=testExisting_triggeredSend-response.xml +72 -0
- package/test/resources/9999999/triggeredSendDefinition/retrieve-CustomerKey=testExisting_triggeredSend_rcb-response.xml +72 -0
- package/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml +1 -1
- package/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINdummy,Active-response.xml +118 -0
- package/test/type.automation.test.js +13 -13
- package/test/type.journey.test.js +79 -5
- package/test/type.query.test.js +2 -2
- package/test/type.triggeredSend.test.js +68 -1
- package/types/mcdev.d.js +2 -1
|
@@ -508,13 +508,15 @@ class MetadataType {
|
|
|
508
508
|
/**
|
|
509
509
|
* Abstract refresh method that needs to be implemented in child metadata type
|
|
510
510
|
*
|
|
511
|
-
* @
|
|
511
|
+
* @param {string[]} [keyArr] metadata keys
|
|
512
|
+
* @param {boolean} [checkKey] whether to check if the key is valid
|
|
513
|
+
* @returns {Promise.<string[]>} Returns list of keys that were refreshed
|
|
512
514
|
*/
|
|
513
|
-
static refresh() {
|
|
515
|
+
static async refresh(keyArr, checkKey = true) {
|
|
514
516
|
Util.logger.error(
|
|
515
517
|
` ☇ skipping ${this.definition.type}: refresh is not supported yet for ${this.definition.type}`
|
|
516
518
|
);
|
|
517
|
-
return;
|
|
519
|
+
return [];
|
|
518
520
|
}
|
|
519
521
|
|
|
520
522
|
/**
|
|
@@ -631,9 +633,10 @@ class MetadataType {
|
|
|
631
633
|
* Abstract execute method that needs to be implemented in child metadata type
|
|
632
634
|
*
|
|
633
635
|
* @param {string[]} keyArr customerkey of the metadata
|
|
636
|
+
* @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching
|
|
634
637
|
* @returns {Promise.<string[]>} Returns list of keys that were executed
|
|
635
638
|
*/
|
|
636
|
-
static async execute(keyArr) {
|
|
639
|
+
static async execute(keyArr, cache) {
|
|
637
640
|
Util.logger.error(
|
|
638
641
|
` ☇ skipping ${this.definition.type}: execute is not supported yet for ${this.definition.type}`
|
|
639
642
|
);
|
|
@@ -644,9 +647,10 @@ class MetadataType {
|
|
|
644
647
|
* Abstract pause method that needs to be implemented in child metadata type
|
|
645
648
|
*
|
|
646
649
|
* @param {string[]} keyArr customerkey of the metadata
|
|
650
|
+
* @param {MetadataTypeMapObj} [cache] metadata cache used by refresh to avoid recaching
|
|
647
651
|
* @returns {Promise.<string[]>} Returns list of keys that were paused
|
|
648
652
|
*/
|
|
649
|
-
static async pause(keyArr) {
|
|
653
|
+
static async pause(keyArr, cache) {
|
|
650
654
|
Util.logger.error(
|
|
651
655
|
` ☇ skipping ${this.definition.type}: pause is not supported yet for ${this.definition.type}`
|
|
652
656
|
);
|
|
@@ -2466,7 +2470,9 @@ class MetadataType {
|
|
|
2466
2470
|
} else {
|
|
2467
2471
|
const errorMsg = ex?.results?.length
|
|
2468
2472
|
? `${ex.results[0].StatusMessage} (Code ${ex.results[0].ErrorCode})`
|
|
2469
|
-
: ex
|
|
2473
|
+
: ex?.json?.Results?.length
|
|
2474
|
+
? `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})`
|
|
2475
|
+
: ex.message;
|
|
2470
2476
|
Util.logger.error(
|
|
2471
2477
|
` - Deleting ${this.definition.type} '${customerKey}' failed: ${errorMsg}`
|
|
2472
2478
|
);
|
|
@@ -6,7 +6,10 @@ import cache from '../util/cache.js';
|
|
|
6
6
|
import asset from './Asset.js';
|
|
7
7
|
import folder from './Folder.js';
|
|
8
8
|
import list from './List.js';
|
|
9
|
+
import sendClassification from './SendClassification.js';
|
|
10
|
+
import senderProfile from './SenderProfile.js';
|
|
9
11
|
import ReplaceCbReference from '../util/replaceContentBlockReference.js';
|
|
12
|
+
import pLimit from 'p-limit';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
|
|
@@ -303,24 +306,32 @@ class TriggeredSend extends MetadataType {
|
|
|
303
306
|
*
|
|
304
307
|
* @param {string[]} [keyArr] metadata keys
|
|
305
308
|
* @param {boolean} [checkKey] whether to check if the key is valid
|
|
306
|
-
* @returns {Promise.<
|
|
309
|
+
* @returns {Promise.<string[]>} Returns list of keys that were refreshed
|
|
307
310
|
*/
|
|
308
311
|
static async refresh(keyArr, checkKey = true) {
|
|
309
|
-
console.time('Time'); // eslint-disable-line no-console
|
|
310
312
|
if (!keyArr) {
|
|
311
313
|
keyArr = await this.getKeysForValidTSDs((await this.findRefreshableItems()).metadata);
|
|
312
314
|
checkKey = false;
|
|
313
315
|
}
|
|
314
316
|
// then executes pause, publish, start on them.
|
|
315
|
-
const refreshList = [];
|
|
316
317
|
Util.logger.info(`Refreshing ${keyArr.length} ${this.definition.typeName}...`);
|
|
317
318
|
Util.logger.debug(`Refreshing keys: ${keyArr.join(', ')}`);
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
319
|
+
const refreshedKeyArr = [];
|
|
320
|
+
const rateLimit = pLimit(10);
|
|
321
|
+
await Promise.all(
|
|
322
|
+
keyArr.map((key) =>
|
|
323
|
+
rateLimit(async () => {
|
|
324
|
+
const result = await this._refreshItem(key, checkKey);
|
|
325
|
+
if (result) {
|
|
326
|
+
refreshedKeyArr.push(key);
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
)
|
|
330
|
+
);
|
|
331
|
+
Util.logger.info(
|
|
332
|
+
`Refreshed ${refreshedKeyArr.length} of ${keyArr.length} ${this.definition.type}`
|
|
333
|
+
);
|
|
334
|
+
return refreshedKeyArr;
|
|
324
335
|
}
|
|
325
336
|
|
|
326
337
|
/**
|
|
@@ -347,7 +358,6 @@ class TriggeredSend extends MetadataType {
|
|
|
347
358
|
static async findRefreshableItems(assetLoaded = false) {
|
|
348
359
|
Util.logger.info('Finding refreshable items...');
|
|
349
360
|
// cache dependencies to test for broken links
|
|
350
|
-
// skip deprecated classic emails here, assuming they cannot be updated and hence are not relevant for {@link refresh}
|
|
351
361
|
const requiredCache = {
|
|
352
362
|
folder: [
|
|
353
363
|
'hidden',
|
|
@@ -359,13 +369,31 @@ class TriggeredSend extends MetadataType {
|
|
|
359
369
|
'triggered_send',
|
|
360
370
|
'triggered_send_journeybuilder',
|
|
361
371
|
],
|
|
362
|
-
asset: ['message'],
|
|
363
|
-
list: null,
|
|
364
372
|
};
|
|
373
|
+
for (const dep of this.definition.dependencies) {
|
|
374
|
+
if (dep === 'email') {
|
|
375
|
+
// skip deprecated classic emails here, assuming they cannot be updated and hence are not relevant for {@link refresh}
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
const [type, subtype] = dep.split('-');
|
|
379
|
+
if (requiredCache[type]) {
|
|
380
|
+
requiredCache[type].push(subtype);
|
|
381
|
+
} else {
|
|
382
|
+
requiredCache[type] = subtype ? [subtype] : null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
for (const [type, subTypeArr] of Object.entries(requiredCache)) {
|
|
386
|
+
if (Array.isArray(subTypeArr)) {
|
|
387
|
+
// make sure entries are unique
|
|
388
|
+
requiredCache[type] = [...new Set(subTypeArr)];
|
|
389
|
+
}
|
|
390
|
+
}
|
|
365
391
|
const cacheTypes = {
|
|
366
392
|
asset,
|
|
367
393
|
folder,
|
|
368
394
|
list,
|
|
395
|
+
sendClassification,
|
|
396
|
+
senderProfile,
|
|
369
397
|
};
|
|
370
398
|
for (const [type, subTypeArr] of Object.entries(requiredCache)) {
|
|
371
399
|
if (type === 'asset' && assetLoaded) {
|
|
@@ -373,6 +401,9 @@ class TriggeredSend extends MetadataType {
|
|
|
373
401
|
}
|
|
374
402
|
Util.logger.info(` - Caching dependent Metadata: ${type}`);
|
|
375
403
|
Util.logSubtypes(subTypeArr);
|
|
404
|
+
if (!cacheTypes[type]) {
|
|
405
|
+
throw new Error(`Cache type ${type} not implemented.`);
|
|
406
|
+
}
|
|
376
407
|
cacheTypes[type].client = this.client;
|
|
377
408
|
cacheTypes[type].buObject = this.buObject;
|
|
378
409
|
cacheTypes[type].properties = this.properties;
|
|
@@ -452,7 +483,7 @@ class TriggeredSend extends MetadataType {
|
|
|
452
483
|
throw new Error(test.Results[0].StatusMessage);
|
|
453
484
|
}
|
|
454
485
|
delete item.TriggeredSendStatus;
|
|
455
|
-
Util.logger.info(` - paused ${this.definition.typeName}: ${key}`);
|
|
486
|
+
Util.logger.info(` - 🛑 paused ${this.definition.typeName}: ${key}`);
|
|
456
487
|
} catch (ex) {
|
|
457
488
|
const errorMsg = super.getSOAPErrorMsg(ex);
|
|
458
489
|
|
|
@@ -470,7 +501,7 @@ class TriggeredSend extends MetadataType {
|
|
|
470
501
|
throw new Error(test.Results[0].StatusMessage);
|
|
471
502
|
}
|
|
472
503
|
delete item.RefreshContent;
|
|
473
|
-
Util.logger.info(` - published ${this.definition.typeName}: ${key}`);
|
|
504
|
+
Util.logger.info(` - 🔃 published ${this.definition.typeName}: ${key}`);
|
|
474
505
|
} catch (ex) {
|
|
475
506
|
const errorMsg = super.getSOAPErrorMsg(ex);
|
|
476
507
|
Util.logger.error(
|
|
@@ -487,7 +518,7 @@ class TriggeredSend extends MetadataType {
|
|
|
487
518
|
throw new Error(test.Results[0].StatusMessage);
|
|
488
519
|
}
|
|
489
520
|
delete item.RefreshContent;
|
|
490
|
-
Util.logger.info(` - started ${this.definition.typeName}: ${key}`);
|
|
521
|
+
Util.logger.info(` - ✅ started ${this.definition.typeName}: ${key}`);
|
|
491
522
|
} catch (ex) {
|
|
492
523
|
const errorMsg = super.getSOAPErrorMsg(ex);
|
|
493
524
|
Util.logger.error(
|
|
@@ -20,6 +20,7 @@ export default {
|
|
|
20
20
|
lastmodNameField: null,
|
|
21
21
|
restPagination: true,
|
|
22
22
|
restPageSize: 100,
|
|
23
|
+
maxKeyLength: 36, // confirmed max length
|
|
23
24
|
type: 'transactionalEmail',
|
|
24
25
|
typeDescription: 'Lets you send immediate Email messages via API events',
|
|
25
26
|
typeRetrieveByDefault: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcdev",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.1",
|
|
4
4
|
"description": "Accenture Salesforce Marketing Cloud DevTools",
|
|
5
5
|
"author": "Accenture: joern.berkefeld, douglas.midgley, robert.zimmermann, maciej.barnas",
|
|
6
6
|
"license": "MIT",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"beauty-amp-core2": "0.4.9",
|
|
72
72
|
"cli-progress": "3.12.0",
|
|
73
73
|
"command-exists": "1.2.9",
|
|
74
|
-
"conf": "13.0
|
|
74
|
+
"conf": "13.1.0",
|
|
75
75
|
"console.table": "0.10.0",
|
|
76
76
|
"deep-equal": "2.2.3",
|
|
77
77
|
"fs-extra": "11.2.0",
|
|
@@ -79,45 +79,45 @@
|
|
|
79
79
|
"json-to-table": "4.2.1",
|
|
80
80
|
"mustache": "4.2.0",
|
|
81
81
|
"p-limit": "6.1.0",
|
|
82
|
-
"prettier": "3.
|
|
82
|
+
"prettier": "3.4.2",
|
|
83
83
|
"prettier-plugin-sql": "0.18.1",
|
|
84
84
|
"semver": "7.6.3",
|
|
85
85
|
"sfmc-sdk": "2.1.2",
|
|
86
86
|
"simple-git": "3.27.0",
|
|
87
87
|
"toposort": "2.0.2",
|
|
88
88
|
"update-notifier": "7.3.1",
|
|
89
|
-
"winston": "3.
|
|
89
|
+
"winston": "3.17.0",
|
|
90
90
|
"yargs": "17.7.2",
|
|
91
91
|
"yocto-spinner": "0.1.1"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@eslint/js": "9.
|
|
94
|
+
"@eslint/js": "9.17.0",
|
|
95
95
|
"@types/fs-extra": "11.0.4",
|
|
96
96
|
"@types/inquirer": "9.0.7",
|
|
97
97
|
"@types/mocha": "10.0.8",
|
|
98
|
-
"@types/node": "22.
|
|
98
|
+
"@types/node": "22.10.2",
|
|
99
99
|
"@types/yargs": "17.0.33",
|
|
100
100
|
"assert": "2.1.0",
|
|
101
|
-
"axios-mock-adapter": "2.
|
|
101
|
+
"axios-mock-adapter": "2.0.0",
|
|
102
102
|
"c8": "10.0.0",
|
|
103
|
-
"chai": "5.1.
|
|
103
|
+
"chai": "5.1.2",
|
|
104
104
|
"chai-files": "1.4.0",
|
|
105
|
-
"eslint": "9.
|
|
105
|
+
"eslint": "9.17.0",
|
|
106
106
|
"eslint-config-prettier": "9.1.0",
|
|
107
107
|
"eslint-config-ssjs": "2.0.0",
|
|
108
|
-
"eslint-plugin-jsdoc": "50.
|
|
108
|
+
"eslint-plugin-jsdoc": "50.6.1",
|
|
109
109
|
"eslint-plugin-mocha": "10.5.0",
|
|
110
110
|
"eslint-plugin-prettier": "5.2.1",
|
|
111
|
-
"eslint-plugin-unicorn": "56.0.
|
|
111
|
+
"eslint-plugin-unicorn": "56.0.1",
|
|
112
112
|
"fast-xml-parser": "4.4.1",
|
|
113
|
-
"globals": "15.
|
|
114
|
-
"husky": "9.1.
|
|
113
|
+
"globals": "15.14.0",
|
|
114
|
+
"husky": "9.1.7",
|
|
115
115
|
"lint-staged": "15.2.10",
|
|
116
|
-
"mocha": "
|
|
116
|
+
"mocha": "11.0.1",
|
|
117
117
|
"mock-fs": "5.3.0",
|
|
118
118
|
"npm-run-all": "4.1.5",
|
|
119
119
|
"prettier-eslint": "16.3.0",
|
|
120
|
-
"typescript": "5.
|
|
120
|
+
"typescript": "5.7.2"
|
|
121
121
|
},
|
|
122
122
|
"optionalDependencies": {
|
|
123
123
|
"fsevents": "*"
|
package/test/general.test.js
CHANGED
|
@@ -708,7 +708,7 @@ describe('GENERAL', () => {
|
|
|
708
708
|
// download first before we test buildTemplate
|
|
709
709
|
await handler.retrieve('testInstance/testBU', ['automation', 'query']);
|
|
710
710
|
|
|
711
|
-
const expectedApiCallsRetrieve =
|
|
711
|
+
const expectedApiCallsRetrieve = 31;
|
|
712
712
|
assert.equal(
|
|
713
713
|
testUtils.getAPIHistoryLength(),
|
|
714
714
|
expectedApiCallsRetrieve,
|
|
@@ -813,7 +813,7 @@ describe('GENERAL', () => {
|
|
|
813
813
|
});
|
|
814
814
|
|
|
815
815
|
it('buildTemplate + buildDefinition for multiple types with keys and --retrieve', async () => {
|
|
816
|
-
const expectedApiCallsRetrieve =
|
|
816
|
+
const expectedApiCallsRetrieve = 31;
|
|
817
817
|
|
|
818
818
|
// preparation
|
|
819
819
|
const argvMetadata = [
|
|
@@ -1170,7 +1170,7 @@ describe('GENERAL', () => {
|
|
|
1170
1170
|
// download first before we test buildTemplate
|
|
1171
1171
|
await handler.retrieve('testInstance/testBU', ['automation', 'query']);
|
|
1172
1172
|
|
|
1173
|
-
const expectedApiCallsRetrieve =
|
|
1173
|
+
const expectedApiCallsRetrieve = 31;
|
|
1174
1174
|
assert.equal(
|
|
1175
1175
|
testUtils.getAPIHistoryLength(),
|
|
1176
1176
|
expectedApiCallsRetrieve,
|
|
@@ -1362,7 +1362,7 @@ describe('GENERAL', () => {
|
|
|
1362
1362
|
// download first before we test buildTemplate
|
|
1363
1363
|
await handler.retrieve('testInstance/testBU', ['automation', 'query']);
|
|
1364
1364
|
|
|
1365
|
-
const expectedApiCallsRetrieve =
|
|
1365
|
+
const expectedApiCallsRetrieve = 31;
|
|
1366
1366
|
assert.equal(
|
|
1367
1367
|
testUtils.getAPIHistoryLength(),
|
|
1368
1368
|
expectedApiCallsRetrieve,
|
|
@@ -1669,7 +1669,7 @@ describe('GENERAL', () => {
|
|
|
1669
1669
|
// download first before we test buildTemplate
|
|
1670
1670
|
await handler.retrieve('testInstance/testBU', ['automation', 'query']);
|
|
1671
1671
|
|
|
1672
|
-
const expectedApiCallsRetrieve =
|
|
1672
|
+
const expectedApiCallsRetrieve = 31;
|
|
1673
1673
|
assert.equal(
|
|
1674
1674
|
testUtils.getAPIHistoryLength(),
|
|
1675
1675
|
expectedApiCallsRetrieve,
|