mcdev 5.0.1 → 5.1.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.
Files changed (138) hide show
  1. package/.coverage-comment-template.svelte +177 -161
  2. package/.eslintrc.json +1 -0
  3. package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
  4. package/.github/dependabot.yml +8 -0
  5. package/.github/workflows/coverage-base-update.yml +6 -2
  6. package/.github/workflows/coverage-develop-branch.yml +7 -6
  7. package/.github/workflows/coverage-main-branch.yml +7 -6
  8. package/.github/workflows/coverage.yml +7 -2
  9. package/.husky/commit-msg +1 -1
  10. package/.husky/post-checkout +35 -3
  11. package/.husky/post-merge +21 -0
  12. package/.husky/pre-commit +1 -0
  13. package/docs/dist/documentation.md +222 -62
  14. package/lib/Deployer.js +3 -4
  15. package/lib/cli.js +36 -8
  16. package/lib/index.js +175 -3
  17. package/lib/metadataTypes/Asset.js +4 -2
  18. package/lib/metadataTypes/Automation.js +413 -195
  19. package/lib/metadataTypes/DataExtension.js +6 -8
  20. package/lib/metadataTypes/DataExtensionField.js +5 -5
  21. package/lib/metadataTypes/Journey.js +11 -10
  22. package/lib/metadataTypes/MetadataType.js +76 -22
  23. package/lib/metadataTypes/MobileKeyword.js +165 -20
  24. package/lib/metadataTypes/MobileMessage.js +20 -28
  25. package/lib/metadataTypes/Query.js +26 -0
  26. package/lib/metadataTypes/Role.js +2 -3
  27. package/lib/metadataTypes/TransactionalSMS.js +5 -5
  28. package/lib/metadataTypes/User.js +3 -17
  29. package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
  30. package/lib/metadataTypes/definitions/Automation.definition.js +52 -6
  31. package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -0
  32. package/lib/metadataTypes/definitions/DataExtract.definition.js +1 -0
  33. package/lib/metadataTypes/definitions/EmailSend.definition.js +1 -0
  34. package/lib/metadataTypes/definitions/Event.definition.js +1 -0
  35. package/lib/metadataTypes/definitions/Filter.definition.js +1 -0
  36. package/lib/metadataTypes/definitions/ImportFile.definition.js +1 -0
  37. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +20 -7
  38. package/lib/metadataTypes/definitions/MobileMessage.definition.js +50 -8
  39. package/lib/metadataTypes/definitions/Query.definition.js +1 -0
  40. package/lib/metadataTypes/definitions/Role.definition.js +1 -0
  41. package/lib/metadataTypes/definitions/TriggeredSend.definition.js +1 -0
  42. package/lib/metadataTypes/definitions/User.definition.js +2 -0
  43. package/lib/util/auth.js +4 -1
  44. package/lib/util/cli.js +1 -1
  45. package/lib/util/devops.js +13 -11
  46. package/lib/util/file.js +5 -3
  47. package/lib/util/util.js +153 -129
  48. package/package.json +11 -11
  49. package/test/general.test.js +26 -0
  50. package/test/mockRoot/.mcdevrc.json +3 -1
  51. package/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +53 -0
  52. package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +46 -0
  53. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword.mobileKeyword-meta.json → 4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.json} +1 -4
  54. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword_blocked.mobileKeyword-meta.json → 4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.json} +1 -4
  55. package/test/mockRoot/deploy/testInstance/testBU/query/{testExistingQuery.query-meta.json → testExisting_query.query-meta.json} +2 -2
  56. package/test/mockRoot/deploy/testInstance/testBU/query/{testNewQuery.query-meta.json → testNew_query.query-meta.json} +2 -2
  57. package/test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testExisting_tsms.transactionalSMS-meta.json +1 -1
  58. package/test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testNew_tsms.transactionalSMS-meta.json +1 -1
  59. package/test/resourceFactory.js +64 -21
  60. package/test/resources/1111111/user/retrieve-expected.md +19 -0
  61. package/test/resources/9999999/automation/build-expected.json +58 -0
  62. package/test/resources/9999999/automation/create-expected.json +46 -0
  63. package/test/resources/9999999/automation/create-testNew_automation-expected.md +28 -0
  64. package/test/resources/9999999/automation/delete-response.xml +40 -0
  65. package/test/resources/9999999/automation/retrieve-expected.json +58 -0
  66. package/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +30 -0
  67. package/test/resources/9999999/automation/template-expected.json +58 -0
  68. package/test/resources/9999999/automation/update-expected.json +46 -0
  69. package/test/resources/9999999/automation/update-testExisting_automation-expected.md +28 -0
  70. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +85 -0
  71. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/patch-response.json +85 -0
  72. package/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +85 -0
  73. package/test/resources/9999999/automation/v1/automations/post-response.json +85 -0
  74. package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/get-response.json +38 -0
  75. package/test/resources/9999999/automation/v1/dataextracts/get-response.json +20 -0
  76. package/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/get-response.json +18 -0
  77. package/test/resources/9999999/automation/v1/filetransfers/get-response.json +15 -0
  78. package/test/resources/9999999/automation/v1/imports/get-response.json +38 -0
  79. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/actions/start/post-response.txt +1 -0
  80. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +2 -2
  81. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +2 -2
  82. package/test/resources/9999999/automation/v1/queries/get-response.json +4 -4
  83. package/test/resources/9999999/automation/v1/queries/post-response.json +2 -2
  84. package/test/resources/9999999/automation/v1/scripts/get-response.json +17 -0
  85. package/test/resources/9999999/dataExtension/retrieve-expected.md +18 -0
  86. package/test/resources/9999999/dataFolder/retrieve-ContentType=automations-response.xml +48 -0
  87. package/test/resources/9999999/dataFolder/retrieve-ContentType=queryactivity-response.xml +48 -0
  88. package/test/resources/9999999/dataFolder/retrieve-response.xml +22 -0
  89. package/test/resources/9999999/emailSendDefinition/retrieve-response.xml +85 -0
  90. package/test/resources/9999999/journey/build-expected.json +1 -1
  91. package/test/resources/9999999/journey/get-expected.json +1 -1
  92. package/test/resources/9999999/journey/put-expected.json +1 -1
  93. package/test/resources/9999999/journey/template-expected.json +1 -1
  94. package/test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/get-response.json +21 -0
  95. package/test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/post-response.json +0 -0
  96. package/test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json +30 -0
  97. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow/get-response.json +1 -1
  98. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/get-response.json +1 -1
  99. package/test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/get-response.json +1 -1
  100. package/test/resources/9999999/legacy/v1/beta/mobile/message/get-response.json +1 -1
  101. package/test/resources/9999999/messaging/v1/sms/definitions/post-response.json +1 -1
  102. package/test/resources/9999999/messaging/v1/sms/definitions/testExisting_tsms/get-response.json +1 -1
  103. package/test/resources/9999999/messaging/v1/sms/definitions/testExisting_tsms/patch-response.json +1 -1
  104. package/test/resources/9999999/mobileKeyword/build-expected.json +1 -4
  105. package/test/resources/9999999/mobileKeyword/get-expected.json +1 -4
  106. package/test/resources/9999999/mobileKeyword/post-create-expected.json +1 -4
  107. package/test/resources/9999999/mobileKeyword/template-expected.json +1 -4
  108. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation-response.xml +30 -0
  109. package/test/resources/9999999/program/retrieve-CustomerKey=testNew_automation-response.xml +30 -0
  110. package/test/resources/9999999/program/retrieve-Name=testExisting_automation-response.xml +31 -0
  111. package/test/resources/9999999/program/retrieve-response.xml +32 -0
  112. package/test/resources/9999999/query/build-expected.json +2 -2
  113. package/test/resources/9999999/query/build-expected.sql +1 -1
  114. package/test/resources/9999999/query/get-expected.json +2 -2
  115. package/test/resources/9999999/query/get-expected.sql +1 -1
  116. package/test/resources/9999999/query/get2-expected.json +2 -2
  117. package/test/resources/9999999/query/patch-expected.json +2 -2
  118. package/test/resources/9999999/query/patch-expected.sql +1 -1
  119. package/test/resources/9999999/query/post-expected.json +2 -2
  120. package/test/resources/9999999/query/post-expected.sql +1 -1
  121. package/test/resources/9999999/query/template-expected.json +2 -2
  122. package/test/resources/9999999/query/template-expected.sql +1 -1
  123. package/test/resources/9999999/transactionalSMS/build-expected.json +1 -1
  124. package/test/resources/9999999/transactionalSMS/get-expected.json +1 -1
  125. package/test/resources/9999999/transactionalSMS/patch-expected.json +1 -1
  126. package/test/resources/9999999/transactionalSMS/post-expected.json +1 -1
  127. package/test/resources/9999999/transactionalSMS/template-expected.json +1 -1
  128. package/test/type.automation.test.js +259 -0
  129. package/test/type.dataExtension.test.js +16 -1
  130. package/test/type.mobileKeyword.test.js +57 -19
  131. package/test/type.query.test.js +39 -26
  132. package/test/type.user.test.js +44 -1
  133. package/test/utils.js +16 -5
  134. package/.coverage-comment-template.md +0 -20
  135. /package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword.mobileKeyword-meta.amp → 4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.amp} +0 -0
  136. /package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword_blocked.mobileKeyword-meta.amp → 4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.amp} +0 -0
  137. /package/test/mockRoot/deploy/testInstance/testBU/query/{testExistingQuery.query-meta.sql → testExisting_query.query-meta.sql} +0 -0
  138. /package/test/mockRoot/deploy/testInstance/testBU/query/{testNewQuery.query-meta.sql → testNew_query.query-meta.sql} +0 -0
