@w5s/mrm-preset 1.0.0-alpha.8 → 1.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.
Files changed (53) hide show
  1. package/.turbo/turbo-build.log +6 -1
  2. package/.turbo/turbo-docs.log +9 -43
  3. package/.turbo/turbo-format.log +6 -0
  4. package/.turbo/turbo-lint.log +6 -52
  5. package/.turbo/turbo-prepare.log +1 -0
  6. package/.turbo/turbo-test.log +28 -21
  7. package/CHANGELOG.md +194 -39
  8. package/README.md +7 -7
  9. package/bootstrap/README.md +1 -1
  10. package/bootstrap/index.js +14 -38
  11. package/ci/_gitlab/AutoDevops.gitlab-ci.yml +1 -2
  12. package/ci/_gitlab/AutoDevopsInclude.gitlab-ci.yml +19 -19
  13. package/ci/_gitlab/Renovate.gitlab-ci.yml +6 -6
  14. package/ci/github.js +53 -0
  15. package/ci/gitlab.js +1 -2
  16. package/ci/index.js +7 -2
  17. package/commitlint/index.js +8 -2
  18. package/config.json +2 -1
  19. package/contributing/index.js +1 -1
  20. package/core/commitlint.js +5 -5
  21. package/core/cspell.js +2 -11
  22. package/core/eslint.js +25 -6
  23. package/core/git.js +4 -23
  24. package/core/githooks.js +13 -21
  25. package/core/githubCI.js +56 -0
  26. package/core/jest.js +26 -36
  27. package/core/jsonFile.js +8 -7
  28. package/core/lintStaged.js +3 -3
  29. package/core/npm.js +15 -13
  30. package/core/pkg.js +71 -14
  31. package/core/project.js +6 -0
  32. package/core/semanticRelease.js +3 -3
  33. package/core/turbo.js +52 -0
  34. package/core/typedoc.js +3 -3
  35. package/core/vitest.js +77 -0
  36. package/core/vscode.js +15 -5
  37. package/cspell/index.js +35 -14
  38. package/editorconfig/index.js +19 -9
  39. package/eslint/index.js +90 -47
  40. package/githooks/index.js +16 -12
  41. package/gitignore/index.js +1 -1
  42. package/lang/.eslintrc.json +1 -3
  43. package/lang/index.js +73 -36
  44. package/lang/templates/index.spec.ts +3 -2
  45. package/lang/templates/index.ts +1 -2
  46. package/licenses/index.js +26 -0
  47. package/package.json +22 -15
  48. package/postconfigure/index.js +11 -3
  49. package/project/index.js +253 -171
  50. package/release/index.js +5 -5
  51. package/renovate/index.js +4 -3
  52. package/tsconfig.json +3 -6
  53. package/{jest → vitest}/index.js +3 -3
package/project/index.js CHANGED
@@ -1,24 +1,29 @@
1
+ const { dirname } = require('node:path');
1
2
  const { packageJson, json, makeDirs } = require('mrm-core');
2
- const git = require('../core/git');
3
- const pkg = require('../core/pkg');
4
- const npm = require('../core/npm');
5
- const { vscodeTask } = require('../core/vscode');
6
- const project = require('../core/project');
3
+ const git = require('../core/git.js');
4
+ const pkg = require('../core/pkg.js');
5
+ const jsonFile = require('../core/pkg.js');
6
+ const npm = require('../core/npm.js');
7
+ const { vscodeTask } = require('../core/vscode.js');
8
+ const project = require('../core/project.js');
7
9
  const mrmPackageJson = require('../package.json');
10
+ const { turbo } = require('../core/turbo.js');
8
11
 
9
12
  /**
10
13
  *
11
14
  * @param {string} script
12
15
  */
