@apollion-dsi/scripts 0.8.1 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/coverage/clover.xml +29 -5
- package/coverage/coverage-final.json +3 -1
- package/coverage/lcov-report/config/env.ts.html +2 -2
- package/coverage/lcov-report/config/index.html +1 -1
- package/coverage/lcov-report/config/paths.ts.html +1 -1
- package/coverage/lcov-report/config/shared.ts.html +1 -1
- package/coverage/lcov-report/index.html +18 -18
- package/coverage/lcov-report/utils/buildWrapperArgs.ts.html +196 -0
- package/coverage/lcov-report/utils/checkRequiredFiles.ts.html +1 -1
- package/coverage/lcov-report/utils/formatWebpackMessages.ts.html +1 -1
- package/coverage/lcov-report/utils/getPublicUrlOrPath.ts.html +1 -1
- package/coverage/lcov-report/utils/index.html +38 -8
- package/coverage/lcov-report/utils/resolveBin.ts.html +193 -0
- package/coverage/lcov.info +54 -2
- package/eslint.config.js +4 -4
- package/lib/bin.js +8 -3
- package/lib/bin.js.map +1 -1
- package/lib/command/audit.d.ts +1 -0
- package/lib/command/audit.js +44 -0
- package/lib/command/audit.js.map +1 -0
- package/lib/command/check-types.d.ts +1 -0
- package/lib/command/check-types.js +18 -0
- package/lib/command/check-types.js.map +1 -0
- package/lib/command/create/helper.js +0 -1
- package/lib/command/create/helper.js.map +1 -1
- package/lib/command/create/index.js +7 -5
- package/lib/command/create/index.js.map +1 -1
- package/lib/command/lint.d.ts +1 -0
- package/lib/command/lint.js +27 -0
- package/lib/command/lint.js.map +1 -0
- package/lib/command/prettier.d.ts +1 -0
- package/lib/command/prettier.js +26 -0
- package/lib/command/prettier.js.map +1 -0
- package/lib/command/validate.d.ts +1 -0
- package/lib/command/validate.js +51 -0
- package/lib/command/validate.js.map +1 -0
- package/lib/utils/buildWrapperArgs.d.ts +32 -0
- package/lib/utils/buildWrapperArgs.js +39 -0
- package/lib/utils/buildWrapperArgs.js.map +1 -0
- package/lib/utils/resolveBin.d.ts +13 -0
- package/lib/utils/resolveBin.js +35 -0
- package/lib/utils/resolveBin.js.map +1 -0
- package/llms.txt +56 -2
- package/package.json +9 -4
- package/src/__tests__/buildWrapperArgs.test.ts +73 -0
- package/src/__tests__/resolveBin.test.ts +68 -0
- package/src/bin.ts +11 -3
- package/src/command/audit.ts +46 -0
- package/src/command/check-types.ts +18 -0
- package/src/command/create/helper.ts +0 -1
- package/src/command/create/index.ts +7 -5
- package/src/command/lint.ts +27 -0
- package/src/command/prettier.ts +27 -0
- package/src/command/validate.ts +66 -0
- package/src/utils/buildWrapperArgs.ts +37 -0
- package/src/utils/resolveBin.ts +36 -0
- package/template/src/App.tsx +5 -2
- package/template/src/index.tsx +8 -6
- package/template/tsconfig.json +3 -24
- package/tsconfig.base.json +19 -0
- package/template/audit-ci.json +0 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prettier.js","sourceRoot":"","sources":["../../src/command/prettier.ts"],"names":[],"mappings":";;;;;AAAA,8DAAgC;AAEhC,gEAA6D;AAC7D,oDAAiD;AAEjD;;;;;;;GAOG;AACH,MAAM,WAAW,GAAG,IAAA,uBAAU,EAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,YAAY,GAAG,+BAA+B,CAAC;AAErD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEvC,MAAM,IAAI,GAAG,IAAA,mCAAgB,EAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;IACnC,MAAM,EAAE,YAAY;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,qBAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAE1F,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
8
|
+
/**
|
|
9
|
+
* `scripts validate` — Apollion's standard pre-merge gate. Runs
|
|
10
|
+
* `check-types`, `prettier --check`, `lint` (parallel) then `test`
|
|
11
|
+
* with `--watchAll=false` (sequential). Bails on the first failure.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the Apollion ecosystem's own `scripts/validate.sh`
|
|
14
|
+
* orchestration so consumers don't have to reinvent it.
|
|
15
|
+
*/
|
|
16
|
+
const userArgs = process.argv.slice(2);
|
|
17
|
+
const skip = new Set(userArgs.filter((arg) => arg.startsWith('--skip=')).flatMap((arg) => arg.slice('--skip='.length).split(',')));
|
|
18
|
+
const parallel = [
|
|
19
|
+
{ name: 'check-types', cmd: 'check-types' },
|
|
20
|
+
{ name: 'prettier', cmd: 'prettier' },
|
|
21
|
+
{ name: 'lint', cmd: 'lint' },
|
|
22
|
+
].filter((s) => !skip.has(s.name));
|
|
23
|
+
const sequential = [{ name: 'test', cmd: 'test --watchAll=false' }].filter((s) => !skip.has(s.name));
|
|
24
|
+
function runStep(step) {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
console.log(chalk_1.default.cyan(`▶ ${step.name}`));
|
|
27
|
+
const [bin, ...rest] = step.cmd.split(' ');
|
|
28
|
+
const child = (0, cross_spawn_1.default)(process.execPath, [require.resolve(`./${bin}`), ...rest], {
|
|
29
|
+
stdio: 'inherit',
|
|
30
|
+
});
|
|
31
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
(async () => {
|
|
35
|
+
const parallelResults = await Promise.all(parallel.map(runStep));
|
|
36
|
+
const parallelFailures = parallel.filter((_, i) => parallelResults[i] !== 0);
|
|
37
|
+
if (parallelFailures.length > 0) {
|
|
38
|
+
console.error(chalk_1.default.red(`✘ validate failed: ${parallelFailures.map((s) => s.name).join(', ')}`));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
for (const step of sequential) {
|
|
42
|
+
const code = await runStep(step);
|
|
43
|
+
if (code !== 0) {
|
|
44
|
+
console.error(chalk_1.default.red(`✘ validate failed: ${step.name}`));
|
|
45
|
+
process.exit(code);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
console.log(chalk_1.default.green('✓ validate passed'));
|
|
49
|
+
process.exit(0);
|
|
50
|
+
})();
|
|
51
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/command/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the argv passed to an underlying CLI (eslint, prettier) for a
|
|
3
|
+
* `scripts <cmd>` wrapper, from the user-provided argv.
|
|
4
|
+
*
|
|
5
|
+
* - Empty input → `defaults` verbatim (the canonical no-args
|
|
6
|
+
* invocation, e.g. `['src', '--quiet']` for lint).
|
|
7
|
+
* - Non-empty input → user args (with the POSIX `--` end-of-options
|
|
8
|
+
* marker removed) followed by `target`.
|
|
9
|
+
*
|
|
10
|
+
* The previous heuristic tried to detect "user-provided path" by
|
|
11
|
+
* scanning for any argv entry not starting with `-`, then handed full
|
|
12
|
+
* control to the user. That broke two real consumer invocations:
|
|
13
|
+
*
|
|
14
|
+
* 1. `scripts lint --max-warnings 0` — the `0` value of the flag was
|
|
15
|
+
* misread as a path, so `src` was dropped and ESLint ran with no
|
|
16
|
+
* files.
|
|
17
|
+
* 2. `scripts lint -- --fix` — every arg started with `-`, so `src`
|
|
18
|
+
* was appended, but the surviving `--` separator forced ESLint to
|
|
19
|
+
* treat `--fix` and `src` as positional files.
|
|
20
|
+
*
|
|
21
|
+
* The wrapper is intentionally narrow: pass flags, get the default
|
|
22
|
+
* target. Consumers that need a non-default target should invoke the
|
|
23
|
+
* underlying CLI directly (`node_modules/.bin/eslint <path>`).
|
|
24
|
+
*
|
|
25
|
+
* @param userArgs - argv after `scripts <cmd>` (i.e. `process.argv.slice(2)`).
|
|
26
|
+
* @param options.defaults - argv to use when `userArgs` is empty.
|
|
27
|
+
* @param options.target - path/glob appended after user flags otherwise.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildWrapperArgs(userArgs: string[], options: {
|
|
30
|
+
defaults: string[];
|
|
31
|
+
target: string;
|
|
32
|
+
}): string[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildWrapperArgs = buildWrapperArgs;
|
|
4
|
+
/**
|
|
5
|
+
* Build the argv passed to an underlying CLI (eslint, prettier) for a
|
|
6
|
+
* `scripts <cmd>` wrapper, from the user-provided argv.
|
|
7
|
+
*
|
|
8
|
+
* - Empty input → `defaults` verbatim (the canonical no-args
|
|
9
|
+
* invocation, e.g. `['src', '--quiet']` for lint).
|
|
10
|
+
* - Non-empty input → user args (with the POSIX `--` end-of-options
|
|
11
|
+
* marker removed) followed by `target`.
|
|
12
|
+
*
|
|
13
|
+
* The previous heuristic tried to detect "user-provided path" by
|
|
14
|
+
* scanning for any argv entry not starting with `-`, then handed full
|
|
15
|
+
* control to the user. That broke two real consumer invocations:
|
|
16
|
+
*
|
|
17
|
+
* 1. `scripts lint --max-warnings 0` — the `0` value of the flag was
|
|
18
|
+
* misread as a path, so `src` was dropped and ESLint ran with no
|
|
19
|
+
* files.
|
|
20
|
+
* 2. `scripts lint -- --fix` — every arg started with `-`, so `src`
|
|
21
|
+
* was appended, but the surviving `--` separator forced ESLint to
|
|
22
|
+
* treat `--fix` and `src` as positional files.
|
|
23
|
+
*
|
|
24
|
+
* The wrapper is intentionally narrow: pass flags, get the default
|
|
25
|
+
* target. Consumers that need a non-default target should invoke the
|
|
26
|
+
* underlying CLI directly (`node_modules/.bin/eslint <path>`).
|
|
27
|
+
*
|
|
28
|
+
* @param userArgs - argv after `scripts <cmd>` (i.e. `process.argv.slice(2)`).
|
|
29
|
+
* @param options.defaults - argv to use when `userArgs` is empty.
|
|
30
|
+
* @param options.target - path/glob appended after user flags otherwise.
|
|
31
|
+
*/
|
|
32
|
+
function buildWrapperArgs(userArgs, options) {
|
|
33
|
+
if (userArgs.length === 0) {
|
|
34
|
+
return [...options.defaults];
|
|
35
|
+
}
|
|
36
|
+
const passthrough = userArgs.filter((a) => a !== '--');
|
|
37
|
+
return [...passthrough, options.target];
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=buildWrapperArgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildWrapperArgs.js","sourceRoot":"","sources":["../../src/utils/buildWrapperArgs.ts"],"names":[],"mappings":";;AA4BA,4CAQC;AApCD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,gBAAgB,CAAC,QAAkB,EAAE,OAA+C;IAClG,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the absolute path to a dependency's CLI entrypoint as declared
|
|
3
|
+
* in its `package.json#bin`. Works for packages whose `exports` map
|
|
4
|
+
* blocks `require.resolve('<pkg>/bin/...')` (e.g. eslint 9+).
|
|
5
|
+
*
|
|
6
|
+
* @param pkgName - dependency name (e.g. `'eslint'`, `'prettier'`)
|
|
7
|
+
* @param binName - bin name when `package.json#bin` is an object map.
|
|
8
|
+
* Defaults to `pkgName`.
|
|
9
|
+
* @param fromPath - directory to resolve `pkgName` from. Defaults to
|
|
10
|
+
* this file's directory so production calls walk up from
|
|
11
|
+
* `@apollion-dsi/scripts`'s install location.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveBin(pkgName: string, binName?: string, fromPath?: string): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveBin = resolveBin;
|
|
7
|
+
const module_1 = require("module");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the absolute path to a dependency's CLI entrypoint as declared
|
|
11
|
+
* in its `package.json#bin`. Works for packages whose `exports` map
|
|
12
|
+
* blocks `require.resolve('<pkg>/bin/...')` (e.g. eslint 9+).
|
|
13
|
+
*
|
|
14
|
+
* @param pkgName - dependency name (e.g. `'eslint'`, `'prettier'`)
|
|
15
|
+
* @param binName - bin name when `package.json#bin` is an object map.
|
|
16
|
+
* Defaults to `pkgName`.
|
|
17
|
+
* @param fromPath - directory to resolve `pkgName` from. Defaults to
|
|
18
|
+
* this file's directory so production calls walk up from
|
|
19
|
+
* `@apollion-dsi/scripts`'s install location.
|
|
20
|
+
*/
|
|
21
|
+
function resolveBin(pkgName, binName = pkgName, fromPath = __dirname) {
|
|
22
|
+
const req = (0, module_1.createRequire)(path_1.default.join(fromPath, 'noop.js'));
|
|
23
|
+
const pkgJsonPath = req.resolve(`${pkgName}/package.json`);
|
|
24
|
+
const pkgJson = req(pkgJsonPath);
|
|
25
|
+
const binField = pkgJson.bin;
|
|
26
|
+
if (!binField) {
|
|
27
|
+
throw new Error(`Package "${pkgName}" has no "bin" field in package.json`);
|
|
28
|
+
}
|
|
29
|
+
const relBin = typeof binField === 'string' ? binField : binField[binName];
|
|
30
|
+
if (!relBin) {
|
|
31
|
+
throw new Error(`Package "${pkgName}" has no bin named "${binName}"`);
|
|
32
|
+
}
|
|
33
|
+
return path_1.default.resolve(path_1.default.dirname(pkgJsonPath), relBin);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=resolveBin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBin.js","sourceRoot":"","sources":["../../src/utils/resolveBin.ts"],"names":[],"mappings":";;;;;AAeA,gCAoBC;AAnCD,mCAAuC;AACvC,gDAAwB;AAExB;;;;;;;;;;;GAWG;AACH,SAAgB,UAAU,CAAC,OAAe,EAAE,UAAkB,OAAO,EAAE,WAAmB,SAAS;IACjG,MAAM,GAAG,GAAG,IAAA,sBAAa,EAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAE1D,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,eAAe,CAAC,CAAC;IAE3D,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAA8C,CAAC;IAE9E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAE7B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,sCAAsC,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE3E,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,uBAAuB,OAAO,GAAG,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,cAAI,CAAC,OAAO,CAAC,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC"}
|
package/llms.txt
CHANGED
|
@@ -15,11 +15,36 @@ behind four commands: `create`, `dev`, `build`, `test`.
|
|
|
15
15
|
| `dev` | webpack-dev-server + HMR (react-refresh) at :3000 |
|
|
16
16
|
| `build` | Production bundle to `build/` |
|
|
17
17
|
| `test` | Jest 30 in watch mode against changed files |
|
|
18
|
+
| `lint` | ESLint over `src` w/ Apollion config (alias for `eslint src --ext ts,tsx --quiet`) |
|
|
19
|
+
| `prettier` | Prettier `--check` over `src/**/*.{ts,tsx,json,css,md}` |
|
|
20
|
+
| `check-types` (alias `tsc`) | `tsc --noEmit` against the consumer's tsconfig |
|
|
21
|
+
| `audit` | `yarn npm audit --severity moderate --no-deprecations` (falls back to `npm audit --audit-level=moderate`) |
|
|
22
|
+
| `validate` | Pre-merge gate: `check-types` + `prettier` + `lint` in parallel, then `test --watchAll=false`. `--skip=lint,prettier` to drop steps. |
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
Every command accepts pass-through args — `scripts lint --fix`,
|
|
25
|
+
`scripts prettier --write`, `scripts check-types -p tsconfig.build.json`, etc.
|
|
26
|
+
Do **not** use the POSIX `--` end-of-options separator: `lint` and
|
|
27
|
+
`prettier` always append the default target (`src` / the default glob),
|
|
28
|
+
so `eslint -- --fix src` would treat `--fix` and `src` as positional
|
|
29
|
+
files. Pass flags directly.
|
|
30
|
+
|
|
31
|
+
Use via `package.json#scripts` — the whole consumer file becomes thin:
|
|
20
32
|
|
|
21
33
|
```json
|
|
22
|
-
{
|
|
34
|
+
{
|
|
35
|
+
"scripts": {
|
|
36
|
+
"dev": "scripts dev",
|
|
37
|
+
"build": "scripts build",
|
|
38
|
+
"test": "scripts test",
|
|
39
|
+
"lint": "scripts lint",
|
|
40
|
+
"lint:fix": "scripts lint --fix",
|
|
41
|
+
"prettier": "scripts prettier",
|
|
42
|
+
"format": "scripts prettier --write",
|
|
43
|
+
"check-types": "scripts check-types",
|
|
44
|
+
"audit-dependencies": "scripts audit",
|
|
45
|
+
"validate": "scripts validate"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
23
48
|
```
|
|
24
49
|
|
|
25
50
|
## Stack (hidden from consumer)
|
|
@@ -28,19 +53,48 @@ Use via `package.json#scripts`:
|
|
|
28
53
|
- `babel-plugin-relay` + `babel-plugin-styled-components`
|
|
29
54
|
- `react-refresh` for HMR
|
|
30
55
|
- Jest 30 + ts-jest + `@testing-library/react`
|
|
56
|
+
- ESLint 9 (`@apollion-dsi/eslint-config`) + Prettier 3
|
|
31
57
|
- Peer: **TypeScript 6.x**
|
|
32
58
|
|
|
59
|
+
Consumers pull *only* `@apollion-dsi/scripts` for tooling — eslint, prettier,
|
|
60
|
+
jest, babel et al. arrive transitively. The consumer's `package.json#scripts`
|
|
61
|
+
should only reference `scripts <cmd>`.
|
|
62
|
+
|
|
33
63
|
## Invariants
|
|
34
64
|
|
|
35
65
|
* **Yarn only** (consumer template uses Yarn 4 Berry).
|
|
36
66
|
* **No webpack config exposed.** If you need a config escape hatch,
|
|
37
67
|
open a ROADMAP entry — the point of this package is to not have one.
|
|
38
68
|
* **TypeScript 6 strict** in the template — non-negotiable.
|
|
69
|
+
* **Template tsconfig modern, never legacy.** `target: es2020`,
|
|
70
|
+
`moduleResolution: bundler`, `jsx: react-jsx`. No `es5`, no `node10`,
|
|
71
|
+
no classic JSX — both warn under TS 6.0 (`TS5107`) and break in TS 7.
|
|
72
|
+
|
|
73
|
+
## tsconfig.base.json (consumer-facing)
|
|
74
|
+
|
|
75
|
+
`@apollion-dsi/scripts` exposes a modern TS base config. Consumers
|
|
76
|
+
extend it instead of copying values:
|
|
77
|
+
|
|
78
|
+
```jsonc
|
|
79
|
+
// tsconfig.json
|
|
80
|
+
{
|
|
81
|
+
"extends": "@apollion-dsi/scripts/tsconfig.base.json",
|
|
82
|
+
"include": ["src"]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The base sets `target: es2020`, `module: esnext`,
|
|
87
|
+
`moduleResolution: bundler`, `jsx: react-jsx` (automatic runtime — no
|
|
88
|
+
`import React` needed for JSX), `strict`, `isolatedModules`,
|
|
89
|
+
`noEmit`. Overriding any field is fine; the goal is a defaultful SSOT,
|
|
90
|
+
not a lock-in.
|
|
39
91
|
|
|
40
92
|
## Files
|
|
41
93
|
|
|
42
94
|
- `lib/bin.js` — CLI entry (resolved by `package.json#bin`).
|
|
43
95
|
- `lib/index.js` — programmatic entry.
|
|
96
|
+
- `tsconfig.base.json` — exported via `package.json#exports` for
|
|
97
|
+
consumer `extends`.
|
|
44
98
|
- `src/` — TS sources.
|
|
45
99
|
- `scripts/validate.sh` — workspace `validate` step.
|
|
46
100
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apollion-dsi/scripts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Apollion Framework CLI",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": "lib/bin.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./lib/index.js",
|
|
9
|
+
"./tsconfig.base.json": "./tsconfig.base.json",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
7
12
|
"scripts": {
|
|
8
13
|
"prepare": "yarn build",
|
|
9
14
|
"audit-dependencies": "yarn npm audit --severity moderate --no-deprecations",
|
|
@@ -19,7 +24,7 @@
|
|
|
19
24
|
"coverage": "jest --coverage",
|
|
20
25
|
"validate:tests": "jest --coverage",
|
|
21
26
|
"build": "tsc -p .",
|
|
22
|
-
"release": "yarn build && changeset publish"
|
|
27
|
+
"release": "yarn build && yarn changeset publish"
|
|
23
28
|
},
|
|
24
29
|
"keywords": [],
|
|
25
30
|
"author": "Apollion DS Team",
|
|
@@ -47,6 +52,7 @@
|
|
|
47
52
|
"detect-port": "2.1.0",
|
|
48
53
|
"dotenv": "17.4.2",
|
|
49
54
|
"dotenv-expand": "13.0.0",
|
|
55
|
+
"eslint": "9.29.0",
|
|
50
56
|
"fork-ts-checker-webpack-plugin": "9.1.0",
|
|
51
57
|
"fs-extra": "11.3.5",
|
|
52
58
|
"git-revision-webpack-plugin": "5.0.0",
|
|
@@ -56,6 +62,7 @@
|
|
|
56
62
|
"jest": "30.4.2",
|
|
57
63
|
"jest-cli": "30.4.2",
|
|
58
64
|
"jest-environment-node": "^30.4.1",
|
|
65
|
+
"prettier": "3.8.3",
|
|
59
66
|
"react-refresh": "0.18.0",
|
|
60
67
|
"resolve": "1.22.12",
|
|
61
68
|
"semver": "7.8.0",
|
|
@@ -74,9 +81,7 @@
|
|
|
74
81
|
"devDependencies": {
|
|
75
82
|
"@testing-library/dom": "10.4.1",
|
|
76
83
|
"@types/jest": "30.0.0",
|
|
77
|
-
"eslint": "9.29.0",
|
|
78
84
|
"npm-run-all": "4.1.5",
|
|
79
|
-
"prettier": "3.8.3",
|
|
80
85
|
"react": "19.2.6",
|
|
81
86
|
"react-dom": "19.2.6",
|
|
82
87
|
"styled-components": "6.4.1",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { buildWrapperArgs } from '../utils/buildWrapperArgs';
|
|
2
|
+
|
|
3
|
+
describe('buildWrapperArgs', () => {
|
|
4
|
+
const lintOptions = { defaults: ['src', '--quiet'], target: 'src' };
|
|
5
|
+
const prettierOptions = {
|
|
6
|
+
defaults: ['--check', 'src/**/*.{ts,tsx,json,css,md}'],
|
|
7
|
+
target: 'src/**/*.{ts,tsx,json,css,md}',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe('lint wrapper semantics', () => {
|
|
11
|
+
it('falls back to defaults when no user args', () => {
|
|
12
|
+
expect(buildWrapperArgs([], lintOptions)).toEqual(['src', '--quiet']);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns a fresh defaults copy (does not alias the input array)', () => {
|
|
16
|
+
const defaults = ['src', '--quiet'];
|
|
17
|
+
const result = buildWrapperArgs([], { defaults, target: 'src' });
|
|
18
|
+
|
|
19
|
+
expect(result).not.toBe(defaults);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('appends target after a single flag (lint --fix)', () => {
|
|
23
|
+
expect(buildWrapperArgs(['--fix'], lintOptions)).toEqual(['--fix', 'src']);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('appends target after --flag=value form', () => {
|
|
27
|
+
expect(buildWrapperArgs(['--max-warnings=0'], lintOptions)).toEqual(['--max-warnings=0', 'src']);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('appends target after --flag value (space-separated) form', () => {
|
|
31
|
+
// Regression: previously the literal `0` was misread as a path,
|
|
32
|
+
// dropping `src` from the eslint invocation so it ran with no files.
|
|
33
|
+
expect(buildWrapperArgs(['--max-warnings', '0'], lintOptions)).toEqual(['--max-warnings', '0', 'src']);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('strips a POSIX `--` end-of-options marker before appending target', () => {
|
|
37
|
+
// Regression: the `--` previously survived into argv, so eslint
|
|
38
|
+
// treated `--fix` and `src` as positional file arguments and failed
|
|
39
|
+
// with "No files matching pattern '--fix'".
|
|
40
|
+
expect(buildWrapperArgs(['--', '--fix'], lintOptions)).toEqual(['--fix', 'src']);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('strips multiple `--` markers (defensive)', () => {
|
|
44
|
+
expect(buildWrapperArgs(['--', '--fix', '--'], lintOptions)).toEqual(['--fix', 'src']);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('preserves the order of user flags', () => {
|
|
48
|
+
expect(buildWrapperArgs(['--cache', '--max-warnings=0', '--fix'], lintOptions)).toEqual([
|
|
49
|
+
'--cache',
|
|
50
|
+
'--max-warnings=0',
|
|
51
|
+
'--fix',
|
|
52
|
+
'src',
|
|
53
|
+
]);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('prettier wrapper semantics', () => {
|
|
58
|
+
it('falls back to --check + DEFAULT_GLOB when no user args', () => {
|
|
59
|
+
expect(buildWrapperArgs([], prettierOptions)).toEqual(['--check', 'src/**/*.{ts,tsx,json,css,md}']);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('appends DEFAULT_GLOB after --write', () => {
|
|
63
|
+
expect(buildWrapperArgs(['--write'], prettierOptions)).toEqual(['--write', 'src/**/*.{ts,tsx,json,css,md}']);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('strips the `--` separator before appending DEFAULT_GLOB', () => {
|
|
67
|
+
expect(buildWrapperArgs(['--', '--write'], prettierOptions)).toEqual([
|
|
68
|
+
'--write',
|
|
69
|
+
'src/**/*.{ts,tsx,json,css,md}',
|
|
70
|
+
]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
import { resolveBin } from '../utils/resolveBin';
|
|
6
|
+
|
|
7
|
+
describe('resolveBin', () => {
|
|
8
|
+
let tmpRoot: string;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tmpRoot = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'apollion-scripts-resolveBin-')));
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function makeFakePkg(name: string, binField: unknown, binFiles: string[] = []): void {
|
|
19
|
+
const pkgDir = path.join(tmpRoot, 'node_modules', name);
|
|
20
|
+
fs.mkdirSync(pkgDir, { recursive: true });
|
|
21
|
+
fs.writeFileSync(path.join(pkgDir, 'package.json'), JSON.stringify({ name, version: '0.0.0', bin: binField }));
|
|
22
|
+
|
|
23
|
+
for (const file of binFiles) {
|
|
24
|
+
const target = path.join(pkgDir, file);
|
|
25
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
26
|
+
fs.writeFileSync(target, '#!/usr/bin/env node\n');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
it('resolves a string-style bin field', () => {
|
|
31
|
+
makeFakePkg('faketool-a', './bin/cli.js', ['bin/cli.js']);
|
|
32
|
+
|
|
33
|
+
const resolved = resolveBin('faketool-a', 'faketool-a', tmpRoot);
|
|
34
|
+
|
|
35
|
+
expect(resolved).toBe(path.join(tmpRoot, 'node_modules', 'faketool-a', 'bin', 'cli.js'));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('resolves a map-style bin field via the pkg name by default', () => {
|
|
39
|
+
makeFakePkg('faketool-b', { 'faketool-b': './bin/main.js', other: './bin/other.js' }, [
|
|
40
|
+
'bin/main.js',
|
|
41
|
+
'bin/other.js',
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
const resolved = resolveBin('faketool-b', 'faketool-b', tmpRoot);
|
|
45
|
+
|
|
46
|
+
expect(resolved).toBe(path.join(tmpRoot, 'node_modules', 'faketool-b', 'bin', 'main.js'));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('resolves a map-style bin field via an explicit alternative name', () => {
|
|
50
|
+
makeFakePkg('faketool-c', { 'faketool-c': './bin/main.js', alt: './bin/alt.js' }, ['bin/main.js', 'bin/alt.js']);
|
|
51
|
+
|
|
52
|
+
const resolved = resolveBin('faketool-c', 'alt', tmpRoot);
|
|
53
|
+
|
|
54
|
+
expect(resolved).toBe(path.join(tmpRoot, 'node_modules', 'faketool-c', 'bin', 'alt.js'));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('throws if the package has no bin field', () => {
|
|
58
|
+
makeFakePkg('faketool-d', undefined);
|
|
59
|
+
|
|
60
|
+
expect(() => resolveBin('faketool-d', 'faketool-d', tmpRoot)).toThrow(/no "bin" field/);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('throws if the requested bin name is missing from the map', () => {
|
|
64
|
+
makeFakePkg('faketool-e', { 'faketool-e': './bin/main.js' }, ['bin/main.js']);
|
|
65
|
+
|
|
66
|
+
expect(() => resolveBin('faketool-e', 'missing', tmpRoot)).toThrow(/no bin named "missing"/);
|
|
67
|
+
});
|
|
68
|
+
});
|
package/src/bin.ts
CHANGED
|
@@ -18,10 +18,18 @@ notifier.notify({
|
|
|
18
18
|
)} \nRun ${chalk.cyan('yarn add {packageName}')} to update.`,
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
const COMMAND_ALIASES: Record<string, string> = {
|
|
22
|
+
tsc: 'check-types',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const SUPPORTED_COMMANDS = new Set(['build', 'dev', 'test', 'lint', 'prettier', 'check-types', 'audit', 'validate']);
|
|
26
|
+
|
|
21
27
|
(async (cmd: string[]) => {
|
|
22
|
-
const [
|
|
28
|
+
const [rawCommand, ...options] = cmd;
|
|
29
|
+
|
|
30
|
+
const command = COMMAND_ALIASES[rawCommand] ?? rawCommand;
|
|
23
31
|
|
|
24
|
-
if (
|
|
32
|
+
if (SUPPORTED_COMMANDS.has(command)) {
|
|
25
33
|
const result = spawn.sync(process.execPath, [require.resolve(`./command/${command}`), ...options], {
|
|
26
34
|
stdio: 'inherit',
|
|
27
35
|
});
|
|
@@ -35,7 +43,7 @@ notifier.notify({
|
|
|
35
43
|
return process.exit(0);
|
|
36
44
|
}
|
|
37
45
|
|
|
38
|
-
console.log(`${chalk.red('Commando não reconhecido:')} ${chalk.yellow(
|
|
46
|
+
console.log(`${chalk.red('Commando não reconhecido:')} ${chalk.yellow(rawCommand)}`);
|
|
39
47
|
|
|
40
48
|
process.exit(1);
|
|
41
49
|
})(process.argv.slice(2));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import spawn from 'cross-spawn';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `scripts audit` — delegates to the active package manager's audit
|
|
5
|
+
* command. Defaults match the Apollion ecosystem standard
|
|
6
|
+
* (`severity moderate`, no deprecation noise). User-supplied args are
|
|
7
|
+
* appended.
|
|
8
|
+
*
|
|
9
|
+
* Resolution order:
|
|
10
|
+
* 1. yarn berry (>=2) — `yarn npm audit --severity moderate --no-deprecations`
|
|
11
|
+
* 2. yarn classic (1.x) — `yarn audit --level moderate`
|
|
12
|
+
* 3. npm fallback — `npm audit --audit-level=moderate`
|
|
13
|
+
*/
|
|
14
|
+
function probeYarnMajor(): number | null {
|
|
15
|
+
const probe = spawn.sync('yarn', ['--version'], { encoding: 'utf8' });
|
|
16
|
+
|
|
17
|
+
if (probe.status !== 0 || !probe.stdout) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const major = Number.parseInt(String(probe.stdout).trim().split('.')[0], 10);
|
|
22
|
+
|
|
23
|
+
return Number.isNaN(major) ? null : major;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const userArgs = process.argv.slice(2);
|
|
27
|
+
|
|
28
|
+
const yarnMajor = probeYarnMajor();
|
|
29
|
+
|
|
30
|
+
let command: string;
|
|
31
|
+
let baseArgs: string[];
|
|
32
|
+
|
|
33
|
+
if (yarnMajor !== null && yarnMajor >= 2) {
|
|
34
|
+
command = 'yarn';
|
|
35
|
+
baseArgs = ['npm', 'audit', '--severity', 'moderate', '--no-deprecations'];
|
|
36
|
+
} else if (yarnMajor !== null) {
|
|
37
|
+
command = 'yarn';
|
|
38
|
+
baseArgs = ['audit', '--level', 'moderate'];
|
|
39
|
+
} else {
|
|
40
|
+
command = 'npm';
|
|
41
|
+
baseArgs = ['audit', '--audit-level=moderate'];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const result = spawn.sync(command, [...baseArgs, ...userArgs], { stdio: 'inherit' });
|
|
45
|
+
|
|
46
|
+
process.exit(result.status ?? 1);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import spawn from 'cross-spawn';
|
|
2
|
+
|
|
3
|
+
import { resolveBin } from '../utils/resolveBin';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `scripts check-types` (alias `scripts tsc`) — runs `tsc --noEmit`
|
|
7
|
+
* resolving the consumer's TypeScript install (peerDep). Extra args
|
|
8
|
+
* pass through verbatim.
|
|
9
|
+
*/
|
|
10
|
+
const tscBin = resolveBin('typescript', 'tsc');
|
|
11
|
+
|
|
12
|
+
const userArgs = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
const args = userArgs.length > 0 ? userArgs : ['--noEmit'];
|
|
15
|
+
|
|
16
|
+
const result = spawn.sync(process.execPath, [tscBin, ...args], { stdio: 'inherit' });
|
|
17
|
+
|
|
18
|
+
process.exit(result.status ?? 1);
|
|
@@ -81,11 +81,13 @@ async function createPackageJson(config) {
|
|
|
81
81
|
start: 'scripts dev',
|
|
82
82
|
build: 'scripts build',
|
|
83
83
|
test: 'scripts test -- --config=jest.config.js',
|
|
84
|
-
lint: '
|
|
85
|
-
'lint:
|
|
86
|
-
|
|
87
|
-
'prettier:write': 'prettier
|
|
88
|
-
'
|
|
84
|
+
lint: 'scripts lint',
|
|
85
|
+
'lint:fix': 'scripts lint --fix',
|
|
86
|
+
prettier: 'scripts prettier',
|
|
87
|
+
'prettier:write': 'scripts prettier --write',
|
|
88
|
+
'check-types': 'scripts check-types',
|
|
89
|
+
'audit-dependencies': 'scripts audit',
|
|
90
|
+
validate: 'scripts validate',
|
|
89
91
|
},
|
|
90
92
|
husky: {
|
|
91
93
|
hooks: {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import spawn from 'cross-spawn';
|
|
2
|
+
|
|
3
|
+
import { buildWrapperArgs } from '../utils/buildWrapperArgs';
|
|
4
|
+
import { resolveBin } from '../utils/resolveBin';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `scripts lint` — ESLint over `src`. ESLint 9 flat config uses
|
|
8
|
+
* `eslint.config.js#files` for filtering (no `--ext`).
|
|
9
|
+
*
|
|
10
|
+
* Flag args pass through; the default `src` target is always appended
|
|
11
|
+
* so the common case (`scripts lint --fix`, `scripts lint
|
|
12
|
+
* --max-warnings 0`, `scripts lint -- --fix`) Just Works. Consumers
|
|
13
|
+
* that need a different target should call `eslint` directly from
|
|
14
|
+
* `node_modules/.bin`.
|
|
15
|
+
*/
|
|
16
|
+
const eslintBin = resolveBin('eslint');
|
|
17
|
+
|
|
18
|
+
const userArgs = process.argv.slice(2);
|
|
19
|
+
|
|
20
|
+
const args = buildWrapperArgs(userArgs, {
|
|
21
|
+
defaults: ['src', '--quiet'],
|
|
22
|
+
target: 'src',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const result = spawn.sync(process.execPath, [eslintBin, ...args], { stdio: 'inherit' });
|
|
26
|
+
|
|
27
|
+
process.exit(result.status ?? 1);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import spawn from 'cross-spawn';
|
|
2
|
+
|
|
3
|
+
import { buildWrapperArgs } from '../utils/buildWrapperArgs';
|
|
4
|
+
import { resolveBin } from '../utils/resolveBin';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `scripts prettier` — `--check` over `src/**\/*.{ts,tsx,json,css,md}`.
|
|
8
|
+
*
|
|
9
|
+
* Flag args pass through; the default glob is always appended so
|
|
10
|
+
* `scripts prettier --write` Just Works. Consumers that need a
|
|
11
|
+
* different target should call `prettier` directly from
|
|
12
|
+
* `node_modules/.bin`.
|
|
13
|
+
*/
|
|
14
|
+
const prettierBin = resolveBin('prettier');
|
|
15
|
+
|
|
16
|
+
const DEFAULT_GLOB = 'src/**/*.{ts,tsx,json,css,md}';
|
|
17
|
+
|
|
18
|
+
const userArgs = process.argv.slice(2);
|
|
19
|
+
|
|
20
|
+
const args = buildWrapperArgs(userArgs, {
|
|
21
|
+
defaults: ['--check', DEFAULT_GLOB],
|
|
22
|
+
target: DEFAULT_GLOB,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const result = spawn.sync(process.execPath, [prettierBin, ...args], { stdio: 'inherit' });
|
|
26
|
+
|
|
27
|
+
process.exit(result.status ?? 1);
|