mcdev 3.0.0 → 3.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 (50) hide show
  1. package/.eslintrc.json +1 -1
  2. package/.github/ISSUE_TEMPLATE/bug.yml +72 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/ISSUE_TEMPLATE/task.md +10 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  6. package/.github/workflows/npm-publish.yml +33 -0
  7. package/.issuetracker +11 -3
  8. package/.vscode/extensions.json +1 -2
  9. package/.vscode/settings.json +19 -4
  10. package/CHANGELOG.md +98 -0
  11. package/README.md +247 -142
  12. package/boilerplate/config.json +3 -2
  13. package/docs/dist/considerations.md +66 -0
  14. package/docs/dist/documentation.md +5794 -0
  15. package/lib/Deployer.js +4 -1
  16. package/lib/MetadataTypeDefinitions.js +1 -0
  17. package/lib/MetadataTypeInfo.js +1 -0
  18. package/lib/Retriever.js +32 -17
  19. package/lib/cli.js +295 -0
  20. package/lib/index.js +774 -1019
  21. package/lib/metadataTypes/AccountUser.js +389 -0
  22. package/lib/metadataTypes/Asset.js +140 -116
  23. package/lib/metadataTypes/Automation.js +119 -54
  24. package/lib/metadataTypes/DataExtension.js +172 -131
  25. package/lib/metadataTypes/DataExtensionField.js +134 -4
  26. package/lib/metadataTypes/Folder.js +66 -69
  27. package/lib/metadataTypes/ImportFile.js +4 -6
  28. package/lib/metadataTypes/MetadataType.js +168 -80
  29. package/lib/metadataTypes/Query.js +54 -25
  30. package/lib/metadataTypes/Role.js +13 -8
  31. package/lib/metadataTypes/Script.js +43 -24
  32. package/lib/metadataTypes/definitions/AccountUser.definition.js +227 -0
  33. package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
  34. package/lib/metadataTypes/definitions/Campaign.definition.js +1 -1
  35. package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -1
  36. package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -1
  37. package/lib/metadataTypes/definitions/Folder.definition.js +1 -1
  38. package/lib/metadataTypes/definitions/ImportFile.definition.js +2 -1
  39. package/lib/metadataTypes/definitions/Script.definition.js +5 -5
  40. package/lib/retrieveChangelog.js +96 -0
  41. package/lib/util/cli.js +4 -6
  42. package/lib/util/init.config.js +3 -0
  43. package/lib/util/init.git.js +2 -1
  44. package/lib/util/util.js +35 -18
  45. package/package.json +20 -24
  46. package/test/util/file.js +51 -0
  47. package/img/README.md/troubleshoot-nodejs-postinstall.jpg +0 -0
  48. package/postinstall.js +0 -41
  49. package/test/deployer.js +0 -16
  50. package/test/util.js +0 -26
