mcdev 3.1.3 → 4.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 (134) hide show
  1. package/.eslintrc.json +67 -7
  2. package/.github/ISSUE_TEMPLATE/bug.yml +2 -1
  3. package/.github/PULL_REQUEST_TEMPLATE.md +5 -3
  4. package/.github/dependabot.yml +14 -0
  5. package/.github/workflows/code-analysis.yml +57 -0
  6. package/.husky/commit-msg +10 -0
  7. package/.husky/post-checkout +5 -0
  8. package/.husky/pre-commit +2 -1
  9. package/.prettierrc +8 -0
  10. package/.vscode/settings.json +1 -1
  11. package/LICENSE +2 -2
  12. package/README.md +134 -45
  13. package/boilerplate/config.json +5 -11
  14. package/boilerplate/files/.prettierrc +8 -0
  15. package/boilerplate/files/.vscode/extensions.json +0 -1
  16. package/boilerplate/files/.vscode/settings.json +28 -2
  17. package/boilerplate/files/README.md +2 -2
  18. package/boilerplate/forcedUpdates.json +10 -0
  19. package/boilerplate/npm-dependencies.json +5 -5
  20. package/docs/dist/documentation.md +2795 -1724
  21. package/jsconfig.json +1 -1
  22. package/lib/Builder.js +166 -75
  23. package/lib/Deployer.js +244 -96
  24. package/lib/MetadataTypeDefinitions.js +2 -0
  25. package/lib/MetadataTypeInfo.js +2 -0
  26. package/lib/Retriever.js +61 -84
  27. package/lib/cli.js +116 -11
  28. package/lib/index.js +241 -561
  29. package/lib/metadataTypes/AccountUser.js +101 -95
  30. package/lib/metadataTypes/Asset.js +677 -248
  31. package/lib/metadataTypes/AttributeGroup.js +23 -12
  32. package/lib/metadataTypes/Automation.js +451 -354
  33. package/lib/metadataTypes/Campaign.js +33 -93
  34. package/lib/metadataTypes/ContentArea.js +31 -11
  35. package/lib/metadataTypes/DataExtension.js +387 -372
  36. package/lib/metadataTypes/DataExtensionField.js +131 -54
  37. package/lib/metadataTypes/DataExtensionTemplate.js +22 -4
  38. package/lib/metadataTypes/DataExtract.js +61 -48
  39. package/lib/metadataTypes/DataExtractType.js +14 -8
  40. package/lib/metadataTypes/Discovery.js +21 -16
  41. package/lib/metadataTypes/Email.js +32 -12
  42. package/lib/metadataTypes/EmailSendDefinition.js +85 -80
  43. package/lib/metadataTypes/EventDefinition.js +61 -43
  44. package/lib/metadataTypes/FileTransfer.js +72 -52
  45. package/lib/metadataTypes/Filter.js +11 -4
  46. package/lib/metadataTypes/Folder.js +149 -117
  47. package/lib/metadataTypes/FtpLocation.js +14 -8
  48. package/lib/metadataTypes/ImportFile.js +61 -64
  49. package/lib/metadataTypes/Interaction.js +19 -4
  50. package/lib/metadataTypes/List.js +54 -13
  51. package/lib/metadataTypes/MetadataType.js +668 -454
  52. package/lib/metadataTypes/MobileCode.js +46 -0
  53. package/lib/metadataTypes/MobileKeyword.js +114 -0
  54. package/lib/metadataTypes/Query.js +204 -103
  55. package/lib/metadataTypes/Role.js +76 -61
  56. package/lib/metadataTypes/Script.js +145 -81
  57. package/lib/metadataTypes/SetDefinition.js +20 -8
  58. package/lib/metadataTypes/TriggeredSendDefinition.js +78 -58
  59. package/lib/metadataTypes/definitions/Asset.definition.js +21 -10
  60. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +12 -0
  61. package/lib/metadataTypes/definitions/Automation.definition.js +10 -5
  62. package/lib/metadataTypes/definitions/Campaign.definition.js +44 -1
  63. package/lib/metadataTypes/definitions/DataExtension.definition.js +4 -0
  64. package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +6 -0
  65. package/lib/metadataTypes/definitions/DataExtract.definition.js +18 -14
  66. package/lib/metadataTypes/definitions/Discovery.definition.js +12 -0
  67. package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +4 -0
  68. package/lib/metadataTypes/definitions/EventDefinition.definition.js +22 -0
  69. package/lib/metadataTypes/definitions/FileTransfer.definition.js +4 -0
  70. package/lib/metadataTypes/definitions/Filter.definition.js +4 -0
  71. package/lib/metadataTypes/definitions/Folder.definition.js +6 -0
  72. package/lib/metadataTypes/definitions/FtpLocation.definition.js +4 -0
  73. package/lib/metadataTypes/definitions/ImportFile.definition.js +10 -5
  74. package/lib/metadataTypes/definitions/Interaction.definition.js +4 -0
  75. package/lib/metadataTypes/definitions/MobileCode.definition.js +163 -0
  76. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +253 -0
  77. package/lib/metadataTypes/definitions/Query.definition.js +4 -0
  78. package/lib/metadataTypes/definitions/Role.definition.js +5 -0
  79. package/lib/metadataTypes/definitions/Script.definition.js +4 -0
  80. package/lib/metadataTypes/definitions/SetDefinition.definition.js +28 -0
  81. package/lib/metadataTypes/definitions/TriggeredSendDefinition.definition.js +4 -0
  82. package/lib/retrieveChangelog.js +7 -6
  83. package/lib/util/auth.js +117 -0
  84. package/lib/util/businessUnit.js +55 -66
  85. package/lib/util/cache.js +194 -0
  86. package/lib/util/cli.js +90 -116
  87. package/lib/util/config.js +302 -0
  88. package/lib/util/devops.js +240 -50
  89. package/lib/util/file.js +120 -191
  90. package/lib/util/init.config.js +195 -69
  91. package/lib/util/init.git.js +45 -50
  92. package/lib/util/init.js +72 -59
  93. package/lib/util/init.npm.js +48 -39
  94. package/lib/util/util.js +280 -564
  95. package/package.json +44 -33
  96. package/test/dataExtension.test.js +152 -0
  97. package/test/mockRoot/.mcdev-auth.json +8 -0
  98. package/test/mockRoot/.mcdevrc.json +67 -0
  99. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/childBU_dataextension_test.dataExtension-meta.json +39 -0
  100. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testDataExtension.dataExtension-meta.json +23 -0
  101. package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.json +11 -0
  102. package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.sql +4 -0
  103. package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.json +11 -0
  104. package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.sql +4 -0
  105. package/test/query.test.js +149 -0
  106. package/test/resourceFactory.js +142 -0
  107. package/test/resources/1111111/dataFolder/retrieve-response.xml +43 -0
  108. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +18 -0
  109. package/test/resources/9999999/automation/v1/queries/get-response.json +24 -0
  110. package/test/resources/9999999/automation/v1/queries/post-response.json +18 -0
  111. package/test/resources/9999999/dataExtension/build-expected.json +51 -0
  112. package/test/resources/9999999/dataExtension/create-expected.json +23 -0
  113. package/test/resources/9999999/dataExtension/create-response.xml +54 -0
  114. package/test/resources/9999999/dataExtension/retrieve-expected.json +51 -0
  115. package/test/resources/9999999/dataExtension/retrieve-response.xml +47 -0
  116. package/test/resources/9999999/dataExtension/template-expected.json +51 -0
  117. package/test/resources/9999999/dataExtension/update-expected.json +55 -0
  118. package/test/resources/9999999/dataExtension/update-response.xml +52 -0
  119. package/test/resources/9999999/dataExtensionField/retrieve-response.xml +93 -0
  120. package/test/resources/9999999/dataExtensionTemplate/retrieve-response.xml +303 -0
  121. package/test/resources/9999999/dataFolder/retrieve-response.xml +65 -0
  122. package/test/resources/9999999/query/build-expected.json +8 -0
  123. package/test/resources/9999999/query/get-expected.json +11 -0
  124. package/test/resources/9999999/query/patch-expected.json +11 -0
  125. package/test/resources/9999999/query/post-expected.json +11 -0
  126. package/test/resources/9999999/query/template-expected.json +8 -0
  127. package/test/resources/auth.json +32 -0
  128. package/test/resources/rest404-response.json +5 -0
  129. package/test/resources/retrieve-response.xml +21 -0
  130. package/test/utils.js +107 -0
  131. package/types/mcdev.d.js +301 -0
  132. package/CHANGELOG.md +0 -126
  133. package/PULL_REQUEST_TEMPLATE.md +0 -19
  134. package/test/util/file.js +0 -51
