mcdev 3.1.1 → 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.
- package/.eslintrc.json +67 -7
- package/.github/ISSUE_TEMPLATE/bug.yml +5 -1
- package/.github/ISSUE_TEMPLATE/task.md +1 -1
- package/.github/PULL_REQUEST_TEMPLATE.md +5 -3
- package/.github/dependabot.yml +14 -0
- package/.github/workflows/code-analysis.yml +57 -0
- package/.husky/commit-msg +10 -0
- package/.husky/post-checkout +5 -0
- package/.husky/pre-commit +2 -1
- package/.prettierrc +8 -0
- package/.vscode/settings.json +1 -1
- package/LICENSE +2 -2
- package/README.md +134 -45
- package/boilerplate/config.json +5 -11
- package/boilerplate/files/.prettierrc +8 -0
- package/boilerplate/files/.vscode/extensions.json +0 -1
- package/boilerplate/files/.vscode/settings.json +28 -2
- package/boilerplate/files/README.md +2 -2
- package/boilerplate/forcedUpdates.json +10 -0
- package/boilerplate/npm-dependencies.json +5 -5
- package/docs/dist/documentation.md +2795 -1724
- package/jsconfig.json +1 -1
- package/lib/Builder.js +166 -75
- package/lib/Deployer.js +244 -96
- package/lib/MetadataTypeDefinitions.js +2 -0
- package/lib/MetadataTypeInfo.js +2 -0
- package/lib/Retriever.js +61 -84
- package/lib/cli.js +133 -25
- package/lib/index.js +242 -563
- package/lib/metadataTypes/AccountUser.js +101 -95
- package/lib/metadataTypes/Asset.js +677 -248
- package/lib/metadataTypes/AttributeGroup.js +23 -12
- package/lib/metadataTypes/Automation.js +456 -357
- package/lib/metadataTypes/Campaign.js +33 -93
- package/lib/metadataTypes/ContentArea.js +31 -11
- package/lib/metadataTypes/DataExtension.js +391 -376
- package/lib/metadataTypes/DataExtensionField.js +131 -54
- package/lib/metadataTypes/DataExtensionTemplate.js +22 -4
- package/lib/metadataTypes/DataExtract.js +67 -50
- package/lib/metadataTypes/DataExtractType.js +14 -8
- package/lib/metadataTypes/Discovery.js +21 -16
- package/lib/metadataTypes/Email.js +32 -12
- package/lib/metadataTypes/EmailSendDefinition.js +85 -80
- package/lib/metadataTypes/EventDefinition.js +69 -47
- package/lib/metadataTypes/FileTransfer.js +78 -54
- package/lib/metadataTypes/Filter.js +11 -4
- package/lib/metadataTypes/Folder.js +149 -117
- package/lib/metadataTypes/FtpLocation.js +14 -8
- package/lib/metadataTypes/ImportFile.js +69 -69
- package/lib/metadataTypes/Interaction.js +19 -4
- package/lib/metadataTypes/List.js +54 -13
- package/lib/metadataTypes/MetadataType.js +687 -479
- package/lib/metadataTypes/MobileCode.js +46 -0
- package/lib/metadataTypes/MobileKeyword.js +114 -0
- package/lib/metadataTypes/Query.js +204 -103
- package/lib/metadataTypes/Role.js +76 -61
- package/lib/metadataTypes/Script.js +146 -82
- package/lib/metadataTypes/SetDefinition.js +20 -8
- package/lib/metadataTypes/TriggeredSendDefinition.js +78 -58
- package/lib/metadataTypes/definitions/Asset.definition.js +21 -10
- package/lib/metadataTypes/definitions/AttributeGroup.definition.js +12 -0
- package/lib/metadataTypes/definitions/Automation.definition.js +10 -5
- package/lib/metadataTypes/definitions/Campaign.definition.js +44 -1
- package/lib/metadataTypes/definitions/DataExtension.definition.js +4 -0
- package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +6 -0
- package/lib/metadataTypes/definitions/DataExtract.definition.js +18 -14
- package/lib/metadataTypes/definitions/Discovery.definition.js +12 -0
- package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +4 -0
- package/lib/metadataTypes/definitions/EventDefinition.definition.js +22 -0
- package/lib/metadataTypes/definitions/FileTransfer.definition.js +4 -0
- package/lib/metadataTypes/definitions/Filter.definition.js +4 -0
- package/lib/metadataTypes/definitions/Folder.definition.js +6 -0
- package/lib/metadataTypes/definitions/FtpLocation.definition.js +4 -0
- package/lib/metadataTypes/definitions/ImportFile.definition.js +10 -5
- package/lib/metadataTypes/definitions/Interaction.definition.js +4 -0
- package/lib/metadataTypes/definitions/MobileCode.definition.js +163 -0
- package/lib/metadataTypes/definitions/MobileKeyword.definition.js +253 -0
- package/lib/metadataTypes/definitions/Query.definition.js +4 -0
- package/lib/metadataTypes/definitions/Role.definition.js +5 -0
- package/lib/metadataTypes/definitions/Script.definition.js +4 -0
- package/lib/metadataTypes/definitions/SetDefinition.definition.js +28 -0
- package/lib/metadataTypes/definitions/TriggeredSendDefinition.definition.js +4 -0
- package/lib/retrieveChangelog.js +7 -6
- package/lib/util/auth.js +117 -0
- package/lib/util/businessUnit.js +55 -66
- package/lib/util/cache.js +194 -0
- package/lib/util/cli.js +90 -116
- package/lib/util/config.js +302 -0
- package/lib/util/devops.js +240 -50
- package/lib/util/file.js +120 -191
- package/lib/util/init.config.js +195 -69
- package/lib/util/init.git.js +45 -50
- package/lib/util/init.js +72 -59
- package/lib/util/init.npm.js +48 -39
- package/lib/util/util.js +280 -564
- package/package.json +44 -33
- package/test/dataExtension.test.js +152 -0
- package/test/mockRoot/.mcdev-auth.json +8 -0
- package/test/mockRoot/.mcdevrc.json +67 -0
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/childBU_dataextension_test.dataExtension-meta.json +39 -0
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testDataExtension.dataExtension-meta.json +23 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.sql +4 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.sql +4 -0
- package/test/query.test.js +149 -0
- package/test/resourceFactory.js +142 -0
- package/test/resources/1111111/dataFolder/retrieve-response.xml +43 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +18 -0
- package/test/resources/9999999/automation/v1/queries/get-response.json +24 -0
- package/test/resources/9999999/automation/v1/queries/post-response.json +18 -0
- package/test/resources/9999999/dataExtension/build-expected.json +51 -0
- package/test/resources/9999999/dataExtension/create-expected.json +23 -0
- package/test/resources/9999999/dataExtension/create-response.xml +54 -0
- package/test/resources/9999999/dataExtension/retrieve-expected.json +51 -0
- package/test/resources/9999999/dataExtension/retrieve-response.xml +47 -0
- package/test/resources/9999999/dataExtension/template-expected.json +51 -0
- package/test/resources/9999999/dataExtension/update-expected.json +55 -0
- package/test/resources/9999999/dataExtension/update-response.xml +52 -0
- package/test/resources/9999999/dataExtensionField/retrieve-response.xml +93 -0
- package/test/resources/9999999/dataExtensionTemplate/retrieve-response.xml +303 -0
- package/test/resources/9999999/dataFolder/retrieve-response.xml +65 -0
- package/test/resources/9999999/query/build-expected.json +8 -0
- package/test/resources/9999999/query/get-expected.json +11 -0
- package/test/resources/9999999/query/patch-expected.json +11 -0
- package/test/resources/9999999/query/post-expected.json +11 -0
- package/test/resources/9999999/query/template-expected.json +8 -0
- package/test/resources/auth.json +32 -0
- package/test/resources/rest404-response.json +5 -0
- package/test/resources/retrieve-response.xml +21 -0
- package/test/utils.js +107 -0
- package/types/mcdev.d.js +301 -0
- package/CHANGELOG.md +0 -126
- package/PULL_REQUEST_TEMPLATE.md +0 -19
- package/test/util/file.js +0 -51
package/jsconfig.json
CHANGED
package/lib/Builder.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const TYPE = require('../types/mcdev.d');
|
|
3
4
|
const Util = require('./util/util');
|
|
4
|
-
|
|
5
|
+
const File = require('./util/file');
|
|
6
|
+
const config = require('./util/config');
|
|
7
|
+
const Cli = require('./util/cli');
|
|
8
|
+
const auth = require('./util/auth');
|
|
5
9
|
const MetadataTypeInfo = require('./MetadataTypeInfo');
|
|
6
10
|
// @ts-ignore
|
|
7
11
|
|
|
@@ -12,50 +16,46 @@ class Builder {
|
|
|
12
16
|
/**
|
|
13
17
|
* Creates a Builder, uses v2 auth if v2AuthOptions are passed.
|
|
14
18
|
*
|
|
15
|
-
* @param {
|
|
16
|
-
|
|
17
|
-
* @param {
|
|
18
|
-
* @param {Object} properties.directories list of default directories
|
|
19
|
-
* @param {String} properties.directories.template where templates are saved
|
|
20
|
-
* @param {String} properties.directories.templateBuilds where template-based deployment definitions are saved
|
|
21
|
-
* @param {String} properties.tenant v2 Auth Tenant Information
|
|
22
|
-
* @param {String} properties.businessUnits ID of Business Unit to authenticate with
|
|
23
|
-
* @param {Object} buObject properties for auth
|
|
24
|
-
* @param {String} buObject.clientId clientId for FuelSDK auth
|
|
25
|
-
* @param {String} buObject.clientSecret clientSecret for FuelSDK auth
|
|
26
|
-
* @param {Object} buObject.credential clientId for FuelSDK auth
|
|
27
|
-
* @param {String} buObject.tenant v2 Auth Tenant Information
|
|
28
|
-
* @param {String} buObject.mid ID of Business Unit to authenticate with
|
|
29
|
-
* @param {String} buObject.businessUnit name of Business Unit to authenticate with
|
|
30
|
-
* @param {Util.ET_Client} client fuel client
|
|
19
|
+
* @param {TYPE.Mcdevrc} properties properties for auth
|
|
20
|
+
saved
|
|
21
|
+
* @param {TYPE.BuObject} buObject properties for auth
|
|
31
22
|
*/
|
|
32
|
-
constructor(properties, buObject
|
|
33
|
-
this.client = client;
|
|
23
|
+
constructor(properties, buObject) {
|
|
34
24
|
this.properties = properties;
|
|
35
25
|
this.templateDir = properties.directories.template;
|
|
26
|
+
this.retrieveDir = File.normalizePath([
|
|
27
|
+
properties.directories.retrieve,
|
|
28
|
+
buObject.credential,
|
|
29
|
+
buObject.businessUnit,
|
|
30
|
+
]);
|
|
31
|
+
this.buObject = buObject;
|
|
36
32
|
|
|
37
33
|
// allow multiple target directories
|
|
38
34
|
const templateBuildsArr = Array.isArray(properties.directories.templateBuilds)
|
|
39
35
|
? properties.directories.templateBuilds
|
|
40
36
|
: [properties.directories.templateBuilds];
|
|
41
|
-
|
|
42
37
|
this.targetDir = templateBuildsArr.map(
|
|
43
38
|
(directoriesTemplateBuilds) =>
|
|
44
39
|
directoriesTemplateBuilds + buObject.credential + '/' + buObject.businessUnit
|
|
45
40
|
);
|
|
46
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @type {TYPE.MultiMetadataTypeList}
|
|
44
|
+
*/
|
|
47
45
|
this.metadata = {};
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
/**
|
|
51
49
|
* Builds a specific metadata file by name
|
|
52
|
-
*
|
|
53
|
-
* @param {
|
|
54
|
-
* @param {
|
|
55
|
-
* @
|
|
50
|
+
*
|
|
51
|
+
* @param {string} metadataType metadata type to build
|
|
52
|
+
* @param {string} name name of metadata to build
|
|
53
|
+
* @param {TYPE.TemplateMap} templateVariables variables to be replaced in the metadata
|
|
54
|
+
* @returns {Promise.<TYPE.MultiMetadataTypeList>} Promise
|
|
56
55
|
*/
|
|
57
|
-
async
|
|
56
|
+
async _buildDefinition(metadataType, name, templateVariables) {
|
|
58
57
|
let nameArr;
|
|
58
|
+
/* eslint-disable unicorn/prefer-ternary */
|
|
59
59
|
if (name.includes(',')) {
|
|
60
60
|
nameArr = name.split(',').map((item) =>
|
|
61
61
|
// allow whitespace in comma-separated lists
|
|
@@ -64,6 +64,8 @@ class Builder {
|
|
|
64
64
|
} else {
|
|
65
65
|
nameArr = [name.trim()];
|
|
66
66
|
}
|
|
67
|
+
/* eslint-enable unicorn/prefer-ternary */
|
|
68
|
+
|
|
67
69
|
const type = metadataType;
|
|
68
70
|
try {
|
|
69
71
|
const result = await Promise.all(
|
|
@@ -72,77 +74,166 @@ class Builder {
|
|
|
72
74
|
// we hence require users to put %20 in their stead and have to convert that back
|
|
73
75
|
name = name.split('%20').join(' ');
|
|
74
76
|
|
|
75
|
-
MetadataTypeInfo[type].
|
|
76
|
-
MetadataTypeInfo[type].client = this.client;
|
|
77
|
+
MetadataTypeInfo[type].client = auth.getSDK(this.buObject);
|
|
77
78
|
MetadataTypeInfo[type].properties = this.properties;
|
|
79
|
+
MetadataTypeInfo[type].buObject = this.buObject;
|
|
78
80
|
return MetadataTypeInfo[type].buildDefinition(
|
|
79
81
|
this.templateDir,
|
|
80
82
|
this.targetDir,
|
|
81
83
|
name,
|
|
82
|
-
|
|
84
|
+
templateVariables
|
|
83
85
|
);
|
|
84
86
|
})
|
|
85
87
|
);
|
|
86
88
|
if (result) {
|
|
87
89
|
this.metadata[result[0].type] = [];
|
|
88
|
-
|
|
90
|
+
for (const element of result) {
|
|
89
91
|
this.metadata[result[0].type].push(element.metadata);
|
|
90
|
-
}
|
|
92
|
+
}
|
|
91
93
|
}
|
|
92
94
|
} catch (ex) {
|
|
93
|
-
Util.logger.
|
|
94
|
-
Util.logger.debug(ex.stack);
|
|
95
|
-
if (Util.logger.level === 'debug') {
|
|
96
|
-
console.log(ex.stack);
|
|
97
|
-
}
|
|
95
|
+
Util.logger.errorStack(ex, 'mcdev.buildDefinition');
|
|
98
96
|
}
|
|
99
97
|
return this.metadata;
|
|
100
98
|
}
|
|
101
99
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* @param {
|
|
105
|
-
* @param {
|
|
106
|
-
* @param {
|
|
107
|
-
* @param {
|
|
108
|
-
* @returns {
|
|
100
|
+
* Build a template based on a list of metadata files in the retrieve folder.
|
|
101
|
+
*
|
|
102
|
+
* @param {string} businessUnit references credentials from properties.json
|
|
103
|
+
* @param {string} selectedType supported metadata type
|
|
104
|
+
* @param {string[]} keyArr customerkey of the metadata
|
|
105
|
+
* @param {string} market market localizations
|
|
106
|
+
* @returns {Promise.<TYPE.MultiMetadataTypeList>} -
|
|
109
107
|
*/
|
|
110
|
-
static
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
108
|
+
static async buildTemplate(businessUnit, selectedType, keyArr, market) {
|
|
109
|
+
const properties = await config.getProperties();
|
|
110
|
+
if (!(await config.checkProperties(properties))) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
if (!Util._isValidType(selectedType)) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (selectedType.includes('-')) {
|
|
117
|
+
Util.logger.error(
|
|
118
|
+
`:: '${selectedType}' is not a valid metadata type. Please don't include subtypes.`
|
|
119
|
+
);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const buObject = await Cli.getCredentialObject(properties, businessUnit);
|
|
123
|
+
if (buObject !== null) {
|
|
124
|
+
const builder = new Builder(properties, buObject);
|
|
125
|
+
if (Util.checkMarket(market, properties)) {
|
|
126
|
+
return builder._buildTemplate(selectedType, keyArr, properties.markets[market]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Build a template based on a list of metadata files in the retrieve folder.
|
|
132
|
+
*
|
|
133
|
+
* @param {string} metadataType metadata type to create a template of
|
|
134
|
+
* @param {string[]} keyArr customerkey of metadata to create a template of
|
|
135
|
+
* @param {TYPE.TemplateMap} templateVariables variables to be replaced in the metadata
|
|
136
|
+
* @returns {Promise.<TYPE.MultiMetadataTypeList>} Promise
|
|
137
|
+
*/
|
|
138
|
+
async _buildTemplate(metadataType, keyArr, templateVariables) {
|
|
139
|
+
const type = metadataType;
|
|
140
|
+
try {
|
|
141
|
+
/** @type {TYPE.MetadataTypeItemObj[]} */
|
|
142
|
+
const result = await Promise.all(
|
|
143
|
+
keyArr.map((key) => {
|
|
144
|
+
MetadataTypeInfo[type].client = this.client;
|
|
145
|
+
MetadataTypeInfo[type].properties = this.properties;
|
|
146
|
+
MetadataTypeInfo[type].buObject = this.buObject;
|
|
116
147
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
148
|
+
/** @type {TYPE.MetadataTypeItemObj} */
|
|
149
|
+
return MetadataTypeInfo[type].buildTemplate(
|
|
150
|
+
this.retrieveDir,
|
|
151
|
+
this.templateDir,
|
|
152
|
+
key,
|
|
153
|
+
templateVariables
|
|
154
|
+
);
|
|
155
|
+
})
|
|
156
|
+
);
|
|
157
|
+
if (result) {
|
|
158
|
+
this.metadata[result[0].type] = result.map((element) => element.metadata);
|
|
159
|
+
}
|
|
160
|
+
} catch (ex) {
|
|
161
|
+
Util.logger.errorStack(ex, 'mcdev.buildTemplate');
|
|
162
|
+
}
|
|
163
|
+
return this.metadata;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Build a specific metadata file based on a template.
|
|
167
|
+
*
|
|
168
|
+
* @param {string} businessUnit references credentials from properties.json
|
|
169
|
+
* @param {string} selectedType supported metadata type
|
|
170
|
+
* @param {string} name name of the metadata
|
|
171
|
+
* @param {string} market market localizations
|
|
172
|
+
* @returns {Promise.<TYPE.MultiMetadataTypeList>} -
|
|
173
|
+
*/
|
|
174
|
+
static async buildDefinition(businessUnit, selectedType, name, market) {
|
|
175
|
+
const properties = await config.getProperties();
|
|
176
|
+
if (!(await config.checkProperties(properties))) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
if (!Util._isValidType(selectedType)) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (selectedType.includes('-')) {
|
|
183
|
+
Util.logger.error(
|
|
184
|
+
`:: '${selectedType}' is not a valid metadata type. Please don't include subtypes.`
|
|
185
|
+
);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const buObject = await Cli.getCredentialObject(properties, businessUnit);
|
|
189
|
+
if (buObject !== null) {
|
|
190
|
+
const builder = new Builder(properties, buObject);
|
|
191
|
+
if (Util.checkMarket(market, properties)) {
|
|
192
|
+
return builder._buildDefinition(selectedType, name, properties.markets[market]);
|
|
142
193
|
}
|
|
143
|
-
|
|
144
|
-
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Build a specific metadata file based on a template using a list of bu-market combos
|
|
198
|
+
*
|
|
199
|
+
* @param {string} listName name of list of BU-market combos
|
|
200
|
+
* @param {string} type supported metadata type
|
|
201
|
+
* @param {string} name name of the metadata
|
|
202
|
+
* @returns {Promise.<void>} -
|
|
203
|
+
*/
|
|
204
|
+
static async buildDefinitionBulk(listName, type, name) {
|
|
205
|
+
const properties = await config.getProperties();
|
|
206
|
+
if (!(await config.checkProperties(properties))) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
Util.verifyMarketList(listName, properties);
|
|
210
|
+
if (type && !MetadataTypeInfo[type]) {
|
|
211
|
+
Util.logger.error(`:: '${type}' is not a valid metadata type`);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
let i = 0;
|
|
215
|
+
for (const businessUnit in properties.marketList[listName]) {
|
|
216
|
+
if (businessUnit === 'description') {
|
|
217
|
+
// skip, it's just a metadata on this list and not a BU
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
i++;
|
|
221
|
+
const market = properties.marketList[listName][businessUnit];
|
|
222
|
+
let marketList = [];
|
|
223
|
+
if ('string' === typeof market) {
|
|
224
|
+
marketList.push(market);
|
|
225
|
+
} else {
|
|
226
|
+
marketList = market;
|
|
145
227
|
}
|
|
228
|
+
for (const market of marketList) {
|
|
229
|
+
if (Util.checkMarket(market, properties)) {
|
|
230
|
+
Util.logger.info(`Executing for '${businessUnit}': '${market}'`);
|
|
231
|
+
this.buildDefinition(businessUnit, type, name, market);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (!i) {
|
|
236
|
+
Util.logger.error('Please define properties.marketList in your config');
|
|
146
237
|
}
|
|
147
238
|
}
|
|
148
239
|
}
|