@adbayb/stack 2.40.0-next-d18b77e → 2.40.0-next-c79a72a
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/configs/oxlint/index.ts +47 -1
- package/dist/configs/oxlint.d.ts +12 -3
- package/dist/configs/oxlint.js +45 -2
- package/dist/index.js +103 -102
- package/package.json +4 -4
package/configs/oxlint/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ const config = defineConfig({
|
|
|
38
38
|
rules: {
|
|
39
39
|
"vitest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }],
|
|
40
40
|
"vitest/no-importing-vitest-globals": "off",
|
|
41
|
+
"vitest/require-test-timeout": "off",
|
|
41
42
|
"vitest/valid-title": ["error", { mustMatch: { test: ["^should "] } }],
|
|
42
43
|
},
|
|
43
44
|
},
|
|
@@ -59,8 +60,10 @@ const config = defineConfig({
|
|
|
59
60
|
`**/*.stories.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
60
61
|
],
|
|
61
62
|
rules: {
|
|
63
|
+
"e18e/prefer-static-regex": "off",
|
|
62
64
|
"import/no-anonymous-default-export": "off",
|
|
63
65
|
"import/no-default-export": "off",
|
|
66
|
+
"react/forbid-component-props": "off",
|
|
64
67
|
},
|
|
65
68
|
},
|
|
66
69
|
],
|
|
@@ -80,6 +83,44 @@ const config = defineConfig({
|
|
|
80
83
|
rules: {
|
|
81
84
|
...e18ePlugin.configs.recommended.rules,
|
|
82
85
|
...perfectionistPlugin["recommended-natural"].rules,
|
|
86
|
+
...Object.fromEntries(
|
|
87
|
+
[
|
|
88
|
+
"sort-export-attributes",
|
|
89
|
+
"sort-import-attributes",
|
|
90
|
+
"sort-interfaces",
|
|
91
|
+
"sort-jsx-props",
|
|
92
|
+
"sort-maps",
|
|
93
|
+
"sort-object-types",
|
|
94
|
+
"sort-objects",
|
|
95
|
+
"sort-union-types",
|
|
96
|
+
"sort-variable-declarations",
|
|
97
|
+
].map((ruleName) => {
|
|
98
|
+
return [
|
|
99
|
+
`perfectionist/${ruleName}`,
|
|
100
|
+
[
|
|
101
|
+
"error",
|
|
102
|
+
{
|
|
103
|
+
customGroups: [
|
|
104
|
+
{
|
|
105
|
+
elementNamePattern: "^(as|id|identifier|htmlFor|key|ref)$",
|
|
106
|
+
groupName: "id-like",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
elementNamePattern: "^(label|name|title)$",
|
|
110
|
+
groupName: "name-like",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
elementNamePattern: "^(description|metadata)$",
|
|
114
|
+
groupName: "metadata-like",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
groups: ["id-like", "name-like", "metadata-like", "unknown"],
|
|
118
|
+
type: "natural",
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
];
|
|
122
|
+
}),
|
|
123
|
+
),
|
|
83
124
|
"@stylistic/jsx-pascal-case": "error",
|
|
84
125
|
"@stylistic/jsx-self-closing-comp": "error",
|
|
85
126
|
"@stylistic/lines-between-class-members": "error",
|
|
@@ -184,6 +225,7 @@ const config = defineConfig({
|
|
|
184
225
|
"no-ternary": "off",
|
|
185
226
|
"no-undef": "off",
|
|
186
227
|
"no-undefined": "off",
|
|
228
|
+
"no-underscore-dangle": "off",
|
|
187
229
|
"no-use-before-define": "off",
|
|
188
230
|
"no-void": "off",
|
|
189
231
|
"no-warning-comments": "off",
|
|
@@ -194,8 +236,11 @@ const config = defineConfig({
|
|
|
194
236
|
"prefer-readonly-parameter-types": "off",
|
|
195
237
|
"react/jsx-filename-extension": ["error", { extensions: ["jsx", "tsx"] }],
|
|
196
238
|
"react/jsx-max-depth": "off",
|
|
239
|
+
"react/jsx-no-literals": "off",
|
|
197
240
|
"react/react-in-jsx-scope": "off",
|
|
198
|
-
"sort-imports":
|
|
241
|
+
"sort-imports": "off", // Already supported by ESLint Perfectionist
|
|
242
|
+
"sort-keys": "off", // Already supported by ESLint Perfectionist
|
|
243
|
+
"sort-vars": "off", // Already supported by ESLint Perfectionist
|
|
199
244
|
"strict-boolean-expressions": "off",
|
|
200
245
|
"typescript/consistent-return": "off",
|
|
201
246
|
"typescript/consistent-type-definitions": ["error", "type"],
|
|
@@ -204,6 +249,7 @@ const config = defineConfig({
|
|
|
204
249
|
"typescript/no-unsafe-type-assertion": "off",
|
|
205
250
|
"unicorn/filename-case": "off",
|
|
206
251
|
"unicorn/import-style": "off",
|
|
252
|
+
"unicorn/no-array-reduce": "off",
|
|
207
253
|
"unicorn/no-useless-undefined": "off",
|
|
208
254
|
},
|
|
209
255
|
});
|
package/dist/configs/oxlint.d.ts
CHANGED
|
@@ -28,21 +28,27 @@ declare const config: {
|
|
|
28
28
|
withinDescribe: "test";
|
|
29
29
|
}];
|
|
30
30
|
"vitest/no-importing-vitest-globals": "off";
|
|
31
|
+
"vitest/require-test-timeout": "off";
|
|
31
32
|
"vitest/valid-title": ["error", {
|
|
32
33
|
mustMatch: {
|
|
33
34
|
test: string[];
|
|
34
35
|
};
|
|
35
36
|
}];
|
|
37
|
+
"e18e/prefer-static-regex"?: never;
|
|
36
38
|
"import/no-anonymous-default-export"?: never;
|
|
37
39
|
"import/no-default-export"?: never;
|
|
40
|
+
"react/forbid-component-props"?: never;
|
|
38
41
|
};
|
|
39
42
|
} | {
|
|
40
43
|
files: string[];
|
|
41
44
|
rules: {
|
|
45
|
+
"e18e/prefer-static-regex": "off";
|
|
42
46
|
"import/no-anonymous-default-export": "off";
|
|
43
47
|
"import/no-default-export": "off";
|
|
48
|
+
"react/forbid-component-props": "off";
|
|
44
49
|
"vitest/consistent-test-it"?: never;
|
|
45
50
|
"vitest/no-importing-vitest-globals"?: never;
|
|
51
|
+
"vitest/require-test-timeout"?: never;
|
|
46
52
|
"vitest/valid-title"?: never;
|
|
47
53
|
};
|
|
48
54
|
plugins?: never;
|
|
@@ -135,6 +141,7 @@ declare const config: {
|
|
|
135
141
|
"no-ternary": "off";
|
|
136
142
|
"no-undef": "off";
|
|
137
143
|
"no-undefined": "off";
|
|
144
|
+
"no-underscore-dangle": "off";
|
|
138
145
|
"no-use-before-define": "off";
|
|
139
146
|
"no-void": "off";
|
|
140
147
|
"no-warning-comments": "off";
|
|
@@ -147,10 +154,11 @@ declare const config: {
|
|
|
147
154
|
extensions: string[];
|
|
148
155
|
}];
|
|
149
156
|
"react/jsx-max-depth": "off";
|
|
157
|
+
"react/jsx-no-literals": "off";
|
|
150
158
|
"react/react-in-jsx-scope": "off";
|
|
151
|
-
"sort-imports":
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
"sort-imports": "off";
|
|
160
|
+
"sort-keys": "off";
|
|
161
|
+
"sort-vars": "off";
|
|
154
162
|
"strict-boolean-expressions": "off";
|
|
155
163
|
"typescript/consistent-return": "off";
|
|
156
164
|
"typescript/consistent-type-definitions": ["error", "type"];
|
|
@@ -159,6 +167,7 @@ declare const config: {
|
|
|
159
167
|
"typescript/no-unsafe-type-assertion": "off";
|
|
160
168
|
"unicorn/filename-case": "off";
|
|
161
169
|
"unicorn/import-style": "off";
|
|
170
|
+
"unicorn/no-array-reduce": "off";
|
|
162
171
|
"unicorn/no-useless-undefined": "off";
|
|
163
172
|
};
|
|
164
173
|
};
|
package/dist/configs/oxlint.js
CHANGED
|
@@ -50,6 +50,7 @@ const config = defineConfig({
|
|
|
50
50
|
withinDescribe: "test"
|
|
51
51
|
}],
|
|
52
52
|
"vitest/no-importing-vitest-globals": "off",
|
|
53
|
+
"vitest/require-test-timeout": "off",
|
|
53
54
|
"vitest/valid-title": ["error", { mustMatch: { test: ["^should "] } }]
|
|
54
55
|
}
|
|
55
56
|
}, {
|
|
@@ -70,8 +71,10 @@ const config = defineConfig({
|
|
|
70
71
|
`**/*.stories.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`
|
|
71
72
|
],
|
|
72
73
|
rules: {
|
|
74
|
+
"e18e/prefer-static-regex": "off",
|
|
73
75
|
"import/no-anonymous-default-export": "off",
|
|
74
|
-
"import/no-default-export": "off"
|
|
76
|
+
"import/no-default-export": "off",
|
|
77
|
+
"react/forbid-component-props": "off"
|
|
75
78
|
}
|
|
76
79
|
}],
|
|
77
80
|
plugins: [
|
|
@@ -90,6 +93,41 @@ const config = defineConfig({
|
|
|
90
93
|
rules: {
|
|
91
94
|
...e18ePlugin.configs.recommended.rules,
|
|
92
95
|
...configs["recommended-natural"].rules,
|
|
96
|
+
...Object.fromEntries([
|
|
97
|
+
"sort-export-attributes",
|
|
98
|
+
"sort-import-attributes",
|
|
99
|
+
"sort-interfaces",
|
|
100
|
+
"sort-jsx-props",
|
|
101
|
+
"sort-maps",
|
|
102
|
+
"sort-object-types",
|
|
103
|
+
"sort-objects",
|
|
104
|
+
"sort-union-types",
|
|
105
|
+
"sort-variable-declarations"
|
|
106
|
+
].map((ruleName) => {
|
|
107
|
+
return [`perfectionist/${ruleName}`, ["error", {
|
|
108
|
+
customGroups: [
|
|
109
|
+
{
|
|
110
|
+
elementNamePattern: "^(as|id|identifier|htmlFor|key|ref)$",
|
|
111
|
+
groupName: "id-like"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
elementNamePattern: "^(label|name|title)$",
|
|
115
|
+
groupName: "name-like"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
elementNamePattern: "^(description|metadata)$",
|
|
119
|
+
groupName: "metadata-like"
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
groups: [
|
|
123
|
+
"id-like",
|
|
124
|
+
"name-like",
|
|
125
|
+
"metadata-like",
|
|
126
|
+
"unknown"
|
|
127
|
+
],
|
|
128
|
+
type: "natural"
|
|
129
|
+
}]];
|
|
130
|
+
})),
|
|
93
131
|
"@stylistic/jsx-pascal-case": "error",
|
|
94
132
|
"@stylistic/jsx-self-closing-comp": "error",
|
|
95
133
|
"@stylistic/lines-between-class-members": "error",
|
|
@@ -198,6 +236,7 @@ const config = defineConfig({
|
|
|
198
236
|
"no-ternary": "off",
|
|
199
237
|
"no-undef": "off",
|
|
200
238
|
"no-undefined": "off",
|
|
239
|
+
"no-underscore-dangle": "off",
|
|
201
240
|
"no-use-before-define": "off",
|
|
202
241
|
"no-void": "off",
|
|
203
242
|
"no-warning-comments": "off",
|
|
@@ -208,8 +247,11 @@ const config = defineConfig({
|
|
|
208
247
|
"prefer-readonly-parameter-types": "off",
|
|
209
248
|
"react/jsx-filename-extension": ["error", { extensions: ["jsx", "tsx"] }],
|
|
210
249
|
"react/jsx-max-depth": "off",
|
|
250
|
+
"react/jsx-no-literals": "off",
|
|
211
251
|
"react/react-in-jsx-scope": "off",
|
|
212
|
-
"sort-imports":
|
|
252
|
+
"sort-imports": "off",
|
|
253
|
+
"sort-keys": "off",
|
|
254
|
+
"sort-vars": "off",
|
|
213
255
|
"strict-boolean-expressions": "off",
|
|
214
256
|
"typescript/consistent-return": "off",
|
|
215
257
|
"typescript/consistent-type-definitions": ["error", "type"],
|
|
@@ -218,6 +260,7 @@ const config = defineConfig({
|
|
|
218
260
|
"typescript/no-unsafe-type-assertion": "off",
|
|
219
261
|
"unicorn/filename-case": "off",
|
|
220
262
|
"unicorn/import-style": "off",
|
|
263
|
+
"unicorn/no-array-reduce": "off",
|
|
221
264
|
"unicorn/no-useless-undefined": "off"
|
|
222
265
|
}
|
|
223
266
|
});
|
package/dist/index.js
CHANGED
|
@@ -173,8 +173,8 @@ const changeset = async (command) => {
|
|
|
173
173
|
//#region src/commands/build.ts
|
|
174
174
|
const createBuildCommand = (program) => {
|
|
175
175
|
program.command({
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
name: "build",
|
|
177
|
+
description: "Build the project in production mode"
|
|
178
178
|
}).task({ async handler() {
|
|
179
179
|
await turbo("build");
|
|
180
180
|
} });
|
|
@@ -207,10 +207,11 @@ const checkDependency = async () => {
|
|
|
207
207
|
const packageContent = require(packagePath);
|
|
208
208
|
const peerDependencies = packageContent.peerDependencies ?? {};
|
|
209
209
|
const devDependencies = packageContent.devDependencies ?? {};
|
|
210
|
+
const dependencies = packageContent.dependencies ?? {};
|
|
210
211
|
return {
|
|
211
|
-
dependencies: packageContent.dependencies ?? {},
|
|
212
|
-
devDependencies,
|
|
213
212
|
name: pkg.name,
|
|
213
|
+
dependencies,
|
|
214
|
+
devDependencies,
|
|
214
215
|
peerDependencies
|
|
215
216
|
};
|
|
216
217
|
});
|
|
@@ -220,35 +221,35 @@ const checkDependency = async () => {
|
|
|
220
221
|
}
|
|
221
222
|
};
|
|
222
223
|
const STARTING_WITH_DIGIT_REGEXP = /^\d/u;
|
|
223
|
-
const checkDependencyVersionRange = ({ dependencies, devDependencies,
|
|
224
|
+
const checkDependencyVersionRange = ({ name, dependencies, devDependencies, peerDependencies }) => {
|
|
224
225
|
for (const [dependencyName, version] of Object.entries(devDependencies)) {
|
|
225
226
|
assertVersion(version, {
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
name: dependencyName,
|
|
228
|
+
consumedBy: name
|
|
228
229
|
});
|
|
229
230
|
if (version !== "workspace:*" && !isExcluded(version) && !STARTING_WITH_DIGIT_REGEXP.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.`, {
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
name: dependencyName,
|
|
232
|
+
consumedBy: name
|
|
232
233
|
});
|
|
233
234
|
}
|
|
234
235
|
for (const [dependencyName, version] of Object.entries(dependencies)) {
|
|
235
236
|
assertVersion(version, {
|
|
236
|
-
|
|
237
|
-
|
|
237
|
+
name: dependencyName,
|
|
238
|
+
consumedBy: name
|
|
238
239
|
});
|
|
239
240
|
if (version !== "workspace:^" && !hasCaret(version) && !isExcluded(version)) throw createPackageError(`As a dependency, \`${dependencyName}\` version must be prefixed with a caret (or set as "workspace:^" for local packages) to optimize the size (whether of installation or bundle output) on the consumer side.`, {
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
name: dependencyName,
|
|
242
|
+
consumedBy: name
|
|
242
243
|
});
|
|
243
244
|
}
|
|
244
245
|
for (const [dependencyName, version] of Object.entries(peerDependencies)) {
|
|
245
246
|
assertVersion(version, {
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
name: dependencyName,
|
|
248
|
+
consumedBy: name
|
|
248
249
|
});
|
|
249
250
|
if (!hasCaret(version) && !isExcluded(version)) throw createPackageError(`As a peer dependency, \`${dependencyName}\` version must be explicit (i.e. the "workspace:^" protocol a version resolver is not allowed) and prefixed with a caret to optimize the size (whether of installation or bundle output) on the consumer side.`, {
|
|
250
|
-
|
|
251
|
-
|
|
251
|
+
name: dependencyName,
|
|
252
|
+
consumedBy: name
|
|
252
253
|
});
|
|
253
254
|
}
|
|
254
255
|
};
|
|
@@ -268,8 +269,8 @@ const createPackagesVersionMismatchChecker = () => {
|
|
|
268
269
|
continue;
|
|
269
270
|
}
|
|
270
271
|
if (!(dependencyVersion === storedVersion)) throw createPackageError(`Mismatched versions: received version \`${dependencyVersion}\` 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 \`${dependencyVersion}\`).`, {
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
name: dependencyName,
|
|
273
|
+
consumedBy: packageName
|
|
273
274
|
});
|
|
274
275
|
}
|
|
275
276
|
};
|
|
@@ -281,11 +282,11 @@ const createPackagesVersionMismatchChecker = () => {
|
|
|
281
282
|
const createPackageError = (message, context) => {
|
|
282
283
|
return createError("stack check", context ? `\`${context.name}\` consumed by \`${context.consumedBy}\` doesn't conform to package guidelines.\n${message}` : message);
|
|
283
284
|
};
|
|
284
|
-
const assertVersion = (version, {
|
|
285
|
+
const assertVersion = (version, { name, consumedBy }) => {
|
|
285
286
|
assert(version, () => {
|
|
286
287
|
return createPackageError(`\`${name}\` must have a valid version specified (current version equals to \`${String(version)}\`).`, {
|
|
287
|
-
|
|
288
|
-
|
|
288
|
+
name,
|
|
289
|
+
consumedBy
|
|
289
290
|
});
|
|
290
291
|
});
|
|
291
292
|
};
|
|
@@ -312,54 +313,54 @@ const ONLY_VALUES = [
|
|
|
312
313
|
];
|
|
313
314
|
const createCheckCommand = (program) => {
|
|
314
315
|
program.command({
|
|
315
|
-
|
|
316
|
-
|
|
316
|
+
name: "check",
|
|
317
|
+
description: "Check code health (static analysis)"
|
|
317
318
|
}).option({
|
|
318
|
-
defaultValue: void 0,
|
|
319
|
-
description: `Filter the compliance check to run (accepted value: ${ONLY_VALUES.join(", ")})`,
|
|
320
319
|
key: "filter",
|
|
321
|
-
name: "filter"
|
|
320
|
+
name: "filter",
|
|
321
|
+
description: `Filter the compliance check to run (accepted value: ${ONLY_VALUES.join(", ")})`,
|
|
322
|
+
defaultValue: void 0
|
|
322
323
|
}).task({
|
|
323
324
|
handler(_, argv) {
|
|
324
325
|
logCheckableFiles(argv.operands);
|
|
325
326
|
},
|
|
326
327
|
skip: ifFilterDefinedAndNotEqualTo("code")
|
|
327
328
|
}).task({
|
|
329
|
+
label: label$4("Prepare the project"),
|
|
328
330
|
async handler() {
|
|
329
331
|
await turbo("build", {
|
|
330
332
|
excludeExamples: true,
|
|
331
333
|
hasLiveOutput: false
|
|
332
334
|
});
|
|
333
335
|
},
|
|
334
|
-
label: label$4("Prepare the project"),
|
|
335
336
|
skip({ filter }) {
|
|
336
337
|
return filter === "commit";
|
|
337
338
|
}
|
|
338
339
|
}).task({
|
|
340
|
+
label: label$4("Check dependency compliance"),
|
|
339
341
|
async handler() {
|
|
340
342
|
await checkDependency();
|
|
341
343
|
},
|
|
342
|
-
label: label$4("Check dependency compliance"),
|
|
343
344
|
skip: ifFilterDefinedAndNotEqualTo("dependency")
|
|
344
345
|
}).task({
|
|
346
|
+
label: label$4("Check formatting compliance"),
|
|
345
347
|
async handler(_, argv) {
|
|
346
348
|
const filenames = argv.operands;
|
|
347
349
|
await checkFormatting(filenames);
|
|
348
350
|
},
|
|
349
|
-
label: label$4("Check formatting compliance"),
|
|
350
351
|
skip: ifFilterDefinedAndNotEqualTo("formatting")
|
|
351
352
|
}).task({
|
|
353
|
+
label: label$4("Check code compliance"),
|
|
352
354
|
async handler(_, argv) {
|
|
353
355
|
const filenames = argv.operands;
|
|
354
356
|
await checkCode(filenames);
|
|
355
357
|
},
|
|
356
|
-
label: label$4("Check code compliance"),
|
|
357
358
|
skip: ifFilterDefinedAndNotEqualTo("code")
|
|
358
359
|
}).task({
|
|
360
|
+
label: label$4("Check commit compliance"),
|
|
359
361
|
async handler() {
|
|
360
362
|
await checkCommit();
|
|
361
363
|
},
|
|
362
|
-
label: label$4("Check commit compliance"),
|
|
363
364
|
skip(context) {
|
|
364
365
|
return context.filter !== "commit";
|
|
365
366
|
}
|
|
@@ -378,24 +379,24 @@ const ifFilterDefinedAndNotEqualTo = (filter) => {
|
|
|
378
379
|
//#region src/commands/clean.ts
|
|
379
380
|
const createCleanCommand = (program) => {
|
|
380
381
|
program.command({
|
|
381
|
-
|
|
382
|
-
|
|
382
|
+
name: "clean",
|
|
383
|
+
description: "Clean the project"
|
|
383
384
|
}).task({
|
|
385
|
+
key: "files",
|
|
386
|
+
label: label$3("Retrieve removable files"),
|
|
384
387
|
async handler() {
|
|
385
388
|
const cachePath = "node_modules/.cache";
|
|
386
389
|
const files = await retrieveIgnoredFiles();
|
|
387
390
|
if (isDirectoryExistAndNotEmpty(resolveFromWorkingDirectory(cachePath))) files.push(cachePath);
|
|
388
391
|
return files;
|
|
389
|
-
}
|
|
390
|
-
key: "files",
|
|
391
|
-
label: label$3("Retrieve removable files")
|
|
392
|
+
}
|
|
392
393
|
}).task({
|
|
394
|
+
label({ files }) {
|
|
395
|
+
return files.length > 0 ? label$3("Clean assets") : "Already clean ✨";
|
|
396
|
+
},
|
|
393
397
|
async handler({ files }) {
|
|
394
398
|
if (files.length === 0) return;
|
|
395
399
|
await cleanFiles(files);
|
|
396
|
-
},
|
|
397
|
-
label({ files }) {
|
|
398
|
-
return files.length > 0 ? label$3("Clean assets") : "Already clean ✨";
|
|
399
400
|
}
|
|
400
401
|
}).task({
|
|
401
402
|
handler({ files }) {
|
|
@@ -441,26 +442,26 @@ const PRESERVE_FILES = ["node_modules"];
|
|
|
441
442
|
|
|
442
443
|
//#endregion
|
|
443
444
|
//#region package.json
|
|
444
|
-
var version = "2.40.0-next-
|
|
445
|
+
var version = "2.40.0-next-c79a72a";
|
|
445
446
|
|
|
446
447
|
//#endregion
|
|
447
448
|
//#region src/commands/create.ts
|
|
448
449
|
const REPOSITORY_REGEXP = /^(?:git@.*:|https?:\/\/.*\/)(?<repoOwner>[^/]+)\/(?<repoName>[^/]+)\.git$/u;
|
|
449
450
|
const createCreateCommand = (program) => {
|
|
450
451
|
program.command({
|
|
451
|
-
|
|
452
|
-
|
|
452
|
+
name: "create",
|
|
453
|
+
description: "Scaffold a new project"
|
|
453
454
|
}).task({ handler() {
|
|
454
455
|
botMessage({
|
|
455
|
-
description: "I can guarantee you a project creation in under 1 minute 🚀",
|
|
456
456
|
title: `I'm Stack v${version} 👋`,
|
|
457
|
+
description: "I can guarantee you a project creation in under 1 minute 🚀",
|
|
457
458
|
type: "information"
|
|
458
459
|
});
|
|
459
460
|
} }).task({
|
|
461
|
+
label: label$2("Check pre-requisites"),
|
|
460
462
|
async handler() {
|
|
461
463
|
await getPnpmVersion();
|
|
462
|
-
}
|
|
463
|
-
label: label$2("Check pre-requisites")
|
|
464
|
+
}
|
|
464
465
|
}).input({
|
|
465
466
|
key: "inputName",
|
|
466
467
|
label: "What's your project name?",
|
|
@@ -470,17 +471,19 @@ const createCreateCommand = (program) => {
|
|
|
470
471
|
label: "How would you describe it?",
|
|
471
472
|
type: "text"
|
|
472
473
|
}).input({
|
|
473
|
-
defaultValue: "git@github.com:adbayb/xxx.git",
|
|
474
474
|
key: "inputUrl",
|
|
475
475
|
label: "Where will it be stored? (Git remote URL)",
|
|
476
|
+
defaultValue: "git@github.com:adbayb/xxx.git",
|
|
476
477
|
type: "text"
|
|
477
478
|
}).input({
|
|
478
|
-
defaultValue: "single-project",
|
|
479
479
|
key: "inputTemplate",
|
|
480
480
|
label: "Which template you would like to apply?",
|
|
481
|
+
defaultValue: "single-project",
|
|
481
482
|
options: ["single-project", "multi-projects"],
|
|
482
483
|
type: "select"
|
|
483
484
|
}).task({
|
|
485
|
+
key: "data",
|
|
486
|
+
label: label$2("Check and format input"),
|
|
484
487
|
async handler({ inputDescription, inputName, inputTemplate, inputUrl }) {
|
|
485
488
|
if (!inputName) throw createError("stack create", "The project name is not optional. Make sure to provide a valid value (non-empty string).");
|
|
486
489
|
const { repoName, repoOwner } = REPOSITORY_REGEXP.exec(inputUrl)?.groups ?? {};
|
|
@@ -499,15 +502,13 @@ const createCreateCommand = (program) => {
|
|
|
499
502
|
templatePath: resolveFromPackageDirectory("templates", inputTemplate),
|
|
500
503
|
workingPath: resolveFromWorkingDirectory(projectName)
|
|
501
504
|
};
|
|
502
|
-
}
|
|
503
|
-
key: "data",
|
|
504
|
-
label: label$2("Check and format input")
|
|
505
|
+
}
|
|
505
506
|
}).input({
|
|
506
|
-
defaultValue: true,
|
|
507
507
|
key: "canRemoveExistingDirectoryInput",
|
|
508
508
|
label({ data: { projectName } }) {
|
|
509
509
|
return label$2(`\`${projectName}\` directory already exists, do you want to remove it?`);
|
|
510
510
|
},
|
|
511
|
+
defaultValue: true,
|
|
511
512
|
skip({ data: { workingPath } }) {
|
|
512
513
|
return !existsSync(workingPath);
|
|
513
514
|
},
|
|
@@ -517,6 +518,10 @@ const createCreateCommand = (program) => {
|
|
|
517
518
|
return createError("mkdir", `Remove or rename the \`${projectName}\` existing directory to apply the template from a clean state.`);
|
|
518
519
|
}
|
|
519
520
|
}).task({
|
|
521
|
+
key: "templateEngine",
|
|
522
|
+
label({ data: { projectName }, inputTemplate }) {
|
|
523
|
+
return label$2(`Copy \`${inputTemplate}\` template to \`${projectName}\` directory`);
|
|
524
|
+
},
|
|
520
525
|
async handler({ canRemoveExistingDirectoryInput, data: { licenseYear, nodeVersion, pnpmVersion, projectDescription, projectName, projectUrl, repoId, templatePath, workingPath }, inputTemplate }) {
|
|
521
526
|
if (canRemoveExistingDirectoryInput) await rm(workingPath, {
|
|
522
527
|
force: true,
|
|
@@ -536,31 +541,28 @@ const createCreateCommand = (program) => {
|
|
|
536
541
|
templateName: inputTemplate,
|
|
537
542
|
templatePath
|
|
538
543
|
});
|
|
539
|
-
},
|
|
540
|
-
key: "templateEngine",
|
|
541
|
-
label({ data: { projectName }, inputTemplate }) {
|
|
542
|
-
return label$2(`Copy \`${inputTemplate}\` template to \`${projectName}\` directory`);
|
|
543
544
|
}
|
|
544
545
|
}).task({
|
|
546
|
+
label() {
|
|
547
|
+
return label$2("Process template");
|
|
548
|
+
},
|
|
545
549
|
async handler({ templateEngine }) {
|
|
546
550
|
await templateEngine.processContents();
|
|
547
551
|
await templateEngine.processPaths();
|
|
548
|
-
},
|
|
549
|
-
label() {
|
|
550
|
-
return label$2("Process template");
|
|
551
552
|
}
|
|
552
553
|
}).task({
|
|
554
|
+
label: label$2("Initialize `git`"),
|
|
553
555
|
async handler({ data: { projectUrl } }) {
|
|
554
556
|
await helpers.exec("git init");
|
|
555
557
|
await helpers.exec(`git remote add origin ${projectUrl}`);
|
|
556
|
-
}
|
|
557
|
-
label: label$2("Initialize `git`")
|
|
558
|
+
}
|
|
558
559
|
}).task({
|
|
560
|
+
label: label$2("Set up the package manager"),
|
|
559
561
|
async handler() {
|
|
560
562
|
await setPackageManager();
|
|
561
|
-
}
|
|
562
|
-
label: label$2("Set up the package manager")
|
|
563
|
+
}
|
|
563
564
|
}).task({
|
|
565
|
+
label: label$2("Install dependencies"),
|
|
564
566
|
async handler({ data: { projectName } }) {
|
|
565
567
|
const localDevelopmentDependencies = ["quickbundle", "vitest"];
|
|
566
568
|
const globalDevelopmentDependencies = ["@adbayb/stack"];
|
|
@@ -571,23 +573,22 @@ const createCreateCommand = (program) => {
|
|
|
571
573
|
} catch (error) {
|
|
572
574
|
throw createError("pnpm", error instanceof Error ? error : new Error(String(error)));
|
|
573
575
|
}
|
|
574
|
-
}
|
|
575
|
-
label: label$2("Install dependencies")
|
|
576
|
+
}
|
|
576
577
|
}).task({
|
|
578
|
+
label: label$2("Run `stack install`"),
|
|
577
579
|
async handler() {
|
|
578
580
|
await helpers.exec("stack install");
|
|
579
|
-
}
|
|
580
|
-
label: label$2("Run `stack install`")
|
|
581
|
+
}
|
|
581
582
|
}).task({
|
|
583
|
+
label: label$2("Commit"),
|
|
582
584
|
async handler() {
|
|
583
585
|
await helpers.exec("git add -A");
|
|
584
586
|
await helpers.exec("git commit -m \"chore: initial commit\"");
|
|
585
|
-
}
|
|
586
|
-
label: label$2("Commit")
|
|
587
|
+
}
|
|
587
588
|
}).task({ handler({ data: { projectName } }) {
|
|
588
589
|
botMessage({
|
|
589
|
-
description: `Run \`cd ./${projectName}\` and Enjoy 🚀`,
|
|
590
590
|
title: "The project was successfully created",
|
|
591
|
+
description: `Run \`cd ./${projectName}\` and Enjoy 🚀`,
|
|
591
592
|
type: "success"
|
|
592
593
|
});
|
|
593
594
|
} });
|
|
@@ -693,28 +694,28 @@ const fixFormatting = oxfmt({ isFixMode: true });
|
|
|
693
694
|
//#region src/commands/fix/fix.ts
|
|
694
695
|
const createFixCommand = (program) => {
|
|
695
696
|
program.command({
|
|
696
|
-
|
|
697
|
-
|
|
697
|
+
name: "fix",
|
|
698
|
+
description: "Fix auto-fixable issues"
|
|
698
699
|
}).task({ handler(_, argv) {
|
|
699
700
|
logCheckableFiles(argv.operands);
|
|
700
701
|
} }).task({
|
|
702
|
+
label: label$1("Prepare the project"),
|
|
701
703
|
async handler() {
|
|
702
704
|
await turbo("build", {
|
|
703
705
|
excludeExamples: true,
|
|
704
706
|
hasLiveOutput: false
|
|
705
707
|
});
|
|
706
|
-
}
|
|
707
|
-
label: label$1("Prepare the project")
|
|
708
|
+
}
|
|
708
709
|
}).task({
|
|
710
|
+
label: label$1("Fix formatting issues"),
|
|
709
711
|
async handler(_, argv) {
|
|
710
712
|
await fixFormatting(argv.operands);
|
|
711
|
-
}
|
|
712
|
-
label: label$1("Fix formatting issues")
|
|
713
|
+
}
|
|
713
714
|
}).task({
|
|
715
|
+
label: label$1("Fix code issues"),
|
|
714
716
|
async handler(_, argv) {
|
|
715
717
|
await fixCode(argv.operands);
|
|
716
|
-
}
|
|
717
|
-
label: label$1("Fix code issues")
|
|
718
|
+
}
|
|
718
719
|
});
|
|
719
720
|
};
|
|
720
721
|
const label$1 = (message) => {
|
|
@@ -725,18 +726,18 @@ const label$1 = (message) => {
|
|
|
725
726
|
//#region src/commands/install.ts
|
|
726
727
|
const createInstallCommand = (program) => {
|
|
727
728
|
program.command({
|
|
728
|
-
|
|
729
|
-
|
|
729
|
+
name: "install",
|
|
730
|
+
description: "Install required setup"
|
|
730
731
|
}).task({
|
|
732
|
+
label: label("Install `git.pre-commit` hook"),
|
|
731
733
|
async handler() {
|
|
732
734
|
await installGitHook("pre-commit", `${getStackCommand(`fix $(node -e 'console.log(require("child_process").execSync("git status --porcelain", {encoding: "utf8"}).split(/${String.raw`\n|\r\n`}/).filter(Boolean).map(item => item.split(" ").at(-1)).join(" "))')`)} && git add -A`);
|
|
733
|
-
}
|
|
734
|
-
label: label("Install `git.pre-commit` hook")
|
|
735
|
+
}
|
|
735
736
|
}).task({
|
|
737
|
+
label: label("Install `git.commit-msg` hook"),
|
|
736
738
|
async handler() {
|
|
737
739
|
await installGitHook("commit-msg", getStackCommand("check --filter commit"));
|
|
738
|
-
}
|
|
739
|
-
label: label("Install `git.commit-msg` hook")
|
|
740
|
+
}
|
|
740
741
|
});
|
|
741
742
|
};
|
|
742
743
|
const label = (message) => {
|
|
@@ -752,24 +753,24 @@ const installGitHook = async (hook, content) => {
|
|
|
752
753
|
//#region src/commands/release.ts
|
|
753
754
|
const createReleaseCommand = (program) => {
|
|
754
755
|
program.command({
|
|
755
|
-
|
|
756
|
-
|
|
756
|
+
name: "release",
|
|
757
|
+
description: "Log, version, and publish package(s)"
|
|
757
758
|
}).option({
|
|
758
|
-
description: "Add a new changelog entry",
|
|
759
759
|
key: "log",
|
|
760
|
-
name: "log"
|
|
760
|
+
name: "log",
|
|
761
|
+
description: "Add a new changelog entry"
|
|
761
762
|
}).option({
|
|
762
|
-
description: "Add an empty changelog entry",
|
|
763
763
|
key: "emptyLog",
|
|
764
|
-
name: "empty-log"
|
|
764
|
+
name: "empty-log",
|
|
765
|
+
description: "Add an empty changelog entry"
|
|
765
766
|
}).option({
|
|
766
|
-
description: "Bump the package(s) version",
|
|
767
767
|
key: "tag",
|
|
768
|
-
name: "tag"
|
|
768
|
+
name: "tag",
|
|
769
|
+
description: "Bump the package(s) version"
|
|
769
770
|
}).option({
|
|
770
|
-
description: "Publish package(s) to the registry",
|
|
771
771
|
key: "publish",
|
|
772
|
-
name: "publish"
|
|
772
|
+
name: "publish",
|
|
773
|
+
description: "Publish package(s) to the registry"
|
|
773
774
|
}).task({
|
|
774
775
|
async handler() {
|
|
775
776
|
helpers.message("New changelog entry\n");
|
|
@@ -806,8 +807,8 @@ const ifNotEqualTo = (validOption) => {
|
|
|
806
807
|
//#region src/commands/start.ts
|
|
807
808
|
const createStartCommand = (program) => {
|
|
808
809
|
program.command({
|
|
809
|
-
|
|
810
|
-
|
|
810
|
+
name: "start",
|
|
811
|
+
description: "Start the project in production mode"
|
|
811
812
|
}).task({ async handler() {
|
|
812
813
|
await turbo("start");
|
|
813
814
|
} });
|
|
@@ -817,8 +818,8 @@ const createStartCommand = (program) => {
|
|
|
817
818
|
//#region src/commands/test.ts
|
|
818
819
|
const createTestCommand = (program) => {
|
|
819
820
|
program.command({
|
|
820
|
-
|
|
821
|
-
|
|
821
|
+
name: "test",
|
|
822
|
+
description: "Test the code execution"
|
|
822
823
|
}).task({ async handler() {
|
|
823
824
|
await turbo("test");
|
|
824
825
|
} });
|
|
@@ -828,8 +829,8 @@ const createTestCommand = (program) => {
|
|
|
828
829
|
//#region src/commands/watch.ts
|
|
829
830
|
const createWatchCommand = (program) => {
|
|
830
831
|
program.command({
|
|
831
|
-
|
|
832
|
-
|
|
832
|
+
name: "watch",
|
|
833
|
+
description: "Build and start the project in development mode"
|
|
833
834
|
}).task({ async handler() {
|
|
834
835
|
await turbo("watch");
|
|
835
836
|
} });
|
|
@@ -839,12 +840,12 @@ const createWatchCommand = (program) => {
|
|
|
839
840
|
//#region src/index.ts
|
|
840
841
|
const createProgram = (...commandFactories) => {
|
|
841
842
|
const program = termost({
|
|
842
|
-
description: "Toolbox to easily scaffold and maintain a project",
|
|
843
843
|
name: "stack",
|
|
844
|
+
description: "Toolbox to easily scaffold and maintain a project",
|
|
844
845
|
onException() {
|
|
845
846
|
botMessage({
|
|
846
|
-
description: "Keep calm and carry on with some coffee ☕️",
|
|
847
847
|
title: "Oops, an error occurred",
|
|
848
|
+
description: "Keep calm and carry on with some coffee ☕️",
|
|
848
849
|
type: "error"
|
|
849
850
|
});
|
|
850
851
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adbayb/stack",
|
|
3
|
-
"version": "2.40.0-next-
|
|
3
|
+
"version": "2.40.0-next-c79a72a",
|
|
4
4
|
"description": "My opinionated JavaScript-based toolchain",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"development",
|
|
@@ -52,17 +52,17 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@changesets/changelog-github": "^0.7.0",
|
|
55
|
-
"@changesets/cli": "^2.31.
|
|
55
|
+
"@changesets/cli": "^2.31.1",
|
|
56
56
|
"@commitlint/cli": "^21.2.1",
|
|
57
57
|
"@commitlint/config-conventional": "^21.2.0",
|
|
58
58
|
"@e18e/eslint-plugin": "^0.5.1",
|
|
59
59
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
60
60
|
"eslint-plugin-perfectionist": "^5.10.0",
|
|
61
61
|
"oxfmt": "^0.58.0",
|
|
62
|
-
"oxlint": "^1.
|
|
62
|
+
"oxlint": "^1.74.0",
|
|
63
63
|
"oxlint-tsgolint": "^0.24.0",
|
|
64
64
|
"termost": "^1.9.1",
|
|
65
|
-
"turbo": "^2.10.
|
|
65
|
+
"turbo": "^2.10.5",
|
|
66
66
|
"typescript": "^6.0.3"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|