@adbayb/stack 0.0.0-next-711fb0a → 0.0.0-next-fd6185e
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/bin/index.js +2 -2
- package/configs/eslint/index.js +2 -0
- package/configs/eslint/presets/eslint.js +6 -3
- package/configs/eslint/presets/import.js +0 -1
- package/configs/eslint/presets/sonar.js +0 -1
- package/configs/eslint/presets/unicorn.js +116 -0
- package/dist/index.js +55 -59
- package/package.json +2 -1
package/bin/index.js
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const package_ = createRequire(import.meta.url)("../package.json");
|
|
7
7
|
|
|
8
|
-
import(join("..",
|
|
8
|
+
import(join("..", package_.exports["."].default));
|
package/configs/eslint/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { config as unicornConfig } from "./presets/unicorn.js";
|
|
1
2
|
import { config as uncategorizedConfig } from "./presets/uncategorized.js";
|
|
2
3
|
import { config as typescriptConfig } from "./presets/typescript.js";
|
|
3
4
|
import { config as testConfig } from "./presets/test.js";
|
|
@@ -24,6 +25,7 @@ export default createConfig(
|
|
|
24
25
|
...sonarConfig,
|
|
25
26
|
...stylisticConfig,
|
|
26
27
|
...testConfig,
|
|
28
|
+
...unicornConfig,
|
|
27
29
|
...uncategorizedConfig,
|
|
28
30
|
...overridableConfig,
|
|
29
31
|
);
|
|
@@ -66,13 +66,16 @@ export const config = [
|
|
|
66
66
|
"no-regex-spaces": "error",
|
|
67
67
|
"no-restricted-syntax": [
|
|
68
68
|
"error",
|
|
69
|
-
|
|
69
|
+
/*
|
|
70
|
+
* https://medium.com/@hbarcelos/why-i-banned-null-from-my-js-code-and-why-you-should-too-13df90323cfa
|
|
71
|
+
* https://www.youtube.com/watch?v=PSGEjv3Tqo0&t=561s
|
|
72
|
+
*/
|
|
70
73
|
{
|
|
71
|
-
message: "Use undefined instead of null",
|
|
74
|
+
message: "Use `undefined` instead of `null`.",
|
|
72
75
|
selector: "VariableDeclarator > Literal[raw='null']",
|
|
73
76
|
},
|
|
74
77
|
{
|
|
75
|
-
message: "Use undefined instead of null",
|
|
78
|
+
message: "Use `undefined` instead of `null`.",
|
|
76
79
|
selector: "AssignmentExpression > Literal[raw='null']",
|
|
77
80
|
},
|
|
78
81
|
],
|
|
@@ -17,7 +17,6 @@ export const config = [
|
|
|
17
17
|
"import-x/no-absolute-path": "error",
|
|
18
18
|
"import-x/no-amd": "error",
|
|
19
19
|
"import-x/no-anonymous-default-export": "error",
|
|
20
|
-
"import-x/no-commonjs": "error",
|
|
21
20
|
"import-x/no-cycle": "error",
|
|
22
21
|
"import-x/no-default-export": "error",
|
|
23
22
|
"import-x/no-deprecated": "error",
|
|
@@ -196,7 +196,6 @@ export const config = [
|
|
|
196
196
|
"sonarjs/sonar-no-misleading-character-class": "error",
|
|
197
197
|
"sonarjs/sonar-no-regex-spaces": "error",
|
|
198
198
|
// "sonarjs/sonar-no-unused-class-component-methods": "error", // Disabled since it involves `eslint-plugin-react` activation
|
|
199
|
-
"sonarjs/sonar-prefer-regexp-exec": "error",
|
|
200
199
|
"sonarjs/sql-queries": "error",
|
|
201
200
|
"sonarjs/stable-tests": "error",
|
|
202
201
|
"sonarjs/stateful-regex": "error",
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import unicornPlugin from "eslint-plugin-unicorn";
|
|
2
|
+
|
|
3
|
+
import { JAVASCRIPT_LIKE_EXTENSIONS } from "../constants.js";
|
|
4
|
+
|
|
5
|
+
export const config = [
|
|
6
|
+
{
|
|
7
|
+
files: JAVASCRIPT_LIKE_EXTENSIONS,
|
|
8
|
+
plugins: {
|
|
9
|
+
unicorn: unicornPlugin,
|
|
10
|
+
},
|
|
11
|
+
rules: {
|
|
12
|
+
"unicorn/better-regex": "error",
|
|
13
|
+
"unicorn/catch-error-name": [
|
|
14
|
+
"error",
|
|
15
|
+
{
|
|
16
|
+
name: "error",
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
"unicorn/consistent-empty-array-spread": "error",
|
|
20
|
+
"unicorn/consistent-existence-index-check": "error",
|
|
21
|
+
"unicorn/consistent-function-scoping": "error",
|
|
22
|
+
"unicorn/custom-error-definition": "error",
|
|
23
|
+
"unicorn/error-message": "error",
|
|
24
|
+
"unicorn/escape-case": "error",
|
|
25
|
+
"unicorn/expiring-todo-comments": "error",
|
|
26
|
+
"unicorn/explicit-length-check": "error",
|
|
27
|
+
"unicorn/filename-case": [
|
|
28
|
+
"error",
|
|
29
|
+
{
|
|
30
|
+
cases: {
|
|
31
|
+
camelCase: true,
|
|
32
|
+
pascalCase: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
"unicorn/new-for-builtins": "error",
|
|
37
|
+
"unicorn/no-abusive-eslint-disable": "error",
|
|
38
|
+
"unicorn/no-array-callback-reference": "error",
|
|
39
|
+
"unicorn/no-array-push-push": "error",
|
|
40
|
+
"unicorn/no-await-in-promise-methods": "error",
|
|
41
|
+
"unicorn/no-console-spaces": "error",
|
|
42
|
+
"unicorn/no-document-cookie": "error",
|
|
43
|
+
"unicorn/no-empty-file": "error",
|
|
44
|
+
"unicorn/no-for-loop": "error",
|
|
45
|
+
"unicorn/no-instanceof-array": "error",
|
|
46
|
+
"unicorn/no-invalid-fetch-options": "error",
|
|
47
|
+
"unicorn/no-invalid-remove-event-listener": "error",
|
|
48
|
+
"unicorn/no-length-as-slice-end": "error",
|
|
49
|
+
"unicorn/no-new-buffer": "error",
|
|
50
|
+
"unicorn/no-object-as-default-parameter": "error",
|
|
51
|
+
"unicorn/no-process-exit": "error",
|
|
52
|
+
"unicorn/no-single-promise-in-promise-methods": "error",
|
|
53
|
+
"unicorn/no-static-only-class": "error",
|
|
54
|
+
"unicorn/no-typeof-undefined": "error",
|
|
55
|
+
"unicorn/no-unnecessary-polyfills": "error",
|
|
56
|
+
"unicorn/no-unreadable-array-destructuring": "error",
|
|
57
|
+
"unicorn/no-unreadable-iife": "error",
|
|
58
|
+
"unicorn/no-unused-properties": "error",
|
|
59
|
+
"unicorn/no-useless-fallback-in-spread": "error",
|
|
60
|
+
"unicorn/no-useless-length-check": "error",
|
|
61
|
+
"unicorn/no-useless-promise-resolve-reject": "error",
|
|
62
|
+
"unicorn/no-useless-spread": "error",
|
|
63
|
+
"unicorn/no-zero-fractions": "error",
|
|
64
|
+
"unicorn/number-literal-case": "error",
|
|
65
|
+
"unicorn/prefer-add-event-listener": "error",
|
|
66
|
+
"unicorn/prefer-array-find": "error",
|
|
67
|
+
"unicorn/prefer-array-flat": "error",
|
|
68
|
+
"unicorn/prefer-array-flat-map": "error",
|
|
69
|
+
"unicorn/prefer-array-index-of": "error",
|
|
70
|
+
"unicorn/prefer-array-some": "error",
|
|
71
|
+
"unicorn/prefer-blob-reading-methods": "error",
|
|
72
|
+
"unicorn/prefer-code-point": "error",
|
|
73
|
+
"unicorn/prefer-date-now": "error",
|
|
74
|
+
"unicorn/prefer-dom-node-append": "error",
|
|
75
|
+
"unicorn/prefer-dom-node-remove": "error",
|
|
76
|
+
"unicorn/prefer-dom-node-text-content": "error",
|
|
77
|
+
"unicorn/prefer-event-target": "error",
|
|
78
|
+
"unicorn/prefer-export-from": "error",
|
|
79
|
+
"unicorn/prefer-global-this": "error",
|
|
80
|
+
"unicorn/prefer-includes": "error",
|
|
81
|
+
"unicorn/prefer-keyboard-event-key": "error",
|
|
82
|
+
"unicorn/prefer-logical-operator-over-ternary": "error",
|
|
83
|
+
"unicorn/prefer-math-min-max": "error",
|
|
84
|
+
"unicorn/prefer-math-trunc": "error",
|
|
85
|
+
"unicorn/prefer-modern-dom-apis": "error",
|
|
86
|
+
"unicorn/prefer-modern-math-apis": "error",
|
|
87
|
+
"unicorn/prefer-module": "error",
|
|
88
|
+
"unicorn/prefer-native-coercion-functions": "error",
|
|
89
|
+
"unicorn/prefer-negative-index": "error",
|
|
90
|
+
"unicorn/prefer-number-properties": "error",
|
|
91
|
+
"unicorn/prefer-object-from-entries": "error",
|
|
92
|
+
"unicorn/prefer-optional-catch-binding": "error",
|
|
93
|
+
"unicorn/prefer-prototype-methods": "error",
|
|
94
|
+
"unicorn/prefer-query-selector": "error",
|
|
95
|
+
"unicorn/prefer-reflect-apply": "error",
|
|
96
|
+
"unicorn/prefer-regexp-test": "error",
|
|
97
|
+
"unicorn/prefer-set-has": "error",
|
|
98
|
+
"unicorn/prefer-set-size": "error",
|
|
99
|
+
"unicorn/prefer-spread": "error",
|
|
100
|
+
"unicorn/prefer-string-raw": "error",
|
|
101
|
+
"unicorn/prefer-string-replace-all": "error",
|
|
102
|
+
"unicorn/prefer-string-slice": "error",
|
|
103
|
+
"unicorn/prefer-string-starts-ends-with": "error",
|
|
104
|
+
"unicorn/prefer-string-trim-start-end": "error",
|
|
105
|
+
"unicorn/prefer-structured-clone": "error",
|
|
106
|
+
"unicorn/prefer-switch": "error",
|
|
107
|
+
"unicorn/prefer-ternary": "error",
|
|
108
|
+
"unicorn/prefer-top-level-await": "error",
|
|
109
|
+
"unicorn/prefer-type-error": "error",
|
|
110
|
+
"unicorn/prevent-abbreviations": "error",
|
|
111
|
+
"unicorn/relative-url-style": ["error", "always"],
|
|
112
|
+
"unicorn/require-array-join-separator": "error",
|
|
113
|
+
"unicorn/require-number-to-fixed-digits-argument": "error",
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
];
|
package/dist/index.js
CHANGED
|
@@ -96,7 +96,7 @@ const getStackCommand = (command, isNodeRuntime = true)=>{
|
|
|
96
96
|
const hasDependency = (packageName)=>{
|
|
97
97
|
return Boolean(require.resolve(packageName));
|
|
98
98
|
};
|
|
99
|
-
const
|
|
99
|
+
const setPackageManager = async ()=>{
|
|
100
100
|
return helpers.exec("corepack enable");
|
|
101
101
|
};
|
|
102
102
|
const request = {
|
|
@@ -117,31 +117,30 @@ const eslint = (options)=>async (files = [])=>{
|
|
|
117
117
|
eslintFiles.push(".");
|
|
118
118
|
} else {
|
|
119
119
|
eslintFiles = files.filter((file)=>{
|
|
120
|
-
return ESLINT_EXTENSIONS.some((
|
|
120
|
+
return ESLINT_EXTENSIONS.some((extension)=>file.endsWith(extension));
|
|
121
121
|
});
|
|
122
|
-
if (eslintFiles.length === 0) return
|
|
122
|
+
if (eslintFiles.length === 0) return;
|
|
123
123
|
}
|
|
124
|
-
const
|
|
124
|
+
const arguments_ = [
|
|
125
125
|
...eslintFiles
|
|
126
126
|
];
|
|
127
|
-
|
|
128
|
-
args.push(`--cache-location ${resolveFromProjectDirectory("node_modules/.cache/.eslintcache")}`);
|
|
129
|
-
// @note: prevent errors when no matched file is found
|
|
130
|
-
args.push("--no-error-on-unmatched-pattern");
|
|
127
|
+
arguments_.push("--cache", `--cache-location ${resolveFromProjectDirectory("node_modules/.cache/.eslintcache")}`, "--no-error-on-unmatched-pattern");
|
|
131
128
|
if (options.isFixMode) {
|
|
132
|
-
|
|
129
|
+
arguments_.push("--fix");
|
|
133
130
|
}
|
|
134
131
|
try {
|
|
135
|
-
return await helpers.exec(`eslint ${
|
|
132
|
+
return await helpers.exec(`eslint ${arguments_.join(" ")}`);
|
|
136
133
|
} catch (error) {
|
|
137
134
|
throw createError("eslint", error);
|
|
138
135
|
}
|
|
139
136
|
};
|
|
140
|
-
const turbo = async (command, options = {
|
|
141
|
-
hasLiveOutput: true
|
|
142
|
-
})=>{
|
|
137
|
+
const turbo = async (command, options = {})=>{
|
|
143
138
|
try {
|
|
144
|
-
|
|
139
|
+
const { hasLiveOutput = true, ...restOptions } = options;
|
|
140
|
+
return await helpers.exec(`turbo run ${command}`, {
|
|
141
|
+
...restOptions,
|
|
142
|
+
hasLiveOutput
|
|
143
|
+
});
|
|
145
144
|
} catch (error) {
|
|
146
145
|
throw createError("turbo", error);
|
|
147
146
|
}
|
|
@@ -168,9 +167,7 @@ const ESLINT_EXTENSIONS = [
|
|
|
168
167
|
"mdx"
|
|
169
168
|
];
|
|
170
169
|
|
|
171
|
-
var version = "0.0.0-next-
|
|
172
|
-
|
|
173
|
-
const VERSION = version;
|
|
170
|
+
var version = "0.0.0-next-fd6185e";
|
|
174
171
|
|
|
175
172
|
const createWatchCommand = (program)=>{
|
|
176
173
|
program.command({
|
|
@@ -286,19 +283,17 @@ const fixFormatting = async (files)=>{
|
|
|
286
283
|
return !PRETTIER_IGNORE_FILES.some((filename)=>file.endsWith(filename)) && // The root `README.md` file is ignored to prevent error due to its symbolic link nature when specified explicitly as a file
|
|
287
284
|
file !== "README.md";
|
|
288
285
|
});
|
|
289
|
-
if (prettierFiles.length === 0) return
|
|
286
|
+
if (prettierFiles.length === 0) return;
|
|
290
287
|
}
|
|
291
|
-
const
|
|
288
|
+
const arguments_ = [
|
|
292
289
|
...prettierFiles
|
|
293
290
|
];
|
|
294
291
|
if (existsSync(resolveFromProjectDirectory(".gitignore"))) {
|
|
295
|
-
|
|
292
|
+
arguments_.push("--ignore-path .gitignore");
|
|
296
293
|
}
|
|
297
|
-
|
|
298
|
-
args.push("--ignore-unknown");
|
|
299
|
-
args.push("--no-error-on-unmatched-pattern");
|
|
294
|
+
arguments_.push("--write", "--ignore-unknown", "--no-error-on-unmatched-pattern");
|
|
300
295
|
try {
|
|
301
|
-
return await helpers.exec(`prettier ${
|
|
296
|
+
return await helpers.exec(`prettier ${arguments_.join(" ")}`);
|
|
302
297
|
} catch (error) {
|
|
303
298
|
throw createError("prettier", error);
|
|
304
299
|
}
|
|
@@ -336,7 +331,7 @@ const createCreateCommand = (program)=>{
|
|
|
336
331
|
}).task({
|
|
337
332
|
handler () {
|
|
338
333
|
botMessage({
|
|
339
|
-
title: `I'm Stack v${
|
|
334
|
+
title: `I'm Stack v${version}, your bot assistant`,
|
|
340
335
|
description: "I can guarantee you a project creation in under 1 minute 🚀",
|
|
341
336
|
type: "information"
|
|
342
337
|
});
|
|
@@ -420,21 +415,21 @@ const createCreateCommand = (program)=>{
|
|
|
420
415
|
}).task({
|
|
421
416
|
label: label$2("Set up the package manager"),
|
|
422
417
|
async handler () {
|
|
423
|
-
await
|
|
418
|
+
await setPackageManager();
|
|
424
419
|
}
|
|
425
420
|
}).task({
|
|
426
421
|
label: label$2("Install dependencies"),
|
|
427
422
|
async handler ({ data }) {
|
|
428
|
-
const
|
|
423
|
+
const localDevelopmentDependencies = [
|
|
429
424
|
"quickbundle",
|
|
430
425
|
"vitest"
|
|
431
426
|
];
|
|
432
|
-
const
|
|
427
|
+
const globalDevelopmentDependencies = [
|
|
433
428
|
"@adbayb/stack"
|
|
434
429
|
];
|
|
435
430
|
try {
|
|
436
|
-
await helpers.exec(`pnpm add ${
|
|
437
|
-
await helpers.exec(`pnpm add ${
|
|
431
|
+
await helpers.exec(`pnpm add ${globalDevelopmentDependencies.join(" ")} --save-dev --ignore-workspace-root-check`);
|
|
432
|
+
await helpers.exec(`pnpm add ${localDevelopmentDependencies.join(" ")} --save-dev --filter ${data.projectName}`);
|
|
438
433
|
await helpers.exec("pnpm install");
|
|
439
434
|
} catch (error) {
|
|
440
435
|
throw createError("pnpm", error);
|
|
@@ -476,7 +471,7 @@ const label$2 = (message)=>`${message} 🔨`;
|
|
|
476
471
|
const projectRootPath = resolveFromProjectDirectory("./");
|
|
477
472
|
const templateExpressionRegExp = /{{(.*?)}}/g;
|
|
478
473
|
const evaluate = (content)=>{
|
|
479
|
-
return content.
|
|
474
|
+
return content.replaceAll(templateExpressionRegExp, (_, key)=>dataModel[key] || "");
|
|
480
475
|
};
|
|
481
476
|
/** Copy the template before mutations. */ cpSync(templateRootPath, projectRootPath, {
|
|
482
477
|
force: true,
|
|
@@ -489,10 +484,10 @@ const label$2 = (message)=>`${message} 🔨`;
|
|
|
489
484
|
writeFileSync(projectFilePath, content, "utf-8");
|
|
490
485
|
});
|
|
491
486
|
/** Template folder mutations. */ new fdir().withBasePath().onlyDirs().filter((path)=>{
|
|
492
|
-
return
|
|
487
|
+
return templateExpressionRegExp.test(path);
|
|
493
488
|
}).crawl(projectRootPath).sync()// Re-order from longest to lowest path length to apply first renaming operations on deepest file structure
|
|
494
489
|
.sort((a, b)=>b.length - a.length).forEach((templateFolderPath)=>{
|
|
495
|
-
const newPath = templateFolderPath.
|
|
490
|
+
const newPath = templateFolderPath.replaceAll(templateExpressionRegExp, (_, dataModelKey)=>{
|
|
496
491
|
return dataModel[dataModelKey];
|
|
497
492
|
});
|
|
498
493
|
renameSync(templateFolderPath, newPath);
|
|
@@ -541,7 +536,8 @@ const isDirectoryExistAndNotEmpty = (path)=>{
|
|
|
541
536
|
return existsSync(path) && readdirSync(path).length > 0;
|
|
542
537
|
};
|
|
543
538
|
const retrieveIgnoredFiles = async ()=>{
|
|
544
|
-
const
|
|
539
|
+
const excludedFiles = PRESERVE_FILES.join(String.raw`\|`);
|
|
540
|
+
const rawFiles = await helpers.exec(`git clean -fdXn | grep -v '${excludedFiles}' | cut -c 14-`);
|
|
545
541
|
return rawFiles.split(/\n/).filter(Boolean);
|
|
546
542
|
};
|
|
547
543
|
const PRESERVE_FILES = [
|
|
@@ -559,25 +555,25 @@ const checkTypes = async ()=>{
|
|
|
559
555
|
const checkPackages = async ()=>{
|
|
560
556
|
const stdout = await helpers.exec("pnpm recursive ls --json");
|
|
561
557
|
const checkPackagesVersionMismatch = createPackagesVersionMismatchChecker();
|
|
562
|
-
const packages = JSON.parse(stdout).map((
|
|
563
|
-
const
|
|
564
|
-
assert(
|
|
565
|
-
const
|
|
566
|
-
const peerDependencies =
|
|
567
|
-
const devDependencies =
|
|
568
|
-
const dependencies =
|
|
558
|
+
const packages = JSON.parse(stdout).map((package_)=>{
|
|
559
|
+
const packagePath = join(package_.path, "package.json");
|
|
560
|
+
assert(package_.name, ()=>createPackageError(`\`${packagePath}\` must have a name field.`));
|
|
561
|
+
const packageContent = require(packagePath);
|
|
562
|
+
const peerDependencies = packageContent.peerDependencies ?? {};
|
|
563
|
+
const devDependencies = packageContent.devDependencies ?? {};
|
|
564
|
+
const dependencies = packageContent.dependencies ?? {};
|
|
569
565
|
return {
|
|
570
|
-
name:
|
|
566
|
+
name: package_.name,
|
|
571
567
|
dependencies,
|
|
572
568
|
devDependencies,
|
|
573
569
|
peerDependencies
|
|
574
570
|
};
|
|
575
571
|
});
|
|
576
|
-
for (const
|
|
572
|
+
for (const package_ of packages){
|
|
577
573
|
// Check version mismatches to guarantee a single copy for a given package in the monorepo (use case: prevent singleton-like issues with React contexts)
|
|
578
|
-
checkPackagesVersionMismatch(
|
|
574
|
+
checkPackagesVersionMismatch(package_);
|
|
579
575
|
// Check version range accordingly to our dependency guidelines (ie. dev dependencies must be pinned and dependencies must have caret)
|
|
580
|
-
checkPackagesVersionRange(
|
|
576
|
+
checkPackagesVersionRange(package_);
|
|
581
577
|
}
|
|
582
578
|
};
|
|
583
579
|
const checkPackagesVersionRange = ({ name, dependencies, devDependencies, peerDependencies })=>{
|
|
@@ -587,13 +583,11 @@ const checkPackagesVersionRange = ({ name, dependencies, devDependencies, peerDe
|
|
|
587
583
|
name: dependencyName,
|
|
588
584
|
consumedBy: name
|
|
589
585
|
});
|
|
590
|
-
if (version !== "workspace:*" && !/^\d/.
|
|
586
|
+
if (version !== "workspace:*" && !/^\d/.test(version)) throw createPackageError(`As a dev dependency, \`${dependencyName}\` version must be fixed (or set as "workspace:*" for local packages) to reduce accidental breaking change risks due to an implicit semver upgrade.`, {
|
|
591
587
|
name: dependencyName,
|
|
592
588
|
consumedBy: name
|
|
593
589
|
});
|
|
594
590
|
}
|
|
595
|
-
const isPreReleaseVersion = (version)=>/\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/.exec(version);
|
|
596
|
-
const hasNoCaret = (version)=>!isPreReleaseVersion(version) && !/^\^/.exec(version);
|
|
597
591
|
for (const dependencyName of Object.keys(dependencies)){
|
|
598
592
|
const version = dependencies[dependencyName];
|
|
599
593
|
assertVersion(version, {
|
|
@@ -623,12 +617,12 @@ const checkPackagesVersionRange = ({ name, dependencies, devDependencies, peerDe
|
|
|
623
617
|
};
|
|
624
618
|
const createPackagesVersionMismatchChecker = ()=>{
|
|
625
619
|
const monorepoDependencies = new Map();
|
|
626
|
-
const
|
|
627
|
-
const lint = (
|
|
628
|
-
const
|
|
629
|
-
const
|
|
630
|
-
const store =
|
|
631
|
-
const dependencies =
|
|
620
|
+
const monorepoDevelopmentDependencies = new Map();
|
|
621
|
+
const lint = (package_, type)=>{
|
|
622
|
+
const packageName = package_.name;
|
|
623
|
+
const isDevelopment = type === "development";
|
|
624
|
+
const store = isDevelopment ? monorepoDevelopmentDependencies : monorepoDependencies;
|
|
625
|
+
const dependencies = isDevelopment ? package_.devDependencies : package_.dependencies;
|
|
632
626
|
for (const dependencyName of Object.keys(dependencies)){
|
|
633
627
|
const depVersion = dependencies[dependencyName];
|
|
634
628
|
if (!depVersion) continue;
|
|
@@ -641,14 +635,14 @@ const createPackagesVersionMismatchChecker = ()=>{
|
|
|
641
635
|
if (!isSameMonorepoVersion) {
|
|
642
636
|
throw createPackageError(`Mismatched versions: received version \`${depVersion}\` while others use \`${storedVersion}\`. To prevent issues with singleton-like code (React contexts, ...), please make sure to update all packages to use the same \`${dependencyName}\` version (either \`${storedVersion}\` or \`${depVersion}\`.`, {
|
|
643
637
|
name: dependencyName,
|
|
644
|
-
consumedBy:
|
|
638
|
+
consumedBy: packageName
|
|
645
639
|
});
|
|
646
640
|
}
|
|
647
641
|
}
|
|
648
642
|
};
|
|
649
|
-
return (
|
|
650
|
-
lint(
|
|
651
|
-
lint(
|
|
643
|
+
return (package_)=>{
|
|
644
|
+
lint(package_, "development");
|
|
645
|
+
lint(package_, "production");
|
|
652
646
|
};
|
|
653
647
|
};
|
|
654
648
|
const createPackageError = (message, context)=>{
|
|
@@ -660,6 +654,8 @@ function assertVersion(version, { name, consumedBy }) {
|
|
|
660
654
|
consumedBy
|
|
661
655
|
}));
|
|
662
656
|
}
|
|
657
|
+
const isPreReleaseVersion = (version)=>/\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/.exec(version);
|
|
658
|
+
const hasNoCaret = (version)=>!isPreReleaseVersion(version) && !version.startsWith("^");
|
|
663
659
|
|
|
664
660
|
const checkLinter = eslint({
|
|
665
661
|
isFixMode: false
|
|
@@ -759,7 +755,7 @@ const createProgram = (...commandFactories)=>{
|
|
|
759
755
|
type: "error"
|
|
760
756
|
});
|
|
761
757
|
},
|
|
762
|
-
version:
|
|
758
|
+
version: version
|
|
763
759
|
});
|
|
764
760
|
for (const commandBuilder of commandFactories){
|
|
765
761
|
commandBuilder(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adbayb/stack",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-fd6185e",
|
|
4
4
|
"description": "My opinionated JavaScript-based toolchain",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"eslint-plugin-react": "^7.37.2",
|
|
68
68
|
"eslint-plugin-sonarjs": "^2.0.4",
|
|
69
69
|
"eslint-plugin-sort-keys-custom-order": "^2.2.0",
|
|
70
|
+
"eslint-plugin-unicorn": "^56.0.0",
|
|
70
71
|
"eslint": "^9.14.0",
|
|
71
72
|
"fdir": "^6.4.2",
|
|
72
73
|
"globals": "^15.12.0",
|