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
@@ -7,14 +7,14 @@
7
7
  * in the generic version of the method
8
8
  */
9
9
 
10
- const TYPE = require('../../types/mcdev.d');
11
- const Util = require('../util/util');
12
- const File = require('../util/file');
13
- const cache = require('../util/cache');
14
-
15
- const deepEqual = require('deep-equal');
16
- const pLimit = require('p-limit');
17
- const Mustache = require('mustache');
10
+ import TYPE from '../../types/mcdev.d.js';
11
+
12
+ import { Util } from '../util/util.js';
13
+ import File from '../util/file.js';
14
+ import cache from '../util/cache.js';
15
+ import deepEqual from 'deep-equal';
16
+ import pLimit from 'p-limit';
17
+ import Mustache from 'mustache';
18
18
  /**
19
19
  * ensure that Mustache does not escape any characters
20
20
  *
@@ -139,9 +139,10 @@ class MetadataType {
139
139
  *
140
140
  * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry
141
141
  * @param {object} apiResponse varies depending on the API call
142
+ * @param {TYPE.MetadataTypeItem} metadataEntryWithAllFields like metadataEntry but before non-creatable fields were stripped
142
143
  * @returns {void}
143
144
  */
144
- static postCreateTasks(metadataEntry, apiResponse) {}
145
+ static postCreateTasks(metadataEntry, apiResponse, metadataEntryWithAllFields) {}
145
146
 
146
147
  /**
147
148
  * helper for {@link MetadataType.updateREST}
@@ -265,11 +266,10 @@ class MetadataType {
265
266
  *
266
267
  * @param {string[]} [additionalFields] Returns specified fields even if their retrieve definition is not set to true
267
268
  * @param {string[]} [subTypeArr] optionally limit to a single subtype
268
- * @param {string} [key] customer key of single item to retrieve
269
269
  * @returns {Promise.<TYPE.MetadataTypeMapObj>} metadata
270
270
  */