13
- const npmRun = (script) => {
14
- switch (script) {
15
- case project.install:
16
- case project.test:
17
- return `npm ${script}`;
18
- default:
19
- return `npm run ${script}`;
20
- }
21
- };
16
+ // const npmRun = (script) => {
17
+ // switch (script) {
18
+ // case project.install:
19
+ // case project.test: {
20
+ // return `npm ${script}`;
21
+ // }
22
+ // default: {
23
+ // return `npm run ${script}`;
24
+ // }
25
+ // }
26
+ // };
22
27
  /**
23
28
  *
24
29
  * @param {string} script
@@ -28,210 +33,287 @@ const turboRun = (script) => `turbo run ${script}`;
28
33
  /**
29
34
  *
30
35
  * @param {string} script
36
+ * @param {boolean} allowEmpty
31
37
  */
32
- const npmRunAll = (script) => `npm-run-all -p "${script}:*"`;
38
+ const npmRunAll = (script, allowEmpty) => `concurrently "npm:${script}:*" ${allowEmpty ? `"${pkg.emptyScript}"` : ''}`;
33
39
  function task() {
34
- const packageFile = packageJson();
40
+ const rootPackageFile = packageJson();
41
+ const rootUseWorkspace = pkg.hasWorkspaces(rootPackageFile);
42
+ const rootEngineMinVersion = {
43
+ // @ts-ignore
44
+ node: '>=12.x',
45
+ yarn: '>=1.x',
46
+ npm: '>=6.x',
47
+ ...mrmPackageJson.engines,
48
+ };
35
49
  const gitSupported = git.hasGit();
36
- const useWorkspace = packageFile.get('mrmConfig.packageArchetype') === 'workspace';
37
- const packageManager = pkg.manager(packageFile);
50
+ const packageManager = pkg.manager(rootPackageFile);
51
+ const gitRepository = git.remoteSync();
38
52
 
39
53
  // Detect git repository
40
- pkg.value(packageFile, {
41
- path: 'repository',
42
- state: 'present',
43
- update: () => {
44
- const gitRepository = git.remoteSync();
45
- if (gitRepository) {
46
- return {
47
- type: 'git',
48
- url: gitRepository,
49
- };
50
- }
54
+ if (rootUseWorkspace) {
55
+ const dirs = pkg.listWorkspaceMatchers(rootPackageFile).map(dirname);
56
+ makeDirs(dirs);
57
+ }
51
58
 
52
- return undefined;
53
- },
54
- });
59
+ const setDefault = (/** @type {import("mrm-core").Json} */ currentPackageFile, /** @type {boolean} */ root) => {
60
+ jsonFile.value(currentPackageFile, {
61
+ path: 'type',
62
+ state: 'present',
63
+ default: 'module',
64
+ });
65
+ jsonFile.value(currentPackageFile, {
66
+ path: 'license',
67
+ state: 'present',
68
+ update: (_) => _ ?? (root && rootUseWorkspace ? 'UNLICENSED' : undefined),
69
+ });
70
+ jsonFile.value(currentPackageFile, {
71
+ path: 'version',
72
+ state: root && rootUseWorkspace ? 'absent' : 'present',
73
+ default: '1.0.0-alpha.0',
74
+ });
75
+ jsonFile.value(currentPackageFile, {
76
+ path: 'description',
77
+ state: 'present',
78
+ update: (_) => _ ?? (root && rootUseWorkspace ? '' : undefined),
79
+ });
80
+ };
81
+ const addScripts = (/** @type {import("mrm-core").Json} */ currentPackageFile, /** @type {boolean} */ root) => {
82
+ const useWorkspace = pkg.hasWorkspaces(currentPackageFile);
55
83
 
56
- // build & clean
57
- pkg.script(packageFile, {
58
- name: project.build,
59
- script: npmRunAll(project.build),
60
- state: 'present',
61
- });
62
- pkg.script(packageFile, {
63
- name: `${project.build}:empty`,
64
- script: pkg.emptyScript,
65
- state: 'present',
66
- });
67
- pkg.script(packageFile, {
68
- name: `${project.build}:packages`,
69
- script: turboRun(project.build),
70
- state: useWorkspace ? 'present' : 'absent',
71
- });
72
- pkg.script(packageFile, {
73
- name: project.clean,
74
- script: useWorkspace ? turboRun(project.clean) : pkg.emptyScript,
75
- state: useWorkspace ? 'present' : 'default',
76
- });
84
+ // build
85
+ pkg.script(currentPackageFile, {
86
+ name: project.build,
87
+ update: useWorkspace ? turboRun(project.build) : npmRunAll(project.build, true),
88
+ state: 'present',
89
+ });
77
90
 
78
- // develop & auto build & load
79
- pkg.script(packageFile, {
80
- name: project.develop,
81
- script: pkg.emptyScript,
82
- state: 'default',
83
- });
91
+ // lint
92
+ pkg.script(currentPackageFile, {
93
+ name: project.lint,
94
+ update: useWorkspace ? turboRun(project.lint) : npmRunAll(project.lint, true),
95
+ state: 'present',
96
+ });
97
+ pkg.script(currentPackageFile, {
98
+ name: project.format,
99
+ update: useWorkspace ? turboRun(project.format) : npmRunAll(project.format, true),
100
+ state: 'present',
101
+ });
84
102
 
85
- // lint
86
- pkg.script(packageFile, {
87
- name: project.lint,
88
- script: pkg.emptyScript,
89
- state: 'default',
90
- });
91
- pkg.script(packageFile, {
92
- name: project.format,
93
- script: pkg.emptyScript,
94
- state: 'default',
95
- });
103
+ // test
104
+ // pkg.script(currentPackageFile, {
105
+ // name: project.coverage,
106
+ // script: pkg.emptyScript,
107
+ // state: 'default',
108
+ // });
109
+ pkg.script(currentPackageFile, {
110
+ name: project.test,
111
+ update: useWorkspace ? turboRun(project.test) : npmRunAll(project.test, true),
112
+ state: 'present',
113
+ default: pkg.emptyScript,
114
+ });
96
115
 
97
- // test
98
- pkg.script(packageFile, {
99
- name: project.coverage,
100
- script: pkg.emptyScript,
101
- state: 'default',
102
- });
103
- pkg.script(packageFile, {
104
- name: project.test,
105
- script: npmRunAll(project.test),
106
- state: 'present',
107
- });
108
- pkg.script(packageFile, {
109
- name: `${project.prepare}:empty`,
110
- script: pkg.emptyScript,
111
- state: 'default',
112
- });
113
- pkg.script(packageFile, {
114
- name: `${project.prepare}:packages`,
115
- script: turboRun(project.test),
116
- state: useWorkspace ? 'present' : 'absent',
117
- });
118
- pkg.script(packageFile, {
119
- name: project.validate,
120
- script: `${npmRun(project.build)} && ${npmRun(project.lint)} && ${npmRun(project.test)}`,
121
- state: 'present',
122
- });
116
+ // prepare
117
+ pkg.script(currentPackageFile, {
118
+ name: project.prepare,
119
+ update: npmRunAll(project.prepare, true),
120
+ state: 'present',
121
+ });
123
122
 
124
- // code analysis
125
- pkg.script(packageFile, {
126
- name: project.codeAnalysis,
127
- script: pkg.emptyScript,
128
- state: 'default',
129
- });
123
+ // clean
124
+ pkg.script(currentPackageFile, {
125
+ name: project.clean,
126
+ update: useWorkspace ? turboRun(project.clean) : npmRunAll(project.clean, true),
127
+ state: 'present',
128
+ });
130
129
 
131
- // prepare
132
- pkg.script(packageFile, {
133
- name: project.prepare,
134
- script: npmRunAll(project.prepare),
135
- state: 'present',
136
- });
137
- pkg.script(packageFile, {
138
- name: `${project.prepare}:empty`,
139
- script: pkg.emptyScript,
140
- state: 'default',
141
- });
142
- pkg.script(packageFile, {
143
- name: `${project.prepare}:packages`,
144
- script: 'lerna bootstrap',
145
- state: useWorkspace ? 'present' : 'absent',
146
- });
130
+ // Root
147
131
 
148
- // rescue
149
- pkg.script(packageFile, {
150
- name: project.rescue,
151
- script: `${gitSupported ? 'git clean -fdx' : ''};${packageManager} install`,
152
- state: 'present',
132
+ // rescue
133
+ pkg.script(currentPackageFile, {
134
+ name: project.rescue,
135
+ update: `${gitSupported ? 'git clean -fdx' : ''};${packageManager} install`,
136
+ state: root ? 'present' : 'absent',
137
+ });
138
+
139
+ // release
140
+ pkg.script(currentPackageFile, {
141
+ name: project.release,
142
+ default: pkg.emptyScript,
143
+ state: root ? 'present' : 'absent',
144
+ });
145
+
146
+ // code analysis
147
+ pkg.script(currentPackageFile, {
148
+ name: project.codeAnalysis,
149
+ default: pkg.emptyScript,
150
+ state: root ? 'present' : 'absent',
151
+ });
152
+
153
+ // develop & auto build & load
154
+ pkg.script(currentPackageFile, {
155
+ name: project.develop,
156
+ default: pkg.emptyScript,
157
+ state: root ? 'present' : 'absent',
158
+ });
159
+
160
+ // TODO: remove
161
+ pkg.script(currentPackageFile, {
162
+ name: `${project.clean}:packages`,
163
+ state: 'absent',
164
+ });
165
+ pkg.script(currentPackageFile, {
166
+ name: `${project.build}:packages`,
167
+ state: 'absent',
168
+ });
169
+ pkg.script(currentPackageFile, {
170
+ name: `${project.test}:packages`,
171
+ state: 'absent',
172
+ });
173
+ };
174
+
175
+ pkg.withPackageJson((packageFile) => {
176
+ pkg.value(packageFile, {
177
+ path: 'repository',
178
+ state: 'present',
179
+ update: () =>
180
+ gitRepository
181
+ ? {
182
+ type: 'git',
183
+ url: gitRepository,
184
+ }
185
+ : undefined,
186
+ });
187
+
188
+ setDefault(packageFile, false);
189
+ addScripts(packageFile, true);
190
+
191
+ pkg.script(packageFile, {
192
+ name: project.validate,
193
+ update: `${turboRun([project.build, project.lint, project.test].join(' '))}`,
194
+ state: 'present',
195
+ });
196
+
197
+ // Engine
198
+ pkg.engineMinVersion(packageFile, rootEngineMinVersion);
153
199
  });
200
+ pkg.forEachWorkspace((workspace) => {
201
+ pkg.value(workspace.packageFile, {
202
+ path: 'repository',
203
+ state: 'present',
204
+ update: () =>
205
+ gitRepository
206
+ ? {
207
+ type: 'git',
208
+ url: gitRepository,
209
+ directory: workspace.projectDir,
210
+ }
211
+ : undefined,
212
+ });
213
+ setDefault(workspace.packageFile, false);
214
+ addScripts(workspace.packageFile, false);
154
215
 
155
- // release
156
- pkg.script(packageFile, {
157
- name: project.release,
158
- script: pkg.emptyScript,
159
- state: 'default',
216
+ // Engine
217
+ pkg.engineMinVersion(workspace.packageFile, { node: rootEngineMinVersion.node });
160
218
  });
161
219
 
162
220
  // workspace
163
- const turboConfig = json('turbo.json', {
164
- $schema: 'https://turborepo.org/schema.json',
165
- pipeline: {
166
- [project.build]: {
167
- dependsOn: ['^build'],
168
- outputs: ['lib/**', 'dist/**', '.next/**'],
169
- },
170
- [project.test]: {},
171
- [project.lint]: {},
172
- [project.format]: {},
173
- [project.clean]: {
174
- cache: false,
175
- },
176
- [project.develop]: {
177
- cache: false,
178
- },
179
- },
180
- globalDependencies: ['tsconfig.settings.json'],
181
- });
182
221
  const lernaConfig = json('lerna.json', {
183
- version: packageFile.get('version'),
222
+ version: rootPackageFile.get('version'),
184
223
  });
185
- if (useWorkspace) {
186
- const packages = ['packages/*'];
224
+ if (rootUseWorkspace) {
187
225
  const versionIndependent = lernaConfig.get('version') === 'independent';
188
- packageFile.merge({ workspaces: { packages } });
226
+ const gitmoji = true;
227
+
189
228
  lernaConfig.merge({
229
+ $schema: 'https://json.schemastore.org/lerna.json',
190
230
  command: {
191
231
  publish: {
192
232
  conventionalCommits: true,
193
233
  npmClient: 'npm',
194
234
  },
195
235
  version: {
196
- message: `chore(release): publish${versionIndependent ? '' : ' %s'}`,
236
+ message: gitmoji
237
+ ? `🔖 Publish${versionIndependent ? '' : ' %s'}`
238
+ : `chore(release): publish${versionIndependent ? '' : ' %s'}`,
197
239
  },
198
240
  },
199
241
  npmClient: packageManager,
200
- useWorkspaces: useWorkspace,
242
+ useWorkspaces: rootUseWorkspace,
243
+ changelogPreset: '@w5s/conventional-changelog',
201
244
  });
202
245
  lernaConfig.save();
203
- turboConfig.save();
204
- makeDirs('packages');
205
246
  } else {
206
- packageFile.unset('workspaces');
207
247
  lernaConfig.delete();
208
- turboConfig.delete();
209
248
  }
210
249
 
211
- // Engine
212
- pkg.engineMinVersion(
213
- packageFile,
214
- Object.assign(
215
- {
216
- node: '>=12.x',
217
- yarn: '>=1.x',
218
- npm: '>=6.x',
250
+ rootPackageFile.save();
251
+
252
+ // Turbo config
253
+ turbo({
254
+ state: 'present',
255
+ update: (_) => ({
256
+ ..._,
257
+ pipeline: {
258
+ [project.build]: {
259
+ dependsOn: [`^${project.build}`, `//#${project.build}:root`],
260
+ outputs: ['lib/**', 'dist/**', '.next/**'],
261
+ },
262
+ [`//#${project.build}:root`]: {},
263
+ [project.test]: {
264
+ dependsOn: [`^${project.build}`, `//#${project.test}:root`],
265
+ },
266
+ [`//#${project.test}:root`]: {},
267
+ [project.lint]: {
268
+ dependsOn: [`^${project.build}`, `//#${project.lint}:root`],
269
+ },
270
+ [`//#${project.lint}:root`]: {},
271
+ [project.prepare]: {},
272
+ [project.format]: {
273
+ dependsOn: [`//#${project.format}:root`],
274
+ },
275
+ [`//#${project.format}:root`]: {},
276
+ [project.docs]: {},
277
+ [project.spellcheck]: {
278
+ dependsOn: [`//#${project.spellcheck}:root`],
279
+ },
280
+ [`//#${project.spellcheck}:root`]: {},
281
+ [project.clean]: {
282
+ dependsOn: [`//#${project.clean}:root`],
283
+ cache: false,
284
+ },
285
+ [`//#${project.clean}:root`]: {
286
+ cache: false,
287
+ },
288
+ [project.develop]: {
289
+ cache: false,
290
+ },
219
291
  },
220
- mrmPackageJson.engines
221
- )
222
- );
223
- packageFile.save();
292
+ globalDependencies: ['tsconfig.settings.json'],
293
+ }),
294
+ });
224
295
 
225
296
  // Dependencies
297
+ // clean
226
298
  npm.dependency({
227
299
  dev: true,
228
300
  name: ['npm-run-all'],
301
+ state: 'absent',
302
+ });
303
+ npm.dependency({
304
+ dev: true,
305
+ name: ['concurrently'],
229
306
  state: 'present',
230
307
  });
231
308
  npm.dependency({
232
309
  dev: true,
233
- name: ['lerna', 'turbo'],
234
- state: useWorkspace ? 'present' : 'absent',
310
+ name: ['lerna'],
311
+ state: rootUseWorkspace ? 'present' : 'absent',
312
+ });
313
+ npm.dependency({
314
+ dev: true,
315
+ name: ['@w5s/conventional-changelog'],
316
+ state: 'present',
235
317
  });
236
318
 
237
319
  // VSCode
package/release/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  const { packageJson } = require('mrm-core');
2
- const pkg = require('../core/pkg');
3
- const project = require('../core/project');
4
- const { semanticRelease } = require('../core/semanticRelease');
2
+ const pkg = require('../core/pkg.js');
3
+ const project = require('../core/project.js');
4
+ const { semanticRelease } = require('../core/semanticRelease.js');
5
5
 
6
6
  function task() {
7
- const useWorkspace = packageJson().get('mrmConfig.packageArchetype') === 'workspace';
7
+ const useWorkspace = pkg.hasWorkspaces(packageJson());
8
8
 
9
9
  // release
10
10
  pkg.withPackageJson((packageFile) => {
11
11
  pkg.script(packageFile, {
12
12
  name: project.release,
13
13
  // eslint-disable-next-line no-template-curly-in-string
14
- script: useWorkspace ? 'is-ci && lerna publish --yes || lerna publish' : semanticRelease.command(),
14
+ update: useWorkspace ? '[ -n "${CI:-}" ] && lerna publish --yes || lerna publish' : semanticRelease.command(),
15
15
  state: 'present',
16
16
  });
17
17
  });
package/renovate/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const { json, packageJson } = require('mrm-core');
2
- const { hasGit } = require('../core/git');
2
+ const { hasGit } = require('../core/git.js');
3
+ const pkg = require('../core/pkg.js');
3
4
 
4
5
  /**
5
6
  *
@@ -19,13 +20,13 @@ function createRenovate({ renovatePresetApplication, renovatePresetLibrary }) {
19
20
  const gitSupported = hasGit();
20
21
 
21
22
  if (gitSupported) {
22
- const packageArchetype = packageJson().get('mrmConfig.packageArchetype', 'library');
23
+ const packageFile = packageJson();
24
+ const packageArchetype = pkg.archetype(packageFile);
23
25
  const renovatePresetResolved =
24
26
  renovatePreset || (packageArchetype === 'application' ? renovatePresetApplication : renovatePresetLibrary);
25
27
  const renovateFile = json('renovate.json');
26
28
  renovateFile.merge({
27
29
  $schema: 'https://docs.renovatebot.com/renovate-schema.json',
28
- ignorePaths: ['**/node_modules/**'],
29
30
  });
30
31
  renovateFile.set(
31
32
  'extends',
package/tsconfig.json CHANGED
@@ -1,14 +1,11 @@
1
1
  {
2
- "$schema": "https://json.schemastore.org/tsconfig",
3
- "extends": "../../tsconfig.json",
2
+ "$schema": "https://json.schemastore.org/tsconfig.json",
3
+ "extends": "../../tsconfig.settings.json",
4
4
  "compilerOptions": {
5
5
  "allowJs": true,
6
6
  "checkJs": true,
7
7
  "noEmit": true,
8
8
  "resolveJsonModule": true
9
9
  },
10
- "exclude": [
11
- "**/templates/**",
12
- "_tester"
13
- ]
10
+ "exclude": ["**/templates/**", "_tester"]
14
11
  }
@@ -1,15 +1,15 @@
1
- const { jest } = require('../core/jest');
1
+ const { vitest } = require('../core/vitest.js');
2
2
 
3
3
  /**
4
4
  *
5
5
  */
6
6
  function task() {
7
- jest({
7
+ vitest({
8
8
  state: 'present',
9
9
  });
10
10
  }
11
11
 
12
- task.description = 'Setup Jest';
12
+ task.description = 'Setup Vitest';
13
13
  task.parameters = {};
14
14
 
15
15
  module.exports = task;