@@ -92,14 +92,10 @@ class Automation extends MetadataType {
92
92
  * @returns {Promise<{metadata:AutomationMap,type:string}>} Promise of metadata
93
93
  */
94
94
  static async retrieve(retrieveDir) {
95
- const results = await new Promise((resolve) => {
96
- this.client.SoapClient.retrieve('Program', ['ObjectID'], (error, response) => {
97
- if (error) {
98
- throw new Error(error);
99
- } else {
100
- resolve(response.body.Results);
101
- }
102
- });
95
+ const results = await new Promise((resolve, reject) => {
96
+ this.client.SoapClient.retrieve('Program', ['ObjectID'], (ex, response) =>
97
+ ex ? reject(ex) : resolve(response.body.Results)
98
+ );
103
99
  });
104
100
  const details = (
105
101
  await Promise.all(
@@ -116,6 +112,60 @@ class Automation extends MetadataType {
116
112
  Util.logger.info(
117
113
  `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})`
118
114
  );
115
+ return { metadata: savedMetadata, type: this.definition.type };
116
+ }
117
+ /**
118
+ * Retrieves Metadata of Automation
119
+ * @returns {Promise<{metadata:AutomationMap,type:string}>} Promise of metadata
120
+ */
121
+ static async retrieveChangelog() {
122
+ const results = await new Promise((resolve, reject) => {
123
+ this.client.SoapClient.retrieve(
124
+ 'Program',
125
+ ['ObjectID'],
126
+
127
+ (ex, response) => (ex ? reject(ex) : resolve(response.body.Results))
128
+ );
129
+ });
130
+ const details = [];
131
+ (
132
+ await Promise.all(
133
+ results.map(async (a) => {
134
+ const options = {
135
+ filter: {
136
+ leftOperand: 'ProgramID',
137
+ operator: 'equals',
138
+ rightOperand: a.ObjectID,
139
+ },
140
+ };
141
+
142
+ return new Promise((resolve, reject) => {
143
+ this.client.SoapClient.retrieve(
144
+ 'Automation',
145
+ [
146
+ 'ProgramID',
147
+ 'Name',
148
+ 'CustomerKey',
149
+ 'LastSaveDate',
150
+ 'LastSavedBy',
151
+ 'CreatedBy',
152
+ 'CreatedDate',
153
+ ],
154
+ options,
155
+ (ex, response) => (ex ? reject(ex) : resolve(response.body.Results))
156
+ );
157
+ });
158
+ })
159
+ )
160
+ ).forEach((item) => {
161
+ details.push(...item);
162
+ });
163
+ details.map((item) => {
164
+ item.key = item.CustomerKey;
165
+ });
166
+
167
+ const parsed = this.parseResponseBody({ items: details });
168
+
119
169
  return { metadata: parsed, type: this.definition.type };
120
170
  }
121
171
 
@@ -180,7 +230,7 @@ class Automation extends MetadataType {
180
230
  // eq-operator returns a similar, not exact match and hence might return more than 1 entry
181
231
  const [metadata] = results.filter((item) => item.Name === name);
182
232
  if (!metadata) {
183
- Util.logger.error(`No ${this.definition.typeName} found with name "${name}"`);
233
+ Util.logger.error(`${this.definition.type} '${name}' not found on server.`);
184
234
  return;
185
235
  }
186
236
  const details = (
@@ -217,7 +267,9 @@ class Automation extends MetadataType {
217
267
  );
218
268
  return { metadata: val, type: this.definition.type };
219
269
  } else if (results) {
220
- throw new Error(`No Automations Found with name '${name}'`);
270
+ Util.logger.error(`${this.definition.type} '${name}' not found on server.`);
271
+ Util.logger.info(`Downloaded: automation (0)`);
272
+ return { metadata: {}, type: this.definition.type };
221
273
  } else {
222
274
  throw new Error(JSON.stringify(results));
223
275
  }
@@ -313,9 +365,8 @@ class Automation extends MetadataType {
313
365
  delete metadata.schedule.scheduledTime;
314
366
  delete metadata.schedule.scheduledStatus;
315
367
  if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) {
316
- metadata.schedule.timezoneId = this.definition.timeZoneMapping[
317
- metadata.schedule.timezoneName
318
- ];
368
+ metadata.schedule.timezoneId =
369
+ this.definition.timeZoneMapping[metadata.schedule.timezoneName];
319
370
  } else {
320
371
  Util.logger.error(
321
372
  `Could not find timezone ${metadata.schedule.timezoneName} in definition.timeZoneMapping`
@@ -433,44 +484,56 @@ class Automation extends MetadataType {
433
484
  }
434
485
  if (schedule !== null) {
435
486
  try {
436
- await new Promise((resolve, reject) => {
437
- this.client.SoapClient.schedule(
438
- 'Automation',
439
- schedule,
440
- {
441
- Interaction: {
442
- ObjectID: metadata[key].id,
443
- },
444
- },
445
- 'start',
446
- null,
447
- (error, response) => {
448
- if (
449
- error ||
450
- (response.body.Results &&
451
- response.body.Results[0] &&
452
- response.body.Results[0].StatusCode &&
453
- response.body.Results[0].StatusCode === 'Error')
454
- ) {
455
- reject(error || response.body.Results[0].StatusMessage);
456
- } else {
457
- resolve(response.body.Results);
458
- }
459
- }
460
- );
461
- });
462
- const intervalString =
463
- (schedule._interval > 1 ? `${schedule._interval} ` : '') +
464
- (schedule.RecurrenceType === 'Daily'
465
- ? 'Day'
466
- : schedule.RecurrenceType.slice(0, -2) +
467
- (schedule._interval > 1 ? 's' : ''));
468
- Util.logger.warn(
469
- `Automation '${
470
- originalMetadata[key].name
471
- }' deployed Active: runs every ${intervalString} starting ${
472
- schedule._StartDateTime.split('T').join(' ').split('.')[0]
473
- } ${schedule._timezoneString}`
487
+ await Util.retryOnError(
488
+ `Retrying ${this.definition.type}`,
489
+ async () => {
490
+ await new Promise((resolve, reject) => {
491
+ this.client.SoapClient.schedule(
492
+ 'Automation',
493
+ schedule,
494
+ {
495
+ Interaction: {
496
+ ObjectID: metadata[key].id,
497
+ },
498
+ },
499
+ 'start',
500
+ null,
501
+ (error, response) => {
502
+ if (
503
+ error ||
504
+ (response.body.Results &&
505
+ response.body.Results[0] &&
506
+ response.body.Results[0].StatusCode &&
507
+ response.body.Results[0].StatusCode ===
508
+ 'Error')
509
+ ) {
510
+ reject(
511
+ error ||
512
+ response.body.Results[0].StatusMessage
513
+ );
514
+ } else {
515
+ resolve(response.body.Results);
516
+ }
517
+ }
518
+ );
519
+ });
520
+ const intervalString =
521
+ (schedule._interval > 1 ? `${schedule._interval} ` : '') +
522
+ (schedule.RecurrenceType === 'Daily'
523
+ ? 'Day'
524
+ : schedule.RecurrenceType.slice(0, -2) +
525
+ (schedule._interval > 1 ? 's' : ''));
526
+ Util.logger.warn(
527
+ `Automation '${
528
+ originalMetadata[key].name
529
+ }' deployed Active: runs every ${intervalString} starting ${
530
+ schedule._StartDateTime
531
+ .split('T')
532
+ .join(' ')
533
+ .split('.')[0]
534
+ } ${schedule._timezoneString}`
535
+ );
536
+ }
474
537
  );
475
538
  } catch (ex) {
476
539
  Util.logger.error(
@@ -682,9 +745,8 @@ class Automation extends MetadataType {
682
745
  }
683
746
 
684
747
  if (this.definition.timeZoneMapping[scheduleObject.timezoneName]) {
685
- scheduleObject.timezoneId = this.definition.timeZoneMapping[
686
- scheduleObject.timezoneName
687
- ];
748
+ scheduleObject.timezoneId =
749
+ this.definition.timeZoneMapping[scheduleObject.timezoneName];
688
750
  } else {
689
751
  Util.logger.error(
690
752
  `Could not find timezone ${scheduleObject.timezoneName} in definition.timeZoneMapping`
@@ -778,6 +840,9 @@ class Automation extends MetadataType {
778
840
  // Assign definition to static attributes
779
841
  Automation.definition = Definitions.automation;
780
842
  Automation.cache = {};
843
+ /**
844
+ * @type {Util.ET_Client}
845
+ */
781
846
  Automation.client = undefined;
782
847
 
783
848
  module.exports = Automation;