271
- static async retrieveForCache(additionalFields, subTypeArr, key) {
272
- return this.retrieve(null, additionalFields, subTypeArr, key);
271
+ static async retrieveForCache(additionalFields, subTypeArr) {
272
+ return this.retrieve(null, additionalFields, subTypeArr);
273
273
  }
274
274
  /**
275
275
  * Gets metadata cache with limited fields and does not store value to disk
@@ -808,11 +808,12 @@ class MetadataType {
808
808
  * @returns {Promise.<object> | null} Promise of API response or null in case of an error
809
809
  */
810
810
  static async createREST(metadataEntry, uri) {
811
+ const metadataClone = JSON.parse(JSON.stringify(metadataEntry));
811
812
  this.removeNotCreateableFields(metadataEntry);
812
813
  try {
813
814
  // set to empty object in case API returned nothing to be able to update it in helper classes
814
815
  const response = (await this.client.rest.post(uri, metadataEntry)) || {};
815
- await this.postCreateTasks(metadataEntry, response);
816
+ await this.postCreateTasks(metadataEntry, response, metadataClone);
816
817
  Util.logger.info(
817
818
  ` - created ${this.definition.type}: ${
818
819
  metadataEntry[this.definition.keyField] ||
@@ -1060,6 +1061,7 @@ class MetadataType {
1060
1061
  const results = this.parseResponseBody(response, singleRetrieve);
1061
1062
  // get extended metadata if applicable
1062
1063
  if (this.definition.hasExtended) {
1064
+ Util.logger.debug(' - retrieving extended metadata');
1063
1065
  const extended = await this.client.rest.getCollection(
1064
1066
  Object.keys(results).map((key) => uri + results[key][this.definition.idField])
1065
1067
  );
@@ -1088,6 +1090,62 @@ class MetadataType {
1088
1090
  type: this.definition.type,
1089
1091
  };
1090
1092
  }
1093
+ /**
1094
+ *
1095
+ * @param {object[]} urlArray {uri: string, id: string} combo of URL and ID/key of metadata
1096
+ * @param {number} [concurrentRequests] optionally set a different amount of concurrent requests
1097
+ * @param {boolean} [logAmountOfUrls] if true, prints an info message about to-be loaded amount of metadata
1098
+ * @returns {Promise.<{metadata: (TYPE.MetadataTypeMap | TYPE.MetadataTypeItem), type: string}>} Promise of item map (single item for templated result)
1099
+ */
1100
+ static async retrieveRESTcollection(urlArray, concurrentRequests = 10, logAmountOfUrls = true) {
1101
+ if (logAmountOfUrls) {
1102
+ Util.logger.info(
1103
+ Util.getGrayMsg(
1104
+ ` - ${urlArray?.length} ${this.definition.type}${
1105
+ urlArray?.length === 1 ? '' : 's'
1106
+ } found. Retrieving details...`
1107
+ )
1108
+ );
1109
+ }
1110
+ const rateLimit = pLimit(concurrentRequests);
1111
+
1112
+ const metadataArr = urlArray.length
1113
+ ? await Promise.all(
1114
+ urlArray.map(async (item) =>
1115
+ rateLimit(async () => {
1116
+ try {
1117
+ return await this.client.rest.get(item.uri);
1118
+ } catch (ex) {
1119
+ return this.handleRESTErrors(ex, item.id);
1120
+ }
1121
+ })
1122
+ )
1123
+ )
1124
+ : [];
1125
+ const results = {};
1126
+ for (const item of metadataArr) {
1127
+ const key = item[this.definition.keyField];
1128
+ results[key] = item;
1129
+ }
1130
+ return {
1131
+ metadata: results,
1132
+ type: this.definition.type,
1133
+ };
1134
+ }
1135
+
1136
+ /**
1137
+ * helper for {@link this.retrieveRESTcollection}
1138
+ *
1139
+ * @param {Error} ex exception
1140
+ * @param {string} id id or key of item
1141
+ * @returns {null} -
1142
+ */
1143
+ static handleRESTErrors(ex, id) {
1144
+ // if the ID is too short, the system will throw the 400 error
1145
+ Util.logger.debug(` ☇ skipping ${this.definition.type} ${id}: ${ex.message} ${ex.code}`);
1146
+
1147
+ return null;
1148
+ }
1091
1149
  /**
1092
1150
  * Used to execute a query/automation etc.
1093
1151
  *
@@ -1590,27 +1648,35 @@ class MetadataType {
1590
1648
  }
1591
1649
 
1592
1650
  const postRetrieveData = results[originalKey];
1651
+ // normalize results[metadataEntry]
1652
+ results[originalKey] = postRetrieveData.json;
1653
+
1654
+ if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey])) {
1655
+ Util.logger.debug(`Filtered ${originalKey} because of --like option`);
1656
+ continue;
1657
+ }
1658
+
1593
1659
  if (postRetrieveData.subFolder) {
1594
1660
  // very complex types have their own subfolder
1595
1661
  baseDir.push(...postRetrieveData.subFolder);
1596
1662
  }
1597
1663
  // save extracted scripts
1598
- for (const script of postRetrieveData.codeArr) {
1599
- const dir = [...baseDir];
1600
- if (script.subFolder) {
1601
- // some files shall be saved in yet a deeper subfolder
1602
- dir.push(...script.subFolder);
1603
- }
1604
- File.writePrettyToFile(
1605
- dir,
1606
- script.fileName + subtypeExtension,
1607
- script.fileExt,
1608
- script.content,
1609
- templateVariables
1610
- );
1611
- }
1612
- // normalize results[metadataEntry]
1613
- results[originalKey] = postRetrieveData.json;
1664
+ await Promise.all(
1665
+ postRetrieveData.codeArr.map(async (script) => {
1666
+ const dir = [...baseDir];
1667
+ if (script.subFolder) {
1668
+ // some files shall be saved in yet a deeper subfolder
1669
+ dir.push(...script.subFolder);
1670
+ }
1671
+ return File.writePrettyToFile(
1672
+ dir,
1673
+ script.fileName + subtypeExtension,
1674
+ script.fileExt,
1675
+ script.content,
1676
+ templateVariables
1677
+ );
1678
+ })
1679
+ );
1614
1680
  } else {
1615
1681
  // not a complex type, run the the entire JSON through templating
1616
1682
  // replace market values with template variable placeholders
@@ -1620,12 +1686,12 @@ class MetadataType {
1620
1686
  templateVariables
1621
1687
  );
1622
1688
  }
1689
+ if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey])) {
1690
+ Util.logger.debug(`Filtered ${originalKey} because of --like option`);
1691
+ continue;
1692
+ }
1623
1693
  }
1624
1694
 
1625
- if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey])) {
1626
- Util.logger.debug(`Filtered ${originalKey} because of --like option`);
1627
- continue;
1628
- }
1629
1695
  // we dont store Id on local disk, but we need it for caching logic,
1630
1696
  // so its in retrieve but not in save. Here we put into the clone so that the original
1631
1697
  // object used for caching doesnt have the Id removed.
@@ -2126,4 +2192,4 @@ MetadataType.subType = null;
2126
2192
  */
2127
2193
  MetadataType.buObject = null;
2128
2194
 
2129
- module.exports = MetadataType;
2195
+ export default MetadataType;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const MetadataType = require('./MetadataType');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import MetadataType from './MetadataType.js';
5
5
 
6
6
  /**
7
7
  * MobileCode MetadataType
@@ -39,6 +39,7 @@ class MobileCode extends MetadataType {
39
39
  }
40
40
 
41
41
  // Assign definition to static attributes
42
- MobileCode.definition = require('../MetadataTypeDefinitions').mobileCode;
42
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
43
+ MobileCode.definition = MetadataTypeDefinitions.mobileCode;
43
44
 
44
- module.exports = MobileCode;
45
+ export default MobileCode;
@@ -1,10 +1,10 @@
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');
7
- 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 File from '../util/file.js';
7
+ import cache from '../util/cache.js';
8
8
 
9
9
  /**
10
10
  * MobileKeyword MetadataType
@@ -501,7 +501,7 @@ class MobileKeyword extends MetadataType {
501
501
  */
502
502
  static async deleteByKey(key) {
503
503
  // get id from cache
504
- const { metadata } = await this.retrieveForCache(key);
504
+ const { metadata } = await this.retrieveForCache(undefined, undefined, key);
505
505
  if (!metadata[key]) {
506
506
  Util.logger.error(`Could not find ${this.definition.type} with key ${key}.`);
507
507
  return false;
@@ -549,6 +549,7 @@ class MobileKeyword extends MetadataType {
549
549
  }
550
550
 
551
551
  // Assign definition to static attributes
552
- MobileKeyword.definition = require('../MetadataTypeDefinitions').mobileKeyword;
552
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
553
+ MobileKeyword.definition = MetadataTypeDefinitions.mobileKeyword;
553
554
 
554
- module.exports = MobileKeyword;
555
+ export default MobileKeyword;
@@ -1,10 +1,10 @@
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');
7
- 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 File from '../util/file.js';
7
+ import cache from '../util/cache.js';
8
8
 
9
9
  /**
10
10
  * MobileMessage MetadataType
@@ -460,6 +460,7 @@ class MobileMessage extends MetadataType {
460
460
  }
461
461
 
462
462
  // Assign definition to static attributes
463
- MobileMessage.definition = require('../MetadataTypeDefinitions').mobileMessage;
463
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
464
+ MobileMessage.definition = MetadataTypeDefinitions.mobileMessage;
464
465
 
465
- module.exports = MobileMessage;
466
+ export default MobileMessage;
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const Util = require('../util/util');
5
- const MetadataType = require('./MetadataType');
6
- const File = require('../util/file');
7
- const cache = require('../util/cache');
8
- const Mustache = require('mustache');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import { Util } from '../util/util.js';
5
+ import MetadataType from './MetadataType.js';
6
+ import File from '../util/file.js';
7
+ import cache from '../util/cache.js';
8
+ import Mustache from 'mustache';
9
9
  /**
10
10
  * ensure that Mustache does not escape any characters
11
11
  *
@@ -471,6 +471,7 @@ class Query extends MetadataType {
471
471
  }
472
472
 
473
473
  // Assign definition & cache to static attributes
474
- Query.definition = require('../MetadataTypeDefinitions').query;
474
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
475
+ Query.definition = MetadataTypeDefinitions.query;
475
476
 
476
- module.exports = Query;
477
+ export default Query;
@@ -1,10 +1,10 @@
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');
7
- 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 File from '../util/file.js';
7
+ import cache from '../util/cache.js';
8
8
 
9
9
  /**
10
10
  * ImportFile MetadataType
@@ -325,6 +325,7 @@ class Role extends MetadataType {
325
325
  }
326
326
 
327
327
  // Assign definition to static attributes
328
- Role.definition = require('../MetadataTypeDefinitions').role;
328
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
329
+ Role.definition = MetadataTypeDefinitions.role;
329
330
 
330
- module.exports = Role;
331
+ export default Role;
@@ -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
  * Script MetadataType
@@ -327,6 +327,7 @@ class Script extends MetadataType {
327
327
  }
328
328
 
329
329
  // Assign definition & cache to static attributes
330
- Script.definition = require('../MetadataTypeDefinitions').script;
330
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
331
+ Script.definition = MetadataTypeDefinitions.script;
331
332
 
332
- module.exports = Script;
333
+ export default Script;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const MetadataType = require('./MetadataType');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import MetadataType from './MetadataType.js';
5
5
 
6
6
  /**
7
7
  * SendClassification MetadataType
@@ -35,6 +35,7 @@ class SendClassification extends MetadataType {
35
35
  }
36
36
 
37
37
  // Assign definition to static attributes
38
- SendClassification.definition = require('../MetadataTypeDefinitions').sendClassification;
38
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
39
+ SendClassification.definition = MetadataTypeDefinitions.sendClassification;
39
40
 
40
- module.exports = SendClassification;
41
+ export default SendClassification;
@@ -1,9 +1,10 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const TransactionalMessage = require('./TransactionalMessage');
5
- const Util = require('../util/util');
6
- const cache = require('../util/cache');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import TransactionalMessage from './TransactionalMessage.js';
5
+ import Journey from './Journey.js';
6
+ import { Util } from '../util/util.js';
7
+ import cache from '../util/cache.js';
7
8
 
8
9
  /**
9
10
  * TransactionalEmail MetadataType
@@ -40,21 +41,24 @@ class TransactionalEmail extends TransactionalMessage {
40
41
  */
41
42
  static async preDeployTasks(metadata) {
42
43
  // asset
43
- if (metadata.content?.customerKey) {
44
+ if (metadata.r__asset_customerKey) {
44
45
  // we merely want to be able to show an error if it does not exist
45
- cache.searchForField(
46
- 'asset',
47
- metadata.content.customerKey,
48
- 'customerKey',
49
- 'customerKey'
50
- );
46
+ metadata.content = {
47
+ customerKey: cache.searchForField(
48
+ 'asset',
49
+ metadata.r__asset_customerKey,
50
+ 'customerKey',
51
+ 'customerKey'
52
+ ),
53
+ };
54
+ delete metadata.r__asset_customerKey;
51
55
  }
52
56
  // subscriptions: dataExtension
53
- if (metadata.subscriptions?.dataExtension) {
57
+ if (metadata.subscriptions?.r__dataExtension_CustomerKey) {
54
58
  // we merely want to be able to show an error if it does not exist
55
- cache.searchForField(
59
+ metadata.subscriptions.dataExtension = cache.searchForField(
56
60
  'dataExtension',
57
- metadata.subscriptions.dataExtension,
61
+ metadata.subscriptions.r__dataExtension_CustomerKey,
58
62
  'CustomerKey',
59
63
  'CustomerKey'
60
64
  );
@@ -69,15 +73,49 @@ class TransactionalEmail extends TransactionalMessage {
69
73
  }
70
74
 
71
75
  // journey
72
- if (metadata.journey?.interactionKey) {
73
- // ! update & create enpoints dont accept journey.interactionKey. They only allow to create a new journey
74
- metadata.options ||= {};
75
- metadata.options.createJourney = true; // only send this during create or else we might end up with an unexpected outcome
76
- delete metadata.journey.interactionKey;
77
- }
76
+ // ! update & create enpoints dont accept journey.interactionKey. They only allow to create a new journey
77
+ metadata.options ||= {};
78
+ metadata.options.createJourney = true; // only send this during create or else we might end up with an unexpected outcome
78
79
 
79
80
  return metadata;
80
81
  }
82
+ /**
83
+ * helper for {@link TransactionalEmail.createREST}
84
+ *
85
+ * @param {TYPE.MetadataTypeItem} _ not used
86
+ * @param {object} apiResponse varies depending on the API call
87
+ * @returns {void}
88
+ */
89
+ static async postCreateTasks(_, apiResponse) {
90
+ if (apiResponse.journey?.interactionKey) {
91
+ Util.logger.warn(
92
+ ` - created journey: ${apiResponse.journey.interactionKey} (auto-created when ${this.definition.type} ${apiResponse.definitionKey} was created)`
93
+ );
94
+ // when we create new transactionalEmails, we should also download the new journey that was created with it
95
+ this._createdJourneyKeys ||= [];
96
+ this._createdJourneyKeys.push(apiResponse.journey?.interactionKey);
97
+
98
+ // do what postRetrieveTasks won't be able to do without spending lots of time on caching
99
+ apiResponse.r__journey_key = apiResponse.journey.interactionKey;
100
+ delete apiResponse.journey;
101
+ }
102
+ }
103
+ /**
104
+ * Gets executed after deployment of metadata type
105
+ *
106
+ * @returns {void}
107
+ */
108
+ static postDeployTasks() {
109
+ if (this._createdJourneyKeys?.length) {
110
+ Util.logger.warn(
111
+ `Please download related journeys via: mcdev r ${this.buObject.credential}/${
112
+ this.buObject.businessUnit
113
+ } journey "${this._createdJourneyKeys.join(',')}"`
114
+ );
115
+ }
116
+ delete this._createdJourneyKeys;
117
+ }
118
+
81
119
  /**
82
120
  * manages post retrieve steps
83
121
  *
@@ -87,6 +125,7 @@ class TransactionalEmail extends TransactionalMessage {
87
125
  static postRetrieveTasks(metadata) {
88
126
  // asset
89
127
  if (metadata.content?.customerKey) {
128
+ metadata.r__asset_customerKey = metadata.content.customerKey;
90
129
  try {
91
130
  // we merely want to be able to show an error if it does not exist
92
131
  cache.searchForField(
@@ -102,9 +141,13 @@ class TransactionalEmail extends TransactionalMessage {
102
141
  }): ${ex.message}.`
103
142
  );
104
143
  }
144
+ delete metadata.content;
105
145
  }
146
+
106
147
  // subscriptions: dataExtension
107
148
  if (metadata.subscriptions?.dataExtension) {
149
+ metadata.subscriptions.r__dataExtension_CustomerKey =
150
+ metadata.subscriptions.dataExtension;
108
151
  try {
109
152
  // we merely want to be able to show a warning if it does not exist
110
153
  cache.searchForField(
@@ -120,6 +163,7 @@ class TransactionalEmail extends TransactionalMessage {
120
163
  }): ${ex.message}.`
121
164
  );
122
165
  }
166
+ delete metadata.subscriptions.dataExtension;
123
167
  }
124
168
  // subscriptions: list
125
169
  if (metadata.subscriptions?.list) {
@@ -140,9 +184,15 @@ class TransactionalEmail extends TransactionalMessage {
140
184
  }
141
185
  // journey
142
186
  if (metadata.journey?.interactionKey) {
187
+ metadata.r__journey_key = metadata.journey.interactionKey;
143
188
  try {
144
189
  // we merely want to be able to show a warning if it does not exist
145
- cache.searchForField('journey', metadata.journey.interactionKey, 'key', 'key');
190
+ metadata.r__journey_key = cache.searchForField(
191
+ 'journey',
192
+ metadata.journey.interactionKey,
193
+ 'key',
194
+ 'key'
195
+ );
146
196
  } catch (ex) {
147
197
  Util.logger.warn(
148
198
  ` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
@@ -150,13 +200,41 @@ class TransactionalEmail extends TransactionalMessage {
150
200
  }): ${ex.message}.`
151
201
  );
152
202
  }
203
+ delete metadata.journey;
153
204
  }
154
205
 
155
206
  return metadata;
156
207
  }
208
+ /**
209
+ * Delete a metadata item from the specified business unit
210
+ *
211
+ * @param {string} key Identifier of item
212
+ * @returns {Promise.<boolean>} deletion success status
213
+ */
214
+ static async deleteByKey(key) {
215
+ const metadataMapObj = await this.retrieveForCache(key);
216
+ const journeyKey = metadataMapObj?.metadata?.[key]?.journey?.interactionKey;
217
+
218
+ const isDeleted = await super.deleteByKeyREST(
219
+ '/messaging/v1/' + this.subType + '/definitions/' + key,
220
+ key,
221
+ false
222
+ );
223
+ if (isDeleted && journeyKey) {
224
+ Util.logger.info(
225
+ ` - deleted ${Journey.definition.type}: ${journeyKey} (SFMC auto-deletes the related journey of ${this.definition.type} ${key})`
226
+ );
227
+ Journey.buObject = this.buObject;
228
+ Journey.properties = this.properties;
229
+ Journey.client = this.client;
230
+ Journey.postDeleteTasks(journeyKey);
231
+ }
232
+ return isDeleted;
233
+ }
157
234
  }
158
235
 
159
236
  // Assign definition to static attributes
160
- TransactionalEmail.definition = require('../MetadataTypeDefinitions').transactionalEmail;
237
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
238
+ TransactionalEmail.definition = MetadataTypeDefinitions.transactionalEmail;
161
239
 
162
- module.exports = TransactionalEmail;
240
+ export default TransactionalEmail;
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const MetadataType = require('./MetadataType');
5
- const Util = require('../util/util');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import MetadataType from './MetadataType.js';
5
+ import { Util } from '../util/util.js';
6
6
 
7
7
  /**
8
8
  * TransactionalMessage MetadataType
@@ -67,13 +67,14 @@ class TransactionalMessage extends MetadataType {
67
67
  /**
68
68
  * Retrieves event definition metadata for caching
69
69
  *
70
+ * @param {string} [key] customer key of single item to cache
70
71
  * @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
71
72
  */
72
- static retrieveForCache() {
73
+ static retrieveForCache(key) {
73
74
  // the call to /messaging/v1/email/definitions/ does not return definitionId
74
75
  // definitionId is required for resolving dependencies on interactions.
75
76
  // we should therefore use the already defined retrieve method
76
- return this.retrieve();
77
+ return this.retrieve(undefined, undefined, undefined, key);
77
78
  }
78
79
  /**
79
80
  * Updates a single item
@@ -114,6 +115,7 @@ class TransactionalMessage extends MetadataType {
114
115
 
115
116
  // Assign definition to static attributes
116
117
  // ! using SMS definitions here as placeholder to have auto completion
117
- TransactionalMessage.definition = require('../MetadataTypeDefinitions').transactionalSMS;
118
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
119
+ TransactionalMessage.definition = MetadataTypeDefinitions.transactionalSMS;
118
120
 
119
- module.exports = TransactionalMessage;
121
+ export default TransactionalMessage;
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const TYPE = require('../../types/mcdev.d');
4
- const TransactionalMessage = require('./TransactionalMessage');
5
- const Util = require('../util/util');
6
- const cache = require('../util/cache');
3
+ import TYPE from '../../types/mcdev.d.js';
4
+ import TransactionalMessage from './TransactionalMessage.js';
5
+ import { Util } from '../util/util.js';
6
+ import cache from '../util/cache.js';
7
7
 
8
8
  /**
9
9
  * TransactionalPush TransactionalMessage
@@ -72,6 +72,7 @@ class TransactionalPush extends TransactionalMessage {
72
72
  }
73
73
 
74
74
  // Assign definition to static attributes
75
- TransactionalPush.definition = require('../MetadataTypeDefinitions').transactionalPush;
75
+ import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
76
+ TransactionalPush.definition = MetadataTypeDefinitions.transactionalPush;
76
77
 
77
- module.exports = TransactionalPush;
78
+ export default TransactionalPush;