mcdev 4.3.4 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/.coverage-comment-template.md +20 -0
  2. package/.coverage-comment-template.svelte +178 -0
  3. package/.eslintrc.json +2 -0
  4. package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
  5. package/.github/workflows/code-test.yml +36 -0
  6. package/.github/workflows/coverage-base-update.yml +57 -0
  7. package/.github/workflows/coverage-develop-branch.yml +41 -0
  8. package/.github/workflows/coverage-main-branch.yml +41 -0
  9. package/.github/workflows/coverage.yml +77 -0
  10. package/.husky/post-checkout +1 -1
  11. package/.prettierrc +1 -1
  12. package/.vscode/extensions.json +0 -4
  13. package/README.md +1 -1
  14. package/boilerplate/config.json +1 -1
  15. package/boilerplate/files/.prettierrc +1 -1
  16. package/boilerplate/files/.vscode/extensions.json +1 -1
  17. package/boilerplate/forcedUpdates.json +4 -0
  18. package/docs/dist/documentation.md +1196 -430
  19. package/lib/Builder.js +6 -1
  20. package/lib/Deployer.js +30 -5
  21. package/lib/MetadataTypeDefinitions.js +8 -6
  22. package/lib/MetadataTypeInfo.js +8 -6
  23. package/lib/cli.js +54 -42
  24. package/lib/index.js +82 -8
  25. package/lib/metadataTypes/Asset.js +73 -1
  26. package/lib/metadataTypes/AttributeGroup.js +0 -1
  27. package/lib/metadataTypes/Automation.js +48 -5
  28. package/lib/metadataTypes/Campaign.js +20 -7
  29. package/lib/metadataTypes/ContentArea.js +1 -1
  30. package/lib/metadataTypes/DataExtension.js +221 -184
  31. package/lib/metadataTypes/DataExtensionField.js +12 -19
  32. package/lib/metadataTypes/DataExtensionTemplate.js +1 -1
  33. package/lib/metadataTypes/DataExtract.js +1 -1
  34. package/lib/metadataTypes/DataExtractType.js +1 -1
  35. package/lib/metadataTypes/Email.js +1 -1
  36. package/lib/metadataTypes/{EmailSendDefinition.js → EmailSend.js} +5 -5
  37. package/lib/metadataTypes/{EventDefinition.js → Event.js} +17 -35
  38. package/lib/metadataTypes/{FtpLocation.js → FileLocation.js} +2 -2
  39. package/lib/metadataTypes/FileTransfer.js +8 -7
  40. package/lib/metadataTypes/Filter.js +1 -1
  41. package/lib/metadataTypes/Folder.js +8 -3
  42. package/lib/metadataTypes/ImportFile.js +6 -6
  43. package/lib/metadataTypes/{Interaction.js → Journey.js} +311 -147
  44. package/lib/metadataTypes/List.js +2 -2
  45. package/lib/metadataTypes/MetadataType.js +318 -90
  46. package/lib/metadataTypes/MobileCode.js +0 -1
  47. package/lib/metadataTypes/MobileKeyword.js +336 -40
  48. package/lib/metadataTypes/MobileMessage.js +473 -0
  49. package/lib/metadataTypes/Query.js +114 -32
  50. package/lib/metadataTypes/Role.js +60 -21
  51. package/lib/metadataTypes/Script.js +2 -3
  52. package/lib/metadataTypes/SendClassification.js +40 -0
  53. package/lib/metadataTypes/SetDefinition.js +1 -7
  54. package/lib/metadataTypes/TransactionalEmail.js +2 -3
  55. package/lib/metadataTypes/TransactionalMessage.js +1 -2
  56. package/lib/metadataTypes/TransactionalSMS.js +8 -15
  57. package/lib/metadataTypes/{TriggeredSendDefinition.js → TriggeredSend.js} +35 -27
  58. package/lib/metadataTypes/User.js +1185 -0
  59. package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
  60. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +1 -0
  61. package/lib/metadataTypes/definitions/Automation.definition.js +3 -2
  62. package/lib/metadataTypes/definitions/Campaign.definition.js +79 -4
  63. package/lib/metadataTypes/definitions/ContentArea.definition.js +1 -0
  64. package/lib/metadataTypes/definitions/DataExtension.definition.js +2 -1
  65. package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -0
  66. package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +1 -0
  67. package/lib/metadataTypes/definitions/DataExtract.definition.js +1 -0
  68. package/lib/metadataTypes/definitions/DataExtractType.definition.js +1 -0
  69. package/lib/metadataTypes/definitions/Discovery.definition.js +1 -0
  70. package/lib/metadataTypes/definitions/Email.definition.js +1 -0
  71. package/lib/metadataTypes/definitions/{EmailSendDefinition.definition.js → EmailSend.definition.js} +4 -2
  72. package/lib/metadataTypes/definitions/{EventDefinition.definition.js → Event.definition.js} +2 -1
  73. package/lib/metadataTypes/definitions/{FtpLocation.definition.js → FileLocation.definition.js} +4 -3
  74. package/lib/metadataTypes/definitions/FileTransfer.definition.js +3 -2
  75. package/lib/metadataTypes/definitions/Filter.definition.js +1 -0
  76. package/lib/metadataTypes/definitions/Folder.definition.js +2 -0
  77. package/lib/metadataTypes/definitions/ImportFile.definition.js +4 -3
  78. package/lib/metadataTypes/definitions/{Interaction.definition.js → Journey.definition.js} +11 -2
  79. package/lib/metadataTypes/definitions/List.definition.js +1 -0
  80. package/lib/metadataTypes/definitions/MobileCode.definition.js +3 -1
  81. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +27 -17
  82. package/lib/metadataTypes/definitions/MobileMessage.definition.js +743 -0
  83. package/lib/metadataTypes/definitions/Query.definition.js +3 -2
  84. package/lib/metadataTypes/definitions/Role.definition.js +5 -0
  85. package/lib/metadataTypes/definitions/Script.definition.js +1 -0
  86. package/lib/metadataTypes/definitions/SendClassification.definition.js +114 -0
  87. package/lib/metadataTypes/definitions/SetDefinition.definition.js +1 -0
  88. package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +2 -1
  89. package/lib/metadataTypes/definitions/TransactionalPush.definition.js +1 -0
  90. package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +1 -0
  91. package/lib/metadataTypes/definitions/{TriggeredSendDefinition.definition.js → TriggeredSend.definition.js} +5 -3
  92. package/lib/metadataTypes/definitions/User.definition.js +365 -0
  93. package/lib/retrieveChangelog.js +1 -2
  94. package/lib/util/auth.js +38 -9
  95. package/lib/util/businessUnit.js +3 -3
  96. package/lib/util/cli.js +55 -7
  97. package/lib/util/devops.js +6 -4
  98. package/lib/util/file.js +55 -13
  99. package/lib/util/init.config.js +1 -2
  100. package/lib/util/init.npm.js +3 -3
  101. package/lib/util/util.js +23 -14
  102. package/package.json +16 -15
  103. package/test/general.test.js +62 -0
  104. package/test/mockRoot/.mcdevrc.json +7 -5
  105. package/test/mockRoot/deploy/testInstance/_ParentBU_/user/testBlocked_user.user-meta.json +23 -0
  106. package/test/mockRoot/deploy/testInstance/_ParentBU_/user/testExisting_user.user-meta.json +31 -0
  107. package/test/mockRoot/deploy/testInstance/_ParentBU_/user/testNew_user.user-meta.json +27 -0
  108. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/{childBU_dataextension_test.dataExtension-meta.json → testExisting_dataExtension.dataExtension-meta.json} +2 -2
  109. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/{testDataExtension.dataExtension-meta.json → testNew_dataExtension.dataExtension-meta.json} +2 -2
  110. package/test/mockRoot/deploy/testInstance/testBU/journey/testExisting_interaction.interaction-meta.json +576 -0
  111. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/testNew_keyword.mobileKeyword-meta.amp +2 -0
  112. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/testNew_keyword.mobileKeyword-meta.json +10 -0
  113. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/testNew_keyword_blocked.mobileKeyword-meta.amp +2 -0
  114. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/testNew_keyword_blocked.mobileKeyword-meta.json +10 -0
  115. package/test/mockRoot/deploy/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.amp +1 -0
  116. package/test/mockRoot/deploy/testInstance/testBU/mobileMessage/NTIzOjc4OjA.mobileMessage-meta.json +61 -0
  117. package/test/mockRoot/deploy/testInstance/testBU/mobileMessage/new.mobileMessage-meta.amp +1 -0
  118. package/test/mockRoot/deploy/testInstance/testBU/mobileMessage/new.mobileMessage-meta.json +60 -0
  119. package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.json +1 -1
  120. package/test/mockRoot/deploy/testInstance/testBU/query/testNewQuery.query-meta.json +1 -1
  121. package/test/mockRoot/deploy/testInstance/testBU/query/testNewQuery.query-meta.sql +1 -1
  122. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +1 -1
  123. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testNew_temail.transactionalEmail-meta.json +1 -1
  124. package/test/resourceFactory.js +13 -0
  125. package/test/resources/1111111/accountUser/configure-response.xml +70 -0
  126. package/test/resources/1111111/accountUser/create-response.xml +97 -0
  127. package/test/resources/1111111/accountUser/retrieve-response.xml +156 -0
  128. package/test/resources/1111111/accountUser/update-response.xml +111 -0
  129. package/test/resources/1111111/accountUserAccount/retrieve-response.xml +77 -0
  130. package/test/resources/1111111/platform/v1/setup/quickflow/data/get-response.json +455 -0
  131. package/test/resources/1111111/role/retrieve-response.xml +76 -0
  132. package/test/resources/1111111/user/build-expected.json +16 -0
  133. package/test/resources/1111111/user/create-expected.json +21 -0
  134. package/test/resources/1111111/user/retrieve-expected.json +24 -0
  135. package/test/resources/1111111/user/template-expected.json +16 -0
  136. package/test/resources/1111111/user/update-expected.json +21 -0
  137. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/delete-response.json +1 -0
  138. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +17 -0
  139. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +3 -3
  140. package/test/resources/9999999/automation/v1/queries/get-response.json +21 -4
  141. package/test/resources/9999999/automation/v1/queries/post-response.json +4 -4
  142. package/test/resources/9999999/data/v1/customobjectdata/key/{childBU_dataextension_test → testExisting_dataExtension}/rowset/get-response.json +1 -1
  143. package/test/resources/9999999/dataExtension/build-expected.json +3 -3
  144. package/test/resources/9999999/dataExtension/create-expected.json +2 -2
  145. package/test/resources/9999999/dataExtension/create-response.xml +8 -3
  146. package/test/resources/9999999/dataExtension/retrieve-expected.json +3 -3
  147. package/test/resources/9999999/dataExtension/retrieve-response.xml +9 -4
  148. package/test/resources/9999999/dataExtension/template-expected.json +3 -3
  149. package/test/resources/9999999/dataExtension/update-expected.json +3 -3
  150. package/test/resources/9999999/dataExtension/update-response.xml +9 -4
  151. package/test/resources/9999999/dataExtensionField/retrieve-response.xml +14 -9
  152. package/test/resources/9999999/interaction/v1/interactions/get-response.json +312 -0
  153. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_interaction/get-response.json +312 -0
  154. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_interaction/put-response.json +592 -0
  155. package/test/resources/9999999/journey/build-expected.json +572 -0
  156. package/test/resources/9999999/journey/get-expected.json +576 -0
  157. package/test/resources/9999999/journey/put-expected.json +576 -0
  158. package/test/resources/9999999/journey/template-expected.json +572 -0
  159. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow/get-response.json +42 -0
  160. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/cTVJaG5oSDJPVUNHcUh6Z3pQT2tVdzo4Njow/delete-response.json +0 -0
  161. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/get-response.json +1 -0
  162. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/post-response.json +3 -0
  163. package/test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/delete-response.json +0 -0
  164. package/test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/get-response.json +106 -0
  165. package/test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/post-response.json +0 -0
  166. package/test/resources/9999999/legacy/v1/beta/mobile/message/NTQ3Ojc4OjA/get-response.json +127 -0
  167. package/test/resources/9999999/legacy/v1/beta/mobile/message/get-response.json +129 -0
  168. package/test/resources/9999999/legacy/v1/beta/mobile/message/post-response.json +3 -0
  169. package/test/resources/9999999/legacy/v1/beta2/data/campaign/get-response.json +29 -0
  170. package/test/resources/9999999/messaging/v1/email/definitions/post-response.json +1 -1
  171. package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/get-response.json +1 -1
  172. package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/patch-response.json +1 -1
  173. package/test/resources/9999999/mobileKeyword/build-expected.amp +2 -0
  174. package/test/resources/9999999/mobileKeyword/build-expected.json +9 -0
  175. package/test/resources/9999999/mobileKeyword/get-expected.amp +2 -0
  176. package/test/resources/9999999/mobileKeyword/get-expected.json +15 -0
  177. package/test/resources/9999999/mobileKeyword/post-create-expected.amp +2 -0
  178. package/test/resources/9999999/mobileKeyword/post-create-expected.json +17 -0
  179. package/test/resources/9999999/mobileKeyword/template-expected.amp +2 -0
  180. package/test/resources/9999999/mobileKeyword/template-expected.json +9 -0
  181. package/test/resources/9999999/mobileMessage/build-expected.amp +1 -0
  182. package/test/resources/9999999/mobileMessage/build-expected.json +60 -0
  183. package/test/resources/9999999/mobileMessage/get-expected.amp +1 -0
  184. package/test/resources/9999999/mobileMessage/get-expected.json +61 -0
  185. package/test/resources/9999999/mobileMessage/post-create-expected.amp +1 -0
  186. package/test/resources/9999999/mobileMessage/post-create-expected.json +63 -0
  187. package/test/resources/9999999/mobileMessage/post-update-expected.amp +1 -0
  188. package/test/resources/9999999/mobileMessage/post-update-expected.json +61 -0
  189. package/test/resources/9999999/mobileMessage/template-expected.amp +1 -0
  190. package/test/resources/9999999/mobileMessage/template-expected.json +60 -0
  191. package/test/resources/9999999/query/build-expected.json +1 -1
  192. package/test/resources/9999999/query/get-expected.json +1 -1
  193. package/test/resources/9999999/query/get2-expected.json +11 -0
  194. package/test/resources/9999999/query/patch-expected.json +1 -1
  195. package/test/resources/9999999/query/post-expected.json +1 -1
  196. package/test/resources/9999999/query/template-expected.json +1 -1
  197. package/test/resources/9999999/queryDefinition/retrieve-response.xml +30 -0
  198. package/test/resources/9999999/transactionalEmail/build-expected.json +5 -5
  199. package/test/resources/9999999/transactionalEmail/get-expected.json +1 -1
  200. package/test/resources/9999999/transactionalEmail/patch-expected.json +1 -1
  201. package/test/resources/9999999/transactionalEmail/post-expected.json +1 -1
  202. package/test/resources/9999999/transactionalEmail/template-expected.json +5 -5
  203. package/test/resources/9999999/transactionalPush/build-expected.json +2 -2
  204. package/test/resources/9999999/transactionalPush/template-expected.json +2 -2
  205. package/test/resources/9999999/transactionalSMS/build-expected.json +3 -3
  206. package/test/resources/9999999/transactionalSMS/template-expected.json +3 -3
  207. package/test/{dataExtension.test.js → type.dataExtension.test.js} +78 -21
  208. package/test/{interaction.test.js → type.journey.test.js} +64 -30
  209. package/test/type.mobileKeyword.test.js +250 -0
  210. package/test/type.mobileMessage.test.js +205 -0
  211. package/test/{query.test.js → type.query.test.js} +102 -5
  212. package/test/{transactionalEmail.test.js → type.transactionalEmail.test.js} +40 -2
  213. package/test/{transactionalPush.test.js → type.transactionalPush.test.js} +41 -2
  214. package/test/{transactionalSMS.test.js → type.transactionalSMS.test.js} +73 -3
  215. package/test/type.user.test.js +160 -0
  216. package/test/utils.js +17 -5
  217. package/types/mcdev.d.js +48 -15
  218. package/.github/workflows/code-analysis.yml +0 -57
  219. package/lib/metadataTypes/AccountUser.js +0 -426
  220. package/lib/metadataTypes/definitions/AccountUser.definition.js +0 -227
  221. package/test/mockRoot/deploy/testInstance/testBU/interaction/testExisting_interaction.interaction-meta.json +0 -266
  222. package/test/resources/9999999/interaction/build-expected.json +0 -260
  223. package/test/resources/9999999/interaction/get-expected.json +0 -264
  224. package/test/resources/9999999/interaction/put-expected.json +0 -264
  225. package/test/resources/9999999/interaction/template-expected.json +0 -260
  226. package/test/resources/9999999/interaction/v1/interactions/put-response.json +0 -280
  227. /package/test/mockRoot/deploy/testInstance/testBU/{interaction → journey}/testNew_interaction.interaction-meta.json +0 -0
  228. /package/test/resources/9999999/{interaction → journey}/post-expected.json +0 -0