package/lib/cli.js CHANGED
@@ -240,7 +240,7 @@ yargs
240
240
  },
241
241
  })
242
242
  .command({
243
- command: 'buildDefinition <BU> <TYPE> <NAME> <MARKET>',
243
+ command: 'buildDefinition <BU> <TYPE> <FILENAME> <MARKET>',
244
244
  aliases: ['bd'],
245
245
  desc: 'builds metadata definition based on template',
246
246
  builder: (yargs) => {
@@ -253,9 +253,9 @@ yargs
253
253
  type: 'string',
254
254
  describe: 'metadata type',
255
255
  })
256
- .positional('NAME', {
256
+ .positional('FILENAME', {
257
257
  type: 'string',
258
- describe: 'name of the metadata component',
258
+ describe: 'File name of the metadata template without the extension',
259
259
  })
260
260
  .positional('MARKET', {
261
261
  type: 'string',
@@ -264,11 +264,11 @@ yargs
264
264
  },
265
265
  handler: (argv) => {
266
266
  Mcdev.setOptions(argv);
267
- Mcdev.buildDefinition(argv.BU, argv.TYPE, argv.NAME, argv.MARKET);
267
+ Mcdev.buildDefinition(argv.BU, argv.TYPE, argv.FILENAME, argv.MARKET);
268
268
  },
269
269
  })
270
270
  .command({
271
- command: 'buildDefinitionBulk <LISTNAME> <TYPE> <NAME>',
271
+ command: 'buildDefinitionBulk <LISTNAME> <TYPE> <FILENAME>',
272
272
  aliases: ['bdb'],
273
273
  desc: 'builds metadata definition based on template en bulk',
274
274
  builder: (yargs) => {
@@ -281,14 +281,14 @@ yargs
281
281
  type: 'string',
282
282
  describe: 'metadata type',
283
283
  })
284
- .positional('NAME', {
284
+ .positional('FILENAME', {
285
285
  type: 'string',
286
- describe: 'name of the metadata component',
286
+ describe: 'File name of the metadata template without the extension',
287
287
  });
288
288
  },
289
289
  handler: (argv) => {
290
290
  Mcdev.setOptions(argv);
291
- Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, argv.NAME);
291
+ Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, argv.FILENAME);
292
292
  },
293
293
  })
