mcdev 5.2.0 → 6.0.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 (191) hide show
  1. package/.eslintrc.json +1 -1
  2. package/.fork/custom-commands.json +12 -0
  3. package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
  4. package/.github/PULL_REQUEST_TEMPLATE/pr_template_release.md +19 -0
  5. package/.github/workflows/code-test.yml +1 -1
  6. package/.github/workflows/coverage-base-update.yml +1 -1
  7. package/.github/workflows/coverage-develop-branch.yml +2 -2
  8. package/.github/workflows/coverage-main-branch.yml +2 -2
  9. package/.github/workflows/coverage.yml +2 -2
  10. package/.github/workflows/npm-publish.yml +2 -2
  11. package/.prettierrc +7 -0
  12. package/docs/dist/documentation.md +388 -482
  13. package/jsconfig.json +5 -1
  14. package/lib/Builder.js +8 -8
  15. package/lib/Deployer.js +10 -10
  16. package/lib/MetadataTypeDefinitions.js +73 -38
  17. package/lib/MetadataTypeInfo.js +72 -37
  18. package/lib/Retriever.js +8 -8
  19. package/lib/cli.js +12 -7
  20. package/lib/index.js +28 -18
  21. package/lib/metadataTypes/Asset.js +12 -10
  22. package/lib/metadataTypes/AttributeGroup.js +7 -6
  23. package/lib/metadataTypes/AttributeSet.js +126 -18
  24. package/lib/metadataTypes/Automation.js +107 -78
  25. package/lib/metadataTypes/Campaign.js +7 -6
  26. package/lib/metadataTypes/ContentArea.js +7 -6
  27. package/lib/metadataTypes/DataExtension.js +475 -78
  28. package/lib/metadataTypes/DataExtensionField.js +36 -18
  29. package/lib/metadataTypes/DataExtensionTemplate.js +5 -4
  30. package/lib/metadataTypes/DataExtract.js +8 -7
  31. package/lib/metadataTypes/DataExtractType.js +5 -4
  32. package/lib/metadataTypes/Discovery.js +6 -5
  33. package/lib/metadataTypes/Email.js +6 -5
  34. package/lib/metadataTypes/EmailSend.js +7 -6
  35. package/lib/metadataTypes/Event.js +8 -7
  36. package/lib/metadataTypes/FileLocation.js +5 -4
  37. package/lib/metadataTypes/FileTransfer.js +8 -7
  38. package/lib/metadataTypes/Filter.js +5 -4
  39. package/lib/metadataTypes/Folder.js +9 -8
  40. package/lib/metadataTypes/ImportFile.js +8 -7
  41. package/lib/metadataTypes/Journey.js +17 -9
  42. package/lib/metadataTypes/List.js +9 -8
  43. package/lib/metadataTypes/MetadataType.js +100 -34
  44. package/lib/metadataTypes/MobileCode.js +5 -4
  45. package/lib/metadataTypes/MobileKeyword.js +9 -8
  46. package/lib/metadataTypes/MobileMessage.js +8 -7
  47. package/lib/metadataTypes/Query.js +9 -8
  48. package/lib/metadataTypes/Role.js +8 -7
  49. package/lib/metadataTypes/Script.js +7 -6
  50. package/lib/metadataTypes/SendClassification.js +5 -4
  51. package/lib/metadataTypes/TransactionalEmail.js +101 -23
  52. package/lib/metadataTypes/TransactionalMessage.js +9 -7
  53. package/lib/metadataTypes/TransactionalPush.js +7 -6
  54. package/lib/metadataTypes/TransactionalSMS.js +9 -8
  55. package/lib/metadataTypes/TriggeredSend.js +15 -12
  56. package/lib/metadataTypes/User.js +8 -7
  57. package/lib/metadataTypes/Verification.js +230 -0
  58. package/lib/metadataTypes/definitions/Asset.definition.js +1 -1
  59. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +3 -3
  60. package/lib/metadataTypes/definitions/AttributeSet.definition.js +75 -22
  61. package/lib/metadataTypes/definitions/Automation.definition.js +2 -1
  62. package/lib/metadataTypes/definitions/Campaign.definition.js +1 -1
  63. package/lib/metadataTypes/definitions/ContentArea.definition.js +1 -1
  64. package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -1
  65. package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -1
  66. package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +1 -1
  67. package/lib/metadataTypes/definitions/DataExtract.definition.js +1 -1
  68. package/lib/metadataTypes/definitions/DataExtractType.definition.js +1 -1
  69. package/lib/metadataTypes/definitions/Discovery.definition.js +1 -1
  70. package/lib/metadataTypes/definitions/Email.definition.js +1 -1
  71. package/lib/metadataTypes/definitions/EmailSend.definition.js +1 -1
  72. package/lib/metadataTypes/definitions/Event.definition.js +1 -1
  73. package/lib/metadataTypes/definitions/FileLocation.definition.js +1 -1
  74. package/lib/metadataTypes/definitions/FileTransfer.definition.js +1 -1
  75. package/lib/metadataTypes/definitions/Filter.definition.js +1 -1
  76. package/lib/metadataTypes/definitions/Folder.definition.js +1 -1
  77. package/lib/metadataTypes/definitions/ImportFile.definition.js +1 -1
  78. package/lib/metadataTypes/definitions/Journey.definition.js +1 -1
  79. package/lib/metadataTypes/definitions/List.definition.js +1 -1
  80. package/lib/metadataTypes/definitions/MobileCode.definition.js +1 -1
  81. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +1 -1
  82. package/lib/metadataTypes/definitions/MobileMessage.definition.js +1 -1
  83. package/lib/metadataTypes/definitions/Query.definition.js +1 -1
  84. package/lib/metadataTypes/definitions/Role.definition.js +1 -1
  85. package/lib/metadataTypes/definitions/Script.definition.js +1 -1
  86. package/lib/metadataTypes/definitions/SendClassification.definition.js +1 -1
  87. package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +20 -2
  88. package/lib/metadataTypes/definitions/TransactionalPush.definition.js +1 -1
  89. package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +1 -1
  90. package/lib/metadataTypes/definitions/TriggeredSend.definition.js +1 -1
  91. package/lib/metadataTypes/definitions/User.definition.js +1 -1
  92. package/lib/metadataTypes/definitions/Verification.definition.js +88 -0
  93. package/lib/retrieveChangelog.js +4 -3
  94. package/lib/util/auth.js +11 -8
  95. package/lib/util/businessUnit.js +5 -5
  96. package/lib/util/cache.js +3 -3
  97. package/lib/util/cli.js +15 -13
  98. package/lib/util/config.js +10 -7
  99. package/lib/util/devops.js +12 -11
  100. package/lib/util/file.js +15 -14
  101. package/lib/util/init.config.js +11 -9
  102. package/lib/util/init.git.js +8 -7
  103. package/lib/util/init.js +12 -12
  104. package/lib/util/init.npm.js +7 -5
  105. package/lib/util/util.js +14 -12
  106. package/package.json +32 -27
  107. package/test/general.test.js +4 -6
  108. package/test/mockRoot/.mcdevrc.json +1 -1
  109. package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testExisting_dataExtensionShared.dataExtension-meta.json +59 -0
  110. package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testNew_dataExtensionShared.dataExtension-meta.json +23 -0
  111. package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +4 -0
  112. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-meta.json +1 -0
  113. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +3 -4
  114. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testNew_temail.transactionalEmail-meta.json +1 -6
  115. package/test/mockRoot/deploy/testInstance/testBU/verification/testExisting_39f6a488-20eb-4ba0-b0b9.verification-meta.json +11 -0
  116. package/test/mockRoot/deploy/testInstance/testBU/verification/testNew_39f6a488-20eb-4ba0-b0b9.verification-meta.json +11 -0
  117. package/test/resourceFactory.js +52 -26
  118. package/test/resources/1111111/data/v1/customobjectdata/key/testExisting_dataExtensionShared/rowset/get-response.json +13 -0
  119. package/test/resources/1111111/dataExtension/create-expected.json +23 -0
  120. package/test/resources/1111111/dataExtension/create-response.xml +59 -0
  121. package/test/resources/1111111/dataExtension/retrieve-expected.json +55 -0
  122. package/test/resources/1111111/dataExtension/retrieve-expected.md +18 -0
  123. package/test/resources/1111111/dataExtension/retrieve-response.xml +27 -1
  124. package/test/resources/1111111/dataExtension/update-expected.json +55 -0
  125. package/test/resources/1111111/dataExtension/update-response.xml +57 -0
  126. package/test/resources/1111111/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtensionShared].[TriggerUpdate_randomNumber_]-response.xml +45 -0
  127. package/test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml +98 -0
  128. package/test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionSharedORDataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml +98 -0
  129. package/test/resources/1111111/dataExtensionField/retrieve-response.xml +98 -0
  130. package/test/resources/1111111/dataExtensionTemplate/retrieve-response.xml +303 -0
  131. package/test/resources/1111111/dataFolder/retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml +387 -0
  132. package/test/resources/1111111/dataFolder/retrieve-response.xml +353 -9
  133. package/test/resources/9999999/attributeSet/retrieve-expected.json +89 -694
  134. package/test/resources/9999999/automation/build-expected.json +4 -0
  135. package/test/resources/9999999/automation/create-expected.json +4 -0
  136. package/test/resources/9999999/automation/create-testNew_automation-expected.md +1 -0
  137. package/test/resources/9999999/automation/retrieve-expected.json +4 -0
  138. package/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +1 -0
  139. package/test/resources/9999999/automation/template-expected.json +4 -0
  140. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +7 -0
  141. package/test/resources/9999999/automation/v1/automations/post-response.json +7 -0
  142. package/test/resources/9999999/automation/v1/dataverifications/post-response.json +12 -0
  143. package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/delete-response.json +0 -0
  144. package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/get-response.json +12 -0
  145. package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/patch-response.json +12 -0
  146. package/test/resources/9999999/dataExtension/build-expected.json +16 -0
  147. package/test/resources/9999999/dataExtension/delete-response.xml +42 -0
  148. package/test/resources/9999999/dataExtension/retrieve-expected.json +16 -0
  149. package/test/resources/9999999/dataExtension/retrieve-expected.md +3 -1
  150. package/test/resources/9999999/dataExtension/template-expected.json +16 -0
  151. package/test/resources/9999999/dataExtension/update-expected.json +17 -1
  152. package/test/resources/9999999/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtension].[LastName]-response.xml +44 -0
  153. package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml +36 -1
  154. package/test/resources/9999999/dataExtensionField/retrieve-response.xml +36 -1
  155. package/test/resources/9999999/dataFolder/retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml +117 -0
  156. package/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json +43 -0
  157. package/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json +387 -0
  158. package/test/resources/9999999/interaction/v1/interactions/233d4413-922c-4568-85a5-e5cc77efc3be/delete-response.json +1 -0
  159. package/test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json +1 -1
  160. package/test/resources/9999999/messaging/v1/email/definitions/post-response.json +1 -1
  161. package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/delete-response.json +6 -0
  162. package/test/resources/9999999/transactionalEmail/build-expected.json +3 -7
  163. package/test/resources/9999999/transactionalEmail/get-expected.json +3 -7
  164. package/test/resources/9999999/transactionalEmail/patch-expected.json +3 -7
  165. package/test/resources/9999999/transactionalEmail/post-expected.json +3 -7
  166. package/test/resources/9999999/transactionalEmail/template-expected.json +3 -7
  167. package/test/resources/9999999/verification/build-expected.json +11 -0
  168. package/test/resources/9999999/verification/get-expected.json +11 -0
  169. package/test/resources/9999999/verification/patch-expected.json +11 -0
  170. package/test/resources/9999999/verification/post-expected.json +11 -0
  171. package/test/resources/9999999/verification/template-expected.json +11 -0
  172. package/test/type.attributeGroup.test.js +9 -12
  173. package/test/type.attributeSet.test.js +10 -13
  174. package/test/type.automation.test.js +34 -32
  175. package/test/type.dataExtension.test.js +210 -54
  176. package/test/type.dataExtract.test.js +15 -9
  177. package/test/type.fileTransfer.test.js +15 -9
  178. package/test/type.importFile.test.js +15 -9
  179. package/test/type.journey.test.js +43 -17
  180. package/test/type.mobileKeyword.test.js +11 -11
  181. package/test/type.mobileMessage.test.js +11 -11
  182. package/test/type.query.test.js +13 -14
  183. package/test/type.script.test.js +11 -9
  184. package/test/type.transactionalEmail.test.js +17 -17
  185. package/test/type.transactionalPush.test.js +7 -10
  186. package/test/type.transactionalSMS.test.js +7 -11
  187. package/test/type.triggeredSend.test.js +11 -10
  188. package/test/type.user.test.js +6 -8
  189. package/test/type.verification.test.js +172 -0
  190. package/test/utils.js +68 -48
  191. package/types/mcdev.d.js +16 -2
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const MetadataType = require('./MetadataType');
5
- const AttributeGroup = require('./AttributeGroup');
6
- const Util = require('../util/util');
7
- const cache = require('../util/cache');
3
+ import AttributeGroup from './AttributeGroup.js';
4
+ import MetadataType from './MetadataType.js';
5
+ import TYPE from '../../types/mcdev.d.js';
6
+ import { Util } from '../util/util.js';
7
+ import cache from '../util/cache.js';
8
8
 
