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/lib/util/init.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const TYPE = require('../../types/mcdev.d');
|
|
3
3
|
const Cli = require('./cli');
|
|
4
4
|
const File = require('./file');
|
|
5
|
+
const config = require('./config');
|
|
5
6
|
const InitGit = require('./init.git');
|
|
6
7
|
const InitNpm = require('./init.npm');
|
|
7
8
|
const InitConfig = require('./init.config');
|
|
@@ -15,27 +16,27 @@ const Util = require('./util');
|
|
|
15
16
|
const Init = {
|
|
16
17
|
/**
|
|
17
18
|
* Creates template file for properties.json
|
|
18
|
-
*
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {
|
|
22
|
-
* @
|
|
23
|
-
* @param {String} skipInteraction.tenant client id of installed package
|
|
24
|
-
* @param {String} skipInteraction.credentialsName how you would like the credential to be named
|
|
25
|
-
* @param {String} skipInteraction.gitRemoteUrl URL of Git remote server
|
|
26
|
-
* @returns {Promise<void>} -
|
|
19
|
+
*
|
|
20
|
+
* @param {TYPE.Mcdevrc} properties config file's json
|
|
21
|
+
* @param {string} credentialName identifying name of the installed package / project
|
|
22
|
+
* @param {TYPE.skipInteraction} [skipInteraction] signals what to insert automatically for things usually asked via wizard
|
|
23
|
+
* @returns {Promise.<void>} -
|
|
27
24
|
*/
|
|
28
|
-
async initProject(properties,
|
|
25
|
+
async initProject(properties, credentialName, skipInteraction) {
|
|
26
|
+
if (!properties) {
|
|
27
|
+
// try to get cached properties because we return null in case of a crucial error
|
|
28
|
+
properties = config.properties;
|
|
29
|
+
}
|
|
29
30
|
const missingCredentials = this._getMissingCredentials(properties);
|
|
30
|
-
if (File.
|
|
31
|
+
if ((await File.pathExists(Util.configFileName)) && properties) {
|
|
31
32
|
// config exists
|
|
32
|
-
if (
|
|
33
|
-
Util.logger.info(`Updating credential '${
|
|
33
|
+
if (credentialName) {
|
|
34
|
+
Util.logger.info(`Updating credential '${credentialName}'`);
|
|
34
35
|
// update-credential mode
|
|
35
|
-
if (!properties.credentials[
|
|
36
|
-
Util.logger.error(`Could not find credential '${
|
|
36
|
+
if (!properties.credentials[credentialName]) {
|
|
37
|
+
Util.logger.error(`Could not find credential '${credentialName}'`);
|
|
37
38
|
const response = await Cli._selectBU(properties, null, true);
|
|
38
|
-
|
|
39
|
+
credentialName = response.credential;
|
|
39
40
|
}
|
|
40
41
|
let error;
|
|
41
42
|
do {
|
|
@@ -43,20 +44,20 @@ const Init = {
|
|
|
43
44
|
try {
|
|
44
45
|
const success = await Cli.updateCredential(
|
|
45
46
|
properties,
|
|
46
|
-
|
|
47
|
+
credentialName,
|
|
47
48
|
skipInteraction
|
|
48
49
|
);
|
|
49
50
|
if (success) {
|
|
50
|
-
Util.logger.info(`✔️ Credential '${
|
|
51
|
+
Util.logger.info(`✔️ Credential '${credentialName}' updated.`);
|
|
51
52
|
} else {
|
|
52
53
|
error = true;
|
|
53
54
|
}
|
|
54
|
-
} catch
|
|
55
|
+
} catch {
|
|
55
56
|
error = true;
|
|
56
57
|
}
|
|
57
58
|
} while (error && !skipInteraction);
|
|
58
59
|
Util.logger.debug('reloading config');
|
|
59
|
-
properties =
|
|
60
|
+
properties = await config.getProperties(true);
|
|
60
61
|
} else if (missingCredentials.length) {
|
|
61
62
|
// forced update-credential mode - user likely cloned repo and is missing mcdev-auth.json
|
|
62
63
|
Util.logger.warn(
|
|
@@ -81,12 +82,12 @@ const Init = {
|
|
|
81
82
|
} else {
|
|
82
83
|
error = true;
|
|
83
84
|
}
|
|
84
|
-
} catch
|
|
85
|
+
} catch {
|
|
85
86
|
error = true;
|
|
86
87
|
}
|
|
87
88
|
} while (error);
|
|
88
89
|
Util.logger.debug('reloading config');
|
|
89
|
-
properties =
|
|
90
|
+
properties = await config.getProperties(true);
|
|
90
91
|
}
|
|
91
92
|
Util.logger.info('✔️ All credentials updated.');
|
|
92
93
|
// assume node dependencies are not installed
|
|
@@ -100,34 +101,30 @@ const Init = {
|
|
|
100
101
|
let responses;
|
|
101
102
|
if (skipInteraction) {
|
|
102
103
|
if (
|
|
103
|
-
skipInteraction.
|
|
104
|
-
skipInteraction.
|
|
105
|
-
skipInteraction.
|
|
106
|
-
skipInteraction.
|
|
104
|
+
skipInteraction.client_id &&
|
|
105
|
+
skipInteraction.client_secret &&
|
|
106
|
+
skipInteraction.auth_url &&
|
|
107
|
+
skipInteraction.account_id &&
|
|
108
|
+
skipInteraction.credentialName
|
|
107
109
|
) {
|
|
108
110
|
// assume automated input; only option here is to add a new credential
|
|
109
|
-
// requires skipInteraction=={
|
|
111
|
+
// requires skipInteraction=={client_id,client_secret,auth_url,account_id,credentialName}
|
|
110
112
|
// will be checked inside of Cli.addExtraCredential()
|
|
111
113
|
Util.logger.info('Adding another credential');
|
|
112
114
|
} else {
|
|
113
115
|
throw new Error(
|
|
114
|
-
'--skipInteraction flag found but missing required input for
|
|
116
|
+
'--skipInteraction flag found but missing required input for client_id,client_secret,auth_url,account_id,credentialName'
|
|
115
117
|
);
|
|
116
118
|
}
|
|
117
119
|
} else {
|
|
118
|
-
|
|
120
|
+
responses = await inquirer.prompt([
|
|
119
121
|
{
|
|
120
122
|
type: 'confirm',
|
|
121
123
|
name: 'isAddCredential',
|
|
122
124
|
message: 'Do you want to add another credential instead?',
|
|
123
125
|
default: false,
|
|
124
126
|
},
|
|
125
|
-
];
|
|
126
|
-
responses = await new Promise((resolve) => {
|
|
127
|
-
inquirer.prompt(questions).then((answers) => {
|
|
128
|
-
resolve(answers);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
127
|
+
]);
|
|
131
128
|
}
|
|
132
129
|
let credentialName;
|
|
133
130
|
if (skipInteraction || responses.isAddCredential) {
|
|
@@ -148,6 +145,7 @@ const Init = {
|
|
|
148
145
|
}
|
|
149
146
|
|
|
150
147
|
// set up IDE files and load npm dependencies
|
|
148
|
+
|
|
151
149
|
let status = await this.upgradeProject(properties, true, initGit.repoName);
|
|
152
150
|
if (!status) {
|
|
153
151
|
return;
|
|
@@ -182,27 +180,23 @@ const Init = {
|
|
|
182
180
|
},
|
|
183
181
|
/**
|
|
184
182
|
* helper for this.initProject()
|
|
185
|
-
*
|
|
186
|
-
* @param {
|
|
187
|
-
* @param {
|
|
188
|
-
* @
|
|
183
|
+
*
|
|
184
|
+
* @param {string} bu cred/bu or cred/* or *
|
|
185
|
+
* @param {string} gitStatus signals what state the git repo is in
|
|
186
|
+
* @param {boolean | TYPE.skipInteraction} [skipInteraction] signals what to insert automatically for things usually asked via wizard
|
|
187
|
+
* @returns {Promise.<void>} -
|
|
189
188
|
*/
|
|
190
189
|
async _downloadAllBUs(bu, gitStatus, skipInteraction) {
|
|
191
190
|
let responses;
|
|
192
191
|
if (!skipInteraction) {
|
|
193
|
-
|
|
192
|
+
responses = await inquirer.prompt([
|
|
194
193
|
{
|
|
195
194
|
type: 'confirm',
|
|
196
195
|
name: 'initialRetrieveAll',
|
|
197
196
|
message: 'Do you want to start downloading all Business Units (recommended)?',
|
|
198
197
|
default: true,
|
|
199
198
|
},
|
|
200
|
-
];
|
|
201
|
-
responses = await new Promise((resolve) => {
|
|
202
|
-
inquirer.prompt(questions).then((answers) => {
|
|
203
|
-
resolve(answers);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
199
|
+
]);
|
|
206
200
|
}
|
|
207
201
|
if (skipInteraction || responses.initialRetrieveAll) {
|
|
208
202
|
Util.execSync('mcdev', ['retrieve', bu]);
|
|
@@ -226,14 +220,15 @@ const Init = {
|
|
|
226
220
|
},
|
|
227
221
|
/**
|
|
228
222
|
* wrapper around npm dependency & configuration file setup
|
|
229
|
-
*
|
|
230
|
-
* @param {
|
|
231
|
-
* @param {
|
|
232
|
-
* @
|
|
223
|
+
*
|
|
224
|
+
* @param {TYPE.Mcdevrc} properties config file's json
|
|
225
|
+
* @param {boolean} [initial] print message if not part of initial setup
|
|
226
|
+
* @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init
|
|
227
|
+
* @returns {Promise.<boolean>} success flag
|
|
233
228
|
*/
|
|
234
229
|
async upgradeProject(properties, initial, repoName) {
|
|
235
230
|
let status;
|
|
236
|
-
|
|
231
|
+
const versionBeforeUpgrade = properties?.version || '0.0.0';
|
|
237
232
|
if (!initial) {
|
|
238
233
|
Util.logger.info(
|
|
239
234
|
'Upgrading project with newest configuration, npm dependencies & other project configurations:'
|
|
@@ -244,10 +239,15 @@ const Init = {
|
|
|
244
239
|
if (!status) {
|
|
245
240
|
return false;
|
|
246
241
|
}
|
|
242
|
+
// version 4 release to simplify auth
|
|
243
|
+
status = await InitConfig.upgradeAuthFile(properties);
|
|
244
|
+
if (!status) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
// create files before installing dependencies to ensure .gitignore is properly set up
|
|
250
|
-
status = await InitConfig.createIdeConfigFiles();
|
|
250
|
+
status = await InitConfig.createIdeConfigFiles(versionBeforeUpgrade);
|
|
251
251
|
if (!status) {
|
|
252
252
|
return false;
|
|
253
253
|
}
|
|
@@ -262,17 +262,30 @@ const Init = {
|
|
|
262
262
|
},
|
|
263
263
|
/**
|
|
264
264
|
* finds credentials that are set up in config but not in auth file
|
|
265
|
-
*
|
|
266
|
-
* @
|
|
265
|
+
*
|
|
266
|
+
* @param {TYPE.Mcdevrc} properties javascript object in .mcdevrc.json
|
|
267
|
+
* @returns {string[]} list of credential names
|
|
267
268
|
*/
|
|
268
269
|
_getMissingCredentials(properties) {
|
|
269
270
|
let missingCredentials;
|
|
270
|
-
if (properties
|
|
271
|
+
if (properties?.credentials) {
|
|
272
|
+
// reload auth file because for some reason we didnt want that in our main properties object
|
|
273
|
+
let auth;
|
|
274
|
+
try {
|
|
275
|
+
auth = File.readJsonSync(Util.authFileName);
|
|
276
|
+
} catch (ex) {
|
|
277
|
+
Util.logger.error(`${ex.code}: ${ex.message}`);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// walk through config credentials and check if the matching credential in the auth file is missing something
|
|
271
281
|
missingCredentials = Object.keys(properties.credentials).filter(
|
|
272
282
|
(cred) =>
|
|
273
|
-
!
|
|
274
|
-
!
|
|
275
|
-
|
|
283
|
+
!auth[cred] ||
|
|
284
|
+
!auth[cred].account_id ||
|
|
285
|
+
properties.credentials[cred].eid != auth[cred].account_id ||
|
|
286
|
+
!auth[cred].client_id ||
|
|
287
|
+
!auth[cred].client_secret ||
|
|
288
|
+
!auth[cred].auth_url
|
|
276
289
|
);
|
|
277
290
|
}
|
|
278
291
|
return missingCredentials || [];
|
package/lib/util/init.npm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const File = require('./file');
|
|
4
|
-
const
|
|
5
|
-
const path = require('path');
|
|
4
|
+
const path = require('node:path');
|
|
6
5
|
const Util = require('./util');
|
|
6
|
+
const semver = require('semver');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* CLI helper class
|
|
@@ -14,15 +14,16 @@ const Init = {
|
|
|
14
14
|
* initiates npm project and then
|
|
15
15
|
* takes care of loading the pre-configured dependency list
|
|
16
16
|
* from the boilerplate directory to them as dev-dependencies
|
|
17
|
-
*
|
|
18
|
-
* @
|
|
17
|
+
*
|
|
18
|
+
* @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init
|
|
19
|
+
* @returns {Promise.<boolean>} install successful or error occured
|
|
19
20
|
*/
|
|
20
21
|
async installDependencies(repoName) {
|
|
21
22
|
let fileContent;
|
|
22
23
|
let projectPackageJson;
|
|
23
|
-
if (File.
|
|
24
|
+
if (await File.pathExists('package.json')) {
|
|
24
25
|
try {
|
|
25
|
-
fileContent = File.
|
|
26
|
+
fileContent = await File.readFile('package.json', 'utf8');
|
|
26
27
|
} catch (ex) {
|
|
27
28
|
Util.logger.error(
|
|
28
29
|
'Your package.json was found but seems to be corrupted: ' + ex.message
|
|
@@ -55,7 +56,7 @@ const Init = {
|
|
|
55
56
|
projectPackageJson = JSON.parse(fileContent);
|
|
56
57
|
}
|
|
57
58
|
Util.logger.info('✔️ package.json created');
|
|
58
|
-
} catch
|
|
59
|
+
} catch {
|
|
59
60
|
Util.logger.error('No package.json found. Please run "npm init" manually');
|
|
60
61
|
return false;
|
|
61
62
|
}
|
|
@@ -67,55 +68,64 @@ const Init = {
|
|
|
67
68
|
Util.boilerplateDirectory,
|
|
68
69
|
'npm-dependencies.json'
|
|
69
70
|
);
|
|
70
|
-
if (!File.
|
|
71
|
+
if (!(await File.pathExists(dependencyFile))) {
|
|
71
72
|
Util.logger.debug(`Dependency file not found in ${dependencyFile}`);
|
|
72
73
|
return false;
|
|
73
74
|
}
|
|
74
|
-
const defaultDependencies = File.
|
|
75
|
+
const defaultDependencies = await File.readJson(dependencyFile);
|
|
76
|
+
const versionsDefault = {};
|
|
77
|
+
for (const name of defaultDependencies) {
|
|
78
|
+
// check mcdev.devDependencies first
|
|
79
|
+
versionsDefault[name] = Object.keys(Util.packageJsonMcdev.dependencies).includes(name)
|
|
80
|
+
? Util.packageJsonMcdev.dependencies[name]
|
|
81
|
+
: // then check mcdev.devDependencies
|
|
82
|
+
Object.keys(Util.packageJsonMcdev.devDependencies).includes(name)
|
|
83
|
+
? Util.packageJsonMcdev.devDependencies[name]
|
|
84
|
+
: // fallback to using latest version if not found
|
|
85
|
+
'latest';
|
|
86
|
+
}
|
|
75
87
|
|
|
88
|
+
const versionsProject = {};
|
|
89
|
+
if (projectPackageJson.devDependencies) {
|
|
90
|
+
for (const name of defaultDependencies) {
|
|
91
|
+
// check project.devDependencies
|
|
92
|
+
versionsProject[name] = Object.keys(projectPackageJson.devDependencies).includes(
|
|
93
|
+
name
|
|
94
|
+
)
|
|
95
|
+
? projectPackageJson.devDependencies[name].replace(/^[\^~]/, '')
|
|
96
|
+
: // fallback to invalid version if not found
|
|
97
|
+
'0.0.0';
|
|
98
|
+
}
|
|
99
|
+
}
|
|
76
100
|
const loadDependencies = defaultDependencies.filter(
|
|
77
101
|
(name) =>
|
|
78
102
|
!projectPackageJson ||
|
|
79
103
|
!projectPackageJson.devDependencies ||
|
|
80
|
-
!projectPackageJson.devDependencies[name]
|
|
104
|
+
!projectPackageJson.devDependencies[name] ||
|
|
105
|
+
versionsDefault[name] == 'latest' ||
|
|
106
|
+
semver.gt(versionsDefault[name], versionsProject[name])
|
|
81
107
|
);
|
|
82
|
-
if (loadDependencies.length < defaultDependencies.length) {
|
|
83
|
-
Util.logger.info(
|
|
84
|
-
`✔️ ${
|
|
85
|
-
!loadDependencies.length ? 'All' : 'Some'
|
|
86
|
-
} default dependencies are already installed: ` + defaultDependencies.join(', ')
|
|
87
|
-
);
|
|
88
|
-
const questions = [
|
|
89
|
-
{
|
|
90
|
-
type: 'confirm',
|
|
91
|
-
name: 'runUpdate',
|
|
92
|
-
message: 'Would you like to attempt updating them?',
|
|
93
|
-
default: true,
|
|
94
|
-
},
|
|
95
|
-
];
|
|
96
|
-
const responses = await new Promise((resolve) => {
|
|
97
|
-
inquirer.prompt(questions).then((answers) => {
|
|
98
|
-
resolve(answers);
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
if (responses.runUpdate) {
|
|
102
|
-
loadDependencies.length = 0;
|
|
103
|
-
loadDependencies.push(...defaultDependencies);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
108
|
if (loadDependencies.length) {
|
|
107
|
-
Util.logger.info('Installing Dependencies:');
|
|
108
|
-
const args = ['install', '--save-dev'].concat(
|
|
109
|
+
Util.logger.info('Installing/Updating Dependencies:');
|
|
110
|
+
const args = ['install', '--save-dev'].concat(
|
|
111
|
+
loadDependencies.map((name) => `${name}@${versionsDefault[name]}`)
|
|
112
|
+
);
|
|
109
113
|
|
|
110
114
|
Util.execSync('npm', args);
|
|
111
115
|
Util.logger.info('✔️ Dependencies installed.');
|
|
116
|
+
} else {
|
|
117
|
+
Util.logger.info(
|
|
118
|
+
`✔️ All default dependencies are already installed: ` +
|
|
119
|
+
defaultDependencies.map((name) => `${name}@${versionsProject[name]}`).join(', ')
|
|
120
|
+
);
|
|
112
121
|
}
|
|
113
122
|
return true;
|
|
114
123
|
},
|
|
115
124
|
/**
|
|
116
125
|
* ensure we have certain default values in our config
|
|
117
|
-
*
|
|
118
|
-
* @
|
|
126
|
+
*
|
|
127
|
+
* @param {object} [currentContent] what was read from existing package.json file
|
|
128
|
+
* @returns {Promise.<{script: object, author: string, license: string}>} extended currentContent
|
|
119
129
|
*/
|
|
120
130
|
async _getDefaultPackageJson(currentContent) {
|
|
121
131
|
currentContent = currentContent || {};
|
|
@@ -124,7 +134,6 @@ const Init = {
|
|
|
124
134
|
build: 'sfmc-build all',
|
|
125
135
|
'build-cp': 'sfmc-build cloudPages',
|
|
126
136
|
'build-email': 'sfmc-build emails',
|
|
127
|
-
upgrade: 'npm-check --update',
|
|
128
137
|
'eslint-check': 'eslint',
|
|
129
138
|
};
|
|
130
139
|
if (!currentContent.scripts) {
|