diff --git a/.agents/PROJECT.md b/.agents/PROJECT.md index 0a88eedc..4c998f3c 100644 --- a/.agents/PROJECT.md +++ b/.agents/PROJECT.md @@ -186,53 +186,52 @@ packages/factory/src/ ## Common commands -**Root-level development:** +**Root-level development (via `@williamthorsen/nmr`):** - `pnpm install` - Install all dependencies -- `pnpm run check` - Run typecheck, format check, lint check, and tests -- `pnpm run check:strict` - Strict checks including coverage and audit -- `pnpm run ci` - Full CI pipeline (strict checks + build) -- `pnpm run build` - Build all packages -- `pnpm run test` - Run tests across all packages -- `pnpm run lint` - Lint all packages -- `pnpm run typecheck` - TypeScript check all packages -- `pnpm run root:test` - Run only root-level tests (in `__tests__/`) -- `pnpm run root:lint` - Lint only root-level files -- `pnpm run root:check` - Run all root-level checks +- `nmr check` - Run typecheck, format check, lint check, and tests +- `nmr check:strict` - Strict checks including coverage and audit +- `nmr ci` - Full CI pipeline (strict checks + build) +- `nmr build` - Build all packages +- `nmr test` - Run tests across all packages +- `nmr lint` - Lint all packages +- `nmr typecheck` - TypeScript check all packages +- `nmr root:test` - Run only root-level tests (in `__tests__/`) +- `nmr root:lint` - Lint only root-level files + +**Workspace packages (via nmr):** + +- `nmr build` - Build the package +- `nmr test` - Run tests +- `nmr test:watch` - Run tests in watch mode +- `nmr test:coverage` - Run tests with coverage +- `nmr lint` - Lint +- `nmr typecheck` - TypeScript check **Factory package (`packages/factory/`):** - `pnpm run dev` - Start both Express server and Vite dev server - `pnpm run dev:server` - Start Express server only (with tsx --watch) - `pnpm run dev:client` - Start Vite dev server only -- `pnpm run ws build` - Build the package -- `pnpm run ws test` - Run tests -- `pnpm run ws test:watch` - Run tests in watch mode -- `pnpm run ws test:coverage` - Run tests with coverage -- `pnpm run ws lint` - Lint -- `pnpm run ws typecheck` - TypeScript check **Agents package (`packages/agents/`):** - `pnpm run build` - Compile TypeScript + copy content to dist -- `pnpm run ws test` - Run tests -- `pnpm run ws lint` - Lint -- `pnpm run ws typecheck` - TypeScript check ## Architecture ### Root-level tests - Located in `__tests__/` directory -- Verify Node.js and pnpm versions match `.tool-versions` +- Consistency checks (Node.js and pnpm version alignment) via `@williamthorsen/nmr/tests` - Use Vitest with config in `vitest.root.config.ts` ### Workspace script system -- Centralized script management via `scripts/run-workspace-script.ts` -- Each package uses `pnpm run ws {command}` for consistent tooling -- Common scripts defined in `run-workspace-script.ts` with package-level overrides -- Supports integration tests with `--int-test` flag +- Centralized script management via `@williamthorsen/nmr` +- Run workspace scripts with `nmr {command}` (e.g., `nmr test`, `nmr build`) +- Default scripts (build, test, lint, typecheck, etc.) provided by nmr +- Package-specific overrides in each package's `package.json` ### Build system diff --git a/.github/workflows/code-quality.yaml b/.github/workflows/code-quality.yaml index fe6ddc1f..95fbfad0 100644 --- a/.github/workflows/code-quality.yaml +++ b/.github/workflows/code-quality.yaml @@ -18,9 +18,10 @@ on: jobs: code-quality: - uses: williamthorsen/.github/.github/workflows/code-quality-pnpm.yaml@v1 + uses: williamthorsen/.github/.github/workflows/code-quality-pnpm-workflow.yaml@v4 secrets: GH_PACKAGES_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }} with: - node-version: '24.14.0' + check-command: 'nmr ci' + node-version: '24.14.1' pnpm-version: '10.33.0' diff --git a/.tool-versions b/.tool-versions index e2926442..78dcfe60 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1 @@ -awscli 2.28.1 -nodejs 24.14.0 -python 3.13.3 +nodejs 24.14.1 diff --git a/__tests__/config.ts b/__tests__/config.ts deleted file mode 100644 index a04c0fee..00000000 --- a/__tests__/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import path from 'node:path'; - -export const ASDF_VERSION_FILE = '.tool-versions'; -export const GITHUB_ACTION_FILE = 'code-quality.yaml'; -export const GITHUB_ACTION_FILE_PATH = path.join('.github/workflows', GITHUB_ACTION_FILE); -export const PACKAGE_JSON_FILE = 'package.json'; diff --git a/__tests__/consistency.app.test.ts b/__tests__/consistency.app.test.ts new file mode 100644 index 00000000..afe15585 --- /dev/null +++ b/__tests__/consistency.app.test.ts @@ -0,0 +1,3 @@ +import { runConsistencyChecks } from '@williamthorsen/nmr/tests'; + +runConsistencyChecks(); diff --git a/__tests__/helpers/getRuntimeVersionFromAsdf.ts b/__tests__/helpers/getRuntimeVersionFromAsdf.ts deleted file mode 100644 index a589dee3..00000000 --- a/__tests__/helpers/getRuntimeVersionFromAsdf.ts +++ /dev/null @@ -1,24 +0,0 @@ -import assert from 'node:assert'; -import fs from 'node:fs'; - -import { ASDF_VERSION_FILE } from '../config.ts'; - -/** - * Reads the .tool-versions file and returns the version for the specified runtime. - * - * @param runtime - The runtime name as it appears at the start of a line in .tool-versions (e.g., "nodejs", "pnpm"). - * @returns The version string for the specified runtime. - * @throws If the runtime is not found or the version is missing. - */ -export async function getRuntimeVersionFromAsdf(runtime: string): Promise { - const toolVersions = await fs.promises.readFile(ASDF_VERSION_FILE, { encoding: 'utf8' }); - - const versionLine = toolVersions.split('\n').find((line) => line.trim().startsWith(runtime)); - - assert.ok(versionLine, `${runtime} not found in .tool-versions`); - - const [, version] = versionLine.trim().split(/\s+/); - assert.ok(version, `${runtime} version missing in .tool-versions`); - - return version; -} diff --git a/__tests__/helpers/getValueAtPathOrThrow.ts b/__tests__/helpers/getValueAtPathOrThrow.ts deleted file mode 100644 index 0dc403e1..00000000 --- a/__tests__/helpers/getValueAtPathOrThrow.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { isObject } from '@williamthorsen/toolbelt.objects'; - -/** - * Retrieves a nested value from an object using a dot-separated path. - * - * @param obj - The root object to query. - * @param path - Dot-separated path string, e.g., "jobs.code-quality.steps". - * @returns The value at the given path. - * @throws If any segment is missing or if an unexpected structure is encountered. - */ -export function getValueAtPathOrThrow(obj: unknown, path: string): unknown { - if (!isObject(obj)) { - throw new Error('Expected an object as root value.'); - } - - const keys = path.split('.'); - let current: unknown = obj; - - for (const key of keys) { - if (Array.isArray(current)) { - const index = Number(key); - if (Number.isNaN(index)) { - throw new TypeError(`Expected array index at segment "${key}" in path "${path}"`); - } - if (index >= 0 && index < current.length) { - current = current[index]; - } else { - throw new Error(`Array index out of bounds: "${key}" in path "${path}"`); - } - } else if (isObject(current)) { - if (!(key in current)) { - throw new Error(`Missing key "${key}" in path "${path}"`); - } - current = current[key]; - } else { - throw new Error(`Unexpected non-object/non-array at segment "${key}" in path "${path}"`); - } - } - - return current; -} diff --git a/__tests__/nodejs-version.app.test.ts b/__tests__/nodejs-version.app.test.ts deleted file mode 100644 index 3b44a6e0..00000000 --- a/__tests__/nodejs-version.app.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import assert from 'node:assert'; -import fs from 'node:fs'; - -import yaml from 'js-yaml'; -import { describe, expect, it } from 'vitest'; - -import { GITHUB_ACTION_FILE, GITHUB_ACTION_FILE_PATH } from '~/__tests__/config.ts'; -import { getRuntimeVersionFromAsdf } from '~/__tests__/helpers/getRuntimeVersionFromAsdf.ts'; -import { getValueAtPathOrThrow } from '~/__tests__/helpers/getValueAtPathOrThrow.ts'; - -describe('Node.js version consistency', () => { - it('version is the same in GitHub action and .tool-versions', async () => { - const toolVersion = await getRuntimeVersionFromAsdf('nodejs'); - const actionVersion = await getNodeVersionFromAction(); - - expect(toolVersion).toBe(actionVersion); - }); -}); - -async function getNodeVersionFromAction() { - const actionYaml = await fs.promises.readFile(GITHUB_ACTION_FILE_PATH, { encoding: 'utf8' }); - const action = yaml.load(actionYaml); - assert.ok(action, `Action not found in ${GITHUB_ACTION_FILE}`); - - const version = getValueAtPathOrThrow(action, 'jobs.code-quality.with.node-version'); - - assert.ok(typeof version === 'string' && version.length > 0, 'Node.js version not found in action'); - - return version; -} diff --git a/__tests__/pnpm-version.app.test.ts b/__tests__/pnpm-version.app.test.ts deleted file mode 100644 index 888f8d31..00000000 --- a/__tests__/pnpm-version.app.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import assert from 'node:assert'; -import fs from 'node:fs'; - -import yaml from 'js-yaml'; -import { describe, expect, it } from 'vitest'; - -import { GITHUB_ACTION_FILE, GITHUB_ACTION_FILE_PATH } from '~/__tests__/config.ts'; -import { getValueAtPathOrThrow } from '~/__tests__/helpers/getValueAtPathOrThrow.ts'; -import rawPackageJson from '~/package.json' with { type: 'json' }; - -describe('pnpm version consistency', () => { - it('pnpm version is the same in GitHub action and package.json', async () => { - const actionVersion = await getPnpmVersionFromAction(); - const packageJsonVersion = getPnpmVersionFromPackageJson(); - - expect(actionVersion).toBe(packageJsonVersion); - }); -}); - -async function getPnpmVersionFromAction(): Promise { - const actionYaml = await fs.promises.readFile(GITHUB_ACTION_FILE_PATH, { encoding: 'utf8' }); - const action = yaml.load(actionYaml); - assert.ok(action, `Action not found in ${GITHUB_ACTION_FILE}`); - - const version = getValueAtPathOrThrow(action, 'jobs.code-quality.with.pnpm-version'); - - assert.ok(typeof version === 'string' && version.length > 0, 'pnpm version not found in action'); - - return version; -} - -/** - * Extracts the pnpm version from the packageManager field in package.json. - * - * @returns The pnpm version string. - * @throws If the packageManager field is missing, malformed, or not for pnpm. - */ -function getPnpmVersionFromPackageJson(): string { - const pm = getValueAtPathOrThrow(rawPackageJson, 'packageManager'); - - if (typeof pm !== 'string') { - throw new TypeError('"packageManager" field missing or not a string in package.json.'); - } - - const [name, version] = pm.split('@'); - if (name !== 'pnpm') { - throw new Error('packageManager is not pnpm.'); - } - if (!version) { - throw new Error('pnpm version missing in package.json.'); - } - - return version; -} diff --git a/package.json b/package.json index 4b9a3051..5408d7aa 100644 --- a/package.json +++ b/package.json @@ -21,52 +21,20 @@ "scripts": { "agents:install": "tsx packages/agents/src/cli.ts install", "agents:install-launchers": "bash packages/agents/scripts/install-launchers.sh", - "audit": "pnpm run audit:prod && pnpm run audit:dev", - "audit:dev": "pnpm dlx audit-ci@^6 --config .audit-ci/config.dev.json5", - "audit:prod": "pnpm dlx audit-ci@^6 --config .audit-ci/config.prod.json5", - "build": "pnpm --recursive run build", - "check": "pnpm run typecheck && pnpm run fmt:check && pnpm run lint:check && pnpm run test", - "check:strict": "pnpm run typecheck && pnpm run fmt:check && pnpm run lint:strict && pnpm run test:coverage && pnpm run audit", - "ci": "pnpm run check:strict && pnpm run build", - "demo:catwalk": "pnpx http-server --port=5189 demos/catwalk/", - "fmt": "sh -c 'prettier --list-different --write \"${@:-.}\"' --", - "fmt:all": "pnpm run fmt && pnpm run fmt:sh", - "fmt:check": "sh -c 'prettier --check \"${@:-.}\"' --", - "fmt:sh": "shfmt --write **/*.sh", - "preinstall": "npx only-allow pnpm", - "postinstall": "tsx scripts/report-overrides.ts", - "lint": "pnpm run root:lint && pnpm --recursive run ws lint", - "lint:check": "pnpm run root:lint:check && pnpm --recursive run ws lint:check", - "lint:strict": "pnpm --recursive run ws lint:strict", - "outdated": "pnpm outdated --compatible --recursive", - "outdated:latest": "pnpm outdated --recursive", - "prepare": "lefthook install", - "root:check": "pnpm run root:typecheck && pnpm run fmt:check && pnpm run root:lint:check && pnpm run root:test", - "root:lint": "eslint --fix --ignore-pattern 'packages/**' .", - "root:lint:check": "eslint --ignore-pattern 'packages/**' .", - "root:lint:strict": "echo \"Error: Not enabled for the workspace root until a pattern is accepted as an argument\" && exit 1", - "root:test": "vitest --config ./vitest.root.config.ts", - "root:typecheck": "tsgo --noEmit", - "test": "pnpm run root:test && pnpm --recursive run ws test", - "test:coverage": "pnpm run root:test && pnpm --recursive run ws test:coverage", - "test:watch": "vitest --watch", - "typecheck": "pnpm run typecheck:root && pnpm --recursive run ws typecheck", - "typecheck:root": "tsgo --noEmit", - "update": "pnpm update --recursive", - "update:latest": "pnpm update --latest --recursive" + "postinstall": "nmr report-overrides --quiet; nmr sync-pnpm-version", + "prepare": "lefthook install" }, "devDependencies": { "@testing-library/dom": "10.4.1", "@types/eslint": "9.6.1", - "@types/js-yaml": "4.0.9", "@types/node": "22.19.15", "@typescript/native-preview": "7.0.0-dev.20260329.1", "@vitejs/plugin-react": "6.0.1", "@vitest/coverage-v8": "4.1.2", "@vitest/eslint-plugin": "1.6.13", "@williamthorsen/eslint-config-typescript": "5.17.3", + "@williamthorsen/nmr": "0.3.0", "@williamthorsen/strict-lint": "6.2.2", - "@williamthorsen/toolbelt.objects": "3.2.6", "dotenv": "17.3.1", "esbuild": "0.27.4", "eslint": "9.39.4", @@ -75,7 +43,6 @@ "eslint-plugin-react-hooks": "5.2.0", "eslint-plugin-testing-library": "7.16.2", "glob": "13.0.6", - "js-yaml": "4.1.1", "lefthook": "2.1.4", "prettier": "3.8.1", "tsx": "4.21.0", diff --git a/packages/agents/package.json b/packages/agents/package.json index db4c29a0..181aee33 100644 --- a/packages/agents/package.json +++ b/packages/agents/package.json @@ -8,8 +8,7 @@ "codeassembly-agents": "dist/esm/cli.js" }, "scripts": { - "build": "pnpm run ws compile && tsx scripts/copy-content.ts", - "ws": "node --import tsx ../../scripts/run-workspace-script.ts" + "build": "nmr compile && tsx scripts/copy-content.ts" }, "dependencies": { "js-yaml": "4.1.1" diff --git a/packages/factory/package.json b/packages/factory/package.json index bbe0a32f..9d10b5a3 100644 --- a/packages/factory/package.json +++ b/packages/factory/package.json @@ -10,8 +10,7 @@ "dev:client": "pnpm vite --host", "dev:server": "tsx --watch src/server/index.ts", "generate-sprites": "tsx scripts/generate-placeholder-pngs.ts", - "validate:run-index": "tsx src/scripts/validate-run-index.ts", - "ws": "node --import tsx ../../scripts/run-workspace-script.ts" + "validate:run-index": "tsx src/scripts/validate-run-index.ts" }, "dependencies": { "@codeassembly/run-core": "workspace:*", diff --git a/packages/mcp/package.json b/packages/mcp/package.json index 5ef63cdd..6ffbad72 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -5,8 +5,8 @@ "description": "MCP server for orchestrated run management", "type": "module", "scripts": { - "prepare": "pnpm run ws compile", - "ws": "node --import tsx ../../scripts/run-workspace-script.ts" + "build": "nmr compile", + "prepare": "nmr compile" }, "dependencies": { "@codeassembly/run-core": "workspace:*", diff --git a/packages/run-core/package.json b/packages/run-core/package.json index ee8aaba3..c3434b5d 100644 --- a/packages/run-core/package.json +++ b/packages/run-core/package.json @@ -31,9 +31,8 @@ "codeassembly-runs": "dist/esm/cli.js" }, "scripts": { - "build": "pnpm run ws compile", - "prepare": "pnpm run ws compile", - "ws": "node --import tsx ../../scripts/run-workspace-script.ts" + "build": "nmr compile", + "prepare": "nmr compile" }, "dependencies": { "js-yaml": "4.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08934c80..cead9613 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,6 @@ importers: '@types/eslint': specifier: 9.6.1 version: 9.6.1 - '@types/js-yaml': - specifier: 4.0.9 - version: 4.0.9 '@types/node': specifier: 22.19.15 version: 22.19.15 @@ -25,22 +22,22 @@ importers: version: 7.0.0-dev.20260329.1 '@vitejs/plugin-react': specifier: 6.0.1 - version: 6.0.1(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)) + version: 6.0.1(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/coverage-v8': specifier: 4.1.2 - version: 4.1.2(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))) + version: 4.1.2(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))) '@vitest/eslint-plugin': specifier: 1.6.13 - version: 1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))) + version: 1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))) '@williamthorsen/eslint-config-typescript': specifier: 5.17.3 - version: 5.17.3(@types/estree@1.0.8)(eslint@9.39.4)(typescript@5.9.3) + version: 5.17.3(@types/estree@1.0.8)(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@williamthorsen/nmr': + specifier: 0.3.0 + version: 0.3.0 '@williamthorsen/strict-lint': specifier: 6.2.2 - version: 6.2.2(eslint@9.39.4) - '@williamthorsen/toolbelt.objects': - specifier: 3.2.6 - version: 3.2.6 + version: 6.2.2(eslint@9.39.4(jiti@2.6.1)) dotenv: specifier: 17.3.1 version: 17.3.1 @@ -49,25 +46,22 @@ importers: version: 0.27.4 eslint: specifier: 9.39.4 - version: 9.39.4 + version: 9.39.4(jiti@2.6.1) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + version: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-jest-dom: specifier: 5.5.0 - version: 5.5.0(@testing-library/dom@10.4.1)(eslint@9.39.4) + version: 5.5.0(@testing-library/dom@10.4.1)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-hooks: specifier: 5.2.0 - version: 5.2.0(eslint@9.39.4) + version: 5.2.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-testing-library: specifier: 7.16.2 - version: 7.16.2(eslint@9.39.4)(typescript@5.9.3) + version: 7.16.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) glob: specifier: 13.0.6 version: 13.0.6 - js-yaml: - specifier: 4.1.1 - version: 4.1.1 lefthook: specifier: 2.1.4 version: 2.1.4 @@ -82,13 +76,13 @@ importers: version: 5.9.3 typescript-eslint: specifier: 8.57.2 - version: 8.57.2(eslint@9.39.4)(typescript@5.9.3) + version: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vite: specifier: 8.0.3 - version: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3) + version: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) vitest: specifier: 4.1.2 - version: 4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) packages/agents: dependencies: @@ -153,10 +147,10 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: 6.0.1 - version: 6.0.1(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)) + version: 6.0.1(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) eslint-plugin-react: specifier: 7.37.5 - version: 7.37.5(eslint@9.39.4) + version: 7.37.5(eslint@9.39.4(jiti@2.6.1)) jsdom: specifier: 28.1.0 version: 28.1.0 @@ -979,16 +973,16 @@ packages: eslint: '>=9' typescript: '>=5' + '@williamthorsen/nmr@0.3.0': + resolution: {integrity: sha512-OYp17Eu8DZSxJ7dddPaP84XyzmhxpD/Z2ArhwT/rf8+3dCYZIoRKKxhvN8p/LDt9M5piiAimlGI6LdF9zlXtkg==} + hasBin: true + '@williamthorsen/strict-lint@6.2.2': resolution: {integrity: sha512-sij/qC9W3B7zR8bMQ89zsheMnhKn6xKoVqfJU3UZvEAy2QTZzBMCCJfJfqKAidXTe6Hev8oXuT9ahryb6hzE1g==} hasBin: true peerDependencies: eslint: '>=9' - '@williamthorsen/toolbelt.objects@3.2.6': - resolution: {integrity: sha512-7BQPMDWcqSBYehjXDGQQw9v/+h/KvYoVwopg/8iOWdW15cZzC/dRIhWSvJenv8wh5YGSn70q/g6SX/rijv/naQ==} - engines: {node: '>=24.0.0'} - '@xyflow/react@12.10.2': resolution: {integrity: sha512-CgIi6HwlcHXwlkTpr0fxLv/0sRVNZ8IdwKLzzeCscaYBwpvfcH1QFOCeaTCuEn1FQEs/B8CjnTSjhs8udgmBgQ==} peerDependencies: @@ -2006,6 +2000,10 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + jose@6.2.1: resolution: {integrity: sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==} @@ -3165,9 +3163,9 @@ snapshots: '@esbuild/win32-x64@0.27.4': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -3472,15 +3470,15 @@ snapshots: '@types/http-errors': 2.0.5 '@types/node': 22.19.15 - '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.2 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.4.0(typescript@5.9.3) @@ -3488,14 +3486,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.57.2 '@typescript-eslint/types': 8.57.2 '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.2 debug: 4.4.3 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3536,13 +3534,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.2 '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -3582,24 +3580,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.1(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.2(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.57.2 '@typescript-eslint/types': 8.57.2 '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3645,12 +3643,12 @@ snapshots: '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260329.1 '@typescript/native-preview-win32-x64': 7.0.0-dev.20260329.1 - '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))': + '@vitejs/plugin-react@6.0.1(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/coverage-v8@4.1.2(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)))': + '@vitest/coverage-v8@4.1.2(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.2 @@ -3662,17 +3660,17 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: 4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) - '@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)))': + '@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) typescript: 5.9.3 - vitest: 4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) transitivePeerDependencies: - supports-color @@ -3685,13 +3683,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.2(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.2(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.2 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) '@vitest/pretty-format@4.1.2': dependencies: @@ -3717,33 +3715,37 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@williamthorsen/eslint-config-typescript@5.17.3(@types/estree@1.0.8)(eslint@9.39.4)(typescript@5.9.3)': - dependencies: - eslint: 9.39.4 - eslint-plugin-eslint-comments: 3.2.0(eslint@9.39.4) - eslint-plugin-jsonc: 3.1.2(eslint@9.39.4) - eslint-plugin-n: 17.24.0(eslint@9.39.4)(typescript@5.9.3) - eslint-plugin-package-json: 0.91.1(@types/estree@1.0.8)(eslint@9.39.4)(jsonc-eslint-parser@3.1.0) - eslint-plugin-promise: 7.2.1(eslint@9.39.4) - eslint-plugin-simple-import-sort: 12.1.1(eslint@9.39.4) - eslint-plugin-unicorn: 63.0.0(eslint@9.39.4) - eslint-plugin-yml: 3.3.1(eslint@9.39.4) + '@williamthorsen/eslint-config-typescript@5.17.3(@types/estree@1.0.8)(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + eslint: 9.39.4(jiti@2.6.1) + eslint-plugin-eslint-comments: 3.2.0(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-jsonc: 3.1.2(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-n: 17.24.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint-plugin-package-json: 0.91.1(@types/estree@1.0.8)(eslint@9.39.4(jiti@2.6.1))(jsonc-eslint-parser@3.1.0) + eslint-plugin-promise: 7.2.1(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-simple-import-sort: 12.1.1(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-unicorn: 63.0.0(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-yml: 3.3.1(eslint@9.39.4(jiti@2.6.1)) globals: 17.4.0 jsonc-eslint-parser: 3.1.0 typescript: 5.9.3 - typescript-eslint: 8.57.2(eslint@9.39.4)(typescript@5.9.3) + typescript-eslint: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) yaml-eslint-parser: 2.0.0 transitivePeerDependencies: - '@eslint/json' - '@types/estree' - supports-color - '@williamthorsen/strict-lint@6.2.2(eslint@9.39.4)': + '@williamthorsen/nmr@0.3.0': dependencies: - eslint: 9.39.4 - tsx: 4.21.0 + jiti: 2.6.1 + js-yaml: 4.1.1 + zod: 4.3.6 - '@williamthorsen/toolbelt.objects@3.2.6': {} + '@williamthorsen/strict-lint@6.2.2(eslint@9.39.4(jiti@2.6.1))': + dependencies: + eslint: 9.39.4(jiti@2.6.1) + tsx: 4.21.0 '@xyflow/react@12.10.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -4349,14 +4351,14 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.39.4): + eslint-compat-utils@0.5.1(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) semver: 7.7.4 - eslint-fix-utils@0.4.2(@types/estree@1.0.8)(eslint@9.39.4): + eslint-fix-utils@0.4.2(@types/estree@1.0.8)(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) optionalDependencies: '@types/estree': 1.0.8 @@ -4368,36 +4370,36 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-json-compat-utils@0.2.3(eslint@9.39.4)(jsonc-eslint-parser@3.1.0): + eslint-json-compat-utils@0.2.3(eslint@9.39.4(jiti@2.6.1))(jsonc-eslint-parser@3.1.0): dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) esquery: 1.7.0 jsonc-eslint-parser: 3.1.0 - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.4): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-es-x@7.8.0(eslint@9.39.4): + eslint-plugin-es-x@7.8.0(eslint@9.39.4(jiti@2.6.1)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 - eslint: 9.39.4 - eslint-compat-utils: 0.5.1(eslint@9.39.4) + eslint: 9.39.4(jiti@2.6.1) + eslint-compat-utils: 0.5.1(eslint@9.39.4(jiti@2.6.1)) - eslint-plugin-eslint-comments@3.2.0(eslint@9.39.4): + eslint-plugin-eslint-comments@3.2.0(eslint@9.39.4(jiti@2.6.1)): dependencies: escape-string-regexp: 1.0.5 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) ignore: 5.3.2 - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -4406,9 +4408,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.4) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.4(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -4420,41 +4422,41 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest-dom@5.5.0(@testing-library/dom@10.4.1)(eslint@9.39.4): + eslint-plugin-jest-dom@5.5.0(@testing-library/dom@10.4.1)(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/runtime': 7.27.6 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) requireindex: 1.2.0 optionalDependencies: '@testing-library/dom': 10.4.1 - eslint-plugin-jsonc@3.1.2(eslint@9.39.4): + eslint-plugin-jsonc@3.1.2(eslint@9.39.4(jiti@2.6.1)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint/core': 1.1.0 '@eslint/plugin-kit': 0.6.0 '@ota-meshi/ast-token-store': 0.3.0 diff-sequences: 29.6.3 - eslint: 9.39.4 - eslint-json-compat-utils: 0.2.3(eslint@9.39.4)(jsonc-eslint-parser@3.1.0) + eslint: 9.39.4(jiti@2.6.1) + eslint-json-compat-utils: 0.2.3(eslint@9.39.4(jiti@2.6.1))(jsonc-eslint-parser@3.1.0) jsonc-eslint-parser: 3.1.0 natural-compare: 1.4.0 synckit: 0.11.12 transitivePeerDependencies: - '@eslint/json' - eslint-plugin-n@17.24.0(eslint@9.39.4)(typescript@5.9.3): + eslint-plugin-n@17.24.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) enhanced-resolve: 5.18.3 - eslint: 9.39.4 - eslint-plugin-es-x: 7.8.0(eslint@9.39.4) + eslint: 9.39.4(jiti@2.6.1) + eslint-plugin-es-x: 7.8.0(eslint@9.39.4(jiti@2.6.1)) get-tsconfig: 4.10.1 globals: 15.15.0 globrex: 0.1.2 @@ -4464,14 +4466,14 @@ snapshots: transitivePeerDependencies: - typescript - eslint-plugin-package-json@0.91.1(@types/estree@1.0.8)(eslint@9.39.4)(jsonc-eslint-parser@3.1.0): + eslint-plugin-package-json@0.91.1(@types/estree@1.0.8)(eslint@9.39.4(jiti@2.6.1))(jsonc-eslint-parser@3.1.0): dependencies: '@altano/repository-tools': 2.0.1 change-case: 5.4.4 detect-indent: 7.0.2 detect-newline: 4.0.1 - eslint: 9.39.4 - eslint-fix-utils: 0.4.2(@types/estree@1.0.8)(eslint@9.39.4) + eslint: 9.39.4(jiti@2.6.1) + eslint-fix-utils: 0.4.2(@types/estree@1.0.8)(eslint@9.39.4(jiti@2.6.1)) jsonc-eslint-parser: 3.1.0 package-json-validator: 1.3.1 semver: 7.7.4 @@ -4481,16 +4483,16 @@ snapshots: transitivePeerDependencies: - '@types/estree' - eslint-plugin-promise@7.2.1(eslint@9.39.4): + eslint-plugin-promise@7.2.1(eslint@9.39.4(jiti@2.6.1)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - eslint: 9.39.4 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-react-hooks@5.2.0(eslint@9.39.4): + eslint-plugin-react-hooks@5.2.0(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-react@7.37.5(eslint@9.39.4): + eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.6.1)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -4498,7 +4500,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.2 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -4512,28 +4514,28 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.4): + eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-testing-library@7.16.2(eslint@9.39.4)(typescript@5.9.3): + eslint-plugin-testing-library@7.16.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-unicorn@63.0.0(eslint@9.39.4): + eslint-plugin-unicorn@63.0.0(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) change-case: 5.4.4 ci-info: 4.4.0 clean-regexp: 1.0.0 core-js-compat: 3.48.0 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) find-up-simple: 1.0.1 globals: 16.4.0 indent-string: 5.0.0 @@ -4545,7 +4547,7 @@ snapshots: semver: 7.7.4 strip-indent: 4.1.1 - eslint-plugin-yml@3.3.1(eslint@9.39.4): + eslint-plugin-yml@3.3.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@eslint/core': 1.1.0 '@eslint/plugin-kit': 0.6.0 @@ -4553,7 +4555,7 @@ snapshots: debug: 4.4.3 diff-sequences: 29.6.3 escape-string-regexp: 5.0.0 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) natural-compare: 1.4.0 yaml-eslint-parser: 2.0.0 transitivePeerDependencies: @@ -4570,9 +4572,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.4: + eslint@9.39.4(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 @@ -4606,6 +4608,8 @@ snapshots: minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -5031,6 +5035,8 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 + jiti@2.6.1: {} + jose@6.2.1: {} js-tokens@10.0.0: {} @@ -5852,13 +5858,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.57.2(eslint@9.39.4)(typescript@5.9.3): + typescript-eslint@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -5901,7 +5907,7 @@ snapshots: vary@1.1.2: {} - vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3): + vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -5912,13 +5918,14 @@ snapshots: '@types/node': 22.19.15 esbuild: 0.27.4 fsevents: 2.3.3 + jiti: 2.6.1 tsx: 4.21.0 yaml: 2.8.3 - vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.2(@types/node@22.19.15)(jsdom@28.1.0)(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.2 - '@vitest/mocker': 4.1.2(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.1.2(vite@8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.2 '@vitest/runner': 4.1.2 '@vitest/snapshot': 4.1.2 @@ -5935,7 +5942,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.15 diff --git a/scripts/assertIsPackageJson.ts b/scripts/assertIsPackageJson.ts deleted file mode 100644 index fb0ce629..00000000 --- a/scripts/assertIsPackageJson.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { isPlainObject } from '@williamthorsen/toolbelt.objects'; -import { hasOwnProperty } from '@williamthorsen/toolbelt.objects/candidate'; - -/** - * Throws an error if the `scripts` field of the object does not conform to the `PackageJson` interface. - */ - -export function assertIsPackageJson(packageJson: unknown): asserts packageJson is PackageJson { - if (!isPlainObject(packageJson)) { - throw new TypeError('Invalid input: Expected an object literal.'); - } - - if (hasOwnProperty(packageJson, 'scripts')) { - if (!isPlainObject(packageJson.scripts)) { - throw new TypeError("Invalid package.json: 'scripts' should be an object"); - } - - for (const [key, value] of Object.entries(packageJson.scripts)) { - if (typeof value !== 'string') { - throw new TypeError(`Invalid package.json: script key '${key}' or its value is not a string`); - } - } - } -} - -/** - * Lists only the fields of the `PackageJson` interface that are relevant to the above assertion. - */ -interface PackageJson { - scripts?: { [key: string]: string } | undefined; -} diff --git a/scripts/report-overrides.ts b/scripts/report-overrides.ts deleted file mode 100644 index 71140f56..00000000 --- a/scripts/report-overrides.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint n/no-process-exit: off */ -/* eslint unicorn/no-process-exit: off */ - -import { isObject } from '@williamthorsen/toolbelt.objects'; - -import packageJson from '../package.json' with { type: 'json' }; - -type PackageJson = typeof packageJson & { - pnpm?: { overrides?: Record }; -}; - -function isStringRecord(value: unknown): value is Record { - return isObject(value) && Object.values(value).every((v) => typeof v === 'string'); -} - -function hasPnpmWithOverrides(pkg: PackageJson): pkg is typeof packageJson & { - pnpm: { - overrides: Record; - }; -} { - return isObject(pkg.pnpm) && isStringRecord(pkg.pnpm.overrides); -} - -const overrides = hasPnpmWithOverrides(packageJson) ? packageJson.pnpm.overrides : {}; - -if (Object.keys(overrides).length === 0) { - process.exit(0); -} - -console.warn('🔒 WARN: pnpm overrides are active! Check whether these are still needed:'); -for (const [name, version] of Object.entries(overrides)) { - if (typeof version !== 'string') continue; // type guard only - console.warn(`- ${name} → ${version}`); -} diff --git a/scripts/run-workspace-script.ts b/scripts/run-workspace-script.ts deleted file mode 100755 index 8483a89f..00000000 --- a/scripts/run-workspace-script.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* eslint n/no-process-exit: off */ -/* eslint unicorn/no-process-exit: off */ -import { execSync } from 'node:child_process'; -import fs from 'node:fs'; -import process from 'node:process'; - -import { assertIsPackageJson } from './assertIsPackageJson.ts'; - -const OK_CODE = 0; -const ERROR_CODE = 1; - -const args = process.argv.slice(2); -const useIntTests = args.includes('--int-test'); -const scripts = getScripts(useIntTests); - -if (useIntTests) { - args.shift(); -} - -const packageJson = getPackageJson(); - -function handleCommand(): void { - if (args.length === 0) { - showHelp(OK_CODE); - } - - const key = args[0]; - const scripts = getScripts(useIntTests); - - if (!key || key === '-?' || key === '--help') { - showHelp(OK_CODE); - } - - if (key in scripts) { - const overrideScript = getOverrideScript(key); - if (overrideScript) { - console.info(`Using override script: ${overrideScript}`); - } else { - if (typeof overrideScript === 'string') { - console.info('Override script is defined but empty. Skipping script.'); - process.exit(OK_CODE); - } - } - - const standardScript = expandScript(scripts[key]); - const script = overrideScript ?? standardScript; - if (!script) { - console.error(`Script not defined: ${key}`); - process.exit(ERROR_CODE); - } - try { - execSync(script, { stdio: 'inherit' }); - } catch { - process.exit(ERROR_CODE); - } - } else { - console.error(`Unknown script: ${key}`); - process.exit(ERROR_CODE); - } -} - -function assertIsError(value: unknown): asserts value is Error { - if (!(value instanceof Error)) { - console.error(value); - throw new TypeError('Expected an Error'); - } -} - -function getOverrideScript(scriptName: string): string | undefined { - return packageJson.scripts?.[scriptName]; -} - -/** - * Returns the contents of `package.json` as an object. - */ -function getPackageJson() { - const packageJsonPath = fs.realpathSync(process.cwd() + '/package.json'); - const content: unknown = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - try { - assertIsPackageJson(content); - } catch (error) { - assertIsError(error); - console.error(error.message); - process.exit(ERROR_CODE); - } - return content; -} - -function getScripts(useIntTests = false): Record { - const commonScripts: Record = { - build: ['compile', 'generate-typings'], - check: ['typecheck', 'fmt:check', 'lint:check', 'test'], - 'check:strict': ['typecheck', 'fmt:check', 'lint:strict', 'test:coverage'], - clean: 'pnpm exec rimraf dist/*', - compile: 'tsx ../../config/build.ts', - fmt: 'prettier --list-different --write .', - 'fmt:check': 'prettier --check .', - 'generate-typings': 'tsc --project tsconfig.generate-typings.json', - lint: 'eslint --fix .', - 'lint:check': 'eslint .', - 'lint:strict': 'strict-lint', - test: 'vitest', - 'test:coverage': 'vitest --coverage', - 'test:watch': 'vitest --watch', - typecheck: 'tsgo --noEmit', - 'view-coverage': 'open coverage/index.html', - }; - - const integrationTestScripts = { - test: 'pnpm exec vitest --config=vitest.standalone.config.ts', - 'test:coverage': 'pnpm exec vitest --config=vitest.standalone.config.ts --coverage', - 'test:integration': 'pnpm exec vitest --config=vitest.integration.config.ts', - 'test:watch': 'pnpm exec vitest --config=vitest.standalone.config.ts --watch', - }; - - const standardTestScripts = { - test: 'pnpm exec vitest', - 'test:coverage': 'pnpm exec vitest --coverage', - 'test:watch': 'pnpm exec vitest --watch', - }; - - return { - ...commonScripts, - ...(useIntTests ? integrationTestScripts : standardTestScripts), - }; -} - -function expandScript(script: string | string[] | undefined): string { - if (!script) { - return ''; - } else if (typeof script === 'string') { - return script; - } else { - return script.map((s) => `pnpm run ws ${s}`).join(' && '); - } -} - -function describeScript(script: string | string[] | undefined): string { - if (!script) { - return ''; - } - return typeof script === 'string' ? script : `pnpm run [${script.join(', ')}]`; -} - -function showHelp(code: number): never { - console.info('Usage: pnpm run ws {script}'); - console.info('Available scripts:'); - - for (const [key, value] of Object.entries(scripts)) { - console.info(` ${key.padEnd(15)} ${describeScript(value)}`); - } - process.exit(code); -} - -handleCommand();