294
294
  .command({
@@ -389,6 +389,30 @@ yargs
389
389
  Mcdev.refresh(argv.BU, argv.TYPE, csvToArray(argv.KEY));
390
390
  },
391
391
  })
392
+ .command({
393
+ command: 'execute <BU> <TYPE> <KEY>',
394
+ aliases: ['exec'],
395
+ desc: 'executes the entity (query/journey/automation etc.)',
396
+ builder: (yargs) => {
397
+ yargs
398
+ .positional('BU', {
399
+ type: 'string',
400
+ describe: 'the business unit where to start an item',
401
+ })
402
+ .positional('TYPE', {
403
+ type: 'string',
404
+ describe: 'metadata type',
405
+ })
406
+ .positional('KEY', {
407
+ type: 'string',
408
+ describe: 'key(s) of the metadata component(s)',
409
+ });
410
+ },
411
+ handler: (argv) => {
412
+ Mcdev.setOptions(argv);
413
+ Mcdev.execute(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY));
414
+ },
415
+ })
392
416
  .command({
393
417
  command: 'upgrade',
394
418
  aliases: ['up'],
@@ -410,6 +434,10 @@ yargs
410
434
  type: 'boolean',
411
435
  description: 'Only output errors to CLI',
412
436
  })
437
+ .option('noLogFile', {
438
+ type: 'boolean',
439
+ description: 'Only output log to CLI but not to files',
440
+ })
413
441
  .option('skipInteraction', {
414
442
  alias: ['yes', 'y'],
415
443
  description: 'Interactive questions where possible and go with defaults instead',
package/lib/index.js CHANGED
@@ -59,6 +59,7 @@ class Mcdev {
59
59
  'json',
60
60
  'refresh',
61
61
  'skipInteraction',
62
+ 'noLogFile',
62
63
  ];
63
64
  for (const option of knownOptions) {
64
65
  if (argv[option] !== undefined) {
@@ -89,6 +90,7 @@ class Mcdev {
89
90
  * @returns {Promise.<TYPE.DeltaPkgItem[]>} list of changed items
90
91
  */
91
92
  static async createDeltaPkg(argv) {
93
+ Util.startLogger();
92
94
  Util.logger.info('Create Delta Package ::');
93
95
  const properties = await config.getProperties();
94
96
  if (!(await config.checkProperties(properties))) {
@@ -111,6 +113,7 @@ class Mcdev {
111
113
  * @returns {Promise} .
112
114
  */
113
115
  static async selectTypes() {
116
+ Util.startLogger();
114
117
  const properties = await config.getProperties();
115
118
  if (!(await config.checkProperties(properties))) {
116
119
  return null;
@@ -127,6 +130,7 @@ class Mcdev {
127
130
  * @returns {Promise.<boolean>} success flag
128
131
  */
129
132
  static async upgrade() {
133
+ Util.startLogger();
130
134
  const properties = await config.getProperties();
131
135
  if (!properties) {
132
136
  Util.logger.error('No config found. Please run mcdev init');
@@ -149,6 +153,7 @@ class Mcdev {
149
153
  * @returns {Promise.<object>} -
150
154
  */
151
155
  static async retrieve(businessUnit, selectedTypesArr, keys, changelogOnly) {
156
+ Util.startLogger();
152
157
  Util.logger.info('mcdev:: Retrieve');
153
158
  const properties = await config.getProperties();
154
159
  if (!(await config.checkProperties(properties))) {
@@ -176,7 +181,7 @@ class Mcdev {
176
181
  for (const bu in properties.credentials[cred].businessUnits) {
177
182
  await this._retrieveBU(cred, bu, selectedTypesArr, keys);
178
183
  counter_credBu++;
179
- Util.restartLogger();
184
+ Util.startLogger(true);
180
185
  }
181
186
  counter_credTotal += counter_credBu;
182
187
  Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`);
@@ -210,7 +215,7 @@ class Mcdev {
210
215
  for (const bu in properties.credentials[cred].businessUnits) {
211
216
  await this._retrieveBU(cred, bu, selectedTypesArr, keys);
212
217
  counter_credBu++;
213
- Util.restartLogger();
218
+ Util.startLogger(true);
214
219
  }
215
220
  Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`);
216
221
  } else {
@@ -256,11 +261,12 @@ class Mcdev {
256
261
  cred = buObject.credential;
257
262
  bu = buObject.businessUnit;
258
263
  // clean up old folders after types were renamed
259
- // TODO: Remove this with version 5.0.0
264
+ // TODO: Remove renamedTypes-logic 6 months after version 5 release
260
265
  const renamedTypes = {
261
266
  emailSend: 'emailSendDefinition',
262
267
  event: 'eventDefinition',
263
268
  fileLocation: 'ftpLocation',
269
+ journey: 'interaction',
264
270
  triggeredSend: 'triggeredSendDefinition',
265
271
  user: 'accountUser',
266
272
  };
@@ -350,6 +356,7 @@ class Mcdev {
350
356
  * @returns {Promise.<Object.<string,TYPE.MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type)
351
357
  */
352
358
  static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve = false) {
359
+ Util.startLogger();
353
360
  return Deployer.deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve);
354
361
  }
355
362
 
@@ -360,6 +367,7 @@ class Mcdev {
360
367
  * @returns {Promise.<void>} -
361
368
  */
362
369
  static async initProject(credentialsName) {
370
+ Util.startLogger();
363
371
  Util.logger.info('mcdev:: Setting up project');
364
372
  const properties = await config.getProperties(!!credentialsName, true);
365
373
  await Init.initProject(properties, credentialsName);
@@ -370,6 +378,7 @@ class Mcdev {
370
378
  * @returns {Promise.<void>} -
371
379
  */
372
380
  static async joinProject() {
381
+ Util.startLogger();
373
382
  Util.logger.info('mcdev:: Joining an existing project');
374
383
  await Init.joinProject();
375
384
  }
@@ -381,6 +390,7 @@ class Mcdev {
381
390
  * @returns {Promise.<void>} -
382
391
  */
383
392
  static async findBUs(credentialsName) {
393
+ Util.startLogger();
384
394
  Util.logger.info('mcdev:: Load BUs');
385
395
  const properties = await config.getProperties();
386
396
  if (!(await config.checkProperties(properties))) {
@@ -400,6 +410,7 @@ class Mcdev {
400
410
  * @returns {Promise.<void>} -
401
411
  */
402
412
  static async document(businessUnit, type) {
413
+ Util.startLogger();
403
414
  Util.logger.info('mcdev:: Document');
404
415
  const properties = await config.getProperties();
405
416
  if (!(await config.checkProperties(properties))) {
@@ -439,6 +450,7 @@ class Mcdev {
439
450
  * @returns {Promise.<boolean>} true if successful, false otherwise
440
451
  */
441
452
  static async deleteByKey(businessUnit, type, customerKey) {
453
+ Util.startLogger();
442
454
  Util.logger.info('mcdev:: delete');
443
455
  if (!Util._isValidType(type)) {
444
456
  return;
@@ -476,6 +488,7 @@ class Mcdev {
476
488
  * @returns {Promise.<void>} -
477
489
  */
478
490
  static async refresh(businessUnit, type, keyArr) {
491
+ Util.startLogger();
479
492
  Util.logger.info('mcdev:: refresh');
480
493
  if (!type || !Util._isValidType(type, true)) {
481
494
  type = 'triggeredSend';
@@ -511,6 +524,7 @@ class Mcdev {
511
524
  * @returns {Promise.<void>} -
512
525
  */
513
526
  static async badKeys(businessUnit) {
527
+ Util.startLogger();
514
528
  const properties = await config.getProperties();
515
529
  if (!(await config.checkProperties(properties))) {
516
530
  return null;
@@ -584,6 +598,7 @@ class Mcdev {
584
598
  * @returns {Promise.<TYPE.MultiMetadataTypeList>} -
585
599
  */
586
600
  static async retrieveAsTemplate(businessUnit, selectedType, name, market) {
601
+ Util.startLogger();
587
602
  Util.logger.info('mcdev:: Retrieve as Template');
588
603
  const properties = await config.getProperties();
589
604
  if (!(await config.checkProperties(properties))) {
@@ -625,6 +640,7 @@ class Mcdev {
625
640
  * @returns {Promise.<TYPE.MultiMetadataTypeList>} -
626
641
  */
627
642
  static async buildTemplate(businessUnit, selectedType, keyArr, market) {
643
+ Util.startLogger();
628
644
  Util.logger.info('mcdev:: Build Template from retrieved files');
629
645
  return Builder.buildTemplate(businessUnit, selectedType, keyArr, market);
630
646
  }
@@ -638,6 +654,7 @@ class Mcdev {
638
654
  * @returns {Promise.<void>} -
639
655
  */
640
656
  static async buildDefinition(businessUnit, selectedType, name, market) {
657
+ Util.startLogger();
641
658
  Util.logger.info('mcdev:: Build Definition from Template');
642
659
  return Builder.buildDefinition(businessUnit, selectedType, name, market);
643
660
  }
@@ -651,6 +668,7 @@ class Mcdev {
651
668
  * @returns {Promise.<void>} -
652
669
  */
653
670
  static async buildDefinitionBulk(listName, type, name) {
671
+ Util.startLogger();
654
672
  Util.logger.info('mcdev:: Build Definition from Template Bulk');
655
673
  return Builder.buildDefinitionBulk(listName, type, name);
656
674
  }
@@ -662,6 +680,7 @@ class Mcdev {
662
680
  * @returns {Promise.<string[]>} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext']
663
681
  */
664
682
  static async getFilesToCommit(businessUnit, selectedType, keyArr) {
683
+ Util.startLogger();
665
684
  Util.logger.info('mcdev:: getFilesToCommit');
666
685
  const properties = await config.getProperties();
667
686
  if (!(await config.checkProperties(properties))) {
@@ -681,6 +700,159 @@ class Mcdev {
681
700
  return DevOps.getFilesToCommit(properties, buObject, selectedType, keyArr);
682
701
  }
683
702
  }
703
+ /**
704
+ * Start an item (query)
705
+ *
706
+ * @param {string} businessUnit name of BU
707
+ * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit to given metadata types
708
+ * @param {string[]} keys customerkey of the metadata
709
+ * @returns {Promise.<boolean>} true if all started successfully, false if not
710
+ */
711
+ static async execute(businessUnit, selectedTypesArr, keys) {
712
+ Util.startLogger();
713
+ Util.logger.info('mcdev:: Execute');
714
+ const properties = await config.getProperties();
715
+ let counter_credBu = 0;
716
+ let counter_failed = 0;
717
+ if (!(await config.checkProperties(properties))) {
718
+ // return null here to avoid seeing 2 error messages for the same issue
719
+ return null;
720
+ }
721
+ if (Array.isArray(selectedTypesArr)) {
722
+ // types and keys can be provided but for each type all provided keys are applied as filter
723
+ for (const selectedType of Array.isArray(selectedTypesArr)
724
+ ? selectedTypesArr
725
+ : Object.keys(selectedTypesArr)) {
726
+ if (!Util._isValidType(selectedType)) {
727
+ return;
728
+ }
729
+ }
730
+ }
731
+ if (businessUnit === '*') {
732
+ Util.logger.info(
733
+ '\n :: Executing the entity on all BUs for all credentials'
734
+ );
735
+ let counter_credTotal = 0;
736
+ for (const cred in properties.credentials) {
737
+ Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`);
738
+
739
+ for (const bu in properties.credentials[cred].businessUnits) {
740
+ if (await this._executeBU(cred, bu, selectedTypesArr, keys)) {
741
+ counter_credBu++;
742
+ } else {
743
+ counter_failed++;
744
+ }
745
+ Util.startLogger(true);
746
+ }
747
+ counter_credTotal += counter_credBu;
748
+ Util.logger.info(
749
+ `\n :: Executed the entity on ${counter_credBu} BUs for ${cred}\n`
750
+ );
751
+ }
752
+ Util.logger.info(
753
+ `\n :: Executed the entity on ${counter_credTotal} BUs in total\n`
754
+ );
755
+ } else {
756
+ let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null];
757
+ // to allow all-BU via user selection we need to run this here already
758
+ if (
759
+ properties.credentials &&
760
+ (!properties.credentials[cred] ||
761
+ (bu !== '*' && !properties.credentials[cred].businessUnits[bu]))
762
+ ) {
763
+ const buObject = await Cli.getCredentialObject(
764
+ properties,
765
+ cred === null ? null : cred + '/' + bu,
766
+ null,
767
+ true
768
+ );
769
+ if (buObject === null) {
770
+ return;
771
+ } else {
772
+ cred = buObject.credential;
773
+ bu = buObject.businessUnit;
774
+ }
775
+ }
776
+ if (bu === '*' && properties.credentials && properties.credentials[cred]) {
777
+ Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`);
778
+ let counter_credBu = 0;
779
+ for (const bu in properties.credentials[cred].businessUnits) {
780
+ if (await this._executeBU(cred, bu, selectedTypesArr, keys)) {
781
+ counter_credBu++;
782
+ } else {
783
+ counter_failed++;
784
+ }
785
+ Util.startLogger(true);
786
+ }
787
+ Util.logger.info(
788
+ `\n :: Executed the entity on ${counter_credBu} BUs for ${cred}\n`
789
+ );
790
+ } else {
791
+ // execute the entity on one BU only
792
+ if (await this._executeBU(cred, bu, selectedTypesArr, keys)) {
793
+ counter_credBu++;
794
+ } else {
795
+ counter_failed++;
796
+ }
797
+ Util.logger.info(`\n :: Done\n`);
798
+ }
799
+ }
800
+ if (counter_credBu !== 0) {
801
+ Util.logger.info(`\n :: Executed query on ${counter_credBu} BUs\n`);
802
+ }
803
+ return counter_failed === 0 ? true : false;
804
+ }
805
+ /**
806
+ * helper for {@link execute}
807
+ *
808
+ * @param {string} cred name of Credential
809
+ * @param {string} bu name of BU
810
+ * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type
811
+ * @param {string[]} keyArr customerkey of the metadata
812
+ * @returns {Promise.<boolean>} true if all items were executed, false otherwise
813
+ */
814
+ static async _executeBU(cred, bu, selectedTypesArr, keyArr) {
815
+ const properties = await config.getProperties();
816
+ let counter_failed = 0;
817
+ const buObject = await Cli.getCredentialObject(
818
+ properties,
819
+ cred === null ? null : cred + '/' + bu,
820
+ null,
821
+ true
822
+ );
823
+ if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) {
824
+ throw new Error('No keys were provided');
825
+ }
826
+ if (!selectedTypesArr || (Array.isArray(selectedTypesArr) && !selectedTypesArr.length)) {
827
+ throw new Error('No type was provided');
828
+ }
829
+ if (buObject !== null) {
830
+ cache.initCache(buObject);
831
+ cred = buObject.credential;
832
+ bu = buObject.businessUnit;
833
+ }
834
+ Util.logger.info(
835
+ `\n :: Executing ${selectedTypesArr.join(', ')} on ${cred}/${bu}\n`
836
+ );
837
+ try {
838
+ // more than one type was provided, iterate types and execute items
839
+ for (const type of selectedTypesArr) {
840
+ try {
841
+ MetadataTypeInfo[type].client = auth.getSDK(buObject);
842
+ } catch (ex) {
843
+ Util.logger.error(ex.message);
844
+ return;
845
+ }
846
+ // result will be undefined (false) if execute is not supported for the type
847
+ if (!(await MetadataTypeInfo[type].execute(keyArr))) {
848
+ counter_failed++;
849
+ }
850
+ }
851
+ } catch (ex) {
852
+ Util.logger.errorStack(ex, 'mcdev.execute failed');
853
+ }
854
+ return counter_failed === 0 ? true : false;
855
+ }
684
856
  }
685
857
 
686
858
  module.exports = Mcdev;
@@ -26,7 +26,9 @@ class Asset extends MetadataType {
26
26
  static async retrieve(retrieveDir, _, subTypeArr, key) {
27
27
  const items = [];
28
28
  subTypeArr ||= this._getSubTypes();
29
- await File.initPrettier();
29
+ if (retrieveDir) {
30
+ await File.initPrettier();
31
+ }
30
32
  // loop through subtypes and return results of each subType for caching (saving is handled per subtype)
31
33
  for (const subType of subTypeArr) {
32
34
  // each subtype contains multiple different specific types (images contains jpg and png for example)
@@ -235,7 +237,7 @@ class Asset extends MetadataType {
235
237
  rightOperand: {
236
238
  property: 'id',
237
239
  simpleOperator: 'greaterThan',
238
- value: items[items.length - 1].id,
240
+ value: items.at(-1).id,
239
241
  },
240
242
  };
241
243
  lastPage = 0;