@w5s/mrm-preset 1.0.0-alpha.9 → 1.0.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/.turbo/turbo-build.log +6 -1
- package/.turbo/turbo-lint.log +6 -52
- package/.turbo/turbo-prepare.log +1 -0
- package/.turbo/turbo-test.log +187 -21
- package/CHANGELOG.md +191 -42
- package/README.md +7 -7
- package/bootstrap/README.md +1 -1
- package/bootstrap/index.js +14 -38
- package/ci/_gitlab/AutoDevops.gitlab-ci.yml +1 -2
- package/ci/_gitlab/AutoDevopsInclude.gitlab-ci.yml +19 -19
- package/ci/_gitlab/Renovate.gitlab-ci.yml +6 -6
- package/ci/github.js +53 -0
- package/ci/gitlab.js +1 -2
- package/ci/index.js +7 -2
- package/commitlint/index.js +8 -2
- package/config.json +2 -1
- package/contributing/index.js +1 -1
- package/core/commitlint.js +5 -5
- package/core/cspell.js +2 -11
- package/core/eslint.js +25 -6
- package/core/git.js +4 -23
- package/core/githooks.js +13 -21
- package/core/githubCI.js +56 -0
- package/core/jest.js +26 -36
- package/core/jsonFile.js +8 -7
- package/core/lintStaged.js +3 -3
- package/core/npm.js +15 -13
- package/core/pkg.js +71 -14
- package/core/project.js +6 -0
- package/core/semanticRelease.js +3 -3
- package/core/turbo.js +52 -0
- package/core/typedoc.js +3 -3
- package/core/vitest.js +77 -0
- package/core/vscode.js +15 -5
- package/cspell/index.js +35 -14
- package/editorconfig/index.js +19 -9
- package/eslint/index.js +90 -47
- package/githooks/index.js +16 -12
- package/gitignore/index.js +1 -1
- package/lang/.eslintrc.json +1 -3
- package/lang/index.js +73 -36
- package/lang/templates/index.spec.ts +3 -2
- package/lang/templates/index.ts +1 -2
- package/licenses/index.js +26 -0
- package/package.json +21 -14
- package/postconfigure/index.js +11 -3
- package/project/index.js +253 -171
- package/release/index.js +5 -5
- package/renovate/index.js +4 -3
- package/tsconfig.json +3 -6
- package/{jest → vitest}/index.js +3 -3
- package/.turbo/turbo-docs.log +0 -43
package/core/jest.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
/* eslint-disable no-template-curly-in-string */
|
|
2
1
|
const { packageJson } = require('mrm-core');
|
|
3
|
-
const pkg = require('./pkg');
|
|
4
|
-
const npm = require('./npm');
|
|
5
|
-
const project = require('./project');
|
|
2
|
+
const pkg = require('./pkg.js');
|
|
3
|
+
const npm = require('./npm.js');
|
|
4
|
+
const project = require('./project.js');
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* @param {{
|
|
@@ -13,57 +12,48 @@ function jest({ state }) {
|
|
|
13
12
|
const packageFileDefault = packageJson();
|
|
14
13
|
const hasJest = state === 'present';
|
|
15
14
|
const hasWorkspaces = pkg.hasWorkspaces(packageFileDefault);
|
|
16
|
-
const hasTypescript = pkg.hasDependency(packageFileDefault, 'typescript', 'dev');
|
|
17
15
|
|
|
18
16
|
pkg.withPackageJson((packageFile) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
const ignorePatterns = ['/node_modules/', '/docs/', '/lib/', '/build/', '/.cache/', '/public/'];
|
|
18
|
+
|
|
19
|
+
pkg.value(packageFile, {
|
|
20
|
+
path: 'jest',
|
|
21
|
+
state: hasJest ? 'present' : 'absent',
|
|
22
|
+
update: hasWorkspaces
|
|
23
|
+
? () => ({
|
|
25
24
|
preset: 'es-jest',
|
|
26
25
|
projects: packageFile
|
|
27
26
|
.get('workspaces.packages', packageFile.get('workspaces', []))
|
|
28
27
|
.map((/** @type {string} */ workspace) => `<rootDir>/${workspace}`),
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const ignorePatterns = ['/node_modules/', '/docs/', '/lib/', '/build/', '/.cache/', '/public/'];
|
|
33
|
-
packageFile.merge({
|
|
34
|
-
jest: {
|
|
28
|
+
})
|
|
29
|
+
: (config) => ({
|
|
30
|
+
...config,
|
|
35
31
|
preset: 'es-jest',
|
|
36
32
|
coveragePathIgnorePatterns: ignorePatterns,
|
|
37
33
|
testPathIgnorePatterns: ignorePatterns,
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} else {
|
|
42
|
-
packageFile.unset('jest');
|
|
43
|
-
}
|
|
44
|
-
|
|
34
|
+
}),
|
|
35
|
+
default: {},
|
|
36
|
+
});
|
|
45
37
|
pkg.script(packageFile, {
|
|
46
|
-
name: project.coverage
|
|
47
|
-
|
|
48
|
-
state:
|
|
38
|
+
name: `${project.coverage}:root`,
|
|
39
|
+
update: (/** @type {string|undefined} */ _) => (hasWorkspaces ? _ : 'jest --coverage'),
|
|
40
|
+
state: 'present',
|
|
41
|
+
default: undefined, // pkg.emptyScript,
|
|
49
42
|
});
|
|
50
43
|
pkg.script(packageFile, {
|
|
51
|
-
name: project.test
|
|
52
|
-
|
|
53
|
-
state:
|
|
44
|
+
name: `${project.test}:root`,
|
|
45
|
+
update: (/** @type {string|undefined} */ _) => (hasWorkspaces ? _ : 'jest'),
|
|
46
|
+
state: 'present',
|
|
47
|
+
default: undefined, // pkg.emptyScript,
|
|
54
48
|
});
|
|
55
49
|
});
|
|
50
|
+
|
|
56
51
|
// Dependencies
|
|
57
52
|
npm.dependency({
|
|
58
53
|
dev: true,
|
|
59
|
-
name: ['jest', 'es-jest'],
|
|
54
|
+
name: ['jest', 'es-jest', '@jest/globals'],
|
|
60
55
|
state: hasJest ? 'present' : 'absent',
|
|
61
56
|
});
|
|
62
|
-
npm.dependency({
|
|
63
|
-
dev: true,
|
|
64
|
-
name: ['@types/jest'],
|
|
65
|
-
state: hasJest && hasTypescript ? 'present' : 'absent',
|
|
66
|
-
});
|
|
67
57
|
|
|
68
58
|
// vscodeSnippets({
|
|
69
59
|
// name: 'jest',
|
package/core/jsonFile.js
CHANGED
|
@@ -41,16 +41,17 @@ function setValue(jsonFile, path, pathValue) {
|
|
|
41
41
|
*/
|
|
42
42
|
function value(jsonFile, { state, path, default: defaultValue, update: nextValue }) {
|
|
43
43
|
if (state === 'present') {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
let currentValue = getValue(jsonFile, path);
|
|
45
|
+
|
|
46
|
+
if (currentValue == null) {
|
|
47
|
+
currentValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
|
48
|
+
if (currentValue != null) {
|
|
49
|
+
setValue(jsonFile, path, currentValue);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const resolvedValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
|
53
|
+
if (nextValue != null) {
|
|
54
|
+
const resolvedValue = typeof nextValue === 'function' ? nextValue(getValue(jsonFile, path)) : nextValue;
|
|
54
55
|
if (resolvedValue != null) {
|
|
55
56
|
setValue(jsonFile, path, resolvedValue);
|
|
56
57
|
}
|
package/core/lintStaged.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const pkg = require('./pkg');
|
|
2
|
-
const npm = require('./npm');
|
|
3
|
-
const jsonFile = require('./jsonFile');
|
|
1
|
+
const pkg = require('./pkg.js');
|
|
2
|
+
const npm = require('./npm.js');
|
|
3
|
+
const jsonFile = require('./jsonFile.js');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {Record<string, string|string[]>} LintStagedConfig
|
package/core/npm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable default-param-last */
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
4
4
|
/* cSpell: disable */
|
|
5
5
|
// @ts-check
|
|
@@ -24,18 +24,20 @@ const MrmError = require('mrm-core/src/error');
|
|
|
24
24
|
const { yaml, json } = require('mrm-core');
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* @typedef
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* @typedef {{
|
|
28
|
+
* dev?: boolean,
|
|
29
|
+
* yarn?: boolean,
|
|
30
|
+
* versions?: Record<string, string>,
|
|
31
|
+
* }} Options
|
|
31
32
|
*/
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
* @typedef
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
35
|
+
* @typedef {{
|
|
36
|
+
* dev?: boolean,
|
|
37
|
+
* remove?: boolean,
|
|
38
|
+
* stdio?: boolean,
|
|
39
|
+
* cwd?: string,
|
|
40
|
+
* }} RunOptions
|
|
39
41
|
*/
|
|
40
42
|
|
|
41
43
|
/**
|
|
@@ -166,7 +168,7 @@ function getVersionedDep(dep, versions) {
|
|
|
166
168
|
/**
|
|
167
169
|
*
|
|
168
170
|
* @param {Options} options
|
|
169
|
-
* @returns {Record<string, string>}
|
|
171
|
+
* @returns {Record<string, string>} - map of package names to versions
|
|
170
172
|
*/
|
|
171
173
|
function getOwnDependencies(options) {
|
|
172
174
|
const pkg = packageJson({
|
|
@@ -181,7 +183,7 @@ function getOwnDependencies(options) {
|
|
|
181
183
|
* Return version of installed npm package
|
|
182
184
|
*
|
|
183
185
|
* @param {string} name
|
|
184
|
-
* @returns {string}
|
|
186
|
+
* @returns {string} - version
|
|
185
187
|
*/
|
|
186
188
|
function getInstalledVersion(name) {
|
|
187
189
|
return json(`./node_modules/${name}/package.json`).get('version');
|
|
@@ -194,7 +196,7 @@ function getInstalledVersion(name) {
|
|
|
194
196
|
* @param {string[]} deps
|
|
195
197
|
* @param {Record<string, string>} versions
|
|
196
198
|
* @param {Options} options
|
|
197
|
-
* @returns {string[]}
|
|
199
|
+
* @returns {string[]} - list of not installed dependencies
|
|
198
200
|
*/
|
|
199
201
|
function getUnsatisfiedDeps(deps, versions, options) {
|
|
200
202
|
const ownDependencies = getOwnDependencies(options);
|
package/core/pkg.js
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
/* cSpell: disable */
|
|
2
2
|
// @ts-check
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {string|boolean|number|null|Array<unknown>|Record<string, unknown>} JsonValue
|
|
6
|
+
*/
|
|
7
|
+
|
|
4
8
|
// @ts-ignore
|
|
5
9
|
const { intersect } = require('semver-intersect');
|
|
6
|
-
const { packageJson, file } = require('mrm-core');
|
|
7
|
-
const
|
|
10
|
+
const { packageJson, file, json } = require('mrm-core');
|
|
11
|
+
const glob = require('glob');
|
|
12
|
+
const path = require('node:path');
|
|
13
|
+
const jsonFile = require('./jsonFile.js');
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* An empty placeholder for npm script
|
|
11
17
|
*/
|
|
12
18
|
const emptyScript = ':';
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @param {import('mrm-core').Json} packageFile
|
|
22
|
+
* @returns {'application'|'library'|'workspace'} the archetype value
|
|
23
|
+
*/
|
|
24
|
+
function archetype(packageFile) {
|
|
25
|
+
if (hasWorkspaces(packageFile)) {
|
|
26
|
+
return 'workspace';
|
|
27
|
+
}
|
|
28
|
+
if (packageFile.get('private') === true || (packageFile.get('main') == null && packageFile.get('exports'))) {
|
|
29
|
+
return 'application';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return 'library';
|
|
33
|
+
}
|
|
34
|
+
|
|
14
35
|
/**
|
|
15
36
|
* @param {(pkg: import('mrm-core').PackageJson) => void} block
|
|
16
37
|
*/
|
|
@@ -21,26 +42,58 @@ function withPackageJson(block) {
|
|
|
21
42
|
}
|
|
22
43
|
|
|
23
44
|
/**
|
|
24
|
-
* @param {import(
|
|
45
|
+
* @param {import("mrm-core").Json} packageFile
|
|
46
|
+
* @returns {string[]} - The list of workspace matchers
|
|
47
|
+
*/
|
|
48
|
+
function listWorkspaceMatchers(packageFile) {
|
|
49
|
+
return packageFile.get('workspaces.packages', packageFile.get('workspaces', []));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {(workspace: {
|
|
54
|
+
* projectDir: string;
|
|
55
|
+
* packageFile: import("mrm-core").Json;
|
|
56
|
+
* }) => void} fn
|
|
57
|
+
*/
|
|
58
|
+
function forEachWorkspace(fn) {
|
|
59
|
+
const packageRoot = packageJson();
|
|
60
|
+
const workspacesMatchers = listWorkspaceMatchers(packageRoot);
|
|
61
|
+
|
|
62
|
+
for (const workspaceMatcher of workspacesMatchers) {
|
|
63
|
+
const directories = glob.sync(workspaceMatcher);
|
|
64
|
+
directories.forEach((directory) => {
|
|
65
|
+
const packageFile = json(path.join(directory, 'package.json'));
|
|
66
|
+
fn({
|
|
67
|
+
projectDir: directory,
|
|
68
|
+
packageFile,
|
|
69
|
+
});
|
|
70
|
+
packageFile.save();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @template {undefined|JsonValue} T
|
|
77
|
+
* @param {import('mrm-core').Json} packageFile
|
|
25
78
|
* @param {{
|
|
26
79
|
* name: string,
|
|
27
|
-
* state: 'present'|'absent'
|
|
28
|
-
*
|
|
80
|
+
* state: 'present'|'absent',
|
|
81
|
+
* update?: T | ((previousValue: T) => T)
|
|
82
|
+
* default?: T | (() => T)
|
|
29
83
|
* }} options
|
|
30
84
|
*/
|
|
31
|
-
function script(packageFile,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
85
|
+
function script(packageFile, options) {
|
|
86
|
+
jsonFile.value(packageFile, {
|
|
87
|
+
...options,
|
|
88
|
+
path: ['scripts', options.name],
|
|
89
|
+
});
|
|
37
90
|
}
|
|
38
91
|
|
|
39
92
|
const defaultManager = 'npm';
|
|
40
93
|
|
|
41
94
|
/**
|
|
42
95
|
* @param {import('mrm-core').PackageJson} packageFile
|
|
43
|
-
* @returns {'yarn'|'npm'}
|
|
96
|
+
* @returns {'yarn'|'npm'} - The manager used by the package
|
|
44
97
|
*/
|
|
45
98
|
function manager(packageFile) {
|
|
46
99
|
if (packageFile.get('packagerManager')) {
|
|
@@ -60,7 +113,7 @@ function manager(packageFile) {
|
|
|
60
113
|
|
|
61
114
|
/**
|
|
62
115
|
*
|
|
63
|
-
* @param {import('mrm-core').
|
|
116
|
+
* @param {import('mrm-core').Json} packageFile
|
|
64
117
|
*/
|
|
65
118
|
function hasWorkspaces(packageFile) {
|
|
66
119
|
return Boolean(packageFile.get('workspaces'));
|
|
@@ -88,7 +141,7 @@ function hasDependency(packageFile, packageName, dependencyType) {
|
|
|
88
141
|
|
|
89
142
|
/**
|
|
90
143
|
*
|
|
91
|
-
* @param {import('mrm-core').
|
|
144
|
+
* @param {import('mrm-core').Json} packageFile
|
|
92
145
|
* @param {Record<string, string>} engineVersionMap
|
|
93
146
|
*/
|
|
94
147
|
function engineMinVersion(packageFile, engineVersionMap) {
|
|
@@ -110,15 +163,19 @@ function engineMinVersion(packageFile, engineVersionMap) {
|
|
|
110
163
|
Object.keys(engineVersionMap).map((engineName) => [engineName, engineConstraint(engineName)])
|
|
111
164
|
),
|
|
112
165
|
});
|
|
166
|
+
return packageFile.get('engines');
|
|
113
167
|
}
|
|
114
168
|
|
|
115
169
|
module.exports = {
|
|
116
170
|
...jsonFile,
|
|
117
171
|
emptyScript,
|
|
172
|
+
archetype,
|
|
118
173
|
script,
|
|
119
174
|
manager,
|
|
120
175
|
engineMinVersion,
|
|
121
176
|
hasDependency,
|
|
122
177
|
hasWorkspaces,
|
|
123
178
|
withPackageJson,
|
|
179
|
+
forEachWorkspace,
|
|
180
|
+
listWorkspaceMatchers,
|
|
124
181
|
};
|
package/core/project.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** @type {'docs'} */
|
|
2
|
+
const docs = 'docs';
|
|
1
3
|
/** @type {'install'} */
|
|
2
4
|
const install = 'install';
|
|
3
5
|
/** @type {'prepare'} */
|
|
@@ -24,6 +26,8 @@ const validate = 'validate';
|
|
|
24
26
|
const release = 'release';
|
|
25
27
|
/** @type {'rescue'} */
|
|
26
28
|
const rescue = 'rescue';
|
|
29
|
+
/** @type {'spellcheck'} */
|
|
30
|
+
const spellcheck = 'spellcheck';
|
|
27
31
|
|
|
28
32
|
/**
|
|
29
33
|
* @param {string} taskName
|
|
@@ -41,6 +45,7 @@ function post(taskName) {
|
|
|
41
45
|
|
|
42
46
|
module.exports = {
|
|
43
47
|
build,
|
|
48
|
+
docs,
|
|
44
49
|
prepare,
|
|
45
50
|
develop,
|
|
46
51
|
clean,
|
|
@@ -55,4 +60,5 @@ module.exports = {
|
|
|
55
60
|
rescue,
|
|
56
61
|
test,
|
|
57
62
|
validate,
|
|
63
|
+
spellcheck,
|
|
58
64
|
};
|
package/core/semanticRelease.js
CHANGED
package/core/turbo.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const { json } = require('mrm-core');
|
|
2
|
+
const npm = require('./npm.js');
|
|
3
|
+
const jsonFile = require('./jsonFile.js');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* $schema: string,
|
|
8
|
+
* pipeline?: Record<string, unknown>,
|
|
9
|
+
* globalDependencies?: Array<string>,
|
|
10
|
+
* }} TurboConfig
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {{
|
|
15
|
+
* state: 'present'|'absent',
|
|
16
|
+
* update: (config: TurboConfig) => TurboConfig
|
|
17
|
+
* }} options
|
|
18
|
+
*/
|
|
19
|
+
function turbo({ state, update }) {
|
|
20
|
+
const hasTurbo = state === 'present';
|
|
21
|
+
const turboFile = json('turbo.json');
|
|
22
|
+
|
|
23
|
+
if (hasTurbo) {
|
|
24
|
+
jsonFile.value(turboFile, {
|
|
25
|
+
path: undefined,
|
|
26
|
+
state,
|
|
27
|
+
update,
|
|
28
|
+
/** @type {TurboConfig} */
|
|
29
|
+
default: {
|
|
30
|
+
$schema: 'https://turborepo.org/schema.json',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Otherwise save the file with content
|
|
36
|
+
*/
|
|
37
|
+
turboFile.save();
|
|
38
|
+
} else {
|
|
39
|
+
turboFile.delete();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Dependencies
|
|
43
|
+
npm.dependency({
|
|
44
|
+
dev: true,
|
|
45
|
+
name: ['turbo'],
|
|
46
|
+
state: hasTurbo ? 'present' : 'absent',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = {
|
|
51
|
+
turbo,
|
|
52
|
+
};
|
package/core/typedoc.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { packageJson, json } = require('mrm-core');
|
|
2
|
-
const pkg = require('./pkg');
|
|
3
|
-
const npm = require('./npm');
|
|
4
|
-
const jsonFile = require('./jsonFile');
|
|
2
|
+
const pkg = require('./pkg.js');
|
|
3
|
+
const npm = require('./npm.js');
|
|
4
|
+
const jsonFile = require('./jsonFile.js');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {{
|
package/core/vitest.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const { file, packageJson } = require('mrm-core');
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
const pkg = require('./pkg.js');
|
|
4
|
+
const npm = require('./npm.js');
|
|
5
|
+
const project = require('./project.js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {{
|
|
9
|
+
* state: 'present'|'absent'
|
|
10
|
+
* }} options
|
|
11
|
+
*/
|
|
12
|
+
function vitest({ state }) {
|
|
13
|
+
const hasVitest = state === 'present';
|
|
14
|
+
const hasWorkspace = pkg.hasWorkspaces(packageJson());
|
|
15
|
+
const vitestScript = 'vitest run';
|
|
16
|
+
const update = (/** @type {string|undefined} */ _) =>
|
|
17
|
+
hasVitest ? vitestScript : _ === vitestScript ? pkg.emptyScript : _;
|
|
18
|
+
|
|
19
|
+
// Dependencies
|
|
20
|
+
npm.dependency({
|
|
21
|
+
dev: true,
|
|
22
|
+
name: ['vite', 'vitest'],
|
|
23
|
+
state: hasVitest ? 'present' : 'absent',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/** @type {string|undefined} */
|
|
27
|
+
let viteVersion;
|
|
28
|
+
/** @type {string|undefined} */
|
|
29
|
+
let vitestVersion;
|
|
30
|
+
pkg.withPackageJson((packageFile) => {
|
|
31
|
+
viteVersion = packageFile.get('devDependencies.vite');
|
|
32
|
+
vitestVersion = packageFile.get('devDependencies.vitest');
|
|
33
|
+
pkg.script(packageFile, {
|
|
34
|
+
name: `${project.test}:root`,
|
|
35
|
+
update,
|
|
36
|
+
state: hasWorkspace ? 'absent' : 'present',
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
pkg.forEachWorkspace(({ projectDir, packageFile }) => {
|
|
41
|
+
const hasSrc = fs.existsSync(`${projectDir}/src`);
|
|
42
|
+
const packageState = hasVitest && hasSrc ? 'present' : 'absent';
|
|
43
|
+
pkg.value(packageFile, {
|
|
44
|
+
path: 'devDependencies.vite',
|
|
45
|
+
state: packageState,
|
|
46
|
+
update: (_) => _ ?? viteVersion,
|
|
47
|
+
});
|
|
48
|
+
pkg.value(packageFile, {
|
|
49
|
+
path: 'devDependencies.vitest',
|
|
50
|
+
state: packageState,
|
|
51
|
+
update: (_) => _ ?? vitestVersion,
|
|
52
|
+
});
|
|
53
|
+
pkg.script(packageFile, {
|
|
54
|
+
name: `${project.test}:src`,
|
|
55
|
+
update,
|
|
56
|
+
state: packageState,
|
|
57
|
+
});
|
|
58
|
+
const viteConfig = file(`${projectDir}/vite.config.ts`);
|
|
59
|
+
if (packageState === 'absent') {
|
|
60
|
+
viteConfig.delete();
|
|
61
|
+
} else if (!viteConfig.exists()) {
|
|
62
|
+
viteConfig.save(
|
|
63
|
+
`/// <reference types="vitest" />
|
|
64
|
+
import { defineConfig } from 'vite';
|
|
65
|
+
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
test: {},
|
|
68
|
+
});
|
|
69
|
+
`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = {
|
|
76
|
+
vitest,
|
|
77
|
+
};
|
package/core/vscode.js
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
const { json } = require('mrm-core');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @param {
|
|
4
|
+
* @param {{
|
|
5
|
+
* name: string,
|
|
6
|
+
* state: 'present'|'absent',
|
|
7
|
+
* }} recommendation
|
|
5
8
|
*/
|
|
6
|
-
function vscodeRecommendedExtension(
|
|
9
|
+
function vscodeRecommendedExtension(recommendation) {
|
|
7
10
|
const packageFile = json('.vscode/extensions.json');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
if (recommendation.state === 'present') {
|
|
12
|
+
packageFile.merge({
|
|
13
|
+
recommendations: [recommendation.name],
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
packageFile.set(
|
|
17
|
+
'recommendations',
|
|
18
|
+
packageFile.get('recommendations', []).filter((/** @type {string} */ _) => _ !== recommendation.name)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
11
21
|
packageFile.save();
|
|
12
22
|
}
|
|
13
23
|
exports.vscodeRecommendedExtension = vscodeRecommendedExtension;
|
package/cspell/index.js
CHANGED
|
@@ -1,25 +1,46 @@
|
|
|
1
|
-
const { cspell } = require('../core/cspell');
|
|
1
|
+
const { cspell } = require('../core/cspell.js');
|
|
2
|
+
const project = require('../core/project.js');
|
|
3
|
+
const pkg = require('../core/pkg.js');
|
|
4
|
+
const npm = require('../core/npm.js');
|
|
2
5
|
|
|
3
6
|
function task() {
|
|
7
|
+
const preset = '@w5s/cspell-config';
|
|
4
8
|
cspell({
|
|
5
9
|
state: 'present',
|
|
6
10
|
update: (_) => ({
|
|
7
11
|
..._,
|
|
8
|
-
|
|
9
|
-
new Set([
|
|
10
|
-
'**/build/**',
|
|
11
|
-
'**/lib/**',
|
|
12
|
-
'**/node_modules/**',
|
|
13
|
-
'**/package.json',
|
|
14
|
-
'**/package-lock.json',
|
|
15
|
-
'**/yarn.lock',
|
|
16
|
-
'**/*.log',
|
|
17
|
-
'**/CHANGELOG.md',
|
|
18
|
-
...(_.ignorePaths || []),
|
|
19
|
-
])
|
|
20
|
-
),
|
|
12
|
+
import: [preset],
|
|
21
13
|
}),
|
|
22
14
|
});
|
|
15
|
+
npm.dependency({
|
|
16
|
+
dev: true,
|
|
17
|
+
name: [preset],
|
|
18
|
+
state: 'present',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
pkg.withPackageJson((packageFile) => {
|
|
22
|
+
const hasWorkspaces = pkg.hasWorkspaces(packageFile);
|
|
23
|
+
const workspaceMatchers = pkg.listWorkspaceMatchers(packageFile);
|
|
24
|
+
pkg.script(packageFile, {
|
|
25
|
+
name: project.spellcheck,
|
|
26
|
+
update: `turbo run spellcheck`,
|
|
27
|
+
state: 'present',
|
|
28
|
+
});
|
|
29
|
+
pkg.script(packageFile, {
|
|
30
|
+
name: `${project.spellcheck}:root`,
|
|
31
|
+
update: `cspell --no-progress '**' ${
|
|
32
|
+
hasWorkspaces ? `${workspaceMatchers.map((_) => `--exclude='${_}/**'`).join(' ')}` : ''
|
|
33
|
+
}`,
|
|
34
|
+
state: 'present',
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
pkg.forEachWorkspace(({ packageFile }) => {
|
|
38
|
+
pkg.script(packageFile, {
|
|
39
|
+
name: project.spellcheck,
|
|
40
|
+
update: `cspell --no-progress '**'`,
|
|
41
|
+
state: 'present',
|
|
42
|
+
});
|
|
43
|
+
});
|
|
23
44
|
}
|
|
24
45
|
|
|
25
46
|
task.description = 'Adds CSpell support';
|
package/editorconfig/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { ini } = require('mrm-core');
|
|
2
2
|
const createDebug = require('debug');
|
|
3
|
-
const { vscodeRecommendedExtension } = require('../core/vscode');
|
|
3
|
+
const { vscodeRecommendedExtension } = require('../core/vscode.js');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
@@ -26,7 +26,7 @@ function createEditorConfig(defaults) {
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @param {string} section
|
|
29
|
-
* @param existing
|
|
29
|
+
* @param {defaults} existing
|
|
30
30
|
*/
|
|
31
31
|
function mergeSection(section, existing = {}) {
|
|
32
32
|
return Object.assign(existing, defaults[section] || {});
|
|
@@ -43,7 +43,10 @@ function createEditorConfig(defaults) {
|
|
|
43
43
|
|
|
44
44
|
editorConfigFile.save();
|
|
45
45
|
|
|
46
|
-
vscodeRecommendedExtension(
|
|
46
|
+
vscodeRecommendedExtension({
|
|
47
|
+
name: 'editorconfig.editorconfig',
|
|
48
|
+
state: 'present',
|
|
49
|
+
});
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
task.description = 'Adds EditorConfig file';
|
|
@@ -66,31 +69,38 @@ module.exports = createEditorConfig({
|
|
|
66
69
|
spaces_around_operators: true,
|
|
67
70
|
trim_trailing_whitespace: true,
|
|
68
71
|
},
|
|
69
|
-
'*.json': {
|
|
72
|
+
'*.{json,json5,webmanifest}': {
|
|
70
73
|
indent_size: 2,
|
|
71
74
|
indent_style: 'space',
|
|
72
75
|
insert_final_newline: 'ignore',
|
|
73
76
|
},
|
|
74
|
-
'*.yml': {
|
|
77
|
+
'*.{yml,yaml}': {
|
|
75
78
|
indent_size: 2,
|
|
76
79
|
indent_style: 'space',
|
|
77
80
|
},
|
|
78
|
-
'*.{bat,reg,ps1,vbs,cs
|
|
81
|
+
'*.{bat,reg,ps1,vbs,cs,cmd,fs,ahk}': {
|
|
79
82
|
end_of_line: 'crlf',
|
|
80
83
|
},
|
|
81
|
-
'*.{
|
|
84
|
+
'*.{sh,zsh}': {
|
|
85
|
+
end_of_line: 'lf',
|
|
86
|
+
},
|
|
87
|
+
'*.{css,sass,scss,less,pcss}': {
|
|
82
88
|
indent_size: 2,
|
|
83
89
|
indent_style: 'space',
|
|
84
90
|
max_line_length: 120,
|
|
85
91
|
quote_type: 'single',
|
|
86
92
|
},
|
|
87
|
-
'*.{js,jsx,ts,tsx,js.hbs}': {
|
|
93
|
+
'*.{js,jsx,jsm,ts,tsx,cjs,cjs,cjsx,cts,ctsx,mjs,mts,mtsx,js.hbs}': {
|
|
88
94
|
indent_size: 2,
|
|
89
95
|
indent_style: 'space',
|
|
90
96
|
max_line_length: 120,
|
|
91
97
|
quote_type: 'single',
|
|
92
98
|
},
|
|
93
|
-
'*.{
|
|
99
|
+
'*.{htm,html,svg,vue}': {
|
|
100
|
+
indent_size: 2,
|
|
101
|
+
indent_style: 'space',
|
|
102
|
+
},
|
|
103
|
+
'*.{md,mdwn,mdown,markdown,mdx,apib}': {
|
|
94
104
|
indent_size: 4,
|
|
95
105
|
indent_style: 'space',
|
|
96
106
|
insert_final_newline: true,
|