@@ -1,122 +1,62 @@
1
1
  'use strict';
2
2
 
3
+ const TYPE = require('../../types/mcdev.d');
3
4
  const MetadataType = require('./MetadataType');
4
5
  const Util = require('../util/util');
5
6
  const File = require('../util/file');
6
7
 
7
8
  /**
8
9
  * Campaign MetadataType
10
+ *
9
11
  * @augments MetadataType
10
12
  */
11
13
  class Campaign extends MetadataType {
12
14
  /**
13
15
  * Retrieves Metadata of campaigns. Afterwards, starts metadata retrieval for their campaign assets
14
- * @param {String} retrieveDir Directory where retrieved metadata directory will be saved
15
- * @returns {Promise} Promise
16
+ *
17
+ * @param {string} retrieveDir Directory where retrieved metadata directory will be saved
18
+ * @param {void} [_] unused parameter
19
+ * @param {void} [__] unused parameter
20
+ * @param {void} [___] unused parameter
21
+ * @param {string} [key] customer key of single item to retrieve
22
+ * @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise
16
23
  */
17
- static retrieve(retrieveDir) {
18
- return new Promise((resolve) => {
19
- const config = {
20
- props: null,
21
- options: {},
22
- };
23
- this.client.campaign(config).get(async (error, response) => {
24
- if (error) {
25
- throw new Error(error);
26
- }
27
- // Save metadata structure
28
- const metadata = Campaign.parseResponseBody(response.body);
29
- // Util.logger.info('Campaign.retrieve:: Parsed Response');
30
- // Write metadata to local filesystem
31
- for (const metadataEntry in metadata) {
32
- File.writeJSONToFile(
33
- retrieveDir + '/campaign/' + metadataEntry + '/',
34
- metadataEntry + '.' + this.definition.type + '-meta',
35
- metadata[metadataEntry]
36
- );
37
- }
38
- const campaignAssetPromises = [];
39
- for (const campaign in metadata) {
40
- try {
41
- campaignAssetPromises.push(
42
- Campaign._retrieveCampaignAsset(
43
- retrieveDir,
44
- metadata[campaign].id,
45
- metadata[campaign].name
46
- )
47
- );
48
- } catch (ex) {
49
- Util.logger.error(ex.message);
50
- }
51
- }
52
- const values = await Promise.all(campaignAssetPromises);
53
- Util.logger.info(
54
- `Downloaded: ${this.definition.type} (${Object.keys(metadata).length})`
55
- );
56
- resolve({ metadata: values, type: 'campaign' });
57
- });
58
- });
59
- }
24
+ static async retrieve(retrieveDir, _, __, ___, key) {
25
+ const res = await super.retrieveREST(retrieveDir, '/hub/v1/campaigns', null, null, key);
26
+ // get assignments
60
27
 
61
- /**
62
- * Retrieves campaign asset for a specific campaign
63
- * @param {String} retrieveDir Directory where retrieved metadata directory will be saved
64
- * @param {Number} id id of the parent campaign
65
- * @param {String} name name of the parent campaign
66
- * @returns {Promise} Promise
67
- */
68
- static _retrieveCampaignAsset(retrieveDir, id, name) {
69
- return new Promise((resolve, reject) => {
70
- const config = {
71
- props: { id: id },
72
- options: {},
73
- };
74
- this.client.campaignAsset(config).get((error, response) => {
75
- if (error) {
76
- reject(error);
77
- } else {
78
- const assets = Campaign._parseAssetResponseBody(response.body);
28
+ const campaignAssets = await Promise.all(
29
+ Object.keys(res.metadata).map((key) =>
30
+ this.getAssetTags(retrieveDir, res.metadata[key].id, key)
31
+ )
32
+ );
33
+ Util.logger.info(`Downloaded: campaignAssets (${campaignAssets.flat().length})`);
79
34
 
80
- for (const asset in assets) {
81
- File.writeJSONToFile(
82
- retrieveDir + '/campaign/' + name + '/assets/',
83
- asset + '.campaignAsset-meta',
84
- assets[asset]
85
- );
86
- }
87
- resolve(assets);
88
- }
89
- });
90
- });
35
+ return res;
91
36
  }
92
37
 
93
38
  /**
94
39
  * Parses campaign asset response body and returns metadata entries mapped to their id
95
- * @param {Object} body response body of metadata retrieval
96
- * @returns {Object} keyField => metadata map
40
+ *
41
+ * @param {string} retrieveDir folder where to save
42
+ * @param {string} id of camapaign to retrieve
43
+ * @param {string} name of camapaign for saving
44
+ * @returns {Promise.<TYPE.MetadataTypeMapObj>} Campaign Asset Object
97
45
  */
98
- static _parseAssetResponseBody(body) {
99
- const metadataStructure = {};
100
- if (body.items) {
101
- for (let i = 0; i < body.items.length; i++) {
102
- const item = body.items[i];
103
- // if needed: Makes sure files can be saved on windows operating systems
104
- // .replace(/[/\\?%*:|"<>]/g, '-');
105
- const key = item.id;
106
- metadataStructure[key] = item;
107
- }
108
- } else {
109
- Util.logger.debug(
110
- `Campaign._parseAssetResponseBody:: Format of 'body' parameter wrong: `,
111
- body
46
+ static async getAssetTags(retrieveDir, id, name) {
47
+ const res = await this.client.rest.getBulk(`/hub/v1/campaigns/${id}/assets`);
48
+
49
+ for (const asset of res.items) {
50
+ await File.writeJSONToFile(
51
+ `${retrieveDir}/campaign/${name}/assets/`,
52
+ asset.id + '.campaignAsset-meta',
53
+ asset
112
54
  );
113
55
  }
114
- return metadataStructure;
56
+ return res.items;
115
57
  }
116
58
  }
117
59
  // Assign definition to static attributes
118
60
  Campaign.definition = require('../MetadataTypeDefinitions').campaign;
119
- Campaign.client = undefined;
120
- Campaign.cache = {};
121
61
 
122
62
  module.exports = Campaign;
@@ -1,43 +1,63 @@
1
1
  'use strict';
2
2
 
3
+ const TYPE = require('../../types/mcdev.d');
3
4
  const MetadataType = require('./MetadataType');
4
5
  const Util = require('../util/util');
6
+ const cache = require('../util/cache');
5
7
 
6
8
  /**
7
9
  * ContentArea MetadataType
10
+ *
8
11
  * @augments MetadataType
9
12
  */
10
13
  class ContentArea extends MetadataType {
11
14
  /**
12
15
  * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata
13
- * @param {String} retrieveDir Directory where retrieved metadata directory will be saved
14
- * @returns {Promise<Object>} Promise of metadata
16
+ *
17
+ * @param {string} retrieveDir Directory where retrieved metadata directory will be saved
18
+ * @param {void} [_] unused parameter
19
+ * @param {void} [__] unused parameter
20
+ * @param {void} [___] unused parameter
21
+ * @param {string} [key] customer key of single item to retrieve
22
+ * @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
15
23
  */
16
- static retrieve(retrieveDir) {
24
+ static retrieve(retrieveDir, _, __, ___, key) {
17
25
  Util.logger.warn(
18
- 'Classic Content Areas are deprecated and will be discontinued by SFMC in the near future. Ensure that you migrate any existing Content Areas to Content Builder as soon as possible.'
26
+ ' - Classic Content Areas are deprecated and will be discontinued by SFMC in the near future. Ensure that you migrate any existing Content Areas to Content Builder as soon as possible.'
19
27
  );
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
+ }
20
39
  // !dont activate `await File.initPrettier('html');` as we only want to retrieve for migration and formatting might mess with the outcome
21
- return super.retrieveSOAPgeneric(retrieveDir);
40
+ return super.retrieveSOAP(retrieveDir, null, requestParams);
22
41
  }
23
42
  /**
24
43
  * manages post retrieve steps
25
- * @param {Object} metadata a single query
26
- * @returns {Object[]} Array with one metadata object and one query string
44
+ *
45
+ * @param {TYPE.MetadataTypeItem} metadata a single item
46
+ * @returns {TYPE.MetadataTypeItem} parsed item
27
47
  */
28
48
  static postRetrieveTasks(metadata) {
29
49
  return this.parseMetadata(metadata);
30
50
  }
31
51
  /**
32
52
  * parses retrieved Metadata before saving
33
- * @param {Object} metadata a single query activity definition
34
- * @returns {Array} Array with one metadata object and one sql string
53
+ *
54
+ * @param {TYPE.MetadataTypeItem} metadata a single item
55
+ * @returns {TYPE.MetadataTypeItem} parsed item
35
56
  */
36
57
  static parseMetadata(metadata) {
37
58
  // folder
38
59
  try {
39
- metadata.r__folder_Path = Util.getFromCache(
40
- this.cache,
60
+ metadata.r__folder_Path = cache.searchForField(
41
61
  'folder',
42
62
  metadata.CategoryID,
43
63
  'ID',