9
9
  /**
10
10
  * AttributeSet MetadataType
@@ -31,13 +31,7 @@ class AttributeSet extends MetadataType {
31
31
  const result = await AttributeGroup.retrieveForCache();
32
32
  cache.setMetadata('attributeGroup', result.metadata);
33
33
  }
34
- return super.retrieveREST(
35
- retrieveDir,
36
- '/hub/v1/contacts/schema/setDefinitions',
37
- null,
38
- null,
39
- key
40
- );
34
+ return super.retrieveREST(retrieveDir, '/hub/v1/contacts/schema/setDefinitions', null, key);
41
35
  }
42
36
  /**
43
37
  * Retrieves Metadata of schema set definitions for caching.
@@ -47,6 +41,110 @@ class AttributeSet extends MetadataType {
47
41
  static retrieveForCache() {
48
42
  return super.retrieveREST(null, '/hub/v1/contacts/schema/setDefinitions');
49
43
  }
44
+ /**
45
+ * used to identify updated shared data extensions that are used in attributeSets.
46
+ * helper for DataExtension.#fixShared_onBU
47
+ *
48
+ * @param {Object.<string, string>} sharedDataExtensionMap ID-Key relationship of shared data extensions
49
+ * @param {object} fixShared_fields DataExtensionField.fixShared_fields
50
+ * @returns {Promise.<string[]>} Promise of list of shared dataExtension IDs
51
+ */
52
+ static async fixShared_retrieve(sharedDataExtensionMap, fixShared_fields) {
53
+ if (!Object.keys(sharedDataExtensionMap).length) {
54
+ return [];
55
+ }
56
+ const result = await super.retrieveREST(null, '/hub/v1/contacts/schema/setDefinitions');
57
+ const metadataMap = result?.metadata;
58
+ if (metadataMap && Object.keys(metadataMap).length) {
59
+ const sharedDeIds = Object.keys(metadataMap)
60
+ .filter(
61
+ (asKey) =>
62
+ metadataMap[asKey].storageLogicalType === 'ExactTargetSchema' ||
63
+ metadataMap[asKey].storageLogicalType === 'DataExtension'
64
+ )
65
+ .filter((asKey) => {
66
+ // check if dataExtension ID is found on any attributeSet of this BU
67
+ if (sharedDataExtensionMap[metadataMap[asKey].storageReferenceID.value]) {
68
+ Util.logger.debug(
69
+ ` shared dataExtension ID ${metadataMap[asKey].storageReferenceID.value} found in attributeSet ${asKey}`
70
+ );
71
+ return true;
72
+ } else {
73
+ return false;
74
+ }
75
+ })
76
+ .filter((asKey) => {
77
+ // check if any of the dataExtension fields dont exist on the attributeSet or are out of date
78
+ const deKey =
79
+ sharedDataExtensionMap[metadataMap[asKey].storageReferenceID.value];
80
+ const asFields = metadataMap[asKey].valueDefinitions;
81
+ const deFields = Object.values(fixShared_fields[deKey]);
82
+ return deFields.some((deField) => {
83
+ const search = asFields.filter((asf) => asf.name === deField.Name);
84
+ if (!search.length) {
85
+ Util.logger.debug(
86
+ Util.getGrayMsg(
87
+ ` - Field ${deField.Name} not found in attributeSet; Note: only first recognized difference is printed to log`
88
+ )
89
+ );
90
+ return true;
91
+ }
92
+ const asField = search[0];
93
+ if (asField.dataType !== deField.FieldType) {
94
+ Util.logger.debug(
95
+ Util.getGrayMsg(
96
+ ` - Field ${deField.Name} FieldType changed (old: ${asField.dataType}; new: ${deField.FieldType}); Note: only first recognized difference is printed to log`
97
+ )
98
+ );
99
+ return true;
100
+ }
101
+ asField.defaultValue ||= '';
102
+ if (
103
+ (asField.defaultValue && deField.DefaultValue === '') ||
104
+ (deField.FieldType === 'Boolean' &&
105
+ deField.DefaultValue !== '' &&
106
+ (deField.DefaultValue
107
+ ? 'True'
108
+ : 'False' !== asField.defaultValue)) ||
109
+ (deField.FieldType !== 'Boolean' &&
110
+ deField.DefaultValue !== asField.defaultValue)
111
+ ) {
112
+ Util.logger.debug(
113
+ ` - Field ${deField.Name} DefaultValue changed (old: ${asField.defaultValue}; new: ${deField.DefaultValue}); Note: only first recognized difference is printed to log`
114
+ );
115
+ return true;
116
+ }
117
+ // some field types don't carry the length property. reset to 0 to ease comparison
118
+ asField.length ||= 0;
119
+ if (asField.length !== deField.MaxLength) {
120
+ Util.logger.debug(
121
+ ` - Field ${deField.Name} MaxLength changed (old: ${asField.length}; new: ${deField.MaxLength}); Note: only first recognized difference is printed to log`
122
+ );
123
+ return true;
124
+ }
125
+ if (asField.isNullable !== deField.IsRequired) {
126
+ Util.logger.debug(
127
+ ` - Field ${deField.Name} IsRequired changed (old: ${asField.isNullable}; new: ${deField.IsRequired}); Note: only first recognized difference is printed to log`
128
+ );
129
+ return true;
130
+ }
131
+ if (asField.isPrimaryKey !== deField.IsPrimaryKey) {
132
+ Util.logger.debug(
133
+ ` - Field ${deField.Name} IsPrimaryKey changed (old: ${asField.isPrimaryKey}; new: ${deField.IsPrimaryKey}); Note: only first recognized difference is printed to log`
134
+ );
135
+ return true;
136
+ }
137
+ return false;
138
+ });
139
+ })
140
+ .map((key) => metadataMap[key].storageReferenceID.value)
141
+ .filter(Boolean);
142
+ return sharedDeIds;
143
+ } else {
144
+ // nothing to do - return empty array
145
+ return [];
146
+ }
147
+ }
50
148
 
