mcdev 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug.yml +1 -0
- package/.vscode/settings.json +1 -1
- package/@types/lib/Builder.d.ts +4 -4
- package/@types/lib/Builder.d.ts.map +1 -1
- package/@types/lib/index.d.ts +26 -13
- package/@types/lib/index.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Event.d.ts +52 -4
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Journey.d.ts +2 -3
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MetadataType.d.ts +7 -0
- package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
- package/@types/lib/metadataTypes/SendClassification.d.ts.map +1 -1
- package/@types/lib/metadataTypes/TriggeredSend.d.ts.map +1 -1
- package/@types/types/mcdev.d.d.ts +123 -0
- package/@types/types/mcdev.d.d.ts.map +1 -1
- package/boilerplate/files/.vscode/settings.json +2 -3
- package/boilerplate/forcedUpdates.json +4 -0
- package/eslint.config.js +1 -1
- package/lib/Builder.js +45 -26
- package/lib/cli.js +67 -5
- package/lib/index.js +117 -48
- package/lib/metadataTypes/Asset.js +1 -1
- package/lib/metadataTypes/Automation.js +5 -5
- package/lib/metadataTypes/DataExtract.js +1 -1
- package/lib/metadataTypes/Event.js +525 -5
- package/lib/metadataTypes/FileTransfer.js +1 -1
- package/lib/metadataTypes/ImportFile.js +1 -1
- package/lib/metadataTypes/Journey.js +144 -33
- package/lib/metadataTypes/MetadataType.js +16 -2
- package/lib/metadataTypes/MobileKeyword.js +1 -1
- package/lib/metadataTypes/Query.js +1 -1
- package/lib/metadataTypes/Script.js +1 -1
- package/lib/metadataTypes/SendClassification.js +10 -8
- package/lib/metadataTypes/TriggeredSend.js +18 -16
- package/lib/metadataTypes/definitions/DataExtension.definition.js +4 -4
- package/lib/metadataTypes/definitions/EmailSend.definition.js +4 -4
- package/lib/metadataTypes/definitions/Event.definition.js +92 -92
- package/lib/metadataTypes/definitions/Journey.definition.js +1 -0
- package/lib/metadataTypes/definitions/Role.definition.js +4 -4
- package/lib/metadataTypes/definitions/SendClassification.definition.js +7 -7
- package/lib/metadataTypes/definitions/SenderProfile.definition.js +4 -4
- package/lib/metadataTypes/definitions/TriggeredSend.definition.js +11 -11
- package/package.json +1 -1
- package/test/general.test.js +20 -20
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/resourceFactory.js +5 -1
- package/test/resources/9999999/dataExtension/update-callout-afterCreatedViaEvent-expected.xml +1 -1
- package/test/resources/9999999/sendClassification/create-response.xml +1 -1
- package/test/resources/9999999/sendClassification/retrieve-response.xml +2 -2
- package/test/resources/9999999/sendClassification/update-response.xml +1 -1
- package/test/resources/9999999/triggeredSendDefinition/create-response.xml +2 -2
- package/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml +4 -4
- package/test/resources/9999999/triggeredSendDefinition/update-response.xml +2 -2
- package/test/type.asset.test.js +3 -3
- package/test/type.automation.test.js +4 -4
- package/test/type.dataExtension.test.js +3 -3
- package/test/type.dataExtract.test.js +3 -3
- package/test/type.emailSend.test.js +2 -2
- package/test/type.event.test.js +3 -3
- package/test/type.fileTransfer.test.js +3 -3
- package/test/type.importFile.test.js +3 -3
- package/test/type.journey.test.js +19 -5
- package/test/type.mobileKeyword.test.js +2 -2
- package/test/type.mobileMessage.test.js +2 -2
- package/test/type.query.test.js +3 -3
- package/test/type.script.test.js +4 -4
- package/test/type.sendClassification.test.js +2 -2
- package/test/type.senderProfile.test.js +3 -3
- package/test/type.transactionalEmail.test.js +2 -2
- package/test/type.transactionalPush.test.js +2 -2
- package/test/type.transactionalSMS.test.js +2 -2
- package/test/type.triggeredSend.test.js +3 -3
- package/test/type.user.test.js +2 -2
- package/test/type.verification.test.js +2 -2
- package/types/mcdev.d.js +37 -0
package/lib/Builder.js
CHANGED
|
@@ -102,10 +102,10 @@ saved
|
|
|
102
102
|
* @param {string} businessUnit references credentials from properties.json
|
|
103
103
|
* @param {string} selectedType supported metadata type
|
|
104
104
|
* @param {string[]} keyArr customerkey of the metadata
|
|
105
|
-
* @param {string}
|
|
105
|
+
* @param {string[]} marketArr market localizations
|
|
106
106
|
* @returns {Promise.<MultiMetadataTypeList>} -
|
|
107
107
|
*/
|
|
108
|
-
static async buildTemplate(businessUnit, selectedType, keyArr,
|
|
108
|
+
static async buildTemplate(businessUnit, selectedType, keyArr, marketArr) {
|
|
109
109
|
const properties = await config.getProperties();
|
|
110
110
|
if (!(await config.checkProperties(properties))) {
|
|
111
111
|
return null;
|
|
@@ -119,12 +119,20 @@ saved
|
|
|
119
119
|
);
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
|
+
/** @type {TemplateMap} */
|
|
123
|
+
const templateVariables = {};
|
|
124
|
+
for (const market of marketArr) {
|
|
125
|
+
if (Util.checkMarket(market, properties)) {
|
|
126
|
+
Object.assign(templateVariables, properties.markets[market]);
|
|
127
|
+
} else {
|
|
128
|
+
// do not execute the rest of this method if a market was invalid
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
122
132
|
const buObject = await Cli.getCredentialObject(properties, businessUnit);
|
|
123
133
|
if (buObject !== null) {
|
|
124
134
|
const builder = new Builder(properties, buObject);
|
|
125
|
-
|
|
126
|
-
return builder._buildTemplate(selectedType, keyArr, properties.markets[market]);
|
|
127
|
-
}
|
|
135
|
+
return builder._buildTemplate(selectedType, keyArr, templateVariables);
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
138
|
|
|
@@ -175,10 +183,10 @@ saved
|
|
|
175
183
|
* @param {string} businessUnit references credentials from properties.json
|
|
176
184
|
* @param {string} selectedType supported metadata type
|
|
177
185
|
* @param {string[]} nameArr name of the metadata
|
|
178
|
-
* @param {string}
|
|
186
|
+
* @param {string[]} marketArr market localizations
|
|
179
187
|
* @returns {Promise.<MultiMetadataTypeList>} -
|
|
180
188
|
*/
|
|
181
|
-
static async buildDefinition(businessUnit, selectedType, nameArr,
|
|
189
|
+
static async buildDefinition(businessUnit, selectedType, nameArr, marketArr) {
|
|
182
190
|
const properties = await config.getProperties();
|
|
183
191
|
if (!(await config.checkProperties(properties))) {
|
|
184
192
|
return null;
|
|
@@ -192,12 +200,20 @@ saved
|
|
|
192
200
|
);
|
|
193
201
|
return;
|
|
194
202
|
}
|
|
203
|
+
/** @type {TemplateMap} */
|
|
204
|
+
const templateVariables = {};
|
|
205
|
+
for (const market of marketArr) {
|
|
206
|
+
if (Util.checkMarket(market, properties)) {
|
|
207
|
+
Object.assign(templateVariables, properties.markets[market]);
|
|
208
|
+
} else {
|
|
209
|
+
// do not execute the rest of this method if a market was invalid
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
195
213
|
const buObject = await Cli.getCredentialObject(properties, businessUnit);
|
|
196
214
|
if (buObject !== null) {
|
|
197
215
|
const builder = new Builder(properties, buObject);
|
|
198
|
-
|
|
199
|
-
return builder._buildDefinition(selectedType, nameArr, properties.markets[market]);
|
|
200
|
-
}
|
|
216
|
+
return builder._buildDefinition(selectedType, nameArr, templateVariables);
|
|
201
217
|
}
|
|
202
218
|
}
|
|
203
219
|
|
|
@@ -233,25 +249,28 @@ saved
|
|
|
233
249
|
continue;
|
|
234
250
|
}
|
|
235
251
|
i++;
|
|
252
|
+
/** @type {string | string[] | string[][]} */
|
|
236
253
|
const market = properties.marketList[listName][businessUnit];
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
marketList.push(market);
|
|
240
|
-
} else {
|
|
241
|
-
marketList = market;
|
|
242
|
-
}
|
|
254
|
+
const marketList = 'string' === typeof market ? [market] : market;
|
|
255
|
+
|
|
243
256
|
for (const market of marketList) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
type,
|
|
251
|
-
nameArr,
|
|
252
|
-
market
|
|
253
|
-
);
|
|
257
|
+
// one can now send multiple markets to buildTemplate/buildDefinition and hence that also needs to work for marketLists
|
|
258
|
+
const marketArr = 'string' === typeof market ? [market] : market;
|
|
259
|
+
for (const market of marketArr) {
|
|
260
|
+
if (!Util.checkMarket(market, properties)) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
254
263
|
}
|
|
264
|
+
|
|
265
|
+
Util.logger.info(`Executing for '${businessUnit}': '${marketArr.join('-')}'`);
|
|
266
|
+
// omitting "await" to speed up creation
|
|
267
|
+
responseObj[businessUnit] ||= {};
|
|
268
|
+
responseObj[businessUnit][marketArr.join('-')] = await this.buildDefinition(
|
|
269
|
+
businessUnit,
|
|
270
|
+
type,
|
|
271
|
+
nameArr,
|
|
272
|
+
marketArr
|
|
273
|
+
);
|
|
255
274
|
}
|
|
256
275
|
}
|
|
257
276
|
|
package/lib/cli.js
CHANGED
|
@@ -363,6 +363,7 @@ yargs(hideBin(process.argv))
|
|
|
363
363
|
})
|
|
364
364
|
.option('marketFrom', {
|
|
365
365
|
type: 'string',
|
|
366
|
+
array: true,
|
|
366
367
|
alias: 'mf',
|
|
367
368
|
group: 'Required parameters for build:',
|
|
368
369
|
describe: 'market used for reverse building template',
|
|
@@ -370,6 +371,7 @@ yargs(hideBin(process.argv))
|
|
|
370
371
|
})
|
|
371
372
|
.option('marketTo', {
|
|
372
373
|
type: 'string',
|
|
374
|
+
array: true,
|
|
373
375
|
alias: 'mt',
|
|
374
376
|
group: 'Required parameters for build:',
|
|
375
377
|
describe: 'market used for building deployable definition',
|
|
@@ -440,6 +442,7 @@ yargs(hideBin(process.argv))
|
|
|
440
442
|
})
|
|
441
443
|
.option('market', {
|
|
442
444
|
type: 'string',
|
|
445
|
+
array: true,
|
|
443
446
|
group: 'Options for buildTemplate:',
|
|
444
447
|
describe: 'market used for reverse building template',
|
|
445
448
|
})
|
|
@@ -472,10 +475,15 @@ yargs(hideBin(process.argv))
|
|
|
472
475
|
argv.BU,
|
|
473
476
|
argv.TYPE,
|
|
474
477
|
csvToArray(argv.KEY),
|
|
475
|
-
argv.MARKET
|
|
478
|
+
argv.MARKET ? [argv.MARKET] : argv.market
|
|
476
479
|
);
|
|
477
480
|
} else {
|
|
478
|
-
Mcdev.buildTemplate(
|
|
481
|
+
Mcdev.buildTemplate(
|
|
482
|
+
argv.BU,
|
|
483
|
+
typeKeyCombo,
|
|
484
|
+
null,
|
|
485
|
+
argv.MARKET ? [argv.MARKET] : argv.market
|
|
486
|
+
);
|
|
479
487
|
}
|
|
480
488
|
}
|
|
481
489
|
)
|
|
@@ -509,6 +517,7 @@ yargs(hideBin(process.argv))
|
|
|
509
517
|
})
|
|
510
518
|
.option('market', {
|
|
511
519
|
type: 'string',
|
|
520
|
+
array: true,
|
|
512
521
|
group: 'Options for buildDefinition:',
|
|
513
522
|
describe: 'market used for building deployable definition',
|
|
514
523
|
})
|
|
@@ -528,10 +537,15 @@ yargs(hideBin(process.argv))
|
|
|
528
537
|
argv.BU,
|
|
529
538
|
argv.TYPE,
|
|
530
539
|
csvToArray(argv.FILENAME),
|
|
531
|
-
argv.MARKET
|
|
540
|
+
argv.MARKET ? [argv.MARKET] : argv.market
|
|
532
541
|
);
|
|
533
542
|
} else {
|
|
534
|
-
Mcdev.buildDefinition(
|
|
543
|
+
Mcdev.buildDefinition(
|
|
544
|
+
argv.BU,
|
|
545
|
+
typeKeyCombo,
|
|
546
|
+
null,
|
|
547
|
+
argv.MARKET ? [argv.MARKET] : argv.market
|
|
548
|
+
);
|
|
535
549
|
}
|
|
536
550
|
}
|
|
537
551
|
)
|
|
@@ -813,7 +827,7 @@ yargs(hideBin(process.argv))
|
|
|
813
827
|
}
|
|
814
828
|
)
|
|
815
829
|
.command(
|
|
816
|
-
['pause <BU> [TYPE] [KEY]', 'p'
|
|
830
|
+
['pause <BU> [TYPE] [KEY]', 'p'],
|
|
817
831
|
'pauses the entity (automation etc.)',
|
|
818
832
|
(yargs) =>
|
|
819
833
|
yargs
|
|
@@ -860,6 +874,54 @@ yargs(hideBin(process.argv))
|
|
|
860
874
|
}
|
|
861
875
|
}
|
|
862
876
|
)
|
|
877
|
+
.command(
|
|
878
|
+
['stop <BU> [TYPE] [KEY]'],
|
|
879
|
+
'stops the entity (journey etc.)',
|
|
880
|
+
(yargs) =>
|
|
881
|
+
yargs
|
|
882
|
+
.positional('BU', {
|
|
883
|
+
type: 'string',
|
|
884
|
+
describe: 'the business unit where to start an item',
|
|
885
|
+
})
|
|
886
|
+
.positional('TYPE', {
|
|
887
|
+
type: 'string',
|
|
888
|
+
describe: 'metadata type',
|
|
889
|
+
})
|
|
890
|
+
.positional('KEY', {
|
|
891
|
+
type: 'string',
|
|
892
|
+
describe: 'key(s) of the metadata component(s)',
|
|
893
|
+
})
|
|
894
|
+
.option('metadata', {
|
|
895
|
+
type: 'string',
|
|
896
|
+
array: true,
|
|
897
|
+
alias: 'm',
|
|
898
|
+
group: 'Options for pause:',
|
|
899
|
+
describe: 'type or type:key or type:i:id or type:n:name to fix',
|
|
900
|
+
})
|
|
901
|
+
.option('like', {
|
|
902
|
+
type: 'string',
|
|
903
|
+
group: 'Options for pause:',
|
|
904
|
+
describe:
|
|
905
|
+
'filter metadata components (can include % as wildcard or _ for a single character)',
|
|
906
|
+
})
|
|
907
|
+
.check((argv) => {
|
|
908
|
+
if (!argv.TYPE && !argv.metadata) {
|
|
909
|
+
throw new Error(
|
|
910
|
+
'Error: Either specify the metadata type after the BU or use --metadata'
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
return true;
|
|
914
|
+
}),
|
|
915
|
+
(argv) => {
|
|
916
|
+
Mcdev.setOptions(argv);
|
|
917
|
+
const typeKeyCombo = Mcdev.metadataToTypeKey(argv.metadata);
|
|
918
|
+
if ('undefined' === typeof typeKeyCombo) {
|
|
919
|
+
Mcdev.stop(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY));
|
|
920
|
+
} else {
|
|
921
|
+
Mcdev.stop(argv.BU, typeKeyCombo);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
)
|
|
863
925
|
.command(
|
|
864
926
|
['fixKeys <BU> [TYPE] [KEY]', 'fx'],
|
|
865
927
|
'changes the key of the items to match the name',
|
package/lib/index.js
CHANGED
|
@@ -16,6 +16,8 @@ import MetadataTypeDefinitions from './MetadataTypeDefinitions.js';
|
|
|
16
16
|
import Retriever from './Retriever.js';
|
|
17
17
|
import cache from './util/cache.js';
|
|
18
18
|
import ReplaceContentBlockReference from './util/replaceContentBlockReference.js';
|
|
19
|
+
import pLimit from 'p-limit';
|
|
20
|
+
import path from 'node:path';
|
|
19
21
|
|
|
20
22
|
import { confirm } from '@inquirer/prompts';
|
|
21
23
|
|
|
@@ -597,10 +599,10 @@ class Mcdev {
|
|
|
597
599
|
*
|
|
598
600
|
* @param {string} businessUnit references credentials from properties.json
|
|
599
601
|
* @param {string | TypeKeyCombo} selectedTypes supported metadata type (single) or complex object
|
|
600
|
-
* @param {string[] | string} [
|
|
602
|
+
* @param {string[] | string} [keys] Identifier of metadata
|
|
601
603
|
* @returns {Promise.<boolean>} true if successful, false otherwise
|
|
602
604
|
*/
|
|
603
|
-
static async deleteByKey(businessUnit, selectedTypes,
|
|
605
|
+
static async deleteByKey(businessUnit, selectedTypes, keys) {
|
|
604
606
|
Util.startLogger();
|
|
605
607
|
Util.logger.info('mcdev:: delete');
|
|
606
608
|
|
|
@@ -609,9 +611,8 @@ class Mcdev {
|
|
|
609
611
|
|
|
610
612
|
/** @typedef {TypeKeyCombo} */
|
|
611
613
|
let selectedTypesObj;
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
614
|
+
let keyArr;
|
|
615
|
+
keyArr = 'string' === typeof keys ? [keys] : keys;
|
|
615
616
|
if ('string' === typeof selectedTypes) {
|
|
616
617
|
selectedTypesArr = [selectedTypes];
|
|
617
618
|
} else {
|
|
@@ -647,22 +648,31 @@ class Mcdev {
|
|
|
647
648
|
Util.logger.error(`No keys set for ${type}`);
|
|
648
649
|
return;
|
|
649
650
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
651
|
+
MetadataTypeInfo[type].client = client;
|
|
652
|
+
MetadataTypeInfo[type].properties = properties;
|
|
653
|
+
MetadataTypeInfo[type].buObject = buObject;
|
|
654
|
+
const deleteLimit = pLimit(20);
|
|
655
|
+
|
|
656
|
+
await Promise.allSettled(
|
|
657
|
+
keyArr.map((key) =>
|
|
658
|
+
deleteLimit(async () => {
|
|
659
|
+
// Util.logger.info(
|
|
660
|
+
// Util.getGrayMsg(` - Deleting ${type} ${key} on BU ${businessUnit}`)
|
|
661
|
+
// );
|
|
662
|
+
try {
|
|
663
|
+
const result = await MetadataTypeInfo[type].deleteByKey(key);
|
|
664
|
+
status &&= result;
|
|
665
|
+
} catch (ex) {
|
|
666
|
+
Util.logger.errorStack(
|
|
667
|
+
ex,
|
|
668
|
+
` - Deleting ${type} ${key} on BU ${businessUnit} failed`
|
|
669
|
+
);
|
|
670
|
+
status = false;
|
|
671
|
+
}
|
|
672
|
+
return status;
|
|
673
|
+
})
|
|
674
|
+
)
|
|
675
|
+
);
|
|
666
676
|
}
|
|
667
677
|
|
|
668
678
|
return status;
|
|
@@ -1086,8 +1096,8 @@ class Mcdev {
|
|
|
1086
1096
|
* @param {string} businessUnitTemplate references credentials from properties.json
|
|
1087
1097
|
* @param {string} businessUnitDefinition references credentials from properties.json
|
|
1088
1098
|
* @param {TypeKeyCombo} typeKeyCombo limit retrieval to given metadata type
|
|
1089
|
-
* @param {string} marketTemplate market localizations
|
|
1090
|
-
* @param {string} marketDefinition market localizations
|
|
1099
|
+
* @param {string[]} marketTemplate market localizations
|
|
1100
|
+
* @param {string[]} marketDefinition market localizations
|
|
1091
1101
|
* @param {boolean} [bulk] runs buildDefinitionBulk instead of buildDefinition; requires marketList to be defined and given via marketDefinition
|
|
1092
1102
|
* @returns {Promise.<MultiMetadataTypeList | object>} response from buildDefinition
|
|
1093
1103
|
*/
|
|
@@ -1105,10 +1115,7 @@ class Mcdev {
|
|
|
1105
1115
|
);
|
|
1106
1116
|
return;
|
|
1107
1117
|
}
|
|
1108
|
-
|
|
1109
|
-
if (!Util.checkMarket(marketTemplate, properties)) {
|
|
1110
|
-
return;
|
|
1111
|
-
}
|
|
1118
|
+
|
|
1112
1119
|
// check if types are valid
|
|
1113
1120
|
for (const type of Object.keys(typeKeyCombo)) {
|
|
1114
1121
|
if (!Util._isValidType(type)) {
|
|
@@ -1123,7 +1130,7 @@ class Mcdev {
|
|
|
1123
1130
|
Util.logger.info('mcdev:: Build Template & Build Definition');
|
|
1124
1131
|
await this.buildTemplate(businessUnitTemplate, typeKeyCombo, null, marketTemplate);
|
|
1125
1132
|
return bulk
|
|
1126
|
-
? this.buildDefinitionBulk(marketDefinition, typeKeyCombo, null)
|
|
1133
|
+
? this.buildDefinitionBulk(marketDefinition[0], typeKeyCombo, null)
|
|
1127
1134
|
: this.buildDefinition(businessUnitDefinition, typeKeyCombo, null, marketDefinition);
|
|
1128
1135
|
}
|
|
1129
1136
|
|
|
@@ -1133,17 +1140,20 @@ class Mcdev {
|
|
|
1133
1140
|
* @param {string} businessUnit references credentials from properties.json
|
|
1134
1141
|
* @param {string | TypeKeyCombo} selectedTypes limit retrieval to given metadata type
|
|
1135
1142
|
* @param {string[] | undefined} keyArr customerkey of the metadata
|
|
1136
|
-
* @param {string}
|
|
1143
|
+
* @param {string[]} marketArr market localizations
|
|
1137
1144
|
* @returns {Promise.<MultiMetadataTypeList>} -
|
|
1138
1145
|
*/
|
|
1139
|
-
static async buildTemplate(businessUnit, selectedTypes, keyArr,
|
|
1146
|
+
static async buildTemplate(businessUnit, selectedTypes, keyArr, marketArr) {
|
|
1140
1147
|
this.#welcomeMessage();
|
|
1141
1148
|
|
|
1142
1149
|
Util.startLogger();
|
|
1143
1150
|
Util.logger.info('mcdev:: Build Template from retrieved files');
|
|
1144
1151
|
const properties = await config.getProperties();
|
|
1145
|
-
|
|
1146
|
-
|
|
1152
|
+
const buObject = await Cli.getCredentialObject(properties, businessUnit);
|
|
1153
|
+
for (const market of marketArr) {
|
|
1154
|
+
if (!Util.checkMarket(market, properties)) {
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1147
1157
|
}
|
|
1148
1158
|
if ('string' === typeof selectedTypes) {
|
|
1149
1159
|
// ensure we have TypeKeyCombo here
|
|
@@ -1163,6 +1173,52 @@ class Mcdev {
|
|
|
1163
1173
|
if (!Util.OPTIONS.dependencies) {
|
|
1164
1174
|
await this._reRetrieve(businessUnit, false, selectedTypes);
|
|
1165
1175
|
}
|
|
1176
|
+
// convert names to keys
|
|
1177
|
+
const retrieveDir = File.normalizePath([
|
|
1178
|
+
properties.directories.retrieve,
|
|
1179
|
+
buObject.credential,
|
|
1180
|
+
buObject.businessUnit,
|
|
1181
|
+
]);
|
|
1182
|
+
for (const type of Object.keys(selectedTypes)) {
|
|
1183
|
+
const keyArr = selectedTypes[type];
|
|
1184
|
+
if (keyArr.some((key) => key.startsWith('name:'))) {
|
|
1185
|
+
// at least one key was provided as a name -> load all files from disk to try and find that key
|
|
1186
|
+
const builTemplateCache = Object.values(
|
|
1187
|
+
await MetadataTypeInfo[type].getJsonFromFS(retrieveDir + path.sep + type)
|
|
1188
|
+
);
|
|
1189
|
+
selectedTypes[type] = keyArr
|
|
1190
|
+
.map((key) => {
|
|
1191
|
+
if (key.startsWith('name:')) {
|
|
1192
|
+
// key was defined by name. try and find matching item on disk
|
|
1193
|
+
const name = key.slice(5);
|
|
1194
|
+
const foundKeysByName = builTemplateCache
|
|
1195
|
+
.filter(
|
|
1196
|
+
(item) =>
|
|
1197
|
+
name == item[MetadataTypeInfo[type].definition.nameField]
|
|
1198
|
+
)
|
|
1199
|
+
.map((item) => item[MetadataTypeInfo[type].definition.keyField]);
|
|
1200
|
+
if (foundKeysByName.length === 1) {
|
|
1201
|
+
key = foundKeysByName[0];
|
|
1202
|
+
Util.logger.debug(
|
|
1203
|
+
`- found ${type} key '${key}' for name '${name}'`
|
|
1204
|
+
);
|
|
1205
|
+
return key;
|
|
1206
|
+
} else if (foundKeysByName.length > 1) {
|
|
1207
|
+
Util.logger.error(
|
|
1208
|
+
`Found multiple keys (${foundKeysByName.join(', ')}) for name: ${key}`
|
|
1209
|
+
);
|
|
1210
|
+
return;
|
|
1211
|
+
} else {
|
|
1212
|
+
Util.logger.error(`Could not find any keys for name: ${name}`);
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
} else {
|
|
1216
|
+
return key;
|
|
1217
|
+
}
|
|
1218
|
+
})
|
|
1219
|
+
.filter(Boolean);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1166
1222
|
|
|
1167
1223
|
// if dependencies are enabled, we need to search for them and add them to our
|
|
1168
1224
|
await this.addDependencies(businessUnit, selectedTypes);
|
|
@@ -1175,19 +1231,11 @@ class Mcdev {
|
|
|
1175
1231
|
businessUnit,
|
|
1176
1232
|
type,
|
|
1177
1233
|
selectedTypes[type],
|
|
1178
|
-
|
|
1234
|
+
marketArr
|
|
1179
1235
|
);
|
|
1180
1236
|
returnObj[type] = result[type];
|
|
1181
1237
|
}
|
|
1182
1238
|
Util.logger.info(`Templated ${Util.getTypeKeyCount(returnObj)} items`);
|
|
1183
|
-
if (Util.OPTIONS.dependencies) {
|
|
1184
|
-
Util.logger.info(
|
|
1185
|
-
`You can now run buildDefinition to create the deployment package. Don't forget to adjust the BU and market!`
|
|
1186
|
-
);
|
|
1187
|
-
Util.logger.info(
|
|
1188
|
-
` mcdev bd ${businessUnit} ${Util.convertTypeKeyToCli(selectedTypes)} --market ${market}`
|
|
1189
|
-
);
|
|
1190
|
-
}
|
|
1191
1239
|
return returnObj;
|
|
1192
1240
|
}
|
|
1193
1241
|
|
|
@@ -1223,17 +1271,19 @@ class Mcdev {
|
|
|
1223
1271
|
* @param {string} businessUnit references credentials from properties.json
|
|
1224
1272
|
* @param {string | TypeKeyCombo} selectedTypes limit retrieval to given metadata type
|
|
1225
1273
|
* @param {string[] | undefined} nameArr name of the metadata
|
|
1226
|
-
* @param {string}
|
|
1274
|
+
* @param {string[]} marketArr market localizations
|
|
1227
1275
|
* @returns {Promise.<MultiMetadataTypeList>} -
|
|
1228
1276
|
*/
|
|
1229
|
-
static async buildDefinition(businessUnit, selectedTypes, nameArr,
|
|
1277
|
+
static async buildDefinition(businessUnit, selectedTypes, nameArr, marketArr) {
|
|
1230
1278
|
this.#welcomeMessage();
|
|
1231
1279
|
|
|
1232
1280
|
Util.startLogger();
|
|
1233
1281
|
Util.logger.info('mcdev:: Build Definition from Template');
|
|
1234
1282
|
const properties = await config.getProperties();
|
|
1235
|
-
|
|
1236
|
-
|
|
1283
|
+
for (const market of marketArr) {
|
|
1284
|
+
if (!Util.checkMarket(market, properties)) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1237
1287
|
}
|
|
1238
1288
|
if ('string' === typeof selectedTypes) {
|
|
1239
1289
|
// ensure we have TypeKeyCombo here
|
|
@@ -1257,7 +1307,7 @@ class Mcdev {
|
|
|
1257
1307
|
businessUnit,
|
|
1258
1308
|
type,
|
|
1259
1309
|
selectedTypes[type],
|
|
1260
|
-
|
|
1310
|
+
marketArr
|
|
1261
1311
|
);
|
|
1262
1312
|
returnObj[type] = result[type];
|
|
1263
1313
|
}
|
|
@@ -1389,6 +1439,18 @@ class Mcdev {
|
|
|
1389
1439
|
return this.#runMethod('pause', businessUnit, selectedTypes, keys);
|
|
1390
1440
|
}
|
|
1391
1441
|
|
|
1442
|
+
/**
|
|
1443
|
+
* stop an item
|
|
1444
|
+
*
|
|
1445
|
+
* @param {string} businessUnit name of BU
|
|
1446
|
+
* @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
|
|
1447
|
+
* @param {string[]} [keys] customerkey of the metadata
|
|
1448
|
+
* @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
|
|
1449
|
+
*/
|
|
1450
|
+
static async stop(businessUnit, selectedTypes, keys) {
|
|
1451
|
+
return this.#runMethod('stop', businessUnit, selectedTypes, keys);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1392
1454
|
/**
|
|
1393
1455
|
* Updates the key to match the name field
|
|
1394
1456
|
*
|
|
@@ -1564,7 +1626,7 @@ class Mcdev {
|
|
|
1564
1626
|
/**
|
|
1565
1627
|
* run a method across BUs
|
|
1566
1628
|
*
|
|
1567
|
-
* @param {'execute'|'pause'|'publish'|'fixKeys'|'replaceCbReference'} methodName what to run
|
|
1629
|
+
* @param {'execute'|'pause'|'stop'|'publish'|'fixKeys'|'replaceCbReference'} methodName what to run
|
|
1568
1630
|
* @param {string} businessUnit name of BU
|
|
1569
1631
|
* @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
|
|
1570
1632
|
* @param {string[]} [keys] customerkey of the metadata
|
|
@@ -1594,6 +1656,13 @@ class Mcdev {
|
|
|
1594
1656
|
checkMetadataSupport = true;
|
|
1595
1657
|
break;
|
|
1596
1658
|
}
|
|
1659
|
+
case 'stop': {
|
|
1660
|
+
lang_past = 'stopped';
|
|
1661
|
+
lang_present = 'stopping';
|
|
1662
|
+
requireKeyOrLike = true;
|
|
1663
|
+
checkMetadataSupport = true;
|
|
1664
|
+
break;
|
|
1665
|
+
}
|
|
1597
1666
|
case 'publish': {
|
|
1598
1667
|
lang_past = 'published';
|
|
1599
1668
|
lang_present = 'publishing';
|
|
@@ -1768,7 +1837,7 @@ class Mcdev {
|
|
|
1768
1837
|
/**
|
|
1769
1838
|
* helper for Mcdev.#runMethod
|
|
1770
1839
|
*
|
|
1771
|
-
* @param {'execute'|'pause'|'publish'|'fixKeys'|'replaceCbReference'} methodName what to run
|
|
1840
|
+
* @param {'execute'|'pause'|'stop'|'publish'|'fixKeys'|'replaceCbReference'} methodName what to run
|
|
1772
1841
|
* @param {string} cred name of Credential
|
|
1773
1842
|
* @param {string} bu name of BU
|
|
1774
1843
|
* @param {string} [type] limit execution to given metadata type
|
|
@@ -2089,7 +2089,7 @@ class Asset extends MetadataType {
|
|
|
2089
2089
|
id = key ? await this._getIdForSingleRetrieve(key) : null;
|
|
2090
2090
|
}
|
|
2091
2091
|
if (!id) {
|
|
2092
|
-
Util.logger.error(` - ${this.definition.type} not found`);
|
|
2092
|
+
Util.logger.error(` - ${this.definition.type} ${key} not found`);
|
|
2093
2093
|
return false;
|
|
2094
2094
|
}
|
|
2095
2095
|
return super.deleteByKeyREST('/asset/v1/content/assets/' + id, key);
|
|
@@ -1612,17 +1612,17 @@ class Automation extends MetadataType {
|
|
|
1612
1612
|
/**
|
|
1613
1613
|
* Delete a metadata item from the specified business unit
|
|
1614
1614
|
*
|
|
1615
|
-
* @param {string}
|
|
1615
|
+
* @param {string} key Identifier of data extension
|
|
1616
1616
|
* @returns {Promise.<boolean>} deletion success status
|
|
1617
1617
|
*/
|
|
1618
|
-
static async deleteByKey(
|
|
1618
|
+
static async deleteByKey(key) {
|
|
1619
1619
|
// the delete endpoint returns a general exception if the automation does not exist; handle it gracefully instead by adding a retrieve first
|
|
1620
|
-
const objectId =
|
|
1620
|
+
const objectId = key ? await this.#getObjectIdForSingleRetrieve(key) : null;
|
|
1621
1621
|
if (!objectId) {
|
|
1622
|
-
Util.logger.error(` - automation not found`);
|
|
1622
|
+
Util.logger.error(` - automation ${key} not found`);
|
|
1623
1623
|
return false;
|
|
1624
1624
|
}
|
|
1625
|
-
return super.deleteByKeySOAP(
|
|
1625
|
+
return super.deleteByKeySOAP(key, 'CustomerKey');
|
|
1626
1626
|
}
|
|
1627
1627
|
|
|
1628
1628
|
/**
|
|
@@ -190,7 +190,7 @@ class DataExtract extends MetadataType {
|
|
|
190
190
|
// delete only works with the query's object id
|
|
191
191
|
const objectId = customerKey ? await this._getObjectIdForSingleRetrieve(customerKey) : null;
|
|
192
192
|
if (!objectId) {
|
|
193
|
-
Util.logger.error(` - dataExtract not found`);
|
|
193
|
+
Util.logger.error(` - dataExtract ${customerKey} not found`);
|
|
194
194
|
return false;
|
|
195
195
|
}
|
|
196
196
|
return super.deleteByKeyREST('/automation/v1/dataextracts/' + objectId, customerKey);
|