@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.
Files changed (62) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/coverage/clover.xml +29 -5
  3. package/coverage/coverage-final.json +3 -1
  4. package/coverage/lcov-report/config/env.ts.html +2 -2
  5. package/coverage/lcov-report/config/index.html +1 -1
  6. package/coverage/lcov-report/config/paths.ts.html +1 -1
  7. package/coverage/lcov-report/config/shared.ts.html +1 -1
  8. package/coverage/lcov-report/index.html +18 -18
  9. package/coverage/lcov-report/utils/buildWrapperArgs.ts.html +196 -0
  10. package/coverage/lcov-report/utils/checkRequiredFiles.ts.html +1 -1
  11. package/coverage/lcov-report/utils/formatWebpackMessages.ts.html +1 -1
  12. package/coverage/lcov-report/utils/getPublicUrlOrPath.ts.html +1 -1
  13. package/coverage/lcov-report/utils/index.html +38 -8
  14. package/coverage/lcov-report/utils/resolveBin.ts.html +193 -0
  15. package/coverage/lcov.info +54 -2
  16. package/eslint.config.js +4 -4
  17. package/lib/bin.js +8 -3
  18. package/lib/bin.js.map +1 -1
  19. package/lib/command/audit.d.ts +1 -0
  20. package/lib/command/audit.js +44 -0
  21. package/lib/command/audit.js.map +1 -0
  22. package/lib/command/check-types.d.ts +1 -0
  23. package/lib/command/check-types.js +18 -0
  24. package/lib/command/check-types.js.map +1 -0
  25. package/lib/command/create/helper.js +0 -1
  26. package/lib/command/create/helper.js.map +1 -1
  27. package/lib/command/create/index.js +7 -5
  28. package/lib/command/create/index.js.map +1 -1
  29. package/lib/command/lint.d.ts +1 -0
  30. package/lib/command/lint.js +27 -0
  31. package/lib/command/lint.js.map +1 -0
  32. package/lib/command/prettier.d.ts +1 -0
  33. package/lib/command/prettier.js +26 -0
  34. package/lib/command/prettier.js.map +1 -0
  35. package/lib/command/validate.d.ts +1 -0
  36. package/lib/command/validate.js +51 -0
  37. package/lib/command/validate.js.map +1 -0
  38. package/lib/utils/buildWrapperArgs.d.ts +32 -0
  39. package/lib/utils/buildWrapperArgs.js +39 -0
  40. package/lib/utils/buildWrapperArgs.js.map +1 -0
  41. package/lib/utils/resolveBin.d.ts +13 -0
  42. package/lib/utils/resolveBin.js +35 -0
  43. package/lib/utils/resolveBin.js.map +1 -0
  44. package/llms.txt +56 -2
  45. package/package.json +9 -4
  46. package/src/__tests__/buildWrapperArgs.test.ts +73 -0
  47. package/src/__tests__/resolveBin.test.ts +68 -0
  48. package/src/bin.ts +11 -3
  49. package/src/command/audit.ts +46 -0
  50. package/src/command/check-types.ts +18 -0
  51. package/src/command/create/helper.ts +0 -1
  52. package/src/command/create/index.ts +7 -5
  53. package/src/command/lint.ts +27 -0
  54. package/src/command/prettier.ts +27 -0
  55. package/src/command/validate.ts +66 -0
  56. package/src/utils/buildWrapperArgs.ts +37 -0
  57. package/src/utils/resolveBin.ts +36 -0
  58. package/template/src/App.tsx +5 -2
  59. package/template/src/index.tsx +8 -6
  60. package/template/tsconfig.json +3 -24
  61. package/tsconfig.base.json +19 -0
  62. package/template/audit-ci.json +0 -5
