-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathinit.npm.js
159 lines (152 loc) · 6.32 KB
/
init.npm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
'use strict';
import File from './file.js';
import path from 'node:path';
import { Util } from './util.js';
import semver from 'semver';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
/**
* CLI helper class
*/
const Init = {
/**
* initiates npm project and then
* takes care of loading the pre-configured dependency list
* from the boilerplate directory to them as dev-dependencies
*
* @param {string} [repoName] if git URL was provided earlier, the repo name was extracted to use it for npm init
* @returns {Promise.<boolean>} install successful or error occured
*/
async installDependencies(repoName) {
let fileContent;
let projectPackageJson;
if (await File.pathExists('package.json')) {
try {
fileContent = await File.readFile('package.json', 'utf8');
} catch (ex) {
Util.logger.error(
'Your package.json was found but seems to be corrupted: ' + ex.message
);
}
if (fileContent) {
projectPackageJson = JSON.parse(fileContent);
this._getDefaultPackageJson(projectPackageJson);
await File.writeJSON('./package.json', projectPackageJson, { spaces: 2 });
Util.logger.info('✔️ package.json found');
}
} else {
Util.logger.warn('No package.json found. Initializing node project:');
// make sure the npm project name is compliant with npm rules
const currentFolderName = path.basename(path.resolve());
const standardNpmName =
repoName ||
currentFolderName
.toLowerCase()
.replaceAll(/[^a-z0-9 ]/gi, '')
.replaceAll(/ /gi, '-');
projectPackageJson = { name: standardNpmName };
this._getDefaultPackageJson(projectPackageJson);
await File.writeToFile('./', 'package', 'json', JSON.stringify(projectPackageJson));
// execute "no questions asked" npm init
Util.execSync('npm', ['init', '--yes'], true);
try {
fileContent = await File.readFile('package.json', 'utf8');
if (fileContent) {
projectPackageJson = JSON.parse(fileContent);
}
Util.logger.info('✔️ package.json created');
} catch {
Util.logger.error('No package.json found. Please run "npm init" manually');
return false;
}
}
// ensure npm dependencies are loaded
const dependencyFile = path.resolve(
__dirname,
Util.boilerplateDirectory,
'npm-dependencies.json'
);
if (!(await File.pathExists(dependencyFile))) {
Util.logger.debug(`Dependency file not found in ${dependencyFile}`);
return false;
}
const defaultDependencies = await File.readJSON(dependencyFile);
const versionsDefault = {};
for (const name of defaultDependencies) {
// check mcdev.devDependencies first
versionsDefault[name] = Object.keys(Util.packageJsonMcdev.dependencies).includes(name)
? Util.packageJsonMcdev.dependencies[name]
: // then check mcdev.devDependencies
Object.keys(Util.packageJsonMcdev.devDependencies).includes(name)
? Util.packageJsonMcdev.devDependencies[name]
: // fallback to using latest version if not found
'latest';
}
const versionsProject = {};
if (projectPackageJson.devDependencies) {
for (const name of defaultDependencies) {
// check project.devDependencies
versionsProject[name] = Object.keys(projectPackageJson.devDependencies).includes(
name
)
? projectPackageJson.devDependencies[name].replace(/^[\^~]/, '')
: // fallback to invalid version if not found
'0.0.0';
}
}
const loadDependencies = defaultDependencies.filter(
(name) =>
!projectPackageJson ||
!projectPackageJson.devDependencies ||
!projectPackageJson.devDependencies[name] ||
versionsDefault[name] == 'latest' ||
semver.gt(versionsDefault[name], versionsProject[name])
);
if (loadDependencies.length) {
Util.logger.info('Installing/Updating Dependencies:');
const args = ['install', '--save-dev'].concat(
loadDependencies.map((name) => `${name}@${versionsDefault[name]}`)
);
Util.execSync('npm', args);
Util.logger.info('✔️ Dependencies installed.');
} else {
Util.logger.info(
`✔️ All default dependencies are already installed: ` +
defaultDependencies.map((name) => `${name}@${versionsProject[name]}`).join(', ')
);
}
return true;
},
/**
* ensure we have certain default values in our config
*
* @param {object} [currentContent] what was read from existing package.json file
* @returns {Promise.<{script: object, author: string, license: string}>} extended currentContent
*/
async _getDefaultPackageJson(currentContent) {
currentContent ||= {};
// #1 scripts
const predefinedCommandList = {
build: 'sfmc-build all',
'build-cp': 'sfmc-build cloudPages',
'build-email': 'sfmc-build emails',
'eslint-check': 'eslint',
};
if (!currentContent.scripts) {
currentContent.scripts = {};
}
for (const key in predefinedCommandList) {
currentContent.scripts[key] = predefinedCommandList[key];
}
// #2 Author
if (!currentContent.author || currentContent.author === '') {
currentContent.author = 'Accenture';
}
// #3 License
if (!currentContent.license || currentContent.license === 'ISC') {
currentContent.license = 'UNLICENSED';
}
return currentContent;
},
};
export default Init;