From 363ace4c1cddc260fcab9d0935c6dc9709f9b98c Mon Sep 17 00:00:00 2001 From: michael faith Date: Sun, 10 Aug 2025 14:45:07 -0500 Subject: [PATCH 01/10] ci: add e2e tests to CI This change adds a new end-to-end test capability. There are two new jobs in the main CI workflow. One job to build the package (which also good to have outside of the need to run e2e tests), executed with the latest LTS node. The build artifact is uploaded for the downstream `e2e` job to use. The `e2e` job, downloads the artifact, run `npm install` and then `npm run e2e`, which executes a custom node script to loop through subdirectories of `/e2e`, which each contain a project fixture with different setups. Both projects have the same simple plugin source code, and each has this plugin (referenced from the root of the repo (aka the result of the build)) and `eslint` installed as `devDependencies`. Each also has a `lint` package.json script that runs `eslint` on the simple plugin. \## `/e2e/all` This fixture has a regular js config and runs our `all` config on the project. \## `/e2e/all-typed-config` This fixture has `typescript` installed and uses a ts-based config and runs our `all` config on the project. It also executes `tsc` as part of the `lint` command, to ensure everything's typed property. --- .github/workflows/main.yml | 45 +++++++++++++++++++++- .npmpackagejsonlintignore | 1 + e2e/all-typed-config/.npmrc | 1 + e2e/all-typed-config/eslint.config.ts | 10 +++++ e2e/all-typed-config/index.js | 25 ++++++++++++ e2e/all-typed-config/package.json | 15 ++++++++ e2e/all-typed-config/rule.js | 32 ++++++++++++++++ e2e/all-typed-config/tsconfig.json | 15 ++++++++ e2e/all/.npmrc | 1 + e2e/all/eslint.config.js | 10 +++++ e2e/all/index.js | 25 ++++++++++++ e2e/all/package.json | 13 +++++++ e2e/all/rule.js | 32 ++++++++++++++++ e2e/runAllTests.js | 55 +++++++++++++++++++++++++++ eslint.config.ts | 2 +- package.json | 1 + 16 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 .npmpackagejsonlintignore create mode 100644 e2e/all-typed-config/.npmrc create mode 100644 e2e/all-typed-config/eslint.config.ts create mode 100644 e2e/all-typed-config/index.js create mode 100644 e2e/all-typed-config/package.json create mode 100644 e2e/all-typed-config/rule.js create mode 100644 e2e/all-typed-config/tsconfig.json create mode 100644 e2e/all/.npmrc create mode 100644 e2e/all/eslint.config.js create mode 100644 e2e/all/index.js create mode 100644 e2e/all/package.json create mode 100644 e2e/all/rule.js create mode 100644 e2e/runAllTests.js diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ba38b63a..a9f2b15e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ on: jobs: test: - name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }} + name: Test / Node.js ${{ matrix.node-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -67,3 +67,46 @@ jobs: node-version: 'lts/*' - run: npm install - run: npm run typecheck + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + - run: npm install + - run: npm run build + - name: Upload build results + uses: actions/upload-artifact@v4 + with: + name: build_dist + path: dist + e2e: + name: E2E / Node.js ${{ matrix.node-version }} on ${{ matrix.os }} + needs: build + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + node-version: + - '24.0.0' # minimum supported v24 + - 24 + - '22.13.1' # minimum supported v22 + - 22 + - '20.19.0' #minimum supported v20 + - 20 + os: + - ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - name: Download build results + uses: actions/download-artifact@v4 + with: + name: build_dist + path: dist + - run: npm install + - run: npm run e2e diff --git a/.npmpackagejsonlintignore b/.npmpackagejsonlintignore new file mode 100644 index 00000000..25594133 --- /dev/null +++ b/.npmpackagejsonlintignore @@ -0,0 +1 @@ +e2e/ \ No newline at end of file diff --git a/e2e/all-typed-config/.npmrc b/e2e/all-typed-config/.npmrc new file mode 100644 index 00000000..c1ca392f --- /dev/null +++ b/e2e/all-typed-config/.npmrc @@ -0,0 +1 @@ +package-lock = false diff --git a/e2e/all-typed-config/eslint.config.ts b/e2e/all-typed-config/eslint.config.ts new file mode 100644 index 00000000..f563dd30 --- /dev/null +++ b/e2e/all-typed-config/eslint.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'eslint/config'; + +import eslintPlugin from 'eslint-plugin-eslint-plugin'; + +export default defineConfig([ + { + extends: [eslintPlugin.configs.all], + files: ['./index.js', './rule.js'], + }, +]); diff --git a/e2e/all-typed-config/index.js b/e2e/all-typed-config/index.js new file mode 100644 index 00000000..a898ca19 --- /dev/null +++ b/e2e/all-typed-config/index.js @@ -0,0 +1,25 @@ +import rule from './rule.js'; + +/** @type {import('eslint').ESLint.Plugin} */ +const plugin = { + meta: { + name: '@e2e/all-typed-config', + version: '1.0.0', + }, + rules: { 'e2e-test': rule }, + configs: { + recommended: { + name: '@e2e/all-typed-config/recommended', + plugins: { + get ['@e2e/all-typed-config']() { + return plugin; + }, + }, + rules: { + '@e2e/all-typed-config/e2e-test': 'error', + }, + }, + }, +}; + +export default plugin; diff --git a/e2e/all-typed-config/package.json b/e2e/all-typed-config/package.json new file mode 100644 index 00000000..881575fc --- /dev/null +++ b/e2e/all-typed-config/package.json @@ -0,0 +1,15 @@ +{ + "name": "@e2e/all-typed-config", + "private": true, + "type": "module", + "scripts": { + "lint": "tsc && eslint" + }, + "main": "./index.js", + "devDependencies": { + "eslint": "^9.33.0", + "eslint-plugin-eslint-plugin": "file:../..", + "jiti": "^2.5.1", + "typescript": "^5.9.2" + } +} diff --git a/e2e/all-typed-config/rule.js b/e2e/all-typed-config/rule.js new file mode 100644 index 00000000..c55644ba --- /dev/null +++ b/e2e/all-typed-config/rule.js @@ -0,0 +1,32 @@ +/** @type {import('eslint').Rule.RuleModule} */ +const rule = { + meta: { + type: 'suggestion', + docs: { + description: 'enforce a test', + recommended: false, + url: 'https://test.org', + }, + fixable: undefined, // or "code" or "whitespace" + schema: [], + messages: { + missingOutput: 'This is a test', + }, + }, + + create(context) { + return { + Program(ast) { + const sourceCode = context.sourceCode; + if (false) { + context.report({ + node: ast, + messageId: 'missingOutput', + }); + } + }, + }; + }, +}; + +export default rule; diff --git a/e2e/all-typed-config/tsconfig.json b/e2e/all-typed-config/tsconfig.json new file mode 100644 index 00000000..ada527dc --- /dev/null +++ b/e2e/all-typed-config/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "rootDir": ".", + "module": "nodenext", + "moduleResolution": "nodenext", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2024", + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": true, + "types": [] + }, + "include": ["eslint.config.ts"] +} diff --git a/e2e/all/.npmrc b/e2e/all/.npmrc new file mode 100644 index 00000000..c1ca392f --- /dev/null +++ b/e2e/all/.npmrc @@ -0,0 +1 @@ +package-lock = false diff --git a/e2e/all/eslint.config.js b/e2e/all/eslint.config.js new file mode 100644 index 00000000..f563dd30 --- /dev/null +++ b/e2e/all/eslint.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from 'eslint/config'; + +import eslintPlugin from 'eslint-plugin-eslint-plugin'; + +export default defineConfig([ + { + extends: [eslintPlugin.configs.all], + files: ['./index.js', './rule.js'], + }, +]); diff --git a/e2e/all/index.js b/e2e/all/index.js new file mode 100644 index 00000000..701a1a25 --- /dev/null +++ b/e2e/all/index.js @@ -0,0 +1,25 @@ +import rule from './rule.js'; + +/** @type {import('eslint').ESLint.Plugin} */ +const plugin = { + meta: { + name: '@e2e/all', + version: '1.0.0', + }, + rules: { 'e2e-test': rule }, + configs: { + recommended: { + name: '@e2e/all/recommended', + plugins: { + get ['@e2e/all']() { + return plugin; + }, + }, + rules: { + '@e2e/all/e2e-test': 'error', + }, + }, + }, +}; + +export default plugin; diff --git a/e2e/all/package.json b/e2e/all/package.json new file mode 100644 index 00000000..039a313c --- /dev/null +++ b/e2e/all/package.json @@ -0,0 +1,13 @@ +{ + "name": "@e2e/all", + "private": true, + "type": "module", + "scripts": { + "lint": "eslint" + }, + "main": "./index.js", + "devDependencies": { + "eslint": "^9.33.0", + "eslint-plugin-eslint-plugin": "file:../.." + } +} diff --git a/e2e/all/rule.js b/e2e/all/rule.js new file mode 100644 index 00000000..c55644ba --- /dev/null +++ b/e2e/all/rule.js @@ -0,0 +1,32 @@ +/** @type {import('eslint').Rule.RuleModule} */ +const rule = { + meta: { + type: 'suggestion', + docs: { + description: 'enforce a test', + recommended: false, + url: 'https://test.org', + }, + fixable: undefined, // or "code" or "whitespace" + schema: [], + messages: { + missingOutput: 'This is a test', + }, + }, + + create(context) { + return { + Program(ast) { + const sourceCode = context.sourceCode; + if (false) { + context.report({ + node: ast, + messageId: 'missingOutput', + }); + } + }, + }; + }, +}; + +export default rule; diff --git a/e2e/runAllTests.js b/e2e/runAllTests.js new file mode 100644 index 00000000..877f4a64 --- /dev/null +++ b/e2e/runAllTests.js @@ -0,0 +1,55 @@ +import { execSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import process from 'node:process'; + +const TEST_COMMAND = 'npm run lint'; + +const getRoot = () => { + return execSync('git rev-parse --show-toplevel', { + encoding: 'utf-8', + }).trim(); +}; + +const executeAllE2eTests = async () => { + const e2eDir = path.resolve(getRoot(), './e2e'); + const failedTests = []; + + // Get all directories in the e2e dir + const testDirs = (await fs.readdir(e2eDir, { withFileTypes: true })) + .filter((dirEnt) => dirEnt.isDirectory()) + .map((dirEnt) => path.join(dirEnt.parentPath, dirEnt.name)); + + for (const testDir of testDirs) { + const dirName = path.basename(testDir); + console.log(`๐Ÿงช Executing test: ${dirName}`); + + // Run install and the test command + execSync('npm install', { + cwd: testDir, + stdio: ['ignore', 'ignore', 'pipe'], + }); + try { + execSync(TEST_COMMAND, { + cwd: testDir, + stdio: ['ignore', 'ignore', 'pipe'], + }); + console.log(`โœ… Test passed\n`); + } catch (error) { + console.log(`โŒ Test failed`); + console.error(`${error}\n`); + failedTests.push(dirName); + } + } + + if (failedTests.length) { + console.log( + `Testing complete. ${failedTests.length} of ${testDirs.length} tests failed!`, + ); + process.exitCode = 1; + } else { + console.log(`Testing complete. All ${testDirs.length} tests passed!`); + } +}; + +executeAllE2eTests(); diff --git a/eslint.config.ts b/eslint.config.ts index 7f7b02b8..258daef3 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -18,7 +18,7 @@ const compat = new FlatCompat({ export default tseslint.config([ // Global ignores { - ignores: ['node_modules', 'coverage', 'dist', 'tests/lib/fixtures'], + ignores: ['node_modules', 'coverage', 'dist', 'tests/lib/fixtures', 'e2e'], }, // Global settings { diff --git a/package.json b/package.json index 73185c4e..6066d2f0 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "license": "MIT", "scripts": { "build": "tsdown", + "e2e": "node ./e2e/runAllTests.js", "format": "prettier --write .", "format:check": "prettier --check .", "lint": "npm-run-all --continue-on-error --aggregate-output --parallel lint:*", From 4dc292f511783384ac99e30914db773fd0e45fde Mon Sep 17 00:00:00 2001 From: michael faith Date: Mon, 11 Aug 2025 12:35:55 -0500 Subject: [PATCH 02/10] add cache to node setup and windows to e2e matrix --- .github/workflows/main.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a9f2b15e..13580ef2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,6 +22,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} + cache: 'npm' - run: npm install - run: npm test @@ -33,6 +34,7 @@ jobs: with: node-version: 'lts/*' check-latest: true + cache: 'npm' - run: npm install - run: npm run lint @@ -44,6 +46,7 @@ jobs: with: node-version: 'lts/*' check-latest: true + cache: 'npm' - run: npm install - run: npm run format:check @@ -55,6 +58,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 'lts/*' + cache: 'npm' - run: npm install - run: npm run test:remote @@ -65,6 +69,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 'lts/*' + cache: 'npm' - run: npm install - run: npm run typecheck @@ -75,6 +80,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 'lts/*' + cache: 'npm' - run: npm install - run: npm run build - name: Upload build results @@ -98,11 +104,13 @@ jobs: - 20 os: - ubuntu-latest + - windows-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} + cache: 'npm' - name: Download build results uses: actions/download-artifact@v4 with: From 1a37f3f6cc4e3e87185ae87cfc478d8e1dccb2a9 Mon Sep 17 00:00:00 2001 From: michael faith Date: Mon, 11 Aug 2025 13:00:59 -0500 Subject: [PATCH 03/10] remove cache option from ci jobs --- .github/workflows/main.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 13580ef2..aca47bc6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - run: npm install - run: npm test @@ -34,7 +33,6 @@ jobs: with: node-version: 'lts/*' check-latest: true - cache: 'npm' - run: npm install - run: npm run lint @@ -46,7 +44,6 @@ jobs: with: node-version: 'lts/*' check-latest: true - cache: 'npm' - run: npm install - run: npm run format:check @@ -58,7 +55,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 'lts/*' - cache: 'npm' - run: npm install - run: npm run test:remote @@ -69,7 +65,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 'lts/*' - cache: 'npm' - run: npm install - run: npm run typecheck @@ -80,7 +75,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 'lts/*' - cache: 'npm' - run: npm install - run: npm run build - name: Upload build results @@ -110,7 +104,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - name: Download build results uses: actions/download-artifact@v4 with: From 09797369bc1ed227906f62a79e06350496fdcf9a Mon Sep 17 00:00:00 2001 From: michael faith Date: Mon, 11 Aug 2025 13:06:34 -0500 Subject: [PATCH 04/10] add newlint to npmpackagejsonlintignore --- .npmpackagejsonlintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.npmpackagejsonlintignore b/.npmpackagejsonlintignore index 25594133..b1e3af62 100644 --- a/.npmpackagejsonlintignore +++ b/.npmpackagejsonlintignore @@ -1 +1 @@ -e2e/ \ No newline at end of file +e2e/ From 7be4d22cef09d2ce27cf4e56181bb152835852a7 Mon Sep 17 00:00:00 2001 From: michael faith Date: Mon, 11 Aug 2025 16:51:12 -0500 Subject: [PATCH 05/10] Make script output more actionable, and add tsdoc --- e2e/runAllTests.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/e2e/runAllTests.js b/e2e/runAllTests.js index 877f4a64..1c841c54 100644 --- a/e2e/runAllTests.js +++ b/e2e/runAllTests.js @@ -3,6 +3,14 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import process from 'node:process'; +/** + * Run All Tests: This script executes the lint command on all subfolders under `fixtures`, in order + * to validate the correctness of our plugin. Each fixture installs the *built* package. So this should + * only be run after a build has been done. + * + * For each directory under fixtures, the script runs `npm install` and `npm run lint`. + */ + const TEST_COMMAND = 'npm run lint'; const getRoot = () => { @@ -32,14 +40,14 @@ const executeAllE2eTests = async () => { try { execSync(TEST_COMMAND, { cwd: testDir, - stdio: ['ignore', 'ignore', 'pipe'], + stdio: 'inherit', }); - console.log(`โœ… Test passed\n`); + console.log(`โœ… Test passed`); } catch (error) { console.log(`โŒ Test failed`); - console.error(`${error}\n`); failedTests.push(dirName); } + console.log(`\n${'-'.repeat(50)}\n`); } if (failedTests.length) { From 3661b44f0d66d26427d1b71ef601cd3eefb527ea Mon Sep 17 00:00:00 2001 From: michael faith Date: Mon, 11 Aug 2025 16:51:33 -0500 Subject: [PATCH 06/10] add inline disables --- e2e/all-typed-config/eslint.config.ts | 5 +++++ e2e/all-typed-config/rule.js | 2 +- e2e/all/eslint.config.js | 5 +++++ e2e/all/rule.js | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/e2e/all-typed-config/eslint.config.ts b/e2e/all-typed-config/eslint.config.ts index f563dd30..43d32a5e 100644 --- a/e2e/all-typed-config/eslint.config.ts +++ b/e2e/all-typed-config/eslint.config.ts @@ -3,6 +3,11 @@ import { defineConfig } from 'eslint/config'; import eslintPlugin from 'eslint-plugin-eslint-plugin'; export default defineConfig([ + { + linterOptions: { + reportUnusedDisableDirectives: 'error', + }, + }, { extends: [eslintPlugin.configs.all], files: ['./index.js', './rule.js'], diff --git a/e2e/all-typed-config/rule.js b/e2e/all-typed-config/rule.js index c55644ba..982bde18 100644 --- a/e2e/all-typed-config/rule.js +++ b/e2e/all-typed-config/rule.js @@ -1,5 +1,6 @@ /** @type {import('eslint').Rule.RuleModule} */ const rule = { + // eslint-disable-next-line eslint-plugin/require-meta-schema meta: { type: 'suggestion', docs: { @@ -8,7 +9,6 @@ const rule = { url: 'https://test.org', }, fixable: undefined, // or "code" or "whitespace" - schema: [], messages: { missingOutput: 'This is a test', }, diff --git a/e2e/all/eslint.config.js b/e2e/all/eslint.config.js index f563dd30..43d32a5e 100644 --- a/e2e/all/eslint.config.js +++ b/e2e/all/eslint.config.js @@ -3,6 +3,11 @@ import { defineConfig } from 'eslint/config'; import eslintPlugin from 'eslint-plugin-eslint-plugin'; export default defineConfig([ + { + linterOptions: { + reportUnusedDisableDirectives: 'error', + }, + }, { extends: [eslintPlugin.configs.all], files: ['./index.js', './rule.js'], diff --git a/e2e/all/rule.js b/e2e/all/rule.js index c55644ba..982bde18 100644 --- a/e2e/all/rule.js +++ b/e2e/all/rule.js @@ -1,5 +1,6 @@ /** @type {import('eslint').Rule.RuleModule} */ const rule = { + // eslint-disable-next-line eslint-plugin/require-meta-schema meta: { type: 'suggestion', docs: { @@ -8,7 +9,6 @@ const rule = { url: 'https://test.org', }, fixable: undefined, // or "code" or "whitespace" - schema: [], messages: { missingOutput: 'This is a test', }, From 32a1987b1c6927d5d6c05201b0832a2bbddd022d Mon Sep 17 00:00:00 2001 From: michael faith Date: Tue, 12 Aug 2025 05:27:43 -0500 Subject: [PATCH 07/10] Move e2e test dirs into `fixtures` --- e2e/.npmrc | 1 + e2e/all-typed-config/.npmrc | 1 - e2e/all/.npmrc | 1 - .../all-typed-config/eslint.config.ts | 0 e2e/{ => fixtures}/all-typed-config/index.js | 0 .../all-typed-config/package.json | 2 +- e2e/{ => fixtures}/all-typed-config/rule.js | 0 .../all-typed-config/tsconfig.json | 0 e2e/{ => fixtures}/all/eslint.config.js | 0 e2e/{ => fixtures}/all/index.js | 0 e2e/{ => fixtures}/all/package.json | 2 +- e2e/{ => fixtures}/all/rule.js | 0 e2e/package-lock.json | 1191 +++++++++++++++++ e2e/package.json | 4 + e2e/runAllTests.js | 22 +- eslint.config.ts | 2 +- 16 files changed, 1215 insertions(+), 11 deletions(-) create mode 100644 e2e/.npmrc delete mode 100644 e2e/all-typed-config/.npmrc delete mode 100644 e2e/all/.npmrc rename e2e/{ => fixtures}/all-typed-config/eslint.config.ts (100%) rename e2e/{ => fixtures}/all-typed-config/index.js (100%) rename e2e/{ => fixtures}/all-typed-config/package.json (82%) rename e2e/{ => fixtures}/all-typed-config/rule.js (100%) rename e2e/{ => fixtures}/all-typed-config/tsconfig.json (100%) rename e2e/{ => fixtures}/all/eslint.config.js (100%) rename e2e/{ => fixtures}/all/index.js (100%) rename e2e/{ => fixtures}/all/package.json (78%) rename e2e/{ => fixtures}/all/rule.js (100%) create mode 100644 e2e/package-lock.json create mode 100644 e2e/package.json diff --git a/e2e/.npmrc b/e2e/.npmrc new file mode 100644 index 00000000..77155769 --- /dev/null +++ b/e2e/.npmrc @@ -0,0 +1 @@ +package-lock = false \ No newline at end of file diff --git a/e2e/all-typed-config/.npmrc b/e2e/all-typed-config/.npmrc deleted file mode 100644 index c1ca392f..00000000 --- a/e2e/all-typed-config/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock = false diff --git a/e2e/all/.npmrc b/e2e/all/.npmrc deleted file mode 100644 index c1ca392f..00000000 --- a/e2e/all/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock = false diff --git a/e2e/all-typed-config/eslint.config.ts b/e2e/fixtures/all-typed-config/eslint.config.ts similarity index 100% rename from e2e/all-typed-config/eslint.config.ts rename to e2e/fixtures/all-typed-config/eslint.config.ts diff --git a/e2e/all-typed-config/index.js b/e2e/fixtures/all-typed-config/index.js similarity index 100% rename from e2e/all-typed-config/index.js rename to e2e/fixtures/all-typed-config/index.js diff --git a/e2e/all-typed-config/package.json b/e2e/fixtures/all-typed-config/package.json similarity index 82% rename from e2e/all-typed-config/package.json rename to e2e/fixtures/all-typed-config/package.json index 881575fc..ddaca7d4 100644 --- a/e2e/all-typed-config/package.json +++ b/e2e/fixtures/all-typed-config/package.json @@ -8,7 +8,7 @@ "main": "./index.js", "devDependencies": { "eslint": "^9.33.0", - "eslint-plugin-eslint-plugin": "file:../..", + "eslint-plugin-eslint-plugin": "file:../../..", "jiti": "^2.5.1", "typescript": "^5.9.2" } diff --git a/e2e/all-typed-config/rule.js b/e2e/fixtures/all-typed-config/rule.js similarity index 100% rename from e2e/all-typed-config/rule.js rename to e2e/fixtures/all-typed-config/rule.js diff --git a/e2e/all-typed-config/tsconfig.json b/e2e/fixtures/all-typed-config/tsconfig.json similarity index 100% rename from e2e/all-typed-config/tsconfig.json rename to e2e/fixtures/all-typed-config/tsconfig.json diff --git a/e2e/all/eslint.config.js b/e2e/fixtures/all/eslint.config.js similarity index 100% rename from e2e/all/eslint.config.js rename to e2e/fixtures/all/eslint.config.js diff --git a/e2e/all/index.js b/e2e/fixtures/all/index.js similarity index 100% rename from e2e/all/index.js rename to e2e/fixtures/all/index.js diff --git a/e2e/all/package.json b/e2e/fixtures/all/package.json similarity index 78% rename from e2e/all/package.json rename to e2e/fixtures/all/package.json index 039a313c..da4355cd 100644 --- a/e2e/all/package.json +++ b/e2e/fixtures/all/package.json @@ -8,6 +8,6 @@ "main": "./index.js", "devDependencies": { "eslint": "^9.33.0", - "eslint-plugin-eslint-plugin": "file:../.." + "eslint-plugin-eslint-plugin": "file:../../.." } } diff --git a/e2e/all/rule.js b/e2e/fixtures/all/rule.js similarity index 100% rename from e2e/all/rule.js rename to e2e/fixtures/all/rule.js diff --git a/e2e/package-lock.json b/e2e/package-lock.json new file mode 100644 index 00000000..0c2c0b37 --- /dev/null +++ b/e2e/package-lock.json @@ -0,0 +1,1191 @@ +{ + "name": "e2e", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "workspaces": [ + "fixtures/*" + ] + }, + "..": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "estraverse": "^5.3.0" + }, + "devDependencies": { + "@commitlint/cli": "^19.8.1", + "@commitlint/config-conventional": "^19.8.1", + "@commitlint/types": "^19.8.1", + "@eslint-community/eslint-plugin-eslint-comments": "^4.3.0", + "@eslint/eslintrc": "^3.0.2", + "@eslint/js": "^9.31.0", + "@release-it/conventional-changelog": "^9.0.3", + "@types/eslint-plugin-markdown": "^2.0.2", + "@types/eslint-scope": "^8.3.0", + "@types/espree": "^10.1.0", + "@types/estraverse": "^5.1.7", + "@types/estree": "^1.0.8", + "@types/lodash": "^4.17.18", + "@types/node": "^20.19.0", + "@typescript-eslint/parser": "^8.39.0", + "@typescript-eslint/utils": "^8.39.0", + "@vitest/coverage-istanbul": "^3.2.4", + "eslint": "^9.31.0", + "eslint-config-not-an-aardvark": "^2.1.0", + "eslint-config-prettier": "^10.1.8", + "eslint-doc-generator": "^2.2.2", + "eslint-plugin-markdown": "^5.1.0", + "eslint-plugin-n": "^17.21.0", + "eslint-plugin-unicorn": "^56.0.1", + "eslint-remote-tester": "^4.0.3", + "eslint-scope": "^8.0.1", + "espree": "^10.0.1", + "husky": "^9.1.7", + "jiti": "^2.5.1", + "lodash": "^4.17.21", + "markdownlint-cli": "^0.43.0", + "npm-package-json-lint": "^8.0.0", + "npm-run-all2": "^7.0.1", + "prettier": "^3.6.2", + "release-it": "^17.2.0", + "tsdown": "^0.13.3", + "typescript": "^5.9.2", + "typescript-eslint": "^8.39.0", + "vitest": "^3.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.1 || >=24.0.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "fixtures/all": { + "name": "@e2e/all", + "devDependencies": { + "eslint": "^9.33.0", + "eslint-plugin-eslint-plugin": "file:../../.." + } + }, + "fixtures/all-typed-config": { + "name": "@e2e/all-typed-config", + "devDependencies": { + "eslint": "^9.33.0", + "eslint-plugin-eslint-plugin": "file:../../..", + "jiti": "^2.5.1", + "typescript": "^5.9.2" + } + }, + "node_modules/@e2e/all": { + "resolved": "fixtures/all", + "link": true + }, + "node_modules/@e2e/all-typed-config": { + "resolved": "fixtures/all-typed-config", + "link": true + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz", + "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz", + "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.33.0", + "@eslint/plugin-kit": "^0.3.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-eslint-plugin": { + "resolved": "..", + "link": true + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 00000000..f2d01ad4 --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,4 @@ +{ + "workspaces": ["fixtures/*"], + "type": "module" +} \ No newline at end of file diff --git a/e2e/runAllTests.js b/e2e/runAllTests.js index 1c841c54..75f8d825 100644 --- a/e2e/runAllTests.js +++ b/e2e/runAllTests.js @@ -21,22 +21,32 @@ const getRoot = () => { const executeAllE2eTests = async () => { const e2eDir = path.resolve(getRoot(), './e2e'); + const fixturesDir = path.resolve(e2eDir, './fixtures'); const failedTests = []; + // First install all dependencies in the fixtures workspace + // Run install and the test command + execSync('npm install', { + cwd: e2eDir, + stdio: ['ignore', 'ignore', 'pipe'], + }); + // Get all directories in the e2e dir - const testDirs = (await fs.readdir(e2eDir, { withFileTypes: true })) + const testDirs = (await fs.readdir(fixturesDir, { withFileTypes: true })) .filter((dirEnt) => dirEnt.isDirectory()) .map((dirEnt) => path.join(dirEnt.parentPath, dirEnt.name)); + if (testDirs.length) { + console.log(`Running ${testDirs.length} end to end tests.`) + console.log(`\n${'-'.repeat(50)}\n`); + } else { + console.log('No end-to-end tests found...'); + } + for (const testDir of testDirs) { const dirName = path.basename(testDir); console.log(`๐Ÿงช Executing test: ${dirName}`); - // Run install and the test command - execSync('npm install', { - cwd: testDir, - stdio: ['ignore', 'ignore', 'pipe'], - }); try { execSync(TEST_COMMAND, { cwd: testDir, diff --git a/eslint.config.ts b/eslint.config.ts index 258daef3..751f9917 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -18,7 +18,7 @@ const compat = new FlatCompat({ export default tseslint.config([ // Global ignores { - ignores: ['node_modules', 'coverage', 'dist', 'tests/lib/fixtures', 'e2e'], + ignores: ['node_modules', 'coverage', 'dist', 'tests/lib/fixtures', 'e2e/fixtures'], }, // Global settings { From 2cb49504a4deeaa902ab623ee8d0d142767f702b Mon Sep 17 00:00:00 2001 From: michael faith Date: Tue, 12 Aug 2025 05:27:56 -0500 Subject: [PATCH 08/10] Move e2e test dirs into `fixtures` --- e2e/{runAllTests.js => run-all-tests.js} | 13 ++++++++----- package.json | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) rename e2e/{runAllTests.js => run-all-tests.js} (86%) diff --git a/e2e/runAllTests.js b/e2e/run-all-tests.js similarity index 86% rename from e2e/runAllTests.js rename to e2e/run-all-tests.js index 75f8d825..8757ff12 100644 --- a/e2e/runAllTests.js +++ b/e2e/run-all-tests.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console -- node script */ import { execSync } from 'node:child_process'; import fs from 'node:fs/promises'; import path from 'node:path'; @@ -15,7 +16,7 @@ const TEST_COMMAND = 'npm run lint'; const getRoot = () => { return execSync('git rev-parse --show-toplevel', { - encoding: 'utf-8', + encoding: 'utf8', }).trim(); }; @@ -32,11 +33,12 @@ const executeAllE2eTests = async () => { }); // Get all directories in the e2e dir - const testDirs = (await fs.readdir(fixturesDir, { withFileTypes: true })) + const allFixtureFiles = await fs.readdir(fixturesDir, { withFileTypes: true }); + const testDirs = allFixtureFiles .filter((dirEnt) => dirEnt.isDirectory()) .map((dirEnt) => path.join(dirEnt.parentPath, dirEnt.name)); - if (testDirs.length) { + if (testDirs.length > 0) { console.log(`Running ${testDirs.length} end to end tests.`) console.log(`\n${'-'.repeat(50)}\n`); } else { @@ -53,14 +55,14 @@ const executeAllE2eTests = async () => { stdio: 'inherit', }); console.log(`โœ… Test passed`); - } catch (error) { + } catch { console.log(`โŒ Test failed`); failedTests.push(dirName); } console.log(`\n${'-'.repeat(50)}\n`); } - if (failedTests.length) { + if (failedTests.length > 0) { console.log( `Testing complete. ${failedTests.length} of ${testDirs.length} tests failed!`, ); @@ -69,5 +71,6 @@ const executeAllE2eTests = async () => { console.log(`Testing complete. All ${testDirs.length} tests passed!`); } }; +/* eslint-enable no-console -- node script */ executeAllE2eTests(); diff --git a/package.json b/package.json index 6066d2f0..f7f42ff6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "license": "MIT", "scripts": { "build": "tsdown", - "e2e": "node ./e2e/runAllTests.js", + "e2e": "node ./e2e/run-all-tests.js", "format": "prettier --write .", "format:check": "prettier --check .", "lint": "npm-run-all --continue-on-error --aggregate-output --parallel lint:*", From de3ae930ac9d871449e05b40db63437883edb393 Mon Sep 17 00:00:00 2001 From: michael faith Date: Tue, 12 Aug 2025 06:46:42 -0500 Subject: [PATCH 09/10] Format --- e2e/package.json | 6 ++++-- e2e/run-all-tests.js | 6 ++++-- eslint.config.ts | 8 +++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/e2e/package.json b/e2e/package.json index f2d01ad4..ba5bbf9c 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -1,4 +1,6 @@ { - "workspaces": ["fixtures/*"], + "workspaces": [ + "fixtures/*" + ], "type": "module" -} \ No newline at end of file +} diff --git a/e2e/run-all-tests.js b/e2e/run-all-tests.js index 8757ff12..9c55b9c8 100644 --- a/e2e/run-all-tests.js +++ b/e2e/run-all-tests.js @@ -33,13 +33,15 @@ const executeAllE2eTests = async () => { }); // Get all directories in the e2e dir - const allFixtureFiles = await fs.readdir(fixturesDir, { withFileTypes: true }); + const allFixtureFiles = await fs.readdir(fixturesDir, { + withFileTypes: true, + }); const testDirs = allFixtureFiles .filter((dirEnt) => dirEnt.isDirectory()) .map((dirEnt) => path.join(dirEnt.parentPath, dirEnt.name)); if (testDirs.length > 0) { - console.log(`Running ${testDirs.length} end to end tests.`) + console.log(`Running ${testDirs.length} end to end tests.`); console.log(`\n${'-'.repeat(50)}\n`); } else { console.log('No end-to-end tests found...'); diff --git a/eslint.config.ts b/eslint.config.ts index 751f9917..e06136c8 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -18,7 +18,13 @@ const compat = new FlatCompat({ export default tseslint.config([ // Global ignores { - ignores: ['node_modules', 'coverage', 'dist', 'tests/lib/fixtures', 'e2e/fixtures'], + ignores: [ + 'node_modules', + 'coverage', + 'dist', + 'tests/lib/fixtures', + 'e2e/fixtures', + ], }, // Global settings { From 4aafaef5c22acabd05f96200a9f214b79498da7d Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Tue, 12 Aug 2025 08:57:26 -0400 Subject: [PATCH 10/10] Update e2e/.npmrc --- e2e/.npmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/.npmrc b/e2e/.npmrc index 77155769..c1ca392f 100644 --- a/e2e/.npmrc +++ b/e2e/.npmrc @@ -1 +1 @@ -package-lock = false \ No newline at end of file +package-lock = false