@w5s/mrm-preset 1.0.0-alpha.1
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/.eslintignore +1 -0
- package/CHANGELOG.md +17 -0
- package/README.md +56 -0
- package/bootstrap/README.md +5 -0
- package/bootstrap/index.js +97 -0
- package/ci/_gitlab/AutoDevops.gitlab-ci.yml +77 -0
- package/ci/_gitlab/AutoDevopsInclude.gitlab-ci.yml +251 -0
- package/ci/_gitlab/README.md +20 -0
- package/ci/_gitlab/Renovate.gitlab-ci.yml +30 -0
- package/ci/gitlab.js +38 -0
- package/ci/index.js +14 -0
- package/commitlint/index.js +40 -0
- package/config.json +20 -0
- package/contributing/index.js +26 -0
- package/contributing/templates/CODE_OF_CONDUCT.md +134 -0
- package/core/block.js +77 -0
- package/core/commitlint.js +39 -0
- package/core/cspell.js +66 -0
- package/core/eslint.js +22 -0
- package/core/file.js +29 -0
- package/core/git.js +73 -0
- package/core/githooks.js +71 -0
- package/core/gitlabCI.js +8 -0
- package/core/jest.js +105 -0
- package/core/jsonFile.js +65 -0
- package/core/lintStaged.js +36 -0
- package/core/npm.js +271 -0
- package/core/pkg.js +97 -0
- package/core/project.js +58 -0
- package/core/semanticRelease.js +43 -0
- package/core/typedoc.js +82 -0
- package/core/vscode.js +92 -0
- package/core/workspace.js +6 -0
- package/cspell/index.js +38 -0
- package/editorconfig/index.js +107 -0
- package/eslint/index.js +127 -0
- package/githooks/index.js +62 -0
- package/githooks/templates/CODEOWNERS +4 -0
- package/gitignore/index.js +25 -0
- package/gitignore/template.js +145 -0
- package/jest/index.js +19 -0
- package/lang/.eslintrc.json +8 -0
- package/lang/index.js +143 -0
- package/lang/templates/index.spec.ts +7 -0
- package/lang/templates/index.ts +6 -0
- package/package.json +48 -0
- package/postconfigure/index.js +17 -0
- package/project/index.js +232 -0
- package/release/index.js +29 -0
- package/renovate/index.js +61 -0
- package/tsconfig.json +13 -0
package/core/jsonFile.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {string|boolean|number|null|Array<unknown>|Record<string, unknown>} JsonValue
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {import('mrm-core').Json} jsonFile
|
|
7
|
+
* @param {undefined | string | string[]} path
|
|
8
|
+
*/
|
|
9
|
+
function getValue(jsonFile, path) {
|
|
10
|
+
if (path == null) {
|
|
11
|
+
return jsonFile.get();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return jsonFile.get(path);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {import('mrm-core').Json} jsonFile
|
|
19
|
+
* @param {undefined | string | string[]} path
|
|
20
|
+
* @param {unknown} pathValue
|
|
21
|
+
*/
|
|
22
|
+
function setValue(jsonFile, path, pathValue) {
|
|
23
|
+
if (path == null) {
|
|
24
|
+
jsonFile.set(pathValue);
|
|
25
|
+
} else {
|
|
26
|
+
jsonFile.set(path, pathValue);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Set state of a json value
|
|
32
|
+
*
|
|
33
|
+
* @template {undefined|JsonValue} T
|
|
34
|
+
* @param {import('mrm-core').Json} jsonFile
|
|
35
|
+
* @param {{
|
|
36
|
+
* path: undefined | string | string[],
|
|
37
|
+
* state: 'present'|'absent',
|
|
38
|
+
* update?: T | ((previousValue: T) => T)
|
|
39
|
+
* default?: T | (() => T)
|
|
40
|
+
* }} options
|
|
41
|
+
*/
|
|
42
|
+
function value(jsonFile, { state, path, default: defaultValue, update: nextValue }) {
|
|
43
|
+
if (state === 'present') {
|
|
44
|
+
if (nextValue != null) {
|
|
45
|
+
const resolvedValue = typeof nextValue === 'function' ? nextValue(getValue(jsonFile, path)) : nextValue;
|
|
46
|
+
if (resolvedValue != null) {
|
|
47
|
+
setValue(jsonFile, path, resolvedValue);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const currentValue = getValue(jsonFile, path);
|
|
52
|
+
if (currentValue == null) {
|
|
53
|
+
const resolvedValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
|
54
|
+
if (resolvedValue != null) {
|
|
55
|
+
setValue(jsonFile, path, resolvedValue);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} else if (path) {
|
|
59
|
+
jsonFile.unset(path);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
value,
|
|
65
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const pkg = require('./pkg');
|
|
2
|
+
const npm = require('./npm');
|
|
3
|
+
const jsonFile = require('./jsonFile');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Record<string, string|string[]>} LintStagedConfig
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {{
|
|
11
|
+
* state: 'present'|'absent',
|
|
12
|
+
* update?: (config: LintStagedConfig) => LintStagedConfig
|
|
13
|
+
* }} options
|
|
14
|
+
*/
|
|
15
|
+
function lintStaged({ state, update }) {
|
|
16
|
+
pkg.withPackageJson((packageFile) => {
|
|
17
|
+
jsonFile.value(packageFile, {
|
|
18
|
+
path: 'lint-staged',
|
|
19
|
+
state,
|
|
20
|
+
update,
|
|
21
|
+
/** @type {LintStagedConfig} */
|
|
22
|
+
default: {},
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Dependencies
|
|
27
|
+
npm.dependency({
|
|
28
|
+
dev: true,
|
|
29
|
+
name: ['lint-staged'],
|
|
30
|
+
state,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
lintStaged,
|
|
36
|
+
};
|
package/core/npm.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
+
/* cSpell: disable */
|
|
3
|
+
// @ts-check
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
const _ = require('lodash');
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const semver = require('semver');
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
const listify = require('listify');
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
const validateNpmPackageName = require('validate-npm-package-name');
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
const log = require('mrm-core/src/util/log');
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
const execCommand = require('mrm-core/src/util/execCommand');
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
const json = require('mrm-core/src/formats/json');
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
const packageJson = require('mrm-core/src/files/packageJson');
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
const MrmError = require('mrm-core/src/error');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef Options
|
|
27
|
+
* @property {boolean} [dev]
|
|
28
|
+
* @property {boolean} [yarn]
|
|
29
|
+
* @property {Record<string, string>} [versions]
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @typedef RunOptions
|
|
34
|
+
* @property {boolean} [dev]
|
|
35
|
+
* @property {boolean} [remove]
|
|
36
|
+
* @property {boolean} [stdio]
|
|
37
|
+
* @property {string} [cwd]
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Install or update given npm packages if needed
|
|
42
|
+
*
|
|
43
|
+
* @param {Record<string, string> | string[] | string} deps
|
|
44
|
+
* @param {Options} [options]
|
|
45
|
+
* @param {Function=} exec
|
|
46
|
+
*/
|
|
47
|
+
function install(deps, options = {}, exec) {
|
|
48
|
+
const dev = options.dev !== false;
|
|
49
|
+
const run = options.yarn || isUsingYarn() ? runYarn : runNpm;
|
|
50
|
+
|
|
51
|
+
// options.versions is a min versions mapping,
|
|
52
|
+
// the list of packages to install will be taken from deps
|
|
53
|
+
let versions = options.versions || {};
|
|
54
|
+
|
|
55
|
+
/** @type string[] */
|
|
56
|
+
let dependencies = [];
|
|
57
|
+
|
|
58
|
+
if (typeof deps === 'string') {
|
|
59
|
+
dependencies = [deps];
|
|
60
|
+
} else if (Array.isArray(deps)) {
|
|
61
|
+
dependencies = deps;
|
|
62
|
+
} else if (typeof deps === 'object' && deps !== null) {
|
|
63
|
+
// deps is an object with required versions
|
|
64
|
+
// prettier-ignore
|
|
65
|
+
versions = deps;
|
|
66
|
+
dependencies = Object.keys(deps);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const newDeps = getUnsatisfiedDeps(dependencies, versions, { dev });
|
|
70
|
+
if (newDeps.length === 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
log.info(`Installing ${listify(newDeps)}...`);
|
|
75
|
+
const versionedDeps = newDeps.map((dep) => {
|
|
76
|
+
return getVersionedDep(dep, versions);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// eslint-disable-next-line consistent-return
|
|
80
|
+
return run(versionedDeps, { dev }, exec);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Uninstall given npm packages
|
|
85
|
+
*
|
|
86
|
+
* @param {string[] | string} deps
|
|
87
|
+
* @param {Options} [options]
|
|
88
|
+
* @param {Function=} exec
|
|
89
|
+
*/
|
|
90
|
+
function uninstall(deps, options = {}, exec) {
|
|
91
|
+
// eslint-disable-next-line no-param-reassign
|
|
92
|
+
deps = _.castArray(deps);
|
|
93
|
+
const dev = options.dev !== false;
|
|
94
|
+
const run = options.yarn || isUsingYarn() ? runYarn : runNpm;
|
|
95
|
+
|
|
96
|
+
const installed = getOwnDependencies({ dev });
|
|
97
|
+
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
const newDeps = deps.filter((dep) => {
|
|
100
|
+
return installed[dep];
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (newDeps.length === 0) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
log.info(`Uninstalling ${listify(newDeps)}...`);
|
|
108
|
+
|
|
109
|
+
// eslint-disable-next-line consistent-return
|
|
110
|
+
return run(newDeps, { dev, remove: true }, exec);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Install given npm packages
|
|
115
|
+
*
|
|
116
|
+
* @param {string[]} deps
|
|
117
|
+
* @param {RunOptions} [options]
|
|
118
|
+
* @param {Function} [exec]
|
|
119
|
+
*/
|
|
120
|
+
function runNpm(deps, options = {}, exec) {
|
|
121
|
+
const args = [options.remove ? 'uninstall' : 'install', options.dev ? '--save-dev' : '--save'].concat(deps);
|
|
122
|
+
|
|
123
|
+
return execCommand(exec, 'npm', args, {
|
|
124
|
+
cwd: options.cwd,
|
|
125
|
+
stdio: options.stdio === undefined ? 'inherit' : options.stdio,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Install given Yarn packages
|
|
131
|
+
*
|
|
132
|
+
* @param {string[]} deps
|
|
133
|
+
* @param {RunOptions} [options]
|
|
134
|
+
* @param {Function} [exec]
|
|
135
|
+
*/
|
|
136
|
+
function runYarn(deps, options = {}, exec) {
|
|
137
|
+
const add = options.dev ? ['add', '--dev'] : ['add'];
|
|
138
|
+
const remove = ['remove'];
|
|
139
|
+
const args = (options.remove ? remove : add).concat(isUsingWorkspaces() ? ['-W'] : []).concat(deps);
|
|
140
|
+
|
|
141
|
+
return execCommand(exec, 'yarn', args, {
|
|
142
|
+
cwd: options.cwd,
|
|
143
|
+
stdio: options.stdio === undefined ? 'inherit' : options.stdio,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Add version or latest to package name
|
|
149
|
+
*
|
|
150
|
+
* @param {string} dep
|
|
151
|
+
* @param {Record<string, string>} versions
|
|
152
|
+
*/
|
|
153
|
+
function getVersionedDep(dep, versions) {
|
|
154
|
+
// Handle non-registry packages (Github, bitbucket, etc.)
|
|
155
|
+
if (!validateNpmPackageName(dep).validForNewPackages) {
|
|
156
|
+
// If we were explicitly passed a version, attempt to
|
|
157
|
+
// load it via the `#semver:<semver>` syntax.
|
|
158
|
+
if (versions[dep]) {
|
|
159
|
+
return `${dep}#semver:${versions[dep]}`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return dep;
|
|
163
|
+
}
|
|
164
|
+
const version = versions[dep] || 'latest';
|
|
165
|
+
|
|
166
|
+
return `${dep}@${version}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
*
|
|
171
|
+
* @param {Options} options
|
|
172
|
+
* @returns {Record<string, string>}
|
|
173
|
+
*/
|
|
174
|
+
function getOwnDependencies(options) {
|
|
175
|
+
const pkg = packageJson({
|
|
176
|
+
dependencies: {},
|
|
177
|
+
devDependencies: {},
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return pkg.get(options.dev ? 'devDependencies' : 'dependencies') || {};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Return version of installed npm package
|
|
185
|
+
*
|
|
186
|
+
* @param {string} name
|
|
187
|
+
* @returns {string}
|
|
188
|
+
*/
|
|
189
|
+
function getInstalledVersion(name) {
|
|
190
|
+
return json(`./node_modules/${name}/package.json`).get('version');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Return only not installed dependencies, or dependencies which installed
|
|
195
|
+
* version doesn't satisfy range.
|
|
196
|
+
*
|
|
197
|
+
* @param {string[]} deps
|
|
198
|
+
* @param {Record<string, string>} versions
|
|
199
|
+
* @param {Options} options
|
|
200
|
+
* @returns {string[]}
|
|
201
|
+
*/
|
|
202
|
+
function getUnsatisfiedDeps(deps, versions, options) {
|
|
203
|
+
const ownDependencies = getOwnDependencies(options);
|
|
204
|
+
|
|
205
|
+
return deps.filter((dep) => {
|
|
206
|
+
const required = versions[dep];
|
|
207
|
+
|
|
208
|
+
// Handle non-registry packages (github, bitbucket, etc.)
|
|
209
|
+
// Because these packages can shift contents without updating version
|
|
210
|
+
// numbers, always attempt an install
|
|
211
|
+
if (!validateNpmPackageName(dep).validForNewPackages) {
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (required && !semver.validRange(required)) {
|
|
216
|
+
throw new MrmError(`Invalid npm version: ${required}. Use proper semver range syntax.`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const installed = getInstalledVersion(dep);
|
|
220
|
+
|
|
221
|
+
// Package isn’t installed yet
|
|
222
|
+
if (!installed) {
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Module is installed but not in package.json dependencies
|
|
227
|
+
if (!ownDependencies[dep]) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// No required version specified
|
|
232
|
+
if (!required) {
|
|
233
|
+
// Install if the pacakge isn’t installed
|
|
234
|
+
return !installed;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Install if installed version doesn't satisfy range
|
|
238
|
+
return !semver.satisfies(installed, required);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/*
|
|
243
|
+
* Is project using Yarn?
|
|
244
|
+
*/
|
|
245
|
+
function isUsingYarn() {
|
|
246
|
+
return fs.existsSync('yarn.lock');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function isUsingWorkspaces() {
|
|
250
|
+
return Boolean(packageJson().get('workspaces'));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @param {{
|
|
255
|
+
* name: string|string[]|Record<string, string>,
|
|
256
|
+
* state: 'present'|'absent',
|
|
257
|
+
* dev?: boolean,
|
|
258
|
+
* yarn?: boolean,
|
|
259
|
+
* }} options
|
|
260
|
+
*/
|
|
261
|
+
function dependency({ name, state, ...options }) {
|
|
262
|
+
if (state === 'present') {
|
|
263
|
+
install(name, options);
|
|
264
|
+
} else {
|
|
265
|
+
uninstall(typeof name === 'string' || Array.isArray(name) ? name : Object.keys(name));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
module.exports = {
|
|
270
|
+
dependency,
|
|
271
|
+
};
|
package/core/pkg.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/* cSpell: disable */
|
|
2
|
+
// @ts-check
|
|
3
|
+
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
const { intersect } = require('semver-intersect');
|
|
6
|
+
const { packageJson, file } = require('mrm-core');
|
|
7
|
+
const jsonFile = require('./jsonFile');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An empty placeholder for npm script
|
|
11
|
+
*/
|
|
12
|
+
const emptyScript = ':';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {(pkg: import('mrm-core').PackageJson) => void} block
|
|
16
|
+
*/
|
|
17
|
+
function withPackageJson(block) {
|
|
18
|
+
const packageFile = packageJson();
|
|
19
|
+
block(packageFile);
|
|
20
|
+
packageFile.save();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {import('mrm-core').PackageJson} packageFile
|
|
25
|
+
* @param {{
|
|
26
|
+
* name: string,
|
|
27
|
+
* state: 'present'|'absent'|'default',
|
|
28
|
+
* script: string,
|
|
29
|
+
* }} options
|
|
30
|
+
*/
|
|
31
|
+
function script(packageFile, { name, state, script: scriptName }) {
|
|
32
|
+
if (state === 'absent') {
|
|
33
|
+
packageFile.removeScript(name);
|
|
34
|
+
} else if (state === 'present' || (state === 'default' && !packageFile.getScript(name))) {
|
|
35
|
+
packageFile.setScript(name, scriptName);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const defaultManager = 'npm';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('mrm-core').PackageJson} packageFile
|
|
43
|
+
* @returns {'yarn'|'npm'}
|
|
44
|
+
*/
|
|
45
|
+
function manager(packageFile) {
|
|
46
|
+
if (packageFile.get('packagerManager')) {
|
|
47
|
+
const [head, tail] = packageFile.get('packagerManager').split('@', 2);
|
|
48
|
+
|
|
49
|
+
return head ?? tail;
|
|
50
|
+
}
|
|
51
|
+
if (file('yarn.lock').exists()) {
|
|
52
|
+
return 'yarn';
|
|
53
|
+
}
|
|
54
|
+
if (file('package-json.lock').exists()) {
|
|
55
|
+
return 'npm';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return defaultManager;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {import('mrm-core').PackageJson} packageFile
|
|
64
|
+
* @param {Record<string, string>} engineVersionMap
|
|
65
|
+
*/
|
|
66
|
+
function engineMinVersion(packageFile, engineVersionMap) {
|
|
67
|
+
/**
|
|
68
|
+
* @param {string} engineName
|
|
69
|
+
*/
|
|
70
|
+
const engineConstraint = (engineName) => {
|
|
71
|
+
const defaultVersion = engineVersionMap[engineName];
|
|
72
|
+
const currentVersion = packageFile.get(`engines.${engineName}`, defaultVersion);
|
|
73
|
+
try {
|
|
74
|
+
return intersect(currentVersion, defaultVersion);
|
|
75
|
+
} catch (_) {
|
|
76
|
+
return currentVersion; // leave unchanged
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
packageFile.merge({
|
|
81
|
+
engines: Object.keys(engineVersionMap).reduce((acc, engineName) => {
|
|
82
|
+
return {
|
|
83
|
+
...acc,
|
|
84
|
+
[engineName]: engineConstraint(engineName),
|
|
85
|
+
};
|
|
86
|
+
}, {}),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
...jsonFile,
|
|
92
|
+
emptyScript,
|
|
93
|
+
script,
|
|
94
|
+
manager,
|
|
95
|
+
engineMinVersion,
|
|
96
|
+
withPackageJson,
|
|
97
|
+
};
|
package/core/project.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** @type {'install'} */
|
|
2
|
+
const install = 'install';
|
|
3
|
+
/** @type {'prepare'} */
|
|
4
|
+
const prepare = 'prepare';
|
|
5
|
+
/** @type {'build'} */
|
|
6
|
+
const build = 'build';
|
|
7
|
+
/** @type {'develop'} */
|
|
8
|
+
const develop = 'develop';
|
|
9
|
+
/** @type {'code-analysis'} */
|
|
10
|
+
const codeAnalysis = 'code-analysis';
|
|
11
|
+
/** @type {'format'} */
|
|
12
|
+
const format = 'format';
|
|
13
|
+
/** @type {'lint'} */
|
|
14
|
+
const lint = 'lint';
|
|
15
|
+
/** @type {'test'} */
|
|
16
|
+
const test = 'test';
|
|
17
|
+
/** @type {'coverage'} */
|
|
18
|
+
const coverage = 'coverage';
|
|
19
|
+
/** @type {'clean'} */
|
|
20
|
+
const clean = 'clean';
|
|
21
|
+
/** @type {'validate'} */
|
|
22
|
+
const validate = 'validate';
|
|
23
|
+
/** @type {'release'} */
|
|
24
|
+
const release = 'release';
|
|
25
|
+
/** @type {'rescue'} */
|
|
26
|
+
const rescue = 'rescue';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {string} taskName
|
|
30
|
+
*/
|
|
31
|
+
function pre(taskName) {
|
|
32
|
+
return `pre${taskName}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} taskName
|
|
37
|
+
*/
|
|
38
|
+
function post(taskName) {
|
|
39
|
+
return `post${taskName}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
build,
|
|
44
|
+
prepare,
|
|
45
|
+
develop,
|
|
46
|
+
clean,
|
|
47
|
+
codeAnalysis,
|
|
48
|
+
coverage,
|
|
49
|
+
format,
|
|
50
|
+
install,
|
|
51
|
+
lint,
|
|
52
|
+
post,
|
|
53
|
+
pre,
|
|
54
|
+
release,
|
|
55
|
+
rescue,
|
|
56
|
+
test,
|
|
57
|
+
validate,
|
|
58
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const npm = require('./npm');
|
|
2
|
+
const pkg = require('./pkg');
|
|
3
|
+
const jsonFile = require('./jsonFile');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* extends: string|string[]
|
|
8
|
+
* }} SemanticReleaseConfig
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {{
|
|
13
|
+
* state: 'present'|'absent',
|
|
14
|
+
* preset?: string,
|
|
15
|
+
* update?: (config: SemanticReleaseConfig) => SemanticReleaseConfig
|
|
16
|
+
* }} options
|
|
17
|
+
*/
|
|
18
|
+
function semanticRelease({ state, update, preset }) {
|
|
19
|
+
npm.dependency({
|
|
20
|
+
dev: true,
|
|
21
|
+
name: ['semantic-release', ...(preset ? [preset] : [])],
|
|
22
|
+
state,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
pkg.withPackageJson((packageFile) => {
|
|
26
|
+
jsonFile.value(packageFile, {
|
|
27
|
+
path: 'release',
|
|
28
|
+
state,
|
|
29
|
+
update,
|
|
30
|
+
/** @type {SemanticReleaseConfig} */
|
|
31
|
+
default: {
|
|
32
|
+
extends: preset ? [preset] : [],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
semanticRelease.command = function () {
|
|
38
|
+
return 'semantic-release';
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
semanticRelease,
|
|
43
|
+
};
|
package/core/typedoc.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const { packageJson, json } = require('mrm-core');
|
|
2
|
+
const pkg = require('./pkg');
|
|
3
|
+
const npm = require('./npm');
|
|
4
|
+
const jsonFile = require('./jsonFile');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {{
|
|
8
|
+
* out?: string,
|
|
9
|
+
* tsconfig?: string,
|
|
10
|
+
* exclude?: Array<string>,
|
|
11
|
+
* excludePrivate?: boolean,
|
|
12
|
+
* excludeExternals?: boolean,
|
|
13
|
+
* readme?: string,
|
|
14
|
+
* theme?: string,
|
|
15
|
+
* }} TypeDocConfig
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {{
|
|
20
|
+
* state: 'present'|'absent',
|
|
21
|
+
* update: (config: TypeDocConfig) => TypeDocConfig
|
|
22
|
+
* }} options
|
|
23
|
+
*/
|
|
24
|
+
function typedoc({ state, update }) {
|
|
25
|
+
const packageFileDefault = packageJson();
|
|
26
|
+
const hasWorkspaces = Boolean(packageFileDefault.get('workspaces'));
|
|
27
|
+
const hasTypedoc = state === 'present';
|
|
28
|
+
|
|
29
|
+
pkg.withPackageJson((packageFile) => {
|
|
30
|
+
pkg.script(packageFile, {
|
|
31
|
+
name: 'typedoc',
|
|
32
|
+
script: 'typedoc',
|
|
33
|
+
state: !hasTypedoc || hasWorkspaces ? 'absent' : 'present',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const typedocFile = json('typedoc.json');
|
|
38
|
+
|
|
39
|
+
if (hasTypedoc) {
|
|
40
|
+
jsonFile.value(typedocFile, {
|
|
41
|
+
path: undefined,
|
|
42
|
+
state,
|
|
43
|
+
update: (config) => ({
|
|
44
|
+
...update(config),
|
|
45
|
+
...(hasWorkspaces
|
|
46
|
+
? {
|
|
47
|
+
'external-modulemap': '.*packages/([^/]+)/.*',
|
|
48
|
+
entryPoints: ['packages/'],
|
|
49
|
+
}
|
|
50
|
+
: {
|
|
51
|
+
'external-modulemap': undefined,
|
|
52
|
+
entryPoints: ['src/index.ts'],
|
|
53
|
+
}),
|
|
54
|
+
}),
|
|
55
|
+
/** @type {TypeDocConfig} */
|
|
56
|
+
default: {},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Otherwise save the file with content
|
|
61
|
+
*/
|
|
62
|
+
typedocFile.save();
|
|
63
|
+
} else {
|
|
64
|
+
typedocFile.delete();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Dependencies
|
|
68
|
+
npm.dependency({
|
|
69
|
+
dev: true,
|
|
70
|
+
name: ['typedoc'],
|
|
71
|
+
state: hasTypedoc ? 'present' : 'absent',
|
|
72
|
+
});
|
|
73
|
+
npm.dependency({
|
|
74
|
+
dev: true,
|
|
75
|
+
name: ['@strictsoftware/typedoc-plugin-monorepo'],
|
|
76
|
+
state: hasTypedoc && hasWorkspaces ? 'present' : 'absent',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = {
|
|
81
|
+
typedoc,
|
|
82
|
+
};
|