mcdev 3.0.2 → 3.1.2
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 +1 -1
- package/.github/ISSUE_TEMPLATE/bug.yml +75 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +3 -2
- package/.issuetracker +11 -3
- package/.vscode/settings.json +3 -3
- package/CHANGELOG.md +88 -0
- package/README.md +245 -141
- package/boilerplate/config.json +3 -2
- package/docs/dist/documentation.md +818 -352
- package/lib/Deployer.js +4 -1
- package/lib/MetadataTypeDefinitions.js +1 -0
- package/lib/MetadataTypeInfo.js +1 -0
- package/lib/Retriever.js +30 -14
- package/lib/cli.js +295 -0
- package/lib/index.js +774 -1019
- package/lib/metadataTypes/AccountUser.js +389 -0
- package/lib/metadataTypes/Asset.js +8 -7
- package/lib/metadataTypes/Automation.js +121 -56
- package/lib/metadataTypes/DataExtension.js +167 -121
- package/lib/metadataTypes/DataExtensionField.js +134 -4
- package/lib/metadataTypes/DataExtract.js +9 -5
- package/lib/metadataTypes/EventDefinition.js +9 -5
- package/lib/metadataTypes/FileTransfer.js +9 -5
- package/lib/metadataTypes/Folder.js +66 -69
- package/lib/metadataTypes/ImportFile.js +13 -12
- package/lib/metadataTypes/MetadataType.js +138 -77
- package/lib/metadataTypes/Query.js +2 -3
- package/lib/metadataTypes/Role.js +13 -8
- package/lib/metadataTypes/Script.js +2 -2
- package/lib/metadataTypes/definitions/AccountUser.definition.js +227 -0
- package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
- package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -1
- package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -1
- package/lib/metadataTypes/definitions/Folder.definition.js +1 -1
- package/lib/metadataTypes/definitions/ImportFile.definition.js +2 -1
- package/lib/metadataTypes/definitions/Script.definition.js +5 -5
- package/lib/retrieveChangelog.js +96 -0
- package/lib/util/cli.js +4 -6
- package/lib/util/init.git.js +2 -1
- package/lib/util/util.js +20 -3
- package/package.json +19 -23
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
- package/img/README.md/troubleshoot-nodejs-postinstall.jpg +0 -0
- package/postinstall.js +0 -41
package/lib/Deployer.js
CHANGED
|
@@ -81,7 +81,10 @@ class Deployer {
|
|
|
81
81
|
MetadataTypeInfo[type].client = this.client;
|
|
82
82
|
MetadataTypeInfo[type].properties = this.properties;
|
|
83
83
|
Util.logger.info('Caching dependent Metadata: ' + metadataType);
|
|
84
|
-
|
|
84
|
+
let result;
|
|
85
|
+
await Util.retryOnError(`Retrying ${type}`, async () => {
|
|
86
|
+
result = await MetadataTypeInfo[type].retrieveForCache(this.buObject, subType);
|
|
87
|
+
});
|
|
85
88
|
this.cache[type] = result.metadata;
|
|
86
89
|
}
|
|
87
90
|
// deploy metadata files, extending cache once deploys
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides access to all metadataType classes
|
|
5
5
|
*/
|
|
6
6
|
const MetadataTypeDefinitions = {
|
|
7
|
+
accountUser: require('./metadataTypes/definitions/AccountUser.definition'),
|
|
7
8
|
asset: require('./metadataTypes/definitions/Asset.definition'),
|
|
8
9
|
attributeGroup: require('./metadataTypes/definitions/AttributeGroup.definition'),
|
|
9
10
|
automation: require('./metadataTypes/definitions/Automation.definition'),
|
package/lib/MetadataTypeInfo.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides access to all metadataType classes
|
|
5
5
|
*/
|
|
6
6
|
const MetadataTypeInfo = {
|
|
7
|
+
accountUser: require('./metadataTypes/AccountUser'),
|
|
7
8
|
asset: require('./metadataTypes/Asset'),
|
|
8
9
|
attributeGroup: require('./metadataTypes/AttributeGroup'),
|
|
9
10
|
automation: require('./metadataTypes/Automation'),
|
package/lib/Retriever.js
CHANGED
|
@@ -40,9 +40,11 @@ class Retriever {
|
|
|
40
40
|
* @param {String[]} metadataTypes String list of metadata types to retrieve
|
|
41
41
|
* @param {String} [name] name of Metadata to retrieve (in case of templating)
|
|
42
42
|
* @param {Object} [templateVariables] Object of values which can be replaced (in case of templating)
|
|
43
|
-
* @
|
|
43
|
+
* @param {boolean} [changelogOnly] skip saving, only create json in memory
|
|
44
|
+
* @returns {Promise<Object<string,Object>>} Promise
|
|
44
45
|
*/
|
|
45
|
-
async retrieve(metadataTypes, name, templateVariables) {
|
|
46
|
+
async retrieve(metadataTypes, name, templateVariables, changelogOnly) {
|
|
47
|
+
const retrieveChangelog = {};
|
|
46
48
|
for (const metadataType of Util.getMetadataHierachy(metadataTypes)) {
|
|
47
49
|
let result;
|
|
48
50
|
const [type, subType] = metadataType.split('-');
|
|
@@ -53,6 +55,10 @@ class Retriever {
|
|
|
53
55
|
|
|
54
56
|
try {
|
|
55
57
|
if (!metadataTypes.includes(type) && !metadataTypes.includes(metadataType)) {
|
|
58
|
+
if (changelogOnly) {
|
|
59
|
+
// no extra caching needed for list view
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
56
62
|
Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
|
|
57
63
|
await Util.retryOnError(
|
|
58
64
|
`Retrying to cache ${metadataType}`,
|
|
@@ -61,10 +67,6 @@ class Retriever {
|
|
|
61
67
|
this.buObject,
|
|
62
68
|
subType
|
|
63
69
|
);
|
|
64
|
-
if (type == 'list') {
|
|
65
|
-
Util.logger.debug('==list==');
|
|
66
|
-
Util.logger.debug(JSON.stringify(result));
|
|
67
|
-
}
|
|
68
70
|
},
|
|
69
71
|
false
|
|
70
72
|
);
|
|
@@ -97,14 +99,24 @@ class Retriever {
|
|
|
97
99
|
});
|
|
98
100
|
} else {
|
|
99
101
|
Util.logger.info('Retrieving: ' + metadataType);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
if (changelogOnly) {
|
|
103
|
+
await Util.retryOnError(`Retrying ${metadataType}`, async () => {
|
|
104
|
+
result = await MetadataTypeInfo[type].retrieveChangelog(
|
|
105
|
+
null,
|
|
106
|
+
this.buObject,
|
|
107
|
+
subType
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
await Util.retryOnError(`Retrying ${metadataType}`, async () => {
|
|
112
|
+
result = await MetadataTypeInfo[type].retrieve(
|
|
113
|
+
this.savePath,
|
|
114
|
+
null,
|
|
115
|
+
this.buObject,
|
|
116
|
+
subType
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
108
120
|
}
|
|
109
121
|
if (result) {
|
|
110
122
|
if (templateVariables && Array.isArray(result)) {
|
|
@@ -112,6 +124,9 @@ class Retriever {
|
|
|
112
124
|
this.metadata[type] = result.map((element) => element.metadata);
|
|
113
125
|
} else {
|
|
114
126
|
this.metadata[type] = result.metadata;
|
|
127
|
+
if (metadataTypes.includes(type) || metadataTypes.includes(metadataType)) {
|
|
128
|
+
retrieveChangelog[type] = result.metadata;
|
|
129
|
+
}
|
|
115
130
|
}
|
|
116
131
|
}
|
|
117
132
|
} catch (ex) {
|
|
@@ -122,6 +137,7 @@ class Retriever {
|
|
|
122
137
|
}
|
|
123
138
|
}
|
|
124
139
|
}
|
|
140
|
+
return retrieveChangelog;
|
|
125
141
|
}
|
|
126
142
|
}
|
|
127
143
|
|
package/lib/cli.js
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* CLI entry for SFMC DevTools
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const Util = require('./util/util');
|
|
9
|
+
const yargs = require('yargs');
|
|
10
|
+
const Mcdev = require('./index');
|
|
11
|
+
|
|
12
|
+
yargs
|
|
13
|
+
.scriptName('mcdev')
|
|
14
|
+
.usage('$0 <command> [options]')
|
|
15
|
+
.command({
|
|
16
|
+
command: 'retrieve [BU] [TYPE]',
|
|
17
|
+
aliases: ['r'],
|
|
18
|
+
desc: 'retrieves metadata of a business unit',
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
builder: (yargs) => {
|
|
21
|
+
yargs
|
|
22
|
+
.positional('BU', {
|
|
23
|
+
type: 'string',
|
|
24
|
+
describe:
|
|
25
|
+
'the business unit to retrieve from (in format "credential name/BU name")',
|
|
26
|
+
})
|
|
27
|
+
.positional('TYPE', {
|
|
28
|
+
type: 'string',
|
|
29
|
+
describe: 'metadata type that shall be exclusively downloaded',
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
handler: (argv) => {
|
|
33
|
+
Mcdev._setLoggingLevel(argv);
|
|
34
|
+
Mcdev.retrieve(argv.BU, argv.TYPE);
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
.command({
|
|
38
|
+
command: 'deploy [BU] [TYPE]',
|
|
39
|
+
aliases: ['d'],
|
|
40
|
+
desc: 'deploys local metadata to a business unit',
|
|
41
|
+
builder: (yargs) => {
|
|
42
|
+
yargs
|
|
43
|
+
.positional('BU', {
|
|
44
|
+
type: 'string',
|
|
45
|
+
describe:
|
|
46
|
+
'the business unit to deploy to (in format "credential name/BU name")',
|
|
47
|
+
})
|
|
48
|
+
.positional('TYPE', {
|
|
49
|
+
type: 'string',
|
|
50
|
+
describe: 'metadata type that shall be exclusively uploaded',
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
handler: (argv) => {
|
|
54
|
+
Mcdev._setLoggingLevel(argv);
|
|
55
|
+
Mcdev.deploy(argv.BU, argv.TYPE);
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
.command({
|
|
59
|
+
command: 'init [credentialsName]',
|
|
60
|
+
desc: `creates '${Util.configFileName}' in your root or adds additional credentials to the existing one`,
|
|
61
|
+
builder: (yargs) => {
|
|
62
|
+
yargs.positional('credentialsName', {
|
|
63
|
+
type: 'string',
|
|
64
|
+
describe: 'name of your installed package',
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
handler: (argv) => {
|
|
68
|
+
Mcdev._setLoggingLevel(argv);
|
|
69
|
+
Mcdev.initProject(argv.credentialsName, argv.skipInteraction);
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
.command({
|
|
73
|
+
command: 'reloadBUs [credentialsName]',
|
|
74
|
+
aliases: ['rb'],
|
|
75
|
+
desc: 'loads the list of available BUs from the server and saves it to your config',
|
|
76
|
+
builder: (yargs) => {
|
|
77
|
+
yargs.positional('credentialsName', {
|
|
78
|
+
type: 'string',
|
|
79
|
+
describe: 'name of your installed package',
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
handler: (argv) => {
|
|
83
|
+
Mcdev._setLoggingLevel(argv);
|
|
84
|
+
Mcdev.findBUs(argv.credentialsName);
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
.command({
|
|
88
|
+
command: 'badKeys [BU]',
|
|
89
|
+
desc: 'lists metadata with random API names in specified Business Unit directory',
|
|
90
|
+
builder: (yargs) => {
|
|
91
|
+
yargs.positional('BU', {
|
|
92
|
+
type: 'string',
|
|
93
|
+
describe: 'the business unit to deploy to',
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
handler: (argv) => {
|
|
97
|
+
Mcdev._setLoggingLevel(argv);
|
|
98
|
+
Mcdev.badKeys(argv.BU);
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
.command({
|
|
102
|
+
command: 'document <BU> <TYPE>',
|
|
103
|
+
aliases: ['doc'],
|
|
104
|
+
desc: 'Creates Markdown or HTML documentation for the selected type',
|
|
105
|
+
builder: (yargs) => {
|
|
106
|
+
yargs
|
|
107
|
+
.positional('TYPE', {
|
|
108
|
+
type: 'string',
|
|
109
|
+
describe:
|
|
110
|
+
'metadata type to generate docs for; currently supported: dataExtension, role',
|
|
111
|
+
})
|
|
112
|
+
.positional('BU', {
|
|
113
|
+
type: 'string',
|
|
114
|
+
describe:
|
|
115
|
+
'the business unit to generate docs for (in format "credential name/BU name")',
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
handler: (argv) => {
|
|
119
|
+
Mcdev._setLoggingLevel(argv);
|
|
120
|
+
Mcdev.document(argv.BU, argv.TYPE);
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
.command({
|
|
124
|
+
command: 'delete <BU> <TYPE> <EXTERNALKEY>',
|
|
125
|
+
aliases: ['del'],
|
|
126
|
+
desc: 'deletes metadata of selected type and external key',
|
|
127
|
+
builder: (yargs) => {
|
|
128
|
+
yargs
|
|
129
|
+
.positional('BU', {
|
|
130
|
+
type: 'string',
|
|
131
|
+
describe:
|
|
132
|
+
'the business unit to delete from (in format "credential name/BU name")',
|
|
133
|
+
})
|
|
134
|
+
.positional('TYPE', {
|
|
135
|
+
type: 'string',
|
|
136
|
+
describe: 'metadata type to delete from; currently supported: dataExtension',
|
|
137
|
+
})
|
|
138
|
+
.positional('EXTERNALKEY', {
|
|
139
|
+
type: 'string',
|
|
140
|
+
describe: 'the key to delete',
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
handler: (argv) => {
|
|
144
|
+
Mcdev._setLoggingLevel(argv);
|
|
145
|
+
Mcdev.deleteByKey(argv.BU, argv.TYPE, argv.EXTERNALKEY);
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
.command({
|
|
149
|
+
command: 'retrieveAsTemplate <BU> <TYPE> <NAME> <MARKET>',
|
|
150
|
+
aliases: ['rt'],
|
|
151
|
+
desc: 'Retrieves a specific metadata file by name for templating',
|
|
152
|
+
builder: (yargs) => {
|
|
153
|
+
yargs
|
|
154
|
+
.positional('BU', {
|
|
155
|
+
type: 'string',
|
|
156
|
+
describe:
|
|
157
|
+
'the business unit to deploy to (in format "credential name/BU name")',
|
|
158
|
+
})
|
|
159
|
+
.positional('TYPE', {
|
|
160
|
+
type: 'string',
|
|
161
|
+
describe: 'metadata type',
|
|
162
|
+
})
|
|
163
|
+
.positional('NAME', {
|
|
164
|
+
type: 'string',
|
|
165
|
+
describe: 'name of the metadata component',
|
|
166
|
+
})
|
|
167
|
+
.positional('MARKET', {
|
|
168
|
+
type: 'string',
|
|
169
|
+
describe: 'market used for reverse building template',
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
handler: (argv) => {
|
|
173
|
+
Mcdev._setLoggingLevel(argv);
|
|
174
|
+
Mcdev.retrieveAsTemplate(argv.BU, argv.TYPE, argv.NAME, argv.MARKET);
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
.command({
|
|
178
|
+
command: 'buildDefinition <BU> <TYPE> <NAME> <MARKET>',
|
|
179
|
+
aliases: ['bd'],
|
|
180
|
+
desc: 'builds metadata definition based on template',
|
|
181
|
+
builder: (yargs) => {
|
|
182
|
+
yargs
|
|
183
|
+
.positional('BU', {
|
|
184
|
+
type: 'string',
|
|
185
|
+
describe: 'the business unit to deploy to',
|
|
186
|
+
})
|
|
187
|
+
.positional('TYPE', {
|
|
188
|
+
type: 'string',
|
|
189
|
+
describe: 'metadata type',
|
|
190
|
+
})
|
|
191
|
+
.positional('NAME', {
|
|
192
|
+
type: 'string',
|
|
193
|
+
describe: 'name of the metadata component',
|
|
194
|
+
})
|
|
195
|
+
.positional('MARKET', {
|
|
196
|
+
type: 'string',
|
|
197
|
+
describe: 'the business unit to deploy to',
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
handler: (argv) => {
|
|
201
|
+
Mcdev._setLoggingLevel(argv);
|
|
202
|
+
Mcdev.buildDefinition(argv.BU, argv.TYPE, argv.NAME, argv.MARKET);
|
|
203
|
+
},
|
|
204
|
+
})
|
|
205
|
+
.command({
|
|
206
|
+
command: 'buildDefinitionBulk <LISTNAME> <TYPE> <NAME>',
|
|
207
|
+
aliases: ['bdb'],
|
|
208
|
+
desc: 'builds metadata definition based on template en bulk',
|
|
209
|
+
builder: (yargs) => {
|
|
210
|
+
yargs
|
|
211
|
+
.positional('LISTNAME', {
|
|
212
|
+
type: 'string',
|
|
213
|
+
describe: 'name of list of BU-market combos',
|
|
214
|
+
})
|
|
215
|
+
.positional('TYPE', {
|
|
216
|
+
type: 'string',
|
|
217
|
+
describe: 'metadata type',
|
|
218
|
+
})
|
|
219
|
+
.positional('NAME', {
|
|
220
|
+
type: 'string',
|
|
221
|
+
describe: 'name of the metadata component',
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
handler: (argv) => {
|
|
225
|
+
Mcdev._setLoggingLevel(argv);
|
|
226
|
+
Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, argv.NAME);
|
|
227
|
+
},
|
|
228
|
+
})
|
|
229
|
+
.command({
|
|
230
|
+
command: 'selectTypes',
|
|
231
|
+
aliases: ['st'],
|
|
232
|
+
desc: 'lets you choose what metadata types to retrieve',
|
|
233
|
+
handler: (argv) => {
|
|
234
|
+
Mcdev._setLoggingLevel(argv);
|
|
235
|
+
Mcdev.selectTypes();
|
|
236
|
+
},
|
|
237
|
+
})
|
|
238
|
+
.command({
|
|
239
|
+
command: 'explainTypes',
|
|
240
|
+
aliases: ['et'],
|
|
241
|
+
desc: 'explains metadata types that can be retrieved',
|
|
242
|
+
handler: (argv) => {
|
|
243
|
+
Mcdev._setLoggingLevel(argv);
|
|
244
|
+
Mcdev.explainTypes();
|
|
245
|
+
},
|
|
246
|
+
})
|
|
247
|
+
.command({
|
|
248
|
+
command: 'createDeltaPkg [range] [filter]',
|
|
249
|
+
aliases: ['cdp'],
|
|
250
|
+
desc: 'Copies commit-based file delta into deploy folder',
|
|
251
|
+
builder: (yargs) => {
|
|
252
|
+
yargs
|
|
253
|
+
.positional('range', {
|
|
254
|
+
type: 'string',
|
|
255
|
+
describe: 'Pull Request target branch or git commit range',
|
|
256
|
+
})
|
|
257
|
+
.positional('filter', {
|
|
258
|
+
type: 'string',
|
|
259
|
+
describe:
|
|
260
|
+
'Disable templating & instead filter by the specified file path (comma separated)',
|
|
261
|
+
});
|
|
262
|
+
},
|
|
263
|
+
handler: Mcdev.createDeltaPkg,
|
|
264
|
+
})
|
|
265
|
+
.command({
|
|
266
|
+
command: 'upgrade',
|
|
267
|
+
aliases: ['up'],
|
|
268
|
+
desc: 'Add NPM dependencies and IDE configuration files to your project',
|
|
269
|
+
handler: (argv) => {
|
|
270
|
+
Mcdev._setLoggingLevel(argv);
|
|
271
|
+
Mcdev.upgrade(argv.skipInteraction);
|
|
272
|
+
},
|
|
273
|
+
})
|
|
274
|
+
.option('verbose', {
|
|
275
|
+
type: 'boolean',
|
|
276
|
+
description: 'Run with verbose CLI output',
|
|
277
|
+
})
|
|
278
|
+
.option('debug', {
|
|
279
|
+
type: 'boolean',
|
|
280
|
+
description: 'Enable developer & edge-case features',
|
|
281
|
+
})
|
|
282
|
+
.option('silent', {
|
|
283
|
+
type: 'boolean',
|
|
284
|
+
description: 'Only output errors to CLI',
|
|
285
|
+
})
|
|
286
|
+
.option('skipInteraction', {
|
|
287
|
+
alias: ['yes', 'y'],
|
|
288
|
+
description: 'Interactive questions where possible and go with defaults instead',
|
|
289
|
+
})
|
|
290
|
+
.demandCommand(1, 'Please enter a valid command')
|
|
291
|
+
.strict()
|
|
292
|
+
.recommendCommands()
|
|
293
|
+
.wrap(yargs.terminalWidth())
|
|
294
|
+
.epilog('Copyright 2021. Accenture.')
|
|
295
|
+
.help().argv;
|