51
149
  /**
52
150
  * Builds map of metadata entries mapped to their keyfields
@@ -83,7 +181,7 @@ class AttributeSet extends MetadataType {
83
181
  switch (metadata.storageLogicalType) {
84
182
  case 'ExactTargetSchema': // synced / shared DEs
85
183
  case 'DataExtension': {
86
- // local DEs
184
+ // shared / local DEs
87
185
  try {
88
186
  metadata.r__dataExtension_CustomerKey = cache.searchForField(
89
187
  'dataExtension',
@@ -226,6 +324,12 @@ class AttributeSet extends MetadataType {
226
324
  // Member ID
227
325
  delete metadata.customObjectOwnerMID;
228
326
 
327
+ // remove duplicate ID fields (main field is definitionID)
328
+ delete metadata.setDefinitionID;
329
+ if (metadata.dataRetentionProperties?.setDefinitionID) {
330
+ delete metadata.dataRetentionProperties?.setDefinitionID;
331
+ }
332
+
229
333
  // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - to be sure we check it here and remove it if it's the case
230
334
  if (metadata.connectingID?.identifierType === 'FullyQualifiedName') {
231
335
  // remove useless field
@@ -241,8 +345,11 @@ class AttributeSet extends MetadataType {
241
345
  * @returns {object[]} all system value definitions
242
346
  */