@@ -0,0 +1,66 @@
1
+ import chalk from 'chalk';
2
+ import spawn from 'cross-spawn';
3
+
4
+ /**
5
+ * `scripts validate` — Apollion's standard pre-merge gate. Runs
6
+ * `check-types`, `prettier --check`, `lint` (parallel) then `test`
7
+ * with `--watchAll=false` (sequential). Bails on the first failure.
8
+ *
9
+ * Mirrors the Apollion ecosystem's own `scripts/validate.sh`
10
+ * orchestration so consumers don't have to reinvent it.
11
+ */
12
+ const userArgs = process.argv.slice(2);
13
+
14
+ const skip = new Set(
15
+ userArgs.filter((arg) => arg.startsWith('--skip=')).flatMap((arg) => arg.slice('--skip='.length).split(',')),
16
+ );
17
+
18
+ type Step = { name: string; cmd: string };
19
+
20
+ const parallel: Step[] = [
21
+ { name: 'check-types', cmd: 'check-types' },
22
+ { name: 'prettier', cmd: 'prettier' },
23
+ { name: 'lint', cmd: 'lint' },
24
+ ].filter((s) => !skip.has(s.name));
25
+
26
+ const sequential: Step[] = [{ name: 'test', cmd: 'test --watchAll=false' }].filter((s) => !skip.has(s.name));
27
+
28
+ function runStep(step: Step): Promise<number> {
29
+ return new Promise((resolve) => {
30
+ console.log(chalk.cyan(`▶ ${step.name}`));
31
+
32
+ const [bin, ...rest] = step.cmd.split(' ');
33
+
34
+ const child = spawn(process.execPath, [require.resolve(`./${bin}`), ...rest], {
35
+ stdio: 'inherit',
36
+ });
37
+
38
+ child.on('close', (code) => resolve(code ?? 1));
39
+ });
40
+ }
41
+
42
+ (async () => {
43
+ const parallelResults = await Promise.all(parallel.map(runStep));
44
+
45
+ const parallelFailures = parallel.filter((_, i) => parallelResults[i] !== 0);
46
+
47
+ if (parallelFailures.length > 0) {
48
+ console.error(chalk.red(`✘ validate failed: ${parallelFailures.map((s) => s.name).join(', ')}`));
49
+
50
+ process.exit(1);
51
+ }
52
+
53
+ for (const step of sequential) {
54
+ const code = await runStep(step);
55
+
56
+ if (code !== 0) {
57
+ console.error(chalk.red(`✘ validate failed: ${step.name}`));
58
+
59
+ process.exit(code);
60
+ }
61
+ }
62
+
63
+ console.log(chalk.green('✓ validate passed'));
64
+
65
+ process.exit(0);
66
+ })();
@@ -0,0 +1,37 @@
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 function buildWrapperArgs(userArgs: string[], options: { defaults: string[]; target: string }): string[] {
30
+ if (userArgs.length === 0) {
31
+ return [...options.defaults];
32
+ }
33
+
34
+ const passthrough = userArgs.filter((a) => a !== '--');
35
+
36
+ return [...passthrough, options.target];
37
+ }
@@ -0,0 +1,36 @@
1
+ import { createRequire } from 'module';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Resolve the absolute path to a dependency's CLI entrypoint as declared
6
+ * in its `package.json#bin`. Works for packages whose `exports` map
7
+ * blocks `require.resolve('<pkg>/bin/...')` (e.g. eslint 9+).
8
+ *
9
+ * @param pkgName - dependency name (e.g. `'eslint'`, `'prettier'`)
10
+ * @param binName - bin name when `package.json#bin` is an object map.
11
+ * Defaults to `pkgName`.
12
+ * @param fromPath - directory to resolve `pkgName` from. Defaults to
13
+ * this file's directory so production calls walk up from
14
+ * `@apollion-dsi/scripts`'s install location.
15
+ */
16
+ export function resolveBin(pkgName: string, binName: string = pkgName, fromPath: string = __dirname): string {
17
+ const req = createRequire(path.join(fromPath, 'noop.js'));
18
+
19
+ const pkgJsonPath = req.resolve(`${pkgName}/package.json`);
20
+
21
+ const pkgJson = req(pkgJsonPath) as { bin?: string | Record<string, string> };
22
+
23
+ const binField = pkgJson.bin;
24
+
25
+ if (!binField) {
26
+ throw new Error(`Package "${pkgName}" has no "bin" field in package.json`);
27
+ }
28
+
29
+ const relBin = typeof binField === 'string' ? binField : binField[binName];
30
+
31
+ if (!relBin) {
32
+ throw new Error(`Package "${pkgName}" has no bin named "${binName}"`);
33
+ }
34
+
35
+ return path.resolve(path.dirname(pkgJsonPath), relBin);
36
+ }
@@ -1,5 +1,8 @@
1
- import { ApollionProvider, Button, Flex, GlobalStyle, Text, useNotification } from '@apollion-dsi/core';
2
- import React from 'react';
1
+ import { Flex } from '@apollion-dsi/core/containers/flex';
2
+ import { useNotification } from '@apollion-dsi/core/containers/notification';
3
+ import { Button } from '@apollion-dsi/core/elements/button';
4
+ import { Text } from '@apollion-dsi/core/elements/text';
5
+ import { ApollionProvider, GlobalStyle } from '@apollion-dsi/core/themes';
3
6
 
4
7
  function App() {
5
8
  const { showNotification } = useNotification();
@@ -1,10 +1,12 @@
1
- import React from 'react';
2
- import { render } from 'react-dom';
1
+ import { StrictMode } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
3
  import { Root } from './App';
4
4
 
5
- render(
6
- <React.StrictMode>
5
+ const container = document.getElementById('root');
6
+ if (!container) throw new Error('Root container #root not found');
7
+
8
+ createRoot(container).render(
9
+ <StrictMode>
7
10
  <Root />
8
- </React.StrictMode>,
9
- document.getElementById('root'),
11
+ </StrictMode>,
10
12
  );
@@ -1,25 +1,4 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "es5",
4
- "lib": [
5
- "dom",
6
- "dom.iterable",
7
- "esnext"
8
- ],
9
- "allowJs": true,
10
- "skipLibCheck": true,
11
- "esModuleInterop": true,
12
- "allowSyntheticDefaultImports": true,
13
- "strict": true,
14
- "forceConsistentCasingInFileNames": true,
15
- "module": "esnext",
16
- "moduleResolution": "node",
17
- "resolveJsonModule": true,
18
- "isolatedModules": true,
19
- "noEmit": true,
20
- "jsx": "react"
21
- },
22
- "include": [
23
- "src"
24
- ]
25
- }
2
+ "extends": "@apollion-dsi/scripts/tsconfig.base.json",
3
+ "include": ["src"]
4
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "compilerOptions": {
4
+ "target": "es2020",
5
+ "lib": ["dom", "dom.iterable", "esnext"],
6
+ "module": "esnext",
7
+ "moduleResolution": "bundler",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "esModuleInterop": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "strict": true,
17
+ "noEmit": true
18
+ }
19
+ }
@@ -1,5 +0,0 @@
1
- {
2
- "high": true,
3
- "package-manager": "yarn",
4
- "report-type": "summary"
5
- }