package/lib/Builder.js CHANGED
@@ -206,7 +206,12 @@ saved
206
206
  if (!(await config.checkProperties(properties))) {
207
207
  return null;
208
208
  }
209
- Util.verifyMarketList(listName, properties);
209
+ try {
210
+ Util.verifyMarketList(listName, properties);
211
+ } catch (ex) {
212
+ Util.logger.error(ex.message);
213
+ return;
214
+ }
210
215
  if (type && !MetadataTypeInfo[type]) {
211
216
  Util.logger.error(`:: '${type}' is not a valid metadata type`);
212
217
  return;
package/lib/Deployer.js CHANGED
@@ -80,6 +80,10 @@ class Deployer {
80
80
  }
81
81
  let counter_credBu = 0;
82
82
  if (businessUnit === '*') {
83
+ if (Util.OPTIONS.changeKeyValue) {
84
+ Util.logger.error('--changeKeyValue is not supported for deployments to all BUs');
85
+ return;
86
+ }
83
87
  // all credentials and all BUs shall be deployed to
84
88
  const deployFolders = await File.readDirectories(
85
89
  properties.directories.deploy,
@@ -127,6 +131,12 @@ class Deployer {
127
131
  }
128
132
 
129
133
  if (bu === '*' && properties.credentials && properties.credentials[cred]) {
134
+ if (Util.OPTIONS.changeKeyValue) {
135
+ Util.logger.error(
136
+ '--changeKeyValue is not supported for deployments to all BUs'
137
+ );
138
+ return;
139
+ }
130
140
  // valid credential given and -all- BUs targeted
131
141
  Util.logger.info(`\n :: Deploying all BUs for ${cred}`);
132
142
  let counter_credBu = 0;
@@ -183,7 +193,7 @@ class Deployer {
183
193
  */
184
194
  static async _deployBU(cred, bu, properties, typeArr, keyArr, fromRetrieve) {
185
195
  const buPath = `${cred}/${bu}`;
186
- Util.logger.info(`::Deploying ${buPath}`);
196
+ Util.logger.info(`:: Deploying to ${buPath}`);
187
197
  const buObject = await Cli.getCredentialObject(properties, buPath, null, true);
188
198
  let multiMetadataTypeMap;
189
199
 
@@ -206,13 +216,16 @@ class Deployer {
206
216
  * @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type (can include subtype)
207
217
  * @param {string[]} [keyArr] limit deployment to given metadata keys
208
218
  * @param {boolean} [fromRetrieve] if true, no folders will be updated/created
219
+ * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets
209
220
  * @returns {Promise.<TYPE.MultiMetadataTypeMap>} Promise of all deployed metadata
210
221
  */
211
- async _deploy(typeArr, keyArr, fromRetrieve) {
222
+ async _deploy(typeArr, keyArr, fromRetrieve, isRefresh) {
212
223
  if (await File.pathExists(this.deployDir)) {
213
224
  /** @type {TYPE.MultiMetadataTypeMap} */
214
225
  this.metadata = Deployer.readBUMetadata(this.deployDir, typeArr);
215
- if (typeArr) {
226
+
227
+ // filter found metadata by key if given
228
+ if (typeArr && Array.isArray(keyArr)) {
216
229
  for (const selectedType of typeArr) {
217
230
  const type = selectedType.split('-')[0];
218
231
  this.metadata[type] = Util.filterObjByKeys(this.metadata[type], keyArr);
@@ -221,14 +234,25 @@ class Deployer {
221
234
  } else {
222
235
  this.metadata = null;
223
236
  Util.logger.error(
224
- 'Deployer.constructor:: Please create a directory called deploy and include your metadata in it: ./' +
237
+ 'Please create a directory called deploy and include your metadata in it: ' +
225
238
  this.deployDir
226
239
  );
240
+ return null;
227
241
  }
228
242
  if (this.metadata === null || !Object.keys(this.metadata).length) {
229
243
  Util.logger.error('No metadata found in deploy folder for selected BU');
230
244
  return null;
231
245
  }
246
+ if (Util.OPTIONS.changeKeyValue && Object.keys(this.metadata).length) {
247
+ if (Object.keys(this.metadata).length > 1) {
248
+ Util.logger.error('--changeKeyValue expects a single type to be deployed');
249
+ return null;
250
+ } else if (Object.keys(Object.values(this.metadata)[0]).length > 1) {
251
+ Util.logger.error('--changeKeyValue expects a single key to be deployed');
252
+ return null;
253
+ }
254
+ }
255
+
232
256
  if (!fromRetrieve) {
233
257
  await Deployer.createFolderDefinitions(
234
258
  this.deployDir,
@@ -274,7 +298,8 @@ class Deployer {
274
298
  const result = await MetadataTypeInfo[type].deploy(
275
299
  this.metadata[type],
276
300
  this.deployDir,
277
- this.retrieveDir
301
+ this.retrieveDir,
302
+ isRefresh
278
303
  );
279
304
  multiMetadataTypeMap[type] = result;
280
305
  cache.mergeMetadata(type, result);
@@ -4,7 +4,6 @@
4
4
  * Provides access to all metadataType classes
5
5
  */
6
6
  const MetadataTypeDefinitions = {
7
- accountUser: require('./metadataTypes/definitions/AccountUser.definition'),
8
7
  asset: require('./metadataTypes/definitions/Asset.definition'),
9
8
  attributeGroup: require('./metadataTypes/definitions/AttributeGroup.definition'),
10
9
  automation: require('./metadataTypes/definitions/Automation.definition'),
@@ -17,25 +16,28 @@ const MetadataTypeDefinitions = {
17
16
  dataExtractType: require('./metadataTypes/definitions/DataExtractType.definition'),
18
17
  discovery: require('./metadataTypes/definitions/Discovery.definition'),
19
18
  email: require('./metadataTypes/definitions/Email.definition'),
20
- emailSendDefinition: require('./metadataTypes/definitions/EmailSendDefinition.definition'),
21
- eventDefinition: require('./metadataTypes/definitions/EventDefinition.definition'),
19
+ emailSend: require('./metadataTypes/definitions/EmailSend.definition'),
20
+ event: require('./metadataTypes/definitions/Event.definition'),
21
+ fileLocation: require('./metadataTypes/definitions/FileLocation.definition'),
22
22
  fileTransfer: require('./metadataTypes/definitions/FileTransfer.definition'),
23
23
  filter: require('./metadataTypes/definitions/Filter.definition'),
24
24
  folder: require('./metadataTypes/definitions/Folder.definition'),
25
- ftpLocation: require('./metadataTypes/definitions/FtpLocation.definition'),
26
25
  importFile: require('./metadataTypes/definitions/ImportFile.definition'),
27
- interaction: require('./metadataTypes/definitions/Interaction.definition'),
26
+ journey: require('./metadataTypes/definitions/Journey.definition'),
28
27
  list: require('./metadataTypes/definitions/List.definition'),
29
28
  mobileCode: require('./metadataTypes/definitions/MobileCode.definition'),
30
29
  mobileKeyword: require('./metadataTypes/definitions/MobileKeyword.definition'),
30
+ mobileMessage: require('./metadataTypes/definitions/MobileMessage.definition'),
31
31
  query: require('./metadataTypes/definitions/Query.definition'),
32
32
  role: require('./metadataTypes/definitions/Role.definition'),
33
33
  script: require('./metadataTypes/definitions/Script.definition'),
34
+ sendClassification: require('./metadataTypes/definitions/SendClassification.definition'),
34
35
  setDefinition: require('./metadataTypes/definitions/SetDefinition.definition'),
35
36
  transactionalEmail: require('./metadataTypes/definitions/TransactionalEmail.definition'),
36
37
  transactionalPush: require('./metadataTypes/definitions/TransactionalPush.definition'),
37
38
  transactionalSMS: require('./metadataTypes/definitions/TransactionalSMS.definition'),
38
- triggeredSendDefinition: require('./metadataTypes/definitions/TriggeredSendDefinition.definition'),
39
+ triggeredSend: require('./metadataTypes/definitions/TriggeredSend.definition'),
40
+ user: require('./metadataTypes/definitions/User.definition'),
39
41
  };
40
42
 
41
43
  module.exports = MetadataTypeDefinitions;
@@ -4,7 +4,6 @@
4
4
  * Provides access to all metadataType classes
5
5
  */
6
6
  const MetadataTypeInfo = {
7
- accountUser: require('./metadataTypes/AccountUser'),
8
7
  asset: require('./metadataTypes/Asset'),
9
8
  attributeGroup: require('./metadataTypes/AttributeGroup'),
10
9
  automation: require('./metadataTypes/Automation'),
@@ -17,25 +16,28 @@ const MetadataTypeInfo = {
17
16
  dataExtractType: require('./metadataTypes/DataExtractType'),
18
17
  discovery: require('./metadataTypes/Discovery'),
19
18
  email: require('./metadataTypes/Email'),
20
- emailSendDefinition: require('./metadataTypes/EmailSendDefinition'),
21
- eventDefinition: require('./metadataTypes/EventDefinition'),
19
+ emailSend: require('./metadataTypes/EmailSend'),
20
+ event: require('./metadataTypes/Event'),
21
+ fileLocation: require('./metadataTypes/FileLocation'),
22
22
  fileTransfer: require('./metadataTypes/FileTransfer'),
23
23
  filter: require('./metadataTypes/Filter'),
24
24
  folder: require('./metadataTypes/Folder'),
25
- ftpLocation: require('./metadataTypes/FtpLocation'),
26
25
  importFile: require('./metadataTypes/ImportFile'),
27
- interaction: require('./metadataTypes/Interaction'),
26
+ journey: require('./metadataTypes/Journey'),
28
27
  list: require('./metadataTypes/List'),
29
28
  mobileCode: require('./metadataTypes/MobileCode'),
30
29
  mobileKeyword: require('./metadataTypes/MobileKeyword'),
30
+ mobileMessage: require('./metadataTypes/MobileMessage'),
31
31
  query: require('./metadataTypes/Query'),
32
32
  role: require('./metadataTypes/Role'),
33
33
  script: require('./metadataTypes/Script'),
34
+ sendClassification: require('./metadataTypes/SendClassification'),
34
35
  setDefinition: require('./metadataTypes/SetDefinition'),
35
36
  transactionalEmail: require('./metadataTypes/TransactionalEmail'),
36
37
  transactionalPush: require('./metadataTypes/TransactionalPush'),
37
38
  transactionalSMS: require('./metadataTypes/TransactionalSMS'),
38
- triggeredSendDefinition: require('./metadataTypes/TriggeredSendDefinition'),
39
+ triggeredSend: require('./metadataTypes/TriggeredSend'),
40
+ user: require('./metadataTypes/User'),
39
41
  };
40
42
 
41
43
  module.exports = MetadataTypeInfo;
package/lib/cli.js CHANGED
@@ -34,13 +34,12 @@ yargs
34
34
  });
35
35
  },
36
36
  handler: (argv) => {
37
- Mcdev.setSkipInteraction(argv.skipInteraction);
38
- Mcdev.setLoggingLevel(argv);
37
+ Mcdev.setOptions(argv);
39
38
  Mcdev.retrieve(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY));
40
39
  },
41
40
  })
42
41
  .command({
43
- command: 'deploy [BU] [TYPE] [KEY] [fromRetrieve]',
42
+ command: 'deploy [BU] [TYPE] [KEY] [--fromRetrieve] [--refresh]',
44
43
  aliases: ['d'],
45
44
  desc: 'deploys local metadata to a business unit',
46
45
  builder: (yargs) => {
@@ -58,14 +57,29 @@ yargs
58
57
  type: 'string',
59
58
  describe: 'metadata key that shall be exclusively uploaded',
60
59
  })
61
- .positional('fromRetrieve', {
60
+ .option('changeKeyField', {
62
61
  type: 'string',
62
+ describe:
63
+ 'enables updating the key of the deployed metadata with the value in provided field (e.g. c__newKey). Can be used to sync name and key fields.',
64
+ })
65
+ .option('changeKeyValue', {
66
+ type: 'string',
67
+ describe:
68
+ 'allows updating the key of the metadata to the provided value. Only available if a single type and key is deployed',
69
+ })
70
+ .option('fromRetrieve', {
71
+ type: 'boolean',
63
72
  describe: 'optionally deploy from retrieve folder',
73
+ })
74
+ .option('refresh', {
75
+ type: 'boolean',
76
+ describe:
77
+ 'optional for asset-message: runs refresh command for related triggeredSends after deploy',
64
78
  });
65
79
  },
66
80
  handler: (argv) => {
67
- Mcdev.setSkipInteraction(argv.skipInteraction);
68
- Mcdev.setLoggingLevel(argv);
81
+ Mcdev.setOptions(argv);
82
+
69
83
  Mcdev.deploy(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY), argv.fromRetrieve);
70
84
  },
71
85
  })
@@ -79,8 +93,7 @@ yargs
79
93
  });
80
94
  },
81
95
  handler: (argv) => {
82
- Mcdev.setSkipInteraction(argv.skipInteraction);
83
- Mcdev.setLoggingLevel(argv);
96
+ Mcdev.setOptions(argv);
84
97
  Mcdev.initProject(argv.credentialsName);
85
98
  },
86
99
  })
@@ -88,8 +101,7 @@ yargs
88
101
  command: 'join',
89
102
  desc: `clones an existing project from git`,
90
103
  handler: (argv) => {
91
- Mcdev.setSkipInteraction(argv.skipInteraction);
92
- Mcdev.setLoggingLevel(argv);
104
+ Mcdev.setOptions(argv);
93
105
  Mcdev.joinProject();
94
106
  },
95
107
  })
@@ -104,8 +116,7 @@ yargs
104
116
  });
105
117
  },
106
118
  handler: (argv) => {
107
- Mcdev.setSkipInteraction(argv.skipInteraction);
108
- Mcdev.setLoggingLevel(argv);
119
+ Mcdev.setOptions(argv);
109
120
  Mcdev.findBUs(argv.credentialsName);
110
121
  },
111
122
  })