243
347
  static _getSystemValueDefinitions() {
244
- if (!this.systemValueDefinitions) {
245
- this.systemValueDefinitions = Object.values(cache.getCache()['attributeSet'])
348
+ this.systemValueDefinitions ||= {};
349
+ if (!this.systemValueDefinitions[this.buObject.mid]) {
350
+ this.systemValueDefinitions[this.buObject.mid] = Object.values(
351
+ cache.getCache()['attributeSet']
352
+ )
246
353
  .flatMap((item) => {
247
354
  if (item.isSystemDefined) {
248
355
  return item.valueDefinitions;
@@ -250,11 +357,12 @@ class AttributeSet extends MetadataType {
250
357
  })
251
358
  .filter(Boolean);
252
359
  }
253
- return this.systemValueDefinitions;
360
+ return this.systemValueDefinitions[this.buObject.mid];
254
361
  }
255
362
  }
256
363
 
257
364
  // Assign definition to static attributes
258
- AttributeSet.definition = require('../MetadataTypeDefinitions').attributeSet;
365
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
366
+ AttributeSet.definition = MetadataTypeDefinitions.attributeSet;
259
367
 
260
- module.exports = AttributeSet;
368
+ export default AttributeSet;
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- const MetadataType = require('./MetadataType');
4
- const TYPE = require('../../types/mcdev.d');
5
- const Util = require('../util/util');
6
- const File = require('../util/file');
7
- const Definitions = require('../MetadataTypeDefinitions');
8
- const cache = require('../util/cache');
9
- const pLimit = require('p-limit');
3
+ import MetadataType from './MetadataType.js';
4
+ import TYPE from '../../types/mcdev.d.js';
5
+ import { Util } from '../util/util.js';
6
+ import File from '../util/file.js';
7
+ import Definitions from '../MetadataTypeDefinitions.js';
8
+ import cache from '../util/cache.js';
9
+ import pLimit from 'p-limit';
10
10
 
11
11
  /**
12
12
  * Automation MetadataType
@@ -25,71 +25,53 @@ class Automation extends MetadataType {
25
25
  * @returns {Promise.<TYPE.AutomationMapObj>} Promise of metadata
26
26
  */
27
27
  static async retrieve(retrieveDir, _, __, key) {
28
- /** @type {TYPE.SoapRequestParams} */
29
- let requestParams = null;
30
- if (key) {
31
- requestParams = {
32
- filter: {
33
- leftOperand: 'CustomerKey',
34
- operator: 'equals',
35
- rightOperand: key,
36
- },
37
- };
38
- }
39
- const results = await this.client.soap.retrieveBulk('Program', ['ObjectID'], requestParams);
40
- if (results.Results?.length && !key) {
41
- // empty results will come back without "Results" defined
42
- Util.logger.info(
43
- Util.getGrayMsg(
44
- ` - ${results.Results?.length} automation${
45
- results.Results?.length === 1 ? '' : 's'
46
- } found. Retrieving details...`
47
- )
28
+ let metadataMap;
29
+ if (key && this._cachedMetadataMap?.[key]) {
30
+ metadataMap = {};
31
+ metadataMap[key] = this._cachedMetadataMap[key];
32
+ delete this._cachedMetadataMap;
33
+ } else if (!key && this._cachedMetadataMap) {
34
+ metadataMap = this._cachedMetadataMap;
35
+ delete this._cachedMetadataMap;
36
+ } else {
37
+ /** @type {TYPE.SoapRequestParams} */
38
+ let requestParams = null;
39
+ if (key) {
40
+ requestParams = {
41
+ filter: {
42
+ leftOperand: 'CustomerKey',
43
+ operator: 'equals',
44
+ rightOperand: key,
45
+ },
46
+ };
47
+ }
48
+ const results = await this.client.soap.retrieveBulk(
49
+ 'Program',
50
+ ['ObjectID'],
51
+ requestParams
48
52
  );
49
- }
50
- // the API seems to handle 50 concurrent requests nicely
51
- const rateLimit = pLimit(50);
52
-
53
- const details = results.Results
54
- ? await Promise.all(
55
- results.Results.map(async (item) =>
56
- rateLimit(async () => {
57
- try {
58
- return await this.client.rest.get(
59
- '/automation/v1/automations/' + item.ObjectID
60
- );
61
- } catch (ex) {
62
- try {
63
- if (ex.message == 'socket hang up') {
64
- // one more retry; it's a rare case but retrying again should solve the issue gracefully
65
- return await this.client.rest.get(
66
- '/automation/v1/automations/' + item.ObjectID
67
- );
68
- }
69
- } catch {
70
- // no extra action needed, handled below
71
- }
72
- // if we do get here, we should log the error and continue instead of failing to download all automations
73
- Util.logger.error(
74
- ` ☇ skipping Automation ${item.ObjectID}: ${ex.message} ${ex.code}`
75
- );
76
- return null;
77
- }
78
- })
53
+ // the API seems to handle 50 concurrent requests nicely
54
+ const response = results?.Results?.length
55
+ ? await this.retrieveRESTcollection(
56
+ results?.Results.map((item) => ({
57
+ id: item.ObjectID,
58
+ uri: '/automation/v1/automations/' + item.ObjectID,
59
+ })),
60
+ 50,
61
+ !key
79
62
  )
80
- )
81
- : [];
82
-
83
- // * if retrieving some automations fails, a null element would remain in the details-array for each of them that needs to be filtered to prevent it from causing issues elsewhere
84
- let metadataMap = this.parseResponseBody({ items: details.filter(Boolean) });
63
+ : null;
64
+ metadataMap = response?.metadata || {};
65
+ }
85
66
 
86
- if (Object.keys(metadataMap).length) {
67
+ if (!this._skipNotificationRetrieve && Object.keys(metadataMap).length) {
87
68
  // attach notification information to each automation that has any
88
69
  await this.#getAutomationNotificationsREST(metadataMap);
89
70
  }
90
71
 
91
72
  // * retrieveDir can be empty when we use it in the context of postDeployTasks
92
73
  if (retrieveDir) {
74
+ this.retrieveDir = retrieveDir;
93
75
  metadataMap = await this.saveResults(metadataMap, retrieveDir, null, null);
94
76
  Util.logger.info(
95
77
  `Downloaded: ${this.definition.type} (${Object.keys(metadataMap).length})` +
@@ -101,6 +83,27 @@ class Automation extends MetadataType {
101
83
  return { metadata: metadataMap, type: this.definition.type };
102
84
  }
103
85
 
86
+ /**
87
+ * helper for {@link this.retrieveRESTcollection}
88
+ *
89
+ * @param {Error} ex exception
90
+ * @param {string} id id or key of item
91
+ * @returns {null} -
92
+ */
93
+ static async handleRESTErrors(ex, id) {
94
+ try {
95
+ if (ex.message == 'socket hang up') {
96
+ // one more retry; it's a rare case but retrying again should solve the issue gracefully
97
+ return await this.client.rest.get('/automation/v1/automations/' + id);
98
+ }
99
+ } catch {
100
+ // no extra action needed, handled below
101
+ }
102
+ // if we do get here, we should log the error and continue instead of failing to download all automations
103
+ Util.logger.error(` ☇ skipping Automation ${id}: ${ex.message} ${ex.code}`);
104
+ return null;
105
+ }
106
+
104
107
  /**
105
108
  * helper for {@link Automation.retrieve} to get Automation Notifications
106
109
  *
@@ -230,12 +233,18 @@ class Automation extends MetadataType {
230
233
  * @returns {Promise.<TYPE.AutomationMapObj>} Promise of metadata
231
234
  */
232
235
  static async retrieveForCache() {
233
- // get automations for cache
234
- const results = await this.client.soap.retrieveBulk('Program', [
235
- 'ObjectID',
236
- 'CustomerKey',
237
- 'Name',
238
- ]);
236
+ let results = {};
237
+ if (this._cachedMetadataMap) {
238
+ results.Results = Object.values(this._cachedMetadataMap);
239
+ delete this._cachedMetadataMap;
240
+ } else {
241
+ // get automations for cache
242
+ results = await this.client.soap.retrieveBulk('Program', [
243
+ 'ObjectID',
244
+ 'CustomerKey',
245
+ 'Name',
246
+ ]);
247
+ }
239
248
  const resultsConverted = {};
240
249
  if (Array.isArray(results?.Results)) {
241
250
  // get encodedAutomationID to retrieve notification information
@@ -252,16 +261,16 @@ class Automation extends MetadataType {
252
261
 
253
262
  // merge encodedAutomationID into results
254
263
  for (const m of results.Results) {
255
- resultsConverted[m.CustomerKey] = {
256
- id: m.ObjectID,
257
- key: m.CustomerKey,
258
- name: m.Name,
259
- programId: automationsLegacy.metadata[m.CustomerKey]?.id,
260
- status: automationsLegacy.metadata[m.CustomerKey]?.status,
264
+ const key = m.CustomerKey || m.key;
265
+ resultsConverted[key] = {
266
+ id: m.ObjectID || m.id,
267
+ key: key,
268
+ name: m.Name || m.name,
269
+ programId: automationsLegacy.metadata[key]?.id,
270
+ status: automationsLegacy.metadata[key]?.status,
261
271
  };
262
272
  }
263
273
  }
264
-
265
274
  return { metadata: resultsConverted, type: this.definition.type };
266
275
  }
267
276
 
@@ -423,6 +432,7 @@ class Automation extends MetadataType {
423
432
  } due to missing activityObjectId: ${JSON.stringify(activity)}`
424
433
  );
425
434
  // empty if block
435
+ continue;
426
436
  } else if (!this.definition.dependencies.includes(activity.r__type)) {
427
437
  Util.logger.debug(
428
438
  ` - skipping ${
@@ -433,9 +443,10 @@ class Automation extends MetadataType {
433
443
  activity.r__type
434
444
  } is not set up as a dependency for ${this.definition.type}`
435
445
  );
446
+ continue;
436
447
  }
437
448
  // / if managed by cache we can update references to support deployment
438
- else if (
449
+ if (
439
450
  Definitions[activity.r__type]?.['idField'] &&
440
451
  cache.getCache(this.buObject.mid)[activity.r__type]
441
452
  ) {
@@ -803,6 +814,7 @@ class Automation extends MetadataType {
803
814
  delete metadata.schedule;
804
815
  delete metadata.type;
805
816
  let i = 0;
817
+ const buName = this.buObject.credential + '/' + this.buObject.businessUnit;
806
818
  if (metadata.steps) {
807
819
  for (const step of metadata.steps) {
808
820
  let displayOrder = 0;
@@ -812,6 +824,23 @@ class Automation extends MetadataType {
812
824
  activity.name &&
813
825
  this.definition.dependencies.includes(activity.r__type)
814
826
  ) {
827
+ if (
828
+ activity.r__type === 'verification' &&
829
+ this.createdKeyMap?.[buName]?.verification?.[activity.name]
830
+ ) {
831
+ Util.logger.info(
832
+ Util.getGrayMsg(
833
+ ` - updated verification activity name from ${
834
+ activity.name
835
+ } to ${
836
+ this.createdKeyMap[buName].verification[activity.name]
837
+ }`
838
+ )
839
+ );
840
+ // map structure: cred/bu --> type --> old key --> new key
841
+ activity.name =
842
+ this.createdKeyMap[buName].verification[activity.name];
843
+ }
815
844
  // automations can have empty placeholder for activities with only their type defined
816
845
  activity.activityObjectId = cache.searchForField(
817
846
  activity.r__type,
@@ -1583,4 +1612,4 @@ class Automation extends MetadataType {
1583
1612
  // Assign definition to static attributes
1584
1613
  Automation.definition = Definitions.automation;
1585
1614
 
1586
- module.exports = Automation;
1615
+ export default Automation;
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const MetadataType = require('./MetadataType');
5
- const Util = require('../util/util');
6
- const File = require('../util/file');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import MetadataType from './MetadataType.js';
5
+ import { Util } from '../util/util.js';
6
+ import File from '../util/file.js';
7
7
 
8
8
  /**
9
9
  * Campaign MetadataType
@@ -71,6 +71,7 @@ class Campaign extends MetadataType {
71
71
  }
72
72
  }
73
73
  // Assign definition to static attributes
74
- Campaign.definition = require('../MetadataTypeDefinitions').campaign;
74
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
75
+ Campaign.definition = MetadataTypeDefinitions.campaign;
75
76
 
76
- module.exports = Campaign;
77
+ export default Campaign;
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const MetadataType = require('./MetadataType');
5
- const Util = require('../util/util');
6
- const cache = require('../util/cache');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import MetadataType from './MetadataType.js';
5
+ import { Util } from '../util/util.js';
6
+ import cache from '../util/cache.js';
7
7
 
8
8
  /**
9
9
  * ContentArea MetadataType
@@ -99,6 +99,7 @@ class ContentArea extends MetadataType {
99
99
  }
100
100
 
101
101
  // Assign definition to static attributes
102
- ContentArea.definition = require('../MetadataTypeDefinitions').contentArea;
102
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
103
+ ContentArea.definition = MetadataTypeDefinitions.contentArea;
103
104
 
104
- module.exports = ContentArea;
105
+ export default ContentArea;