@adbayb/stack 0.0.0-next-2a0b6a2 → 0.0.0-next-4a5e303
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.mjs +1 -1
- package/config/eslint/index.mjs +95 -54
- package/config/prettier/index.mjs +1 -1
- package/config/typescript/base.json +1 -1
- package/dist/index.mjs +174 -174
- package/package.json +7 -6
package/bin/index.mjs
CHANGED
package/config/eslint/index.mjs
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-custom-order/object-keys */
|
|
2
|
-
import { includeIgnoreFile } from "@eslint/compat";
|
|
3
|
-
import { FlatCompat } from "@eslint/eslintrc";
|
|
4
|
-
import vitestPlugin from "@vitest/eslint-plugin";
|
|
5
|
-
import importPlugin from "eslint-plugin-import";
|
|
6
|
-
import jestFormattingPlugin from "eslint-plugin-jest-formatting";
|
|
7
|
-
import jsdocPlugin from "eslint-plugin-jsdoc";
|
|
8
|
-
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
|
|
9
|
-
import reactPlugin from "eslint-plugin-react";
|
|
10
|
-
import reactHooksPlugin from "eslint-plugin-react-hooks";
|
|
11
|
-
import sonarjsPlugin from "eslint-plugin-sonarjs";
|
|
12
|
-
import sortKeysCustomOrderPlugin from "eslint-plugin-sort-keys-custom-order";
|
|
13
|
-
import globals from "globals";
|
|
14
|
-
import { resolve } from "node:path";
|
|
15
2
|
import { cwd } from "node:process";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
|
|
16
6
|
import tseslint from "typescript-eslint";
|
|
7
|
+
import globals from "globals";
|
|
8
|
+
import sortKeysCustomOrderPlugin from "eslint-plugin-sort-keys-custom-order";
|
|
9
|
+
import sonarjsPlugin from "eslint-plugin-sonarjs";
|
|
10
|
+
import reactHooksPlugin from "eslint-plugin-react-hooks";
|
|
11
|
+
import reactPlugin from "eslint-plugin-react";
|
|
12
|
+
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
|
|
13
|
+
import nodePlugin from "eslint-plugin-n";
|
|
14
|
+
import jsdocPlugin from "eslint-plugin-jsdoc";
|
|
15
|
+
import jestFormattingPlugin from "eslint-plugin-jest-formatting";
|
|
16
|
+
import importPlugin from "eslint-plugin-import-x";
|
|
17
|
+
import vitestPlugin from "@vitest/eslint-plugin";
|
|
18
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
19
|
+
import { includeIgnoreFile } from "@eslint/compat";
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* TODO:
|
|
20
|
-
* - Review Sonar rules: remove duplicated rules between SonarJS rules and ESLint/Import/TS rules.
|
|
21
23
|
* - Review TS rules: attempt to include all rules from https://typescript-eslint.io/users/configs/#strict-type-checked and https://typescript-eslint.io/users/configs/#stylistic-type-checked ?
|
|
22
|
-
* - Review import rules: at least, add a better behaviour for import order rules (node:* built-in imports should come first for example).
|
|
23
24
|
* - Review JSDoc rules.
|
|
24
25
|
*/
|
|
25
26
|
|
|
27
|
+
const require = createRequire(import.meta.url);
|
|
26
28
|
const CWD = cwd();
|
|
27
29
|
|
|
28
30
|
export default tseslint.config(
|
|
@@ -54,22 +56,26 @@ export default tseslint.config(
|
|
|
54
56
|
},
|
|
55
57
|
},
|
|
56
58
|
plugins: {
|
|
57
|
-
import: importPlugin,
|
|
58
|
-
jsdoc: jsdocPlugin,
|
|
59
|
-
|
|
59
|
+
"import-x": importPlugin,
|
|
60
|
+
"jsdoc": jsdocPlugin,
|
|
61
|
+
"n": nodePlugin,
|
|
62
|
+
"sonarjs": sonarjsPlugin,
|
|
60
63
|
"sort-keys-custom-order": sortKeysCustomOrderPlugin,
|
|
61
64
|
"@typescript-eslint": tseslint.plugin,
|
|
62
65
|
},
|
|
63
66
|
settings: {
|
|
64
|
-
"import/resolver": {
|
|
67
|
+
"import-x/resolver": {
|
|
65
68
|
node: true,
|
|
66
69
|
typescript: true,
|
|
67
70
|
},
|
|
71
|
+
"node": {
|
|
72
|
+
version: require(join(CWD, "package.json")).engines.node,
|
|
73
|
+
},
|
|
68
74
|
},
|
|
69
75
|
rules: {
|
|
70
76
|
//#region eslint
|
|
71
77
|
"constructor-super": "error",
|
|
72
|
-
eqeqeq: "error",
|
|
78
|
+
"eqeqeq": "error",
|
|
73
79
|
"for-direction": "error",
|
|
74
80
|
"getter-return": "error",
|
|
75
81
|
"no-alert": "error",
|
|
@@ -193,53 +199,56 @@ export default tseslint.config(
|
|
|
193
199
|
"valid-typeof": "error",
|
|
194
200
|
//#endregion
|
|
195
201
|
//#region import
|
|
196
|
-
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
197
|
-
"import/export": "error",
|
|
198
|
-
"import/first": "error",
|
|
199
|
-
"import/newline-after-import": "error",
|
|
200
|
-
"import/no-absolute-path": "error",
|
|
201
|
-
"import/no-amd": "error",
|
|
202
|
-
"import/no-
|
|
203
|
-
"import/no-
|
|
204
|
-
"import/no-
|
|
205
|
-
"import/no-
|
|
206
|
-
"import/no-
|
|
207
|
-
"import/no-
|
|
208
|
-
"import/no-
|
|
209
|
-
"import/no-
|
|
210
|
-
"import/no-
|
|
211
|
-
"import/no-
|
|
212
|
-
"import/no-
|
|
213
|
-
"import/no-
|
|
214
|
-
"import/no-
|
|
215
|
-
"import/no-
|
|
216
|
-
"import/no-
|
|
217
|
-
"import/no-
|
|
202
|
+
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
|
203
|
+
"import-x/export": "error",
|
|
204
|
+
"import-x/first": "error",
|
|
205
|
+
"import-x/newline-after-import": "error",
|
|
206
|
+
"import-x/no-absolute-path": "error",
|
|
207
|
+
"import-x/no-amd": "error",
|
|
208
|
+
"import-x/no-anonymous-default-export": "error",
|
|
209
|
+
"import-x/no-commonjs": "error",
|
|
210
|
+
"import-x/no-cycle": "error",
|
|
211
|
+
"import-x/no-default-export": "error",
|
|
212
|
+
"import-x/no-deprecated": "error",
|
|
213
|
+
"import-x/no-duplicates": "error",
|
|
214
|
+
"import-x/no-empty-named-blocks": "error",
|
|
215
|
+
"import-x/no-extraneous-dependencies": "error",
|
|
216
|
+
"import-x/no-import-module-exports": "error",
|
|
217
|
+
"import-x/no-mutable-exports": "error",
|
|
218
|
+
"import-x/no-named-default": "error",
|
|
219
|
+
"import-x/no-namespace": "error",
|
|
220
|
+
"import-x/no-relative-packages": "error",
|
|
221
|
+
"import-x/no-self-import": "error",
|
|
222
|
+
"import-x/no-unassigned-import": "error",
|
|
223
|
+
"import-x/no-unused-modules": "error",
|
|
224
|
+
"import-x/no-useless-path-segments": [
|
|
218
225
|
"error",
|
|
219
226
|
{
|
|
220
227
|
commonjs: true,
|
|
221
228
|
noUselessIndex: true,
|
|
222
229
|
},
|
|
223
230
|
],
|
|
224
|
-
"import/no-webpack-loader-syntax": "error",
|
|
225
|
-
"import/order": [
|
|
231
|
+
"import-x/no-webpack-loader-syntax": "error",
|
|
232
|
+
"import-x/order": [
|
|
226
233
|
"error",
|
|
227
234
|
{
|
|
228
|
-
alphabetize: {
|
|
235
|
+
"alphabetize": {
|
|
229
236
|
caseInsensitive: false,
|
|
230
|
-
order: "
|
|
237
|
+
order: "desc",
|
|
231
238
|
orderImportKind: "desc",
|
|
232
239
|
},
|
|
233
|
-
groups: [
|
|
234
|
-
|
|
240
|
+
"groups": [
|
|
241
|
+
"builtin",
|
|
242
|
+
"external",
|
|
235
243
|
"internal",
|
|
244
|
+
["parent", "sibling", "index"],
|
|
245
|
+
"object",
|
|
236
246
|
"unknown",
|
|
237
|
-
"parent",
|
|
238
|
-
["sibling", "index"],
|
|
239
247
|
],
|
|
240
248
|
"newlines-between": "always",
|
|
241
249
|
},
|
|
242
250
|
],
|
|
251
|
+
"import-x/unambiguous": "error",
|
|
243
252
|
//#endregion
|
|
244
253
|
//#region jsdoc
|
|
245
254
|
"jsdoc/check-access": "error",
|
|
@@ -307,6 +316,37 @@ export default tseslint.config(
|
|
|
307
316
|
"jsdoc/tag-lines": "error",
|
|
308
317
|
"jsdoc/valid-types": "error",
|
|
309
318
|
//#endregion
|
|
319
|
+
//#region n
|
|
320
|
+
"n/callback-return": "error",
|
|
321
|
+
"n/exports-style": ["error", "module.exports"],
|
|
322
|
+
"n/hashbang": "error",
|
|
323
|
+
"n/no-exports-assign": "error",
|
|
324
|
+
"n/no-path-concat": "error",
|
|
325
|
+
"n/no-process-env": [
|
|
326
|
+
"error",
|
|
327
|
+
{
|
|
328
|
+
allowedVariables: ["NODE_ENV"],
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
"n/no-unpublished-bin": "error",
|
|
332
|
+
"n/no-unsupported-features/es-builtins": "error",
|
|
333
|
+
"n/no-unsupported-features/es-syntax": "error",
|
|
334
|
+
"n/no-unsupported-features/node-builtins": [
|
|
335
|
+
"error",
|
|
336
|
+
{ allowExperimental: true },
|
|
337
|
+
],
|
|
338
|
+
"n/prefer-global/buffer": ["error", "never"],
|
|
339
|
+
"n/prefer-global/console": ["error", "always"],
|
|
340
|
+
"n/prefer-global/process": ["error", "never"],
|
|
341
|
+
"n/prefer-global/text-decoder": ["error", "always"],
|
|
342
|
+
"n/prefer-global/text-encoder": ["error", "always"],
|
|
343
|
+
"n/prefer-global/url": ["error", "always"],
|
|
344
|
+
"n/prefer-global/url-search-params": ["error", "always"],
|
|
345
|
+
"n/prefer-node-protocol": "error",
|
|
346
|
+
"n/prefer-promises/dns": "error",
|
|
347
|
+
"n/prefer-promises/fs": "error",
|
|
348
|
+
"n/process-exit-as-throw": "error",
|
|
349
|
+
//#endregion
|
|
310
350
|
//#region sonarjs
|
|
311
351
|
"sonarjs/alt-text": "error",
|
|
312
352
|
"sonarjs/anchor-has-content": "error",
|
|
@@ -548,7 +588,7 @@ export default tseslint.config(
|
|
|
548
588
|
"@typescript-eslint/ban-ts-comment": [
|
|
549
589
|
"error",
|
|
550
590
|
{
|
|
551
|
-
minimumDescriptionLength: 3,
|
|
591
|
+
"minimumDescriptionLength": 3,
|
|
552
592
|
"ts-check": false,
|
|
553
593
|
"ts-expect-error": "allow-with-description",
|
|
554
594
|
"ts-ignore": "allow-with-description",
|
|
@@ -684,7 +724,7 @@ export default tseslint.config(
|
|
|
684
724
|
{
|
|
685
725
|
files: ["**/*.{jsx,tsx}"],
|
|
686
726
|
plugins: {
|
|
687
|
-
react: reactPlugin,
|
|
727
|
+
"react": reactPlugin,
|
|
688
728
|
"react-hooks": reactHooksPlugin,
|
|
689
729
|
},
|
|
690
730
|
settings: {
|
|
@@ -758,7 +798,7 @@ export default tseslint.config(
|
|
|
758
798
|
],
|
|
759
799
|
plugins: {
|
|
760
800
|
"jest-formatting": jestFormattingPlugin,
|
|
761
|
-
vitest: vitestPlugin,
|
|
801
|
+
"vitest": vitestPlugin,
|
|
762
802
|
},
|
|
763
803
|
rules: {
|
|
764
804
|
"jest-formatting/padding-around-all": "error",
|
|
@@ -828,7 +868,8 @@ export default tseslint.config(
|
|
|
828
868
|
"**/*.test.{js,ts,jsx,tsx,cjs,cts,mjs,mts}",
|
|
829
869
|
],
|
|
830
870
|
rules: {
|
|
831
|
-
"import/no-default-export": "off",
|
|
871
|
+
"import-x/no-anonymous-default-export": "off",
|
|
872
|
+
"import-x/no-default-export": "off",
|
|
832
873
|
"sonarjs/sonar-no-magic-numbers": "off",
|
|
833
874
|
},
|
|
834
875
|
},
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { helpers, termost } from 'termost';
|
|
2
|
-
import { existsSync, readdirSync, cpSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { createRequire } from 'node:module';
|
|
4
|
-
import { resolve, join } from 'node:path';
|
|
5
2
|
import process from 'node:process';
|
|
3
|
+
import { resolve, join } from 'node:path';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { existsSync, cpSync, readFileSync, renameSync, writeFileSync, readdirSync } from 'node:fs';
|
|
6
|
+
import { writeFile, chmod, mkdir, symlink } from 'node:fs/promises';
|
|
6
7
|
import { fdir } from 'fdir';
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
var version = "0.0.0-next-4a5e303";
|
|
10
|
+
|
|
11
|
+
const VERSION = version;
|
|
8
12
|
|
|
9
13
|
const require = createRequire(import.meta.url);
|
|
10
14
|
/**
|
|
@@ -210,126 +214,126 @@ const PRETTIER_IGNORE_FILES = [
|
|
|
210
214
|
"pnpm-lock.yaml"
|
|
211
215
|
];
|
|
212
216
|
|
|
213
|
-
const
|
|
217
|
+
const createWatchCommand = (program)=>{
|
|
214
218
|
program.command({
|
|
215
|
-
name: "
|
|
216
|
-
description: "Build the project in
|
|
219
|
+
name: "watch",
|
|
220
|
+
description: "Build and start the project in development mode"
|
|
217
221
|
}).task({
|
|
218
222
|
async handler () {
|
|
219
|
-
await turbo("
|
|
223
|
+
await turbo("watch");
|
|
220
224
|
}
|
|
221
225
|
});
|
|
222
226
|
};
|
|
223
227
|
|
|
224
|
-
const
|
|
225
|
-
"commit",
|
|
226
|
-
"lint",
|
|
227
|
-
"type"
|
|
228
|
-
];
|
|
229
|
-
const createCheckCommand = (program)=>{
|
|
228
|
+
const createTestCommand = (program)=>{
|
|
230
229
|
program.command({
|
|
231
|
-
name: "
|
|
232
|
-
description: "
|
|
233
|
-
}).option({
|
|
234
|
-
key: "only",
|
|
235
|
-
name: "only",
|
|
236
|
-
description: `Run only one specified task (accepted value: ${onlyValues.join(", ")})`,
|
|
237
|
-
defaultValue: undefined
|
|
230
|
+
name: "test",
|
|
231
|
+
description: "Test the code execution"
|
|
238
232
|
}).task({
|
|
239
|
-
label: label$4("Preparing the project"),
|
|
240
233
|
async handler () {
|
|
241
|
-
await turbo("
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
234
|
+
await turbo("test");
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const createStartCommand = (program)=>{
|
|
240
|
+
program.command({
|
|
241
|
+
name: "start",
|
|
242
|
+
description: "Start the project in production mode"
|
|
243
|
+
}).task({
|
|
244
|
+
async handler () {
|
|
245
|
+
await turbo("start");
|
|
247
246
|
}
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const createReleaseCommand = (program)=>{
|
|
251
|
+
program.command({
|
|
252
|
+
name: "release",
|
|
253
|
+
description: "Log, version, and publish package(s)"
|
|
254
|
+
}).option({
|
|
255
|
+
key: "log",
|
|
256
|
+
name: "log",
|
|
257
|
+
description: "Add a new changelog entry"
|
|
258
|
+
}).option({
|
|
259
|
+
key: "tag",
|
|
260
|
+
name: "tag",
|
|
261
|
+
description: "Bump the package(s) version"
|
|
262
|
+
}).option({
|
|
263
|
+
key: "publish",
|
|
264
|
+
name: "publish",
|
|
265
|
+
description: "Publish package(s) to the registry"
|
|
248
266
|
}).task({
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
await checkLints(filenames);
|
|
267
|
+
async handler () {
|
|
268
|
+
helpers.message("New changelog entry\n");
|
|
269
|
+
await changeset("changeset");
|
|
253
270
|
},
|
|
254
|
-
skip:
|
|
271
|
+
skip: ifNotEqualTo("log")
|
|
255
272
|
}).task({
|
|
256
|
-
label: label$4("Checking types"),
|
|
257
273
|
async handler () {
|
|
258
|
-
|
|
274
|
+
helpers.message("Bumping the package(s) version\n");
|
|
275
|
+
await changeset("changeset version && pnpm install --no-frozen-lockfile");
|
|
259
276
|
},
|
|
260
|
-
skip (
|
|
261
|
-
return ifOnlyDefinedAndNotEqualTo("type")(context) || !hasDependency("typescript") || // For now, skip type-checking if some files are passed down
|
|
262
|
-
// @see: https://github.com/microsoft/TypeScript/issues/27379
|
|
263
|
-
argv.operands.length > 0;
|
|
264
|
-
}
|
|
277
|
+
skip: ifNotEqualTo("tag")
|
|
265
278
|
}).task({
|
|
266
|
-
label: label$4("Checking commit"),
|
|
267
279
|
async handler () {
|
|
268
|
-
|
|
280
|
+
helpers.message("Publishing package(s) to the registry\n");
|
|
281
|
+
await changeset("stack build && pnpm changeset publish");
|
|
269
282
|
},
|
|
270
|
-
skip (
|
|
271
|
-
return only !== "commit";
|
|
272
|
-
}
|
|
283
|
+
skip: ifNotEqualTo("publish")
|
|
273
284
|
});
|
|
274
285
|
};
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
return context.only !== undefined && context.only !== only;
|
|
286
|
+
const ifNotEqualTo = (validOption)=>(context)=>{
|
|
287
|
+
return !context[validOption];
|
|
278
288
|
};
|
|
279
289
|
|
|
280
|
-
const
|
|
290
|
+
const createInstallCommand = (program)=>{
|
|
281
291
|
program.command({
|
|
282
|
-
name: "
|
|
283
|
-
description: "
|
|
292
|
+
name: "install",
|
|
293
|
+
description: "Setup initial requirements"
|
|
284
294
|
}).task({
|
|
285
|
-
|
|
286
|
-
label: label$3("Retrieving removable assets"),
|
|
295
|
+
label: label$4("Installing `git.pre-commit` hook"),
|
|
287
296
|
async handler () {
|
|
288
|
-
|
|
289
|
-
const files = await retrieveIgnoredFiles();
|
|
290
|
-
if (isDirectoryExistAndNotEmpty(resolveFromProjectDirectory(cachePath))) {
|
|
291
|
-
files.push(cachePath);
|
|
292
|
-
}
|
|
293
|
-
return files;
|
|
297
|
+
await installGitHook("pre-commit", `${getStackCommand("fix $(git status --porcelain | awk 'BEGIN{ ORS=\" \" } { print $2 }')", false)} && git add -A`);
|
|
294
298
|
}
|
|
295
299
|
}).task({
|
|
296
|
-
label (
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
async handler ({ files }) {
|
|
300
|
-
if (files.length === 0) return;
|
|
301
|
-
await cleanFiles(files);
|
|
300
|
+
label: label$4("Installing `git.commit-msg` hook"),
|
|
301
|
+
async handler () {
|
|
302
|
+
await installGitHook("commit-msg", `${getStackCommand("check --only commit", false)}`);
|
|
302
303
|
}
|
|
304
|
+
});
|
|
305
|
+
};
|
|
306
|
+
const label$4 = (message)=>`${message} 📲`;
|
|
307
|
+
const installGitHook = async (hook, content)=>{
|
|
308
|
+
const filename = resolveFromProjectDirectory(`.git/hooks/${hook}`);
|
|
309
|
+
await writeFile(filename, content);
|
|
310
|
+
return chmod(filename, "0755");
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const createFixCommand = (program)=>{
|
|
314
|
+
program.command({
|
|
315
|
+
name: "fix",
|
|
316
|
+
description: "Fix auto-fixable issues"
|
|
303
317
|
}).task({
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
318
|
+
label: label$3("Preparing the project"),
|
|
319
|
+
async handler () {
|
|
320
|
+
await turbo("build", {
|
|
321
|
+
hasLiveOutput: false
|
|
307
322
|
});
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
323
|
+
}
|
|
324
|
+
}).task({
|
|
325
|
+
label: label$3("Fixing lints"),
|
|
326
|
+
async handler (_, argv) {
|
|
327
|
+
await fixLints(argv.operands);
|
|
328
|
+
}
|
|
329
|
+
}).task({
|
|
330
|
+
label: label$3("Fixing formatting"),
|
|
331
|
+
async handler (_, argv) {
|
|
332
|
+
await fixFormatting(argv.operands);
|
|
311
333
|
}
|
|
312
334
|
});
|
|
313
335
|
};
|
|
314
|
-
const label$3 = (message)=>`${message}
|
|
315
|
-
const cleanFiles = async (files)=>{
|
|
316
|
-
return helpers.exec(`rm -rf ${files.join(" ")}`);
|
|
317
|
-
};
|
|
318
|
-
const isDirectoryExistAndNotEmpty = (path)=>{
|
|
319
|
-
return existsSync(path) && readdirSync(path).length > 0;
|
|
320
|
-
};
|
|
321
|
-
const retrieveIgnoredFiles = async ()=>{
|
|
322
|
-
const rawFiles = await helpers.exec(`git clean -fdXn | grep -v '${PRESERVE_FILES.join("\\|")}' | cut -c 14-`);
|
|
323
|
-
return rawFiles.split(/\n/).filter(Boolean);
|
|
324
|
-
};
|
|
325
|
-
const PRESERVE_FILES = [
|
|
326
|
-
"node_modules",
|
|
327
|
-
".turbo"
|
|
328
|
-
];
|
|
329
|
-
|
|
330
|
-
var version = "0.0.0-next-2a0b6a2";
|
|
331
|
-
|
|
332
|
-
const VERSION = version;
|
|
336
|
+
const label$3 = (message)=>`${message} 🚑`;
|
|
333
337
|
|
|
334
338
|
const createCreateCommand = (program)=>{
|
|
335
339
|
program.command({
|
|
@@ -507,123 +511,119 @@ const label$2 = (message)=>`${message} 🔨`;
|
|
|
507
511
|
});
|
|
508
512
|
};
|
|
509
513
|
|
|
510
|
-
const
|
|
514
|
+
const createCleanCommand = (program)=>{
|
|
511
515
|
program.command({
|
|
512
|
-
name: "
|
|
513
|
-
description: "
|
|
516
|
+
name: "clean",
|
|
517
|
+
description: "Clean the project"
|
|
514
518
|
}).task({
|
|
515
|
-
|
|
519
|
+
key: "files",
|
|
520
|
+
label: label$1("Retrieving removable assets"),
|
|
516
521
|
async handler () {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
522
|
+
const cachePath = "node_modules/.cache";
|
|
523
|
+
const files = await retrieveIgnoredFiles();
|
|
524
|
+
if (isDirectoryExistAndNotEmpty(resolveFromProjectDirectory(cachePath))) {
|
|
525
|
+
files.push(cachePath);
|
|
526
|
+
}
|
|
527
|
+
return files;
|
|
520
528
|
}
|
|
521
529
|
}).task({
|
|
522
|
-
label
|
|
523
|
-
|
|
524
|
-
|
|
530
|
+
label ({ files }) {
|
|
531
|
+
return files.length > 0 ? label$1("Cleaning assets") : "Already clean ✨";
|
|
532
|
+
},
|
|
533
|
+
async handler ({ files }) {
|
|
534
|
+
if (files.length === 0) return;
|
|
535
|
+
await cleanFiles(files);
|
|
525
536
|
}
|
|
526
537
|
}).task({
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
538
|
+
handler ({ files }) {
|
|
539
|
+
helpers.message(`Removed assets: ${files.join(", ")}\n`, {
|
|
540
|
+
type: "information"
|
|
541
|
+
});
|
|
542
|
+
},
|
|
543
|
+
skip ({ files }) {
|
|
544
|
+
return files.length === 0;
|
|
530
545
|
}
|
|
531
546
|
});
|
|
532
547
|
};
|
|
533
|
-
const label$1 = (message)=>`${message}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
program.command({
|
|
537
|
-
name: "install",
|
|
538
|
-
description: "Setup initial requirements"
|
|
539
|
-
}).task({
|
|
540
|
-
label: label("Installing `git.pre-commit` hook"),
|
|
541
|
-
async handler () {
|
|
542
|
-
await installGitHook("pre-commit", `${getStackCommand("fix $(git status --porcelain | awk 'BEGIN{ ORS=\" \" } { print $2 }')", false)} && git add -A`);
|
|
543
|
-
}
|
|
544
|
-
}).task({
|
|
545
|
-
label: label("Installing `git.commit-msg` hook"),
|
|
546
|
-
async handler () {
|
|
547
|
-
await installGitHook("commit-msg", `${getStackCommand("check --only commit", false)}`);
|
|
548
|
-
}
|
|
549
|
-
});
|
|
548
|
+
const label$1 = (message)=>`${message} 🧹`;
|
|
549
|
+
const cleanFiles = async (files)=>{
|
|
550
|
+
return helpers.exec(`rm -rf ${files.join(" ")}`);
|
|
550
551
|
};
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
552
|
+
const isDirectoryExistAndNotEmpty = (path)=>{
|
|
553
|
+
return existsSync(path) && readdirSync(path).length > 0;
|
|
554
|
+
};
|
|
555
|
+
const retrieveIgnoredFiles = async ()=>{
|
|
556
|
+
const rawFiles = await helpers.exec(`git clean -fdXn | grep -v '${PRESERVE_FILES.join("\\|")}' | cut -c 14-`);
|
|
557
|
+
return rawFiles.split(/\n/).filter(Boolean);
|
|
556
558
|
};
|
|
559
|
+
const PRESERVE_FILES = [
|
|
560
|
+
"node_modules",
|
|
561
|
+
".turbo"
|
|
562
|
+
];
|
|
557
563
|
|
|
558
|
-
const
|
|
564
|
+
const onlyValues = [
|
|
565
|
+
"commit",
|
|
566
|
+
"lint",
|
|
567
|
+
"type"
|
|
568
|
+
];
|
|
569
|
+
const createCheckCommand = (program)=>{
|
|
559
570
|
program.command({
|
|
560
|
-
name: "
|
|
561
|
-
description: "
|
|
562
|
-
}).option({
|
|
563
|
-
key: "log",
|
|
564
|
-
name: "log",
|
|
565
|
-
description: "Add a new changelog entry"
|
|
566
|
-
}).option({
|
|
567
|
-
key: "tag",
|
|
568
|
-
name: "tag",
|
|
569
|
-
description: "Bump the package(s) version"
|
|
571
|
+
name: "check",
|
|
572
|
+
description: "Check code health (static analysis)"
|
|
570
573
|
}).option({
|
|
571
|
-
key: "
|
|
572
|
-
name: "
|
|
573
|
-
description:
|
|
574
|
+
key: "only",
|
|
575
|
+
name: "only",
|
|
576
|
+
description: `Run only one specified task (accepted value: ${onlyValues.join(", ")})`,
|
|
577
|
+
defaultValue: undefined
|
|
574
578
|
}).task({
|
|
579
|
+
label: label("Preparing the project"),
|
|
575
580
|
async handler () {
|
|
576
|
-
|
|
577
|
-
|
|
581
|
+
await turbo("build", {
|
|
582
|
+
hasLiveOutput: false
|
|
583
|
+
});
|
|
578
584
|
},
|
|
579
|
-
skip
|
|
585
|
+
skip ({ only }) {
|
|
586
|
+
return only === "commit"; // No need to build if only commitlint is run
|
|
587
|
+
}
|
|
580
588
|
}).task({
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
589
|
+
label: label("Checking linters"),
|
|
590
|
+
async handler (_, argv) {
|
|
591
|
+
const filenames = argv.operands;
|
|
592
|
+
await checkLints(filenames);
|
|
584
593
|
},
|
|
585
|
-
skip:
|
|
594
|
+
skip: ifOnlyDefinedAndNotEqualTo("lint")
|
|
586
595
|
}).task({
|
|
596
|
+
label: label("Checking types"),
|
|
587
597
|
async handler () {
|
|
588
|
-
|
|
589
|
-
await changeset("stack build && pnpm changeset publish");
|
|
598
|
+
await checkTypes();
|
|
590
599
|
},
|
|
591
|
-
skip
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return !context[validOption];
|
|
596
|
-
};
|
|
597
|
-
|
|
598
|
-
const createStartCommand = (program)=>{
|
|
599
|
-
program.command({
|
|
600
|
-
name: "start",
|
|
601
|
-
description: "Start the project in production mode"
|
|
602
|
-
}).task({
|
|
603
|
-
async handler () {
|
|
604
|
-
await turbo("start");
|
|
600
|
+
skip (context, argv) {
|
|
601
|
+
return ifOnlyDefinedAndNotEqualTo("type")(context) || !hasDependency("typescript") || // For now, skip type-checking if some files are passed down
|
|
602
|
+
// @see: https://github.com/microsoft/TypeScript/issues/27379
|
|
603
|
+
argv.operands.length > 0;
|
|
605
604
|
}
|
|
606
|
-
});
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
const createTestCommand = (program)=>{
|
|
610
|
-
program.command({
|
|
611
|
-
name: "test",
|
|
612
|
-
description: "Test the code execution"
|
|
613
605
|
}).task({
|
|
606
|
+
label: label("Checking commit"),
|
|
614
607
|
async handler () {
|
|
615
|
-
await
|
|
608
|
+
await checkCommit();
|
|
609
|
+
},
|
|
610
|
+
skip ({ only }) {
|
|
611
|
+
return only !== "commit";
|
|
616
612
|
}
|
|
617
613
|
});
|
|
618
614
|
};
|
|
615
|
+
const label = (message)=>`${message} 🧐`;
|
|
616
|
+
const ifOnlyDefinedAndNotEqualTo = (only)=>(context)=>{
|
|
617
|
+
return context.only !== undefined && context.only !== only;
|
|
618
|
+
};
|
|
619
619
|
|
|
620
|
-
const
|
|
620
|
+
const createBuildCommand = (program)=>{
|
|
621
621
|
program.command({
|
|
622
|
-
name: "
|
|
623
|
-
description: "Build
|
|
622
|
+
name: "build",
|
|
623
|
+
description: "Build the project in production mode"
|
|
624
624
|
}).task({
|
|
625
625
|
async handler () {
|
|
626
|
-
await turbo("
|
|
626
|
+
await turbo("build");
|
|
627
627
|
}
|
|
628
628
|
});
|
|
629
629
|
};
|
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-4a5e303",
|
|
4
4
|
"description": "My opinionated JavaScript-based toolchain",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -55,24 +55,25 @@
|
|
|
55
55
|
"@eslint/compat": "^1.2.1",
|
|
56
56
|
"@eslint/eslintrc": "^3.1.0",
|
|
57
57
|
"@vitest/eslint-plugin": "^1.1.7",
|
|
58
|
-
"eslint": "^9.13.0",
|
|
59
|
-
"eslint-plugin-react": "^7.37.2",
|
|
60
|
-
"globals": "^15.11.0",
|
|
61
|
-
"typescript-eslint": "^8.11.0",
|
|
62
58
|
"eslint-config-prettier": "^9.1.0",
|
|
63
59
|
"eslint-import-resolver-typescript": "^3.6.3",
|
|
64
|
-
"eslint-plugin-import": "^
|
|
60
|
+
"eslint-plugin-import-x": "^4.3.1",
|
|
65
61
|
"eslint-plugin-jest-formatting": "^3.1.0",
|
|
66
62
|
"eslint-plugin-jsdoc": "^50.4.3",
|
|
67
63
|
"eslint-plugin-mdx": "^3.1.5",
|
|
64
|
+
"eslint-plugin-n": "^17.11.1",
|
|
68
65
|
"eslint-plugin-prettier": "^5.2.1",
|
|
69
66
|
"eslint-plugin-react-hooks": "^5.0.0",
|
|
67
|
+
"eslint-plugin-react": "^7.37.2",
|
|
70
68
|
"eslint-plugin-sonarjs": "^2.0.4",
|
|
71
69
|
"eslint-plugin-sort-keys-custom-order": "^2.2.0",
|
|
70
|
+
"eslint": "^9.13.0",
|
|
72
71
|
"fdir": "^6.4.2",
|
|
72
|
+
"globals": "^15.11.0",
|
|
73
73
|
"prettier": "^3.3.3",
|
|
74
74
|
"termost": "^0.17.0",
|
|
75
75
|
"turbo": "^2.2.3",
|
|
76
|
+
"typescript-eslint": "^8.11.0",
|
|
76
77
|
"typescript": "^5.6.3"
|
|
77
78
|
},
|
|
78
79
|
"scripts": {
|