@@ -119,8 +130,7 @@ yargs
119
130
  });
120
131
  },
121
132
  handler: (argv) => {
122
- Mcdev.setSkipInteraction(argv.skipInteraction);
123
- Mcdev.setLoggingLevel(argv);
133
+ Mcdev.setOptions(argv);
124
134
  Mcdev.badKeys(argv.BU);
125
135
  },
126
136
  })
@@ -142,8 +152,7 @@ yargs
142
152
  });
143
153
  },
144
154
  handler: (argv) => {
145
- Mcdev.setSkipInteraction(argv.skipInteraction);
146
- Mcdev.setLoggingLevel(argv);
155
+ Mcdev.setOptions(argv);
147
156
  Mcdev.document(argv.BU, argv.TYPE);
148
157
  },
149
158
  })
@@ -168,8 +177,7 @@ yargs
168
177
  });
169
178
  },
170
179
  handler: (argv) => {
171
- Mcdev.setSkipInteraction(argv.skipInteraction);
172
- Mcdev.setLoggingLevel(argv);
180
+ Mcdev.setOptions(argv);
173
181
  Mcdev.deleteByKey(argv.BU, argv.TYPE, argv.EXTERNALKEY);
174
182
  },
175
183
  })
@@ -198,8 +206,7 @@ yargs
198
206
  });
199
207
  },
200
208
  handler: (argv) => {
201
- Mcdev.setSkipInteraction(argv.skipInteraction);
202
- Mcdev.setLoggingLevel(argv);
209
+ Mcdev.setOptions(argv);
203
210
  Mcdev.retrieveAsTemplate(argv.BU, argv.TYPE, csvToArray(argv.NAME), argv.MARKET);
204
211
  },
205
212
  })
@@ -228,8 +235,7 @@ yargs
228
235
  });
229
236
  },
230
237
  handler: (argv) => {
231
- Mcdev.setSkipInteraction(argv.skipInteraction);
232
- Mcdev.setLoggingLevel(argv);
238
+ Mcdev.setOptions(argv);
233
239
  Mcdev.buildTemplate(argv.BU, argv.TYPE, csvToArray(argv.KEY), argv.MARKET);
234
240
  },
235
241
  })
@@ -257,8 +263,7 @@ yargs
257
263
  });
258
264
  },
259
265
  handler: (argv) => {
260
- Mcdev.setSkipInteraction(argv.skipInteraction);
261
- Mcdev.setLoggingLevel(argv);
266
+ Mcdev.setOptions(argv);
262
267
  Mcdev.buildDefinition(argv.BU, argv.TYPE, argv.NAME, argv.MARKET);
263
268
  },
264
269
  })
@@ -282,8 +287,7 @@ yargs
282
287
  });
283
288
  },
284
289
  handler: (argv) => {
285
- Mcdev.setSkipInteraction(argv.skipInteraction);
286
- Mcdev.setLoggingLevel(argv);
290
+ Mcdev.setOptions(argv);
287
291
  Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, argv.NAME);
288
292
  },
289
293
  })
@@ -292,8 +296,7 @@ yargs
292
296
  aliases: ['st'],
293
297
  desc: 'lets you choose what metadata types to retrieve',
294
298
  handler: (argv) => {
295
- Mcdev.setSkipInteraction(argv.skipInteraction);
296
- Mcdev.setLoggingLevel(argv);
299
+ Mcdev.setOptions(argv);
297
300
  Mcdev.selectTypes();
298
301
  },
299
302
  })
@@ -301,14 +304,19 @@ yargs
301
304
  command: 'explainTypes',
302
305
  aliases: ['et'],
303
306
  desc: 'explains metadata types that can be retrieved',
307
+ builder: (yargs) => {
308
+ yargs.option('json', {
309
+ type: 'boolean',
310
+ describe: 'optionaly return info in json format',
311
+ });
312
+ },
304
313
  handler: (argv) => {
305
- Mcdev.setSkipInteraction(argv.skipInteraction);
306
- Mcdev.setLoggingLevel(argv);
314
+ Mcdev.setOptions(argv);
307
315
  Mcdev.explainTypes();
308
316
  },
309
317
  })
310
318
  .command({
311
- command: 'createDeltaPkg [range] [filter]',
319
+ command: 'createDeltaPkg [range] [--filter <BU>] [--commitHistory <number>]',
312
320
  aliases: ['cdp'],
313
321
  desc: 'Copies commit-based file delta into deploy folder',
314
322
  builder: (yargs) => {
@@ -317,15 +325,18 @@ yargs
317
325
  type: 'string',
318
326
  describe: 'Pull Request target branch or git commit range',
319
327
  })
320
- .positional('filter', {
328
+ .option('filter', {
321
329
  type: 'string',
322
330
  describe:
323
- 'Disable templating & instead filter by the specified file path (comma separated)',
331
+ 'Disable templating & instead filter by the specified BU path (comma separated), can include subtype, will be prefixed with "retrieve/"',
332
+ })
333
+ .option('commitHistory', {
334
+ type: 'number',
335
+ describe: 'Number of commits to look back for changes (supersedes config)',
324
336
  });
325
337
  },
326
338
  handler: (argv) => {
327
- Mcdev.setSkipInteraction(argv.skipInteraction);
328
- Mcdev.setLoggingLevel(argv);
339
+ Mcdev.setOptions(argv);
329
340
  Mcdev.createDeltaPkg(argv);
330
341
  },
331
342
  })
@@ -350,8 +361,7 @@ yargs
350
361
  });
351
362
  },
352
363
  handler: (argv) => {
353
- Mcdev.setSkipInteraction(argv.skipInteraction);
354
- Mcdev.setLoggingLevel(argv);
364
+ Mcdev.setOptions(argv);
355
365
  Mcdev.getFilesToCommit(argv.BU, argv.TYPE, csvToArray(argv.KEY));
356
366
  },
357
367
  })
@@ -375,8 +385,7 @@ yargs
375
385
  });
376
386
  },
377
387
  handler: (argv) => {
378
- Mcdev.setSkipInteraction(argv.skipInteraction);
379
- Mcdev.setLoggingLevel(argv);
388
+ Mcdev.setOptions(argv);
380
389
  Mcdev.refresh(argv.BU, argv.TYPE, csvToArray(argv.KEY));
381
390
  },
382
391
  })
@@ -385,8 +394,7 @@ yargs
385
394
  aliases: ['up'],
386
395
  desc: 'Add NPM dependencies and IDE configuration files to your project',
387
396
  handler: (argv) => {
388
- Mcdev.setSkipInteraction(argv.skipInteraction);
389
- Mcdev.setLoggingLevel(argv);
397
+ Mcdev.setOptions(argv);
390
398
  Mcdev.upgrade(argv.skipInteraction);
391
399
  },
392
400
  })
@@ -406,12 +414,16 @@ yargs
406
414
  alias: ['yes', 'y'],
407
415
  description: 'Interactive questions where possible and go with defaults instead',
408
416
  })
417
+ .option('api', {
418
+ description: 'Print API calls to log ',
419
+ choices: ['log', 'cli'],
420
+ })
409
421
  .demandCommand(1, 'Please enter a valid command')
410
422
  .strict()
411
423
  .recommendCommands()
412
424
  .wrap(yargs.terminalWidth())
413
425
  .epilog(
414
- 'Copyright 2022. Accenture. Get support at https://github.com/Accenture/sfmc-devtools/issues'
426
+ 'Copyright 2023. Accenture. Get support at https://github.com/Accenture/sfmc-devtools/issues'
415
427
  )
416
428
  .help().argv;
417
429
 
package/lib/index.js CHANGED
@@ -42,6 +42,42 @@ class Mcdev {
42
42
  static setLoggingLevel(argv) {
43
43
  Util.setLoggingLevel(argv);
44
44
  }
45
+ /**
46
+ * allows setting system wide / command related options
47
+ *
48
+ * @param {object} argv list of command line parameters given by user
49
+ * @returns {void}
50
+ */
51
+ static setOptions(argv) {
52
+ const knownOptions = [
53
+ 'api',
54
+ 'commitHistory',
55
+ 'changeKeyField',
56
+ 'changeKeyValue',
57
+ 'filter',
58
+ 'fromRetrieve',
59
+ 'json',
60
+ 'refresh',
61
+ 'skipInteraction',
62
+ ];
63
+ for (const option of knownOptions) {
64
+ if (argv[option] !== undefined) {
65
+ Util.OPTIONS[option] = argv[option];
66
+ }
67
+ }
68
+ // set logging level
69
+ const loggingOptions = ['silent', 'verbose', 'debug'];
70
+ for (const option of loggingOptions) {
71
+ if (argv[option] !== undefined) {
72
+ this.setLoggingLevel(argv);
73
+ break;
74
+ }
75
+ }
76
+ // set skip interaction
77
+ if (argv.skipInteraction !== undefined) {
78
+ this.setSkipInteraction(argv.skipInteraction);
79
+ }
80
+ }
45
81
  /**
46
82
  * handler for 'mcdev createDeltaPkg
47
83
  *
@@ -61,9 +97,14 @@ class Mcdev {
61
97
 
62
98
  return argv.filter
63
99
  ? // get source market and source BU from config
64
- DevOps.getDeltaList(properties, argv.range, true, argv.filter)
100
+ DevOps.getDeltaList(properties, argv.range, true, argv.filter, argv.commitHistory)
65
101
  : // If no custom filter was provided, use deployment marketLists & templating
66
- DevOps.buildDeltaDefinitions(properties, argv.range, argv.diffArr);
102
+ DevOps.buildDeltaDefinitions(
103
+ properties,
104
+ argv.range,
105
+ argv.diffArr,
106
+ argv.commitHistory
107
+ );
67
108
  }
68
109
 
69
110
  /**
@@ -77,10 +118,10 @@ class Mcdev {
77
118
  await Cli.selectTypes(properties);
78
119
  }
79
120
  /**
80
- * @returns {void}
121
+ * @returns {object[]} list of supported types with their apiNames
81
122
  */
82
123
  static explainTypes() {
83
- Cli.explainTypes();
124
+ return Cli.explainTypes();
84
125
  }
85
126
  /**
86
127
  * @returns {Promise.<boolean>} success flag
@@ -214,6 +255,15 @@ class Mcdev {
214
255
  cache.initCache(buObject);
215
256
  cred = buObject.credential;
216
257
  bu = buObject.businessUnit;
258
+ // clean up old folders after types were renamed
259
+ // TODO: Remove this with version 5.0.0
260
+ const renamedTypes = {
261
+ emailSend: 'emailSendDefinition',
262
+ event: 'eventDefinition',
263
+ fileLocation: 'ftpLocation',
264
+ triggeredSend: 'triggeredSendDefinition',
265
+ user: 'accountUser',
266
+ };
217
267
  Util.logger.info(`\n :: Retrieving ${cred}/${bu}\n`);
218
268
  const retrieveTypesArr = [];
219
269
  if (selectedTypesArr) {
@@ -238,6 +288,18 @@ class Mcdev {
238
288
  if (!keys) {
239
289
  // dont delete directories if we are just re-retrieving a single file
240
290
  await File.remove(File.normalizePath(removePathArr));
291
+ // clean up old folders after types were renamed
292
+ // TODO: Remove this with version 5.0.0
293
+ if (renamedTypes[type]) {
294
+ await File.remove(
295
+ File.normalizePath([
296
+ properties.directories.retrieve,
297
+ cred,
298
+ bu,
299
+ renamedTypes[type],
300
+ ])
301
+ );
302
+ }
241
303
  }
242
304
  }
243
305
  }
@@ -249,6 +311,15 @@ class Mcdev {
249
311
  retrieveTypesArr.push(
250
312
  ...new Set(properties.metaDataTypes.retrieve.map((type) => type.split('-')[0]))
251
313
  );
314
+ for (const selectedType of retrieveTypesArr) {
315
+ const test = Util._isValidType(selectedType);
316
+ if (!test) {
317
+ Util.logger.error(
318
+ `Please remove the type ${selectedType} from your ${Util.configFileName}`
319
+ );
320
+ return;
321
+ }
322
+ }
252
323
  }
253
324
  const retriever = new Retriever(properties, buObject);
254
325
 
@@ -339,7 +410,7 @@ class Mcdev {
339
410
  return;
340
411
  }
341
412
  try {
342
- const parentBUOnlyTypes = ['accountUser', 'role'];
413
+ const parentBUOnlyTypes = ['user', 'role'];
343
414
  const buObject = await Cli.getCredentialObject(
344
415
  properties,
345
416
  parentBUOnlyTypes.includes(type) ? businessUnit.split('/')[0] : businessUnit,
@@ -365,7 +436,7 @@ class Mcdev {
365
436
  * @param {string} businessUnit references credentials from properties.json
366
437
  * @param {string} type supported metadata type
367
438
  * @param {string} customerKey Identifier of metadata
368
- * @returns {Promise.<void>} -
439
+ * @returns {Promise.<boolean>} true if successful, false otherwise
369
440
  */
370
441
  static async deleteByKey(businessUnit, type, customerKey) {
371
442
  Util.logger.info('mcdev:: delete');
@@ -384,10 +455,13 @@ class Mcdev {
384
455
  Util.logger.error(ex.message);
385
456
  return;
386
457
  }
458
+ Util.logger.info(
459
+ Util.getGrayMsg(` - Deleting ${type} with key ${customerKey} on BU ${businessUnit}`)
460
+ );
387
461
  try {
388
462
  MetadataTypeInfo[type].properties = properties;
389
463
  MetadataTypeInfo[type].buObject = buObject;
390
- await MetadataTypeInfo[type].deleteByKey(customerKey);
464
+ return await MetadataTypeInfo[type].deleteByKey(customerKey);
391
465
  } catch (ex) {
392
466
  Util.logger.errorStack(ex, ` - Deleting ${type} failed`);
393
467
  }
@@ -404,7 +478,7 @@ class Mcdev {
404
478
  static async refresh(businessUnit, type, keyArr) {
405
479
  Util.logger.info('mcdev:: refresh');
406
480
  if (!type || !Util._isValidType(type, true)) {
407
- type = 'triggeredSendDefinition';
481
+ type = 'triggeredSend';
408
482
  Util.logger.info(' - setting type to ' + type);
409
483
  }
410
484
  const properties = await config.getProperties();