From 5f751d37216cffb1a95cc27cb7564abffdc70947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Tue, 28 May 2024 15:19:49 +0300 Subject: [PATCH] feat!: support `eslint@9` and flat config --- README.md | 4 +- package.json | 3 +- .../eslint-local-rules.cjs | 0 ...fig.cjs => eslint-remote-tester.config.js} | 22 +- .../eslint-remote-tester.config.ts | 36 ++ packages/eslint-remote-tester/package.json | 35 +- .../eslint-remote-tester/src/config/config.ts | 4 +- .../eslint-remote-tester/src/config/load.ts | 52 +- .../eslint-remote-tester/src/config/types.ts | 11 +- .../src/config/validator.ts | 29 +- .../src/engine/worker-task.ts | 18 +- .../test/integration/base.config.cjs | 20 - .../test/integration/base.config.js | 26 + .../integration.action-exports.test.ts | 2 +- .../test/integration/integration.test.ts | 533 +++++++++--------- .../test/smoke/base.config.cjs | 15 - .../test/smoke/base.config.js | 20 + .../test/smoke/smoke.test.ts | 18 +- packages/eslint-remote-tester/test/utils.ts | 59 +- pnpm-lock.yaml | 365 +++--------- 20 files changed, 575 insertions(+), 697 deletions(-) rename eslint-local-rules.js => packages/eslint-remote-tester/eslint-local-rules.cjs (100%) rename packages/eslint-remote-tester/{eslint-remote-tester.config.cjs => eslint-remote-tester.config.js} (77%) create mode 100644 packages/eslint-remote-tester/eslint-remote-tester.config.ts delete mode 100644 packages/eslint-remote-tester/test/integration/base.config.cjs create mode 100644 packages/eslint-remote-tester/test/integration/base.config.js delete mode 100644 packages/eslint-remote-tester/test/smoke/base.config.cjs create mode 100644 packages/eslint-remote-tester/test/smoke/base.config.js diff --git a/README.md b/README.md index 829dcf39..3086b24a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ # In your project directory $ npm install --save-dev eslint-remote-tester -# eslint is also required as peer dependency +# eslint@>=9 is also required as peer dependency $ npm install --save-dev eslint ``` @@ -66,7 +66,7 @@ module.exports = { }; ``` -Configuration file can also be written in TypeScript if [`ts-node`](https://www.npmjs.com/package/ts-node) is installed. Use `--config` argument for TypeScript configuration file, e.g. `--config eslint-remote-tester.config.ts`. +Configuration file can also be written in TypeScript if [`jiti`](https://www.npmjs.com/package/jiti) or [`importx`](https://www.npmjs.com/package/importx) is installed. Use `--config` argument for TypeScript configuration file, e.g. `--config eslint-remote-tester.config.ts`. ```ts import type { Config } from 'eslint-remote-tester'; diff --git a/package.json b/package.json index 145cf033..9166e116 100644 --- a/package.json +++ b/package.json @@ -28,9 +28,8 @@ "conventional-changelog-cli": "^5.0.0", "eslint": "^9.3.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-local-rules": "^2.0.1", "eslint-plugin-prettier": "^5.1.3", - "pkg-pr-new": "^0.0.5", + "pkg-pr-new": "^0.0.8", "prettier": "^3.2.5", "publint": "^0.2.8", "typescript": "^5.4.5", diff --git a/eslint-local-rules.js b/packages/eslint-remote-tester/eslint-local-rules.cjs similarity index 100% rename from eslint-local-rules.js rename to packages/eslint-remote-tester/eslint-local-rules.cjs diff --git a/packages/eslint-remote-tester/eslint-remote-tester.config.cjs b/packages/eslint-remote-tester/eslint-remote-tester.config.js similarity index 77% rename from packages/eslint-remote-tester/eslint-remote-tester.config.cjs rename to packages/eslint-remote-tester/eslint-remote-tester.config.js index 7858126c..3af6313f 100644 --- a/packages/eslint-remote-tester/eslint-remote-tester.config.cjs +++ b/packages/eslint-remote-tester/eslint-remote-tester.config.js @@ -1,4 +1,7 @@ -module.exports = { +import js from '@eslint/js'; + +/** @type {import('./src/config/types').Config} */ +const config = { repositories: [ 'AriPerkkio/eslint-remote-tester-integration-test-target', 'AriPerkkio/aria-live-capture', @@ -17,20 +20,7 @@ module.exports = { concurrentTasks: 3, - eslintrc: { - root: true, - env: { - es6: true, - }, - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - extends: ['eslint:recommended'], - }, + eslintConfig: [js.configs.recommended], cache: true, @@ -61,3 +51,5 @@ module.exports = { */ onComplete: undefined, }; + +export default config; diff --git a/packages/eslint-remote-tester/eslint-remote-tester.config.ts b/packages/eslint-remote-tester/eslint-remote-tester.config.ts new file mode 100644 index 00000000..4b99a119 --- /dev/null +++ b/packages/eslint-remote-tester/eslint-remote-tester.config.ts @@ -0,0 +1,36 @@ +import js from '@eslint/js'; +import type { Config } from './src/types'; + +export default defineConfig({ + repositories: [ + 'AriPerkkio/eslint-remote-tester-integration-test-target', + 'AriPerkkio/aria-live-capture', + 'AriPerkkio/extend-to-be-announced', + 'AriPerkkio/state-mgmt-examples', + 'AriPerkkio/suspense-examples', + ], + + extensions: ['js', 'jsx', 'ts', 'tsx'], + + maxFileSizeBytes: undefined, + + rulesUnderTesting: [], + + resultParser: undefined, + + concurrentTasks: 3, + + eslintConfig: [js.configs.recommended] as any, + + cache: true, + + compare: false, + + updateComparisonReference: true, + + onComplete: undefined, +}); + +function defineConfig(config: Config) { + return config; +} diff --git a/packages/eslint-remote-tester/package.json b/packages/eslint-remote-tester/package.json index 05a38419..539fa506 100644 --- a/packages/eslint-remote-tester/package.json +++ b/packages/eslint-remote-tester/package.json @@ -6,8 +6,17 @@ "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", - "exports": "./dist/index.js", - "types": "./dist/index.d.ts", + "types": "./dist/types.d.ts", + "exports": { + ".": { + "types": "./dist/types.d.ts", + "import": "./dist/index.js" + }, + "./github-actions": { + "types": "./dist/exports-for-compare-action.d.ts", + "import": "./dist/exports-for-compare-action.js" + } + }, "files": [ "dist" ], @@ -22,9 +31,8 @@ "scripts": { "prebuild": "rm -rf ./dist", "build": "tsc --project tsconfig.prod.json", - "start": "node dist --config eslint-remote-tester.config.cjs", + "start": "node dist --config eslint-remote-tester.config.js", "start:memory-limit-crash": "NODE_OPTIONS=--max_old_space_size=50 node dist", - "lint": "eslint . --max-warnings 0 --ext .js,.ts,.tsx && publint", "test:integration": "vitest run --config test/integration/vitest.config.integration.ts", "test:smoke": "vitest run --config test/smoke/vitest.config.smoke.ts", "validate": "pnpm build && pnpm lint && pnpm test && pnpm test:integration" @@ -45,29 +53,34 @@ "simple-git": "^3.24.0" }, "devDependencies": { + "@eslint/eslintrc": "^3.1.0", "@types/babel__code-frame": "^7.0.6", "@types/eslint": "^8.56.10", "@types/node": "^20.12.12", "@types/object-hash": "^3.0.6", "@types/react": "^17.0.80", - "@typescript-eslint/eslint-plugin": "^7.11.0", - "@typescript-eslint/parser": "^7.11.0", "conventional-changelog-cli": "^5.0.0", - "eslint": "^8.57.0", + "eslint": "^9.3.0", + "eslint-plugin-local-rules": "^2.0.1", "eslint-remote-tester-repositories": "workspace:*", + "importx": "^0.3.5", "ink-testing-library": "^2.1.0", + "jiti": "^1.21.3", "node-pty": "^1.0.0", "strip-ansi": "^6.0.1", - "ts-node": "^10.9.2", "typescript": "^5.4.5", "vitest": "^1.6.0" }, "peerDependencies": { - "eslint": ">=7", - "ts-node": ">=9.0.0" + "eslint": ">=9", + "importx": ">=0.3.5", + "jiti": ">=1" }, "peerDependenciesMeta": { - "ts-node": { + "importx": { + "optional": true + }, + "jiti": { "optional": true } }, diff --git a/packages/eslint-remote-tester/src/config/config.ts b/packages/eslint-remote-tester/src/config/config.ts index e2119170..f2694d63 100644 --- a/packages/eslint-remote-tester/src/config/config.ts +++ b/packages/eslint-remote-tester/src/config/config.ts @@ -8,7 +8,7 @@ import { loadConfig } from './load.js'; import { WorkerData } from '../engine/types.js'; const DEFAULT_CONFIGURATION_FILE_NAME = 'eslint-remote-tester.config'; -const DEFAULT_CONFIGURATION_FILE_JS = `${DEFAULT_CONFIGURATION_FILE_NAME}.cjs`; +const DEFAULT_CONFIGURATION_FILE_JS = `${DEFAULT_CONFIGURATION_FILE_NAME}.js`; const DEFAULT_CONFIGURATION_FILE_TS = `${DEFAULT_CONFIGURATION_FILE_NAME}.ts`; const CLI_ARGS_CONFIG = ['-c', '--config']; @@ -48,7 +48,7 @@ if (!fs.existsSync(CONFIGURATION_FILE)) { process.exit(); } -const configFileContents = loadConfig(path.resolve(CONFIGURATION_FILE)); +const configFileContents = await loadConfig(path.resolve(CONFIGURATION_FILE)); const config = getConfigWithDefaults(configFileContents); export default config; diff --git a/packages/eslint-remote-tester/src/config/load.ts b/packages/eslint-remote-tester/src/config/load.ts index 308c5358..8fa0110b 100644 --- a/packages/eslint-remote-tester/src/config/load.ts +++ b/packages/eslint-remote-tester/src/config/load.ts @@ -1,42 +1,42 @@ -import { createRequire } from 'node:module'; -import type { Service, RegisterOptions } from 'ts-node'; - -let registerer: Service | null = null; -const require = createRequire(import.meta.url); - -/* istanbul ignore next */ -const interopRequireDefault = (obj: any): { default: any } => - obj && obj.__esModule ? obj : { default: obj }; - /** @internal */ -export const loadTSConfig = (configPath: string) => { +export const loadTSConfig = async (configPath: string) => { + let importx: typeof import('importx') | undefined = undefined; + let jiti: typeof import('jiti') | undefined = undefined; + try { - registerer ||= require('ts-node').register({ - moduleTypes: { '**/*.ts': 'cjs' }, - } satisfies RegisterOptions) as Service; - } catch (e: any) { - if (e.code === 'MODULE_NOT_FOUND') { + importx = await import('importx'); + } catch { + try { + jiti = await import('jiti'); + } catch { throw new Error( - `'ts-node' is required for TypeScript configuration files. Make sure it is installed\nError: ${e.message}` + "'jiti' or 'importx' is required for loading TypeScript configuration files. Make sure to install one of them." ); } - - throw e; } - registerer.enabled(true); - - const configObject = interopRequireDefault(require(configPath)).default; + if (importx) { + const config = await importx.import(configPath, import.meta.url); + return config.default; + } - registerer.enabled(false); + if (jiti) { + return jiti.default(import.meta.url, { + interopDefault: true, + esmResolve: true, + })(configPath); + } - return configObject; + throw new Error( + "'jiti' or 'importx' is required for loading TypeScript configuration files. Make sure to install one of them." + ); }; -export const loadConfig = (configPath: string) => { +export const loadConfig = async (configPath: string) => { if (configPath.endsWith('.ts')) { return loadTSConfig(configPath); } - return require(configPath); + const { default: config } = await import(configPath); + return config; }; diff --git a/packages/eslint-remote-tester/src/config/types.ts b/packages/eslint-remote-tester/src/config/types.ts index 3f645876..e63cb572 100644 --- a/packages/eslint-remote-tester/src/config/types.ts +++ b/packages/eslint-remote-tester/src/config/types.ts @@ -45,12 +45,12 @@ export interface Config { * Supports lazy initialization based on currently tested repository when a function is passed. * Function is called with current repository and its location on filesystem. */ - eslintrc: - | Linter.Config + eslintConfig: + | Linter.FlatConfig | ((options?: { repository: string; location: string; - }) => Linter.Config); + }) => Linter.FlatConfig | Promise); /** Flag used to set CI mode. `process.env.CI` is used when not set. */ CI: boolean; @@ -102,7 +102,10 @@ export interface Config { ) => Promise | void; } -type RequiredFields = Pick; +type RequiredFields = Pick< + Config, + 'repositories' | 'extensions' | 'eslintConfig' +>; type OptionalFields = AllKeysOptional< Pick< Config, diff --git a/packages/eslint-remote-tester/src/config/validator.ts b/packages/eslint-remote-tester/src/config/validator.ts index 437ac32a..151b2922 100644 --- a/packages/eslint-remote-tester/src/config/validator.ts +++ b/packages/eslint-remote-tester/src/config/validator.ts @@ -100,7 +100,7 @@ export default async function validate( rulesUnderTesting, resultParser, concurrentTasks, - eslintrc, + eslintConfig, CI, logLevel, slowLintTimeLimit, @@ -127,24 +127,29 @@ export default async function validate( errors.push(validateStringArray('extensions', extensions)); - if (!eslintrc) { - errors.push(`Missing eslintrc.`); + if (!eslintConfig) { + errors.push(`Missing eslintConfig.`); } else { try { - // This will throw when eslintrc is invalid + // This will throw when eslintConfig is invalid const linter = new ESLint({ - useEslintrc: false, + // @ts-expect-error -- `@types/eslint` for v9 are unavailable + overrideConfigFile: true, + + // @ts-expect-error -- `@types/eslint` for v9 are unavailable overrideConfig: - typeof eslintrc === 'function' ? eslintrc() : eslintrc, + typeof eslintConfig === 'function' + ? await eslintConfig() + : eslintConfig, }); errors.push(await validateEslintRules(linter)); } catch (e) { - errors.push(`eslintrc: ${e.message}`); + errors.push(`eslintConfig: ${e.message}`); - if (typeof eslintrc === 'function') { + if (typeof eslintConfig === 'function') { errors.push( - 'Note that "config.eslintrc" is called with empty options during configuration validation.' + 'Note that "config.eslintConfig" is called with empty options during configuration validation.' ); } } @@ -152,7 +157,7 @@ export default async function validate( // Optional fields - // TODO nice-to-have: Validate rules match eslintrc config + // TODO nice-to-have: Validate rules match eslintConfig config // https://eslint.org/docs/developer-guide/nodejs-api#lintergetrules if (rulesUnderTesting) { if (Array.isArray(rulesUnderTesting)) { @@ -294,7 +299,7 @@ export function getConfigWithDefaults(config: ConfigWithOptionals): Config { } /** - * Validate given rules of `config.eslintrc.rules` + * Validate given rules of `config.eslintConfig.rules` * - When unknown rules are defined, or known ones are misspelled they are not * reported during linting. We need to specifically look for them. */ @@ -313,7 +318,7 @@ async function validateEslintRules( } if (errors.length) { - return `Configuration validation errors at eslintrc.rules: \n - ${errors.join( + return `Configuration validation errors at eslintConfig.rules: \n - ${errors.join( '\n - ' )}`; } diff --git a/packages/eslint-remote-tester/src/engine/worker-task.ts b/packages/eslint-remote-tester/src/engine/worker-task.ts index e122ede8..1d390515 100644 --- a/packages/eslint-remote-tester/src/engine/worker-task.ts +++ b/packages/eslint-remote-tester/src/engine/worker-task.ts @@ -211,17 +211,20 @@ export default async function workerTask(): Promise { onReadFailure: () => postMessage({ type: 'READ_FAILURE' }), }); - const eslintrc = - typeof config.eslintrc === 'function' - ? config.eslintrc({ + const eslintConfig = + typeof config.eslintConfig === 'function' + ? await config.eslintConfig({ repository, location: resolve(`${CACHE_LOCATION}/${repository}`), }) - : config.eslintrc; + : config.eslintConfig; const linter = new ESLint({ - useEslintrc: false, - overrideConfig: eslintrc, + // @ts-expect-error -- `@types/eslint` for v9 are unavailable + overrideConfigFile: true, + + // @ts-expect-error -- `@types/eslint` for v9 are unavailable + overrideConfig: eslintConfig, // Only rules set in configuration are expected. // Ignore all inline configurations found from target repositories. @@ -229,7 +232,8 @@ export default async function workerTask(): Promise { // Lint all given files, ignore none. Cache is located under node_modules. // config.pathIgnorePattern is used for exclusions. - ignore: false, + ignore: true, + ignorePatterns: ['!**/node_modules/'], }); postMessage({ type: 'LINT_START', payload: files.length }); diff --git a/packages/eslint-remote-tester/test/integration/base.config.cjs b/packages/eslint-remote-tester/test/integration/base.config.cjs deleted file mode 100644 index 1530ea3c..00000000 --- a/packages/eslint-remote-tester/test/integration/base.config.cjs +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - repositories: ['AriPerkkio/eslint-remote-tester-integration-test-target'], - extensions: ['.js'], - pathIgnorePattern: '(expected-to-be-excluded)', - rulesUnderTesting: [ - 'no-unreachable', - 'no-undef', - 'no-empty', - 'getter-return', - 'no-compare-neg-zero', - ], - eslintrc: { - root: true, - extends: ['eslint:recommended'], - plugins: ['eslint-plugin-local-rules'], - rules: { - 'local-rules/some-unstable-rule': 'error', - }, - }, -}; diff --git a/packages/eslint-remote-tester/test/integration/base.config.js b/packages/eslint-remote-tester/test/integration/base.config.js new file mode 100644 index 00000000..9cc1054d --- /dev/null +++ b/packages/eslint-remote-tester/test/integration/base.config.js @@ -0,0 +1,26 @@ +/** @type {import('../../src/config/types').Config} */ +const config = { + repositories: ['AriPerkkio/eslint-remote-tester-integration-test-target'], + extensions: ['.js'], + pathIgnorePattern: '(expected-to-be-excluded)', + rulesUnderTesting: [ + 'no-unreachable', + 'no-undef', + 'no-empty', + 'getter-return', + 'no-compare-neg-zero', + ], + eslintConfig: `async function initialize() { + const { default: js } = await import('@eslint/js'); + const { FlatCompat } = await import('@eslint/eslintrc'); + const compat = new FlatCompat({ baseDirectory: process.cwd() }); + + return [ + js.configs.recommended, + ...compat.plugins('eslint-plugin-local-rules'), + { rules: { 'local-rules/some-unstable-rule': 'error' } }, + ]; + }`, +}; + +export default config; diff --git a/packages/eslint-remote-tester/test/integration/integration.action-exports.test.ts b/packages/eslint-remote-tester/test/integration/integration.action-exports.test.ts index e7fc4829..6056d504 100644 --- a/packages/eslint-remote-tester/test/integration/integration.action-exports.test.ts +++ b/packages/eslint-remote-tester/test/integration/integration.action-exports.test.ts @@ -42,7 +42,7 @@ test('exports validateConfig', async () => { [Error: Configuration validation errors: - Missing repositories. - Missing extensions. - - Missing eslintrc.] + - Missing eslintConfig.] `); console.log = consolelog; diff --git a/packages/eslint-remote-tester/test/integration/integration.test.ts b/packages/eslint-remote-tester/test/integration/integration.test.ts index abf8d920..bf594f5b 100644 --- a/packages/eslint-remote-tester/test/integration/integration.test.ts +++ b/packages/eslint-remote-tester/test/integration/integration.test.ts @@ -9,9 +9,12 @@ import { INTEGRATION_REPO_NAME, REPOSITORY_CACHE, } from '../utils'; -import { Config } from '../../src/config/types'; const DEBUG_LOG_PATTERN = /\[DEBUG (\S|:)*\] /g; +const ESLINT_CONFIG_ALL = `async function initialize() { + const { default: js } = await import('@eslint/js'); + return [js.configs.all]; +}`; test('results are rendered on CI mode', async () => { const { output } = await runProductionBuild({ CI: true }); @@ -35,7 +38,7 @@ test('results are rendered on CI mode', async () => { TypeError: Cannot read property 'someAttribute' of undefined Occurred while linting /node_modules/.cache-eslint-remote-tester/AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js Rule: "local-rules/some-unstable-rule" - at Identifier (/eslint-local-rules.js) + at Identifier (/eslint-local-rules.cjs:22:56) at ruleErrorHandler (//node_modules/eslint/lib/linter/linter.js) at //node_modules/eslint/lib/linter/safe-emitter.js at Array.forEach () @@ -43,8 +46,8 @@ test('results are rendered on CI mode', async () => { at NodeEventGenerator.applySelector (//node_modules/eslint/lib/linter/node-event-generator.js) at NodeEventGenerator.applySelectors (//node_modules/eslint/lib/linter/node-event-generator.js) at NodeEventGenerator.enterNode (//node_modules/eslint/lib/linter/node-event-generator.js) - at CodePathAnalyzer.enterNode (//node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js) - at //node_modules/eslint/lib/linter/linter.js + at runRules (//node_modules/eslint/lib/linter/linter.js) + at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (//node_modules/eslint/lib/linter/linter.js) Repository: AriPerkkio/eslint-remote-tester-integration-test-target Rule: no-undef @@ -127,7 +130,7 @@ test('results are written to file system on CLI mode', async () => { TypeError: Cannot read property 'someAttribute' of undefined Occurred while linting /node_modules/.cache-eslint-remote-tester/AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js Rule: "local-rules/some-unstable-rule" - at Identifier (/eslint-local-rules.js) + at Identifier (/eslint-local-rules.cjs:22:56) at ruleErrorHandler (//node_modules/eslint/lib/linter/linter.js) at //node_modules/eslint/lib/linter/safe-emitter.js at Array.forEach () @@ -135,8 +138,8 @@ test('results are written to file system on CLI mode', async () => { at NodeEventGenerator.applySelector (//node_modules/eslint/lib/linter/node-event-generator.js) at NodeEventGenerator.applySelectors (//node_modules/eslint/lib/linter/node-event-generator.js) at NodeEventGenerator.enterNode (//node_modules/eslint/lib/linter/node-event-generator.js) - at CodePathAnalyzer.enterNode (//node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js) - at //node_modules/eslint/lib/linter/linter.js + at runRules (//node_modules/eslint/lib/linter/linter.js) + at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (//node_modules/eslint/lib/linter/linter.js) \`\`\` ## Rule: no-undef @@ -325,10 +328,7 @@ test('erroneous scan exits with error code', async () => { test('successful scan exits without error code', async () => { const { exitCode } = await runProductionBuild({ rulesUnderTesting: [], - eslintrc: { - root: true, - extends: ['eslint:recommended'], - }, + eslintConfig: [], }); expect(exitCode).toBe(0); @@ -410,7 +410,7 @@ test('calls onComplete hook with the results', async () => { TypeError: Cannot read property 'someAttribute' of undefined Occurred while linting /node_modules/.cache-eslint-remote-tester/AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js Rule: "local-rules/some-unstable-rule" - at Identifier (/eslint-local-rules.js) + at Identifier (/eslint-local-rules.cjs:22:56) at ruleErrorHandler (//node_modules/eslint/lib/linter/linter.js) at //node_modules/eslint/lib/linter/safe-emitter.js at Array.forEach () @@ -418,8 +418,8 @@ test('calls onComplete hook with the results', async () => { at NodeEventGenerator.applySelector (//node_modules/eslint/lib/linter/node-event-generator.js) at NodeEventGenerator.applySelectors (//node_modules/eslint/lib/linter/node-event-generator.js) at NodeEventGenerator.enterNode (//node_modules/eslint/lib/linter/node-event-generator.js) - at CodePathAnalyzer.enterNode (//node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js) - at //node_modules/eslint/lib/linter/linter.js + at runRules (//node_modules/eslint/lib/linter/linter.js) + at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (//node_modules/eslint/lib/linter/linter.js) [ERROR] . [REPOSITORY] @@ -596,10 +596,7 @@ test('erroneous onComplete does not crash application', async () => { const { output, exitCode } = await runProductionBuild({ CI: true, rulesUnderTesting: [], - eslintrc: { - root: true, - extends: ['eslint:recommended'], - }, + eslintConfig: [], onComplete: function onComplete(results) { // @ts-expect-error -- intentional error results.some.nonexisting.field; @@ -623,29 +620,23 @@ test('comparison results are written to file system on CLI mode', async () => { await runProductionBuild({ compare: true, CI: false, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ 'no-compare-neg-zero', // Used in initial scan, not in second // 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); const { output } = await runProductionBuild({ compare: true, CI: false, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ // 'no-compare-neg-zero', // Used in initial scan, not in second 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); expect(output.find(row => /comparison/.test(row))).toMatch( @@ -721,15 +712,12 @@ test('comparison result reference updating can be disabled', async () => { await runProductionBuild({ compare: true, CI: false, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ 'no-compare-neg-zero', // Used in initial scan, not in second // 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -738,15 +726,12 @@ test('comparison result reference updating can be disabled', async () => { updateComparisonReference: false, compare: true, CI: false, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ // 'no-compare-neg-zero', // Used in initial scan, not in second 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); // Comparison results should not change between runs @@ -760,29 +745,23 @@ test('comparison results are rendered on CI mode', async () => { await runProductionBuild({ compare: true, CI: true, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ 'no-compare-neg-zero', // Used in initial scan, not in second // 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); const { output } = await runProductionBuild({ compare: true, CI: true, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ // 'no-compare-neg-zero', // Used in initial scan, not in second 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); // Remaining errors should be visible in results but not in comparison @@ -790,45 +769,45 @@ test('comparison results are rendered on CI mode', async () => { expect(results).toMatch(/no-empty/); expect(comparisonResults).toMatchInlineSnapshot(` - "Comparison results: - Added: - Rule: no-undef - Message: 'window' is not defined. - Path: AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js - Link: https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/expected-to-crash-linter.js#L2-L2 + "Comparison results: + Added: + Rule: no-undef + Message: 'window' is not defined. + Path: AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js + Link: https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/expected-to-crash-linter.js#L2-L2 - 1 | // Identifier.name = attributeForCrashing - > 2 | window.attributeForCrashing(); - | ^^^^^^ - 3 | + 1 | // Identifier.name = attributeForCrashing + > 2 | window.attributeForCrashing(); + | ^^^^^^ + 3 | - Rule: no-undef - Message: 'bar' is not defined. - Path: AriPerkkio/eslint-remote-tester-integration-test-target/index.js - Link: https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L1-L1 + Rule: no-undef + Message: 'bar' is not defined. + Path: AriPerkkio/eslint-remote-tester-integration-test-target/index.js + Link: https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L1-L1 - > 1 | var foo = bar; - | ^^^ - 2 | - 3 | if (foo) { - 4 | } + > 1 | var foo = bar; + | ^^^ + 2 | + 3 | if (foo) { + 4 | } - Removed: - Rule: no-compare-neg-zero - Message: Do not use the '===' operator to compare against -0. - Path: AriPerkkio/eslint-remote-tester-integration-test-target/index.js - Link: https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L14-L14 + Removed: + Rule: no-compare-neg-zero + Message: Do not use the '===' operator to compare against -0. + Path: AriPerkkio/eslint-remote-tester-integration-test-target/index.js + Link: https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L14-L14 - 12 | - 13 | - > 14 | if (foo === -0) { - | ^^^^^^^^^^ - 15 | // prevent no-empty - 16 | } + 12 | + 13 | + > 14 | if (foo === -0) { + | ^^^^^^^^^^ + 15 | // prevent no-empty + 16 | } - " + " `); }); @@ -836,29 +815,23 @@ test('calls onComplete hook with the comparison results', async () => { await runProductionBuild({ compare: true, CI: true, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ 'no-compare-neg-zero', // Used in initial scan, not in second // 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, }); const { output } = await runProductionBuild({ compare: true, CI: true, + eslintConfig: ESLINT_CONFIG_ALL, rulesUnderTesting: [ // 'no-compare-neg-zero', // Used in initial scan, not in second 'no-undef', // Used in second scan, not in first 'no-empty', // Used in both scans ], - eslintrc: { - root: true, - extends: ['eslint:all'], - }, onComplete: function onComplete(_, comparisonResults) { console.log(`[TEST-ON-COMPLETE-START]`); @@ -888,128 +861,128 @@ test('calls onComplete hook with the comparison results', async () => { .match(/\[TEST-ON-COMPLETE-START\]([\s|\S]*)\[TEST-ON-COMPLETE-END\]/)!; expect(onCompleteCall).toMatchInlineSnapshot(` - "[TEST-ON-COMPLETE-START] - [ADDED] - . - [REPOSITORY] - eslint-remote-tester-integration-test-target - [REPOSITORY] - . - [REPOSITORYOWNER] - AriPerkkio - [REPOSITORYOWNER] - . - [RULE] - no-undef - [RULE] - . - [MESSAGE] - 'window' is not defined. - [MESSAGE] - . - [PATH] - AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js - [PATH] - . - [LINK] - https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/expected-to-crash-linter.js#L2-L2 - [LINK] - . - [EXTENSION] - js - [EXTENSION] - . - [SOURCE] - 1 | // Identifier.name = attributeForCrashing - > 2 | window.attributeForCrashing(); - | ^^^^^^ - 3 | - [SOURCE] - . - [ERROR] - undefined - [ERROR] - . - [REPOSITORY] - eslint-remote-tester-integration-test-target - [REPOSITORY] - . - [REPOSITORYOWNER] - AriPerkkio - [REPOSITORYOWNER] - . - [RULE] - no-undef - [RULE] - . - [MESSAGE] - 'bar' is not defined. - [MESSAGE] - . - [PATH] - AriPerkkio/eslint-remote-tester-integration-test-target/index.js - [PATH] - . - [LINK] - https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L1-L1 - [LINK] - . - [EXTENSION] - js - [EXTENSION] - . - [SOURCE] - > 1 | var foo = bar; - | ^^^ - 2 | - 3 | if (foo) { - 4 | } - [SOURCE] - . - [ERROR] - undefined - [ERROR] - [ADDED] - [REMOVED] - . - [REPOSITORY] - eslint-remote-tester-integration-test-target - [REPOSITORY] - . - [REPOSITORYOWNER] - AriPerkkio - [REPOSITORYOWNER] - . - [RULE] - no-compare-neg-zero - [RULE] - . - [MESSAGE] - Do not use the '===' operator to compare against -0. - [MESSAGE] - . - [PATH] - AriPerkkio/eslint-remote-tester-integration-test-target/index.js - [PATH] - . - [LINK] - https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L14-L14 - [LINK] - . - [EXTENSION] - js - [EXTENSION] - . - [SOURCE] - 12 | - 13 | - > 14 | if (foo === -0) { - | ^^^^^^^^^^ - 15 | // prevent no-empty - 16 | } - [SOURCE] - [REMOVED] - [TEST-ON-COMPLETE-END]" + "[TEST-ON-COMPLETE-START] + [ADDED] + . + [REPOSITORY] + eslint-remote-tester-integration-test-target + [REPOSITORY] + . + [REPOSITORYOWNER] + AriPerkkio + [REPOSITORYOWNER] + . + [RULE] + no-undef + [RULE] + . + [MESSAGE] + 'window' is not defined. + [MESSAGE] + . + [PATH] + AriPerkkio/eslint-remote-tester-integration-test-target/expected-to-crash-linter.js + [PATH] + . + [LINK] + https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/expected-to-crash-linter.js#L2-L2 + [LINK] + . + [EXTENSION] + js + [EXTENSION] + . + [SOURCE] + 1 | // Identifier.name = attributeForCrashing + > 2 | window.attributeForCrashing(); + | ^^^^^^ + 3 | + [SOURCE] + . + [ERROR] + undefined + [ERROR] + . + [REPOSITORY] + eslint-remote-tester-integration-test-target + [REPOSITORY] + . + [REPOSITORYOWNER] + AriPerkkio + [REPOSITORYOWNER] + . + [RULE] + no-undef + [RULE] + . + [MESSAGE] + 'bar' is not defined. + [MESSAGE] + . + [PATH] + AriPerkkio/eslint-remote-tester-integration-test-target/index.js + [PATH] + . + [LINK] + https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L1-L1 + [LINK] + . + [EXTENSION] + js + [EXTENSION] + . + [SOURCE] + > 1 | var foo = bar; + | ^^^ + 2 | + 3 | if (foo) { + 4 | } + [SOURCE] + . + [ERROR] + undefined + [ERROR] + [ADDED] + [REMOVED] + . + [REPOSITORY] + eslint-remote-tester-integration-test-target + [REPOSITORY] + . + [REPOSITORYOWNER] + AriPerkkio + [REPOSITORYOWNER] + . + [RULE] + no-compare-neg-zero + [RULE] + . + [MESSAGE] + Do not use the '===' operator to compare against -0. + [MESSAGE] + . + [PATH] + AriPerkkio/eslint-remote-tester-integration-test-target/index.js + [PATH] + . + [LINK] + https://github.com/AriPerkkio/eslint-remote-tester-integration-test-target/blob/HEAD/index.js#L14-L14 + [LINK] + . + [EXTENSION] + js + [EXTENSION] + . + [SOURCE] + 12 | + 13 | + > 14 | if (foo === -0) { + | ^^^^^^^^^^ + 15 | // prevent no-empty + 16 | } + [SOURCE] + [REMOVED] + [TEST-ON-COMPLETE-END]" `); }); @@ -1017,28 +990,25 @@ test('enables all rules when rulesUnderTesting returns true', async () => { await runProductionBuild({ CI: false, rulesUnderTesting: () => true, - eslintrc: { root: true, extends: ['eslint:all'] }, + eslintConfig: ESLINT_CONFIG_ALL, }); const results = getResults(); const rules = results.match(/Rule: (\S)*/g) || []; expect(rules.join('\n')).toMatchInlineSnapshot(` - "Rule: no-undef - Rule: no-var - Rule: no-implicit-globals - Rule: no-undef - Rule: no-empty - Rule: one-var - Rule: vars-on-top - Rule: no-var - Rule: no-implicit-globals - Rule: id-length - Rule: getter-return - Rule: strict - Rule: capitalized-comments - Rule: no-compare-neg-zero - Rule: no-magic-numbers - Rule: capitalized-comments" + "Rule: no-undef + Rule: no-var + Rule: no-undef + Rule: no-empty + Rule: one-var + Rule: vars-on-top + Rule: no-var + Rule: id-length + Rule: getter-return + Rule: capitalized-comments + Rule: no-compare-neg-zero + Rule: no-magic-numbers + Rule: capitalized-comments" `); }); @@ -1046,16 +1016,17 @@ test('calls rulesUnderTesting filter with ruleId and repository', async () => { const { output } = await runProductionBuild({ CI: false, logLevel: 'verbose', - rulesUnderTesting: (ruleId, options) => { - const { parentPort } = require(`worker_threads`); - - parentPort.postMessage({ - type: `DEBUG`, - payload: `${ruleId} - ${options.repository}`, + rulesUnderTesting: `(ruleId, options) => { + void import('worker_threads').then(w => { + w.parentPort.postMessage({ + type: 'DEBUG', + payload: \`\${ruleId} - \${options.repository}\`, + }); }); + return true; - }, - eslintrc: { root: true, extends: [`eslint:all`] }, + }`, + eslintConfig: ESLINT_CONFIG_ALL, }); const finalLog = output.pop(); @@ -1065,21 +1036,18 @@ test('calls rulesUnderTesting filter with ruleId and repository', async () => { "Full log: no-undef - AriPerkkio/eslint-remote-tester-integration-test-target no-var - AriPerkkio/eslint-remote-tester-integration-test-target - no-implicit-globals - AriPerkkio/eslint-remote-tester-integration-test-target no-undef - AriPerkkio/eslint-remote-tester-integration-test-target no-empty - AriPerkkio/eslint-remote-tester-integration-test-target one-var - AriPerkkio/eslint-remote-tester-integration-test-target vars-on-top - AriPerkkio/eslint-remote-tester-integration-test-target no-var - AriPerkkio/eslint-remote-tester-integration-test-target - no-implicit-globals - AriPerkkio/eslint-remote-tester-integration-test-target id-length - AriPerkkio/eslint-remote-tester-integration-test-target getter-return - AriPerkkio/eslint-remote-tester-integration-test-target - strict - AriPerkkio/eslint-remote-tester-integration-test-target capitalized-comments - AriPerkkio/eslint-remote-tester-integration-test-target no-compare-neg-zero - AriPerkkio/eslint-remote-tester-integration-test-target no-magic-numbers - AriPerkkio/eslint-remote-tester-integration-test-target capitalized-comments - AriPerkkio/eslint-remote-tester-integration-test-target - [ERROR] AriPerkkio/eslint-remote-tester-integration-test-target 16 errors + [ERROR] AriPerkkio/eslint-remote-tester-integration-test-target 13 errors [DONE] Finished scan of 1 repositories [INFO] Cached repositories (1) at ./node_modules/.cache-eslint-remote-tester @@ -1087,42 +1055,44 @@ test('calls rulesUnderTesting filter with ruleId and repository', async () => { `); }); -test('calls eslintrc function with repository and its location', async () => { +test('calls eslingConfig function with repository and its location', async () => { const { output } = await runProductionBuild({ CI: false, logLevel: 'verbose', - eslintrc: options => { - const { parentPort } = require(`worker_threads`); + eslintConfig: `async function init(options) { + const { parentPort } = await import('worker_threads'); if (parentPort) { parentPort.postMessage({ - type: `DEBUG`, - payload: `location: ${options?.location}`, + type: 'DEBUG', + payload: \`location: \${options?.location}\`, }); parentPort.postMessage({ - type: `DEBUG`, - payload: `repository: ${options?.repository}`, + type: 'DEBUG', + payload: \`repository: \${options?.repository}\`, }); } - return { root: true, extends: [`eslint:all`] }; - }, + return []; + }`, }); const finalLog = output.pop(); const withoutTimestamps = finalLog!.replace(DEBUG_LOG_PATTERN, ''); - expect(withoutTimestamps).toMatchInlineSnapshot(` + expect(withoutTimestamps).toMatchInlineSnapshot( + ` "Full log: location: /node_modules/.cache-eslint-remote-tester/AriPerkkio/eslint-remote-tester-integration-test-target repository: AriPerkkio/eslint-remote-tester-integration-test-target - [ERROR] AriPerkkio/eslint-remote-tester-integration-test-target 5 errors + [SUCCESS] AriPerkkio/eslint-remote-tester-integration-test-target [DONE] Finished scan of 1 repositories [INFO] Cached repositories (1) at ./node_modules/.cache-eslint-remote-tester " - `); + ` + ); }); test('loads typescript configuration file', async () => { @@ -1130,8 +1100,9 @@ test('loads typescript configuration file', async () => { { CI: true, rulesUnderTesting: [], - eslintrc: { root: true }, - onComplete: `function onComplete() { + onComplete: `async function onComplete() { + const {readFileSync} = await import('node:fs'); + console.log('[TEST-ON-COMPLETE-START]'); type SomeType = 'a' | 'b' | 'c'; @@ -1141,10 +1112,10 @@ test('loads typescript configuration file', async () => { console.log('config file:'); const index = process.argv.findIndex(a => a === '--config'); const config = process.argv[index + 1]; - console.log(require('fs').readFileSync(config, 'utf8')); + console.log(readFileSync(config, 'utf8')); console.log('[TEST-ON-COMPLETE-END]'); - }` as unknown as Config['onComplete'], + }`, }, undefined, 'ts' @@ -1155,34 +1126,42 @@ test('loads typescript configuration file', async () => { .match(/\[TEST-ON-COMPLETE-START\]([\s|\S]*)\[TEST-ON-COMPLETE-END\]/)!; expect(onCompleteCall).toMatchInlineSnapshot(` - "[TEST-ON-COMPLETE-START] - Value of typed const b - config file: - export default { - "repositories": [ - "AriPerkkio/eslint-remote-tester-integration-test-target" - ], - "extensions": [ - ".js" - ], - "pathIgnorePattern": "(expected-to-be-excluded)", - "rulesUnderTesting": [], - "eslintrc": { - "root": true - }, - "CI": true, - "onComplete": function onComplete() { - console.log('[TEST-ON-COMPLETE-START]'); - type SomeType = 'a' | 'b' | 'c'; - const value: SomeType = 'b'; - console.log('Value of typed const', value); - console.log('config file:'); - const index = process.argv.findIndex(a => a === '--config'); - const config = process.argv[index + 1]; - console.log(require('fs').readFileSync(config, 'utf8')); - console.log('[TEST-ON-COMPLETE-END]'); - } - } - [TEST-ON-COMPLETE-END]" + "[TEST-ON-COMPLETE-START] + Value of typed const b + config file: + export default { + "repositories": [ + "AriPerkkio/eslint-remote-tester-integration-test-target" + ], + "extensions": [ + ".js" + ], + "pathIgnorePattern": "(expected-to-be-excluded)", + "rulesUnderTesting": [], + "eslintConfig": async function initialize() { + const { default: js } = await import('@eslint/js'); + const { FlatCompat } = await import('@eslint/eslintrc'); + const compat = new FlatCompat({ baseDirectory: process.cwd() }); + return [ + js.configs.recommended, + ...compat.plugins('eslint-plugin-local-rules'), + { rules: { 'local-rules/some-unstable-rule': 'error' } }, + ]; + }, + "CI": true, + "onComplete": async function onComplete() { + const {readFileSync} = await import('node:fs'); + console.log('[TEST-ON-COMPLETE-START]'); + type SomeType = 'a' | 'b' | 'c'; + const value: SomeType = 'b'; + console.log('Value of typed const', value); + console.log('config file:'); + const index = process.argv.findIndex(a => a === '--config'); + const config = process.argv[index + 1]; + console.log(readFileSync(config, 'utf8')); + console.log('[TEST-ON-COMPLETE-END]'); + } + } + [TEST-ON-COMPLETE-END]" `); }); diff --git a/packages/eslint-remote-tester/test/smoke/base.config.cjs b/packages/eslint-remote-tester/test/smoke/base.config.cjs deleted file mode 100644 index d9aaa317..00000000 --- a/packages/eslint-remote-tester/test/smoke/base.config.cjs +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - repositories: ['AriPerkkio/eslint-remote-tester-integration-test-target'], - extensions: ['.js'], - rulesUnderTesting: [ - 'local-rules/verbose-rule', - 'local-rules/verbose-rule-2', - ], - eslintrc: { - root: true, - plugins: ['local-rules'], - rules: { - 'local-rules/verbose-rule': 'error', - }, - }, -}; diff --git a/packages/eslint-remote-tester/test/smoke/base.config.js b/packages/eslint-remote-tester/test/smoke/base.config.js new file mode 100644 index 00000000..df049c58 --- /dev/null +++ b/packages/eslint-remote-tester/test/smoke/base.config.js @@ -0,0 +1,20 @@ +/** @type {import('../../src/config/types').Config} */ +const config = { + repositories: ['AriPerkkio/eslint-remote-tester-integration-test-target'], + extensions: ['.js'], + rulesUnderTesting: [ + 'local-rules/verbose-rule', + 'local-rules/verbose-rule-2', + ], + eslintConfig: `async function initialize() { + const { FlatCompat } = await import('@eslint/eslintrc'); + const compat = new FlatCompat({ baseDirectory: process.cwd() }); + + return [ + ...compat.plugins('eslint-plugin-local-rules'), + { rules: { 'local-rules/verbose-rule': 'error' } }, + ]; + }`, +}; + +export default config; diff --git a/packages/eslint-remote-tester/test/smoke/smoke.test.ts b/packages/eslint-remote-tester/test/smoke/smoke.test.ts index 0212f828..91b95bbb 100644 --- a/packages/eslint-remote-tester/test/smoke/smoke.test.ts +++ b/packages/eslint-remote-tester/test/smoke/smoke.test.ts @@ -1,7 +1,7 @@ import { expect, test } from 'vitest'; import { runProductionBuild } from '../utils'; -const BASE_CONFIG = './smoke/base.config.cjs'; +const BASE_CONFIG = './smoke/base.config.js'; test('does not crash when handling 500Mb results', async () => { await runProductionBuild({ CI: false, compare: true }, BASE_CONFIG); @@ -10,13 +10,15 @@ test('does not crash when handling 500Mb results', async () => { { CI: false, compare: true, - eslintrc: { - root: true, - plugins: ['local-rules'], - rules: { - 'local-rules/verbose-rule-2': 'error', - }, - }, + eslintConfig: `async function initialize() { + const { FlatCompat } = await import('@eslint/eslintrc'); + const compat = new FlatCompat({ baseDirectory: process.cwd() }); + + return [ + ...compat.plugins('eslint-plugin-local-rules'), + { rules: { 'local-rules/verbose-rule-2': 'error' } }, + ]; + }` as any, }, BASE_CONFIG ); diff --git a/packages/eslint-remote-tester/test/utils.ts b/packages/eslint-remote-tester/test/utils.ts index 892de5ef..beaf7485 100644 --- a/packages/eslint-remote-tester/test/utils.ts +++ b/packages/eslint-remote-tester/test/utils.ts @@ -11,12 +11,19 @@ import { import { ComparisonTypes } from '../src/file-client/result-templates'; import { removeDirectorySync } from '../src/file-client/file-utils'; import { Config, ConfigToValidate } from '../src/config/types'; -import { createRequire } from 'node:module'; import { resolve } from 'node:path'; declare const console: { log: Mock; error: (...args: any) => void }; -const require = createRequire(import.meta.url); +type TestConfig = Omit< + ConfigToValidate, + 'eslintConfig' | 'rulesUnderTesting' | 'onComplete' +> & { + eslintConfig?: ConfigToValidate['eslintConfig'] | string | []; + rulesUnderTesting?: ConfigToValidate['rulesUnderTesting'] | string; + onComplete?: ConfigToValidate['onComplete'] | string; +}; + export const INTEGRATION_REPO_OWNER = 'AriPerkkio'; export const INTEGRATION_REPO_NAME = 'eslint-remote-tester-integration-test-target'; @@ -25,24 +32,25 @@ export const REPOSITORY_CACHE = `${CACHE_LOCATION}/${INTEGRATION_REPO_OWNER}/${I const LAST_RENDER_PATTERN = /(Results|Full log)[\s|\S]*/; const COMPARISON_RESULTS_PATTERN = /(Comparison results:[\s|\S]*)Results/; const ON_COMPLETE_PATTERN = /("onComplete": )"([\s|\S]*)"/; -const RULES_UNDER_TESTING_PATTERN = /("rulesUnderTesting": )"([\s|\S]*)",/; -const ESLINTRC_PATTERN = /("eslintrc": )"([\s|\S]*)",/; +const RULES_UNDER_TESTING_PATTERN = /("rulesUnderTesting": )"([^"]*)"/; +const ESLINT_CONFIG_PATTERN = /("eslintConfig": )"([^"]*)"/; const ESCAPED_NEWLINE_PATTERN = /\\n/g; +const ESCAPED_QUOTE_PATTERN = /\\"/g; let idCounter = 0; /** * Create temporary configuration file for integration test */ -function createConfiguration( - options: ConfigToValidate, - baseConfigPath = './integration/base.config.cjs', - fileExtension: 'cjs' | 'ts' -): { name: string; cleanup: () => void } { +async function createConfiguration( + options: TestConfig, + baseConfigPath = './integration/base.config.js', + fileExtension: 'js' | 'ts' +): Promise<{ name: string; cleanup: () => void }> { const name = `./test/integration/integration.config-${idCounter++}.${fileExtension}`; - const baseConfig: Config = require(baseConfigPath); - const config = { ...baseConfig, ...options }; + const { default: baseConfig } = await import(baseConfigPath); + const config: Config = { ...baseConfig, ...options }; // Passing function to config file is tricky // - Add it as string to JSON @@ -53,20 +61,21 @@ function createConfiguration( if (typeof options.rulesUnderTesting === 'function') { config.rulesUnderTesting = options.rulesUnderTesting.toString() as any; } - if (typeof options.eslintrc === 'function') { - config.eslintrc = options.eslintrc.toString() as any; + if (typeof options.eslintConfig === 'function') { + config.eslintConfig = options.eslintConfig.toString() as any; + } + if (typeof config.eslintConfig === 'function') { + config.eslintConfig = config.eslintConfig.toString() as any; } const configText = JSON.stringify(config, null, 4) .replace(ON_COMPLETE_PATTERN, '$1$2') - .replace(RULES_UNDER_TESTING_PATTERN, '$1$2,') - .replace(ESLINTRC_PATTERN, '$1$2,') - .replace(ESCAPED_NEWLINE_PATTERN, '\n'); - - const configExport = - fileExtension === 'ts' ? 'export default' : 'module.exports='; + .replace(RULES_UNDER_TESTING_PATTERN, '$1$2') + .replace(ESLINT_CONFIG_PATTERN, '$1$2') + .replace(ESCAPED_NEWLINE_PATTERN, '\n') + .replace(ESCAPED_QUOTE_PATTERN, '"'); - fs.writeFileSync(name, `${configExport} ${configText}`, 'utf8'); + fs.writeFileSync(name, `export default ${configText}`, 'utf8'); return { name, cleanup: () => fs.unlinkSync(name) }; } @@ -75,11 +84,11 @@ function createConfiguration( * Spawn terminal and run the actual production build on it */ export async function runProductionBuild( - options: ConfigToValidate = {}, + options: TestConfig = {}, baseConfigPath?: string, - fileExtension: 'cjs' | 'ts' = 'cjs' + fileExtension: 'js' | 'ts' = 'js' ): Promise<{ output: string[]; exitCode: number }> { - const { name, cleanup } = createConfiguration( + const { name, cleanup } = await createConfiguration( options, baseConfigPath, fileExtension @@ -111,6 +120,10 @@ export async function runProductionBuild( const parsedOutput = parsePtyOutput(output); + if (parsedOutput.find(line => line.includes('Node.js v'))) { + reject(new Error(stripAnsi(output.join('\n')))); + } + // Identify any 'failed to' messages - these are not expected during // testing but can happen due to unstable network etc. const failureSteps = parsedOutput diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 140450c3..b1e164d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,15 +20,12 @@ importers: eslint-config-prettier: specifier: ^9.1.0 version: 9.1.0(eslint@9.3.0) - eslint-plugin-local-rules: - specifier: ^2.0.1 - version: 2.0.1 eslint-plugin-prettier: specifier: ^5.1.3 version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@9.3.0)(prettier@3.2.5) pkg-pr-new: - specifier: ^0.0.5 - version: 0.0.5 + specifier: ^0.0.8 + version: 0.0.8 prettier: specifier: ^3.2.5 version: 3.2.5 @@ -66,6 +63,9 @@ importers: specifier: ^3.24.0 version: 3.24.0 devDependencies: + '@eslint/eslintrc': + specifier: ^3.1.0 + version: 3.1.0 '@types/babel__code-frame': specifier: ^7.0.6 version: 7.0.6 @@ -81,33 +81,33 @@ importers: '@types/react': specifier: ^17.0.80 version: 17.0.80 - '@typescript-eslint/eslint-plugin': - specifier: ^7.11.0 - version: 7.11.0(@typescript-eslint/parser@7.11.0)(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': - specifier: ^7.11.0 - version: 7.11.0(eslint@8.57.0)(typescript@5.4.5) conventional-changelog-cli: specifier: ^5.0.0 version: 5.0.0 eslint: - specifier: ^8.57.0 - version: 8.57.0 + specifier: ^9.3.0 + version: 9.3.0 + eslint-plugin-local-rules: + specifier: ^2.0.1 + version: 2.0.1 eslint-remote-tester-repositories: specifier: workspace:* version: link:../repositories + importx: + specifier: ^0.3.5 + version: 0.3.5 ink-testing-library: specifier: ^2.1.0 version: 2.1.0(@types/react@17.0.80) + jiti: + specifier: ^1.21.3 + version: 1.21.3 node-pty: specifier: ^1.0.0 version: 1.0.0 strip-ansi: specifier: ^6.0.1 version: 6.0.1 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) typescript: specifier: ^5.4.5 version: 5.4.5 @@ -392,16 +392,6 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.57.0 - eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@9.3.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -417,23 +407,6 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.4: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - /@eslint/eslintrc@3.1.0: resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -451,27 +424,11 @@ packages: - supports-color dev: true - /@eslint/js@8.57.0: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - /@eslint/js@9.3.0: resolution: {integrity: sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true - /@humanwhocodes/config-array@0.11.14: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - /@humanwhocodes/config-array@0.13.0: resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -896,33 +853,6 @@ packages: resolution: {integrity: sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==} dev: false - /@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0)(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.11.0 - '@typescript-eslint/type-utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.11.0 - eslint: 8.57.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/eslint-plugin@7.11.0(@typescript-eslint/parser@7.11.0)(eslint@9.3.0)(typescript@5.4.5): resolution: {integrity: sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==} engines: {node: ^18.18.0 || >=20.0.0} @@ -950,27 +880,6 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@7.11.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 7.11.0 - '@typescript-eslint/types': 7.11.0 - '@typescript-eslint/typescript-estree': 7.11.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.11.0 - debug: 4.3.4 - eslint: 8.57.0 - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/parser@7.11.0(eslint@9.3.0)(typescript@5.4.5): resolution: {integrity: sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1000,26 +909,6 @@ packages: '@typescript-eslint/visitor-keys': 7.11.0 dev: true - /@typescript-eslint/type-utils@7.11.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 7.11.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.11.0(eslint@8.57.0)(typescript@5.4.5) - debug: 4.3.4 - eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/type-utils@7.11.0(eslint@9.3.0)(typescript@5.4.5): resolution: {integrity: sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1067,22 +956,6 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@7.11.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.11.0 - '@typescript-eslint/types': 7.11.0 - '@typescript-eslint/typescript-estree': 7.11.0(typescript@5.4.5) - eslint: 8.57.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /@typescript-eslint/utils@7.11.0(eslint@9.3.0)(typescript@5.4.5): resolution: {integrity: sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1107,10 +980,6 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true - /@vitest/expect@1.6.0: resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} dependencies: @@ -1294,6 +1163,16 @@ packages: fill-range: 7.0.1 dev: true + /bundle-require@4.2.1(esbuild@0.20.2): + resolution: {integrity: sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + dependencies: + esbuild: 0.20.2 + load-tsconfig: 0.2.5 + dev: true + /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -1595,6 +1474,18 @@ packages: dependencies: ms: 2.1.2 + /debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + /decode-uri-component@0.4.1: resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==} engines: {node: '>=14.16'} @@ -1637,13 +1528,6 @@ packages: path-type: 4.0.0 dev: true - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - /dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -1734,14 +1618,6 @@ packages: synckit: 0.8.8 dev: true - /eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true - /eslint-scope@8.0.1: resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1760,53 +1636,6 @@ packages: engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true - /eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.1 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - /eslint@9.3.0: resolution: {integrity: sha512-5Iv4CsZW030lpUqHBapdPo3MJetAPtejVW8B84GIcIIv8+ohFaddXsrn1Gn8uD9ijDb+kcYKFUVmC8qG8B2ORQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1859,15 +1688,6 @@ packages: eslint-visitor-keys: 4.0.0 dev: true - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - dev: true - /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -1946,13 +1766,6 @@ packages: reusify: 1.0.4 dev: true - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.2.0 - dev: true - /file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -1985,15 +1798,6 @@ packages: path-exists: 4.0.0 dev: true - /flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.3.1 - keyv: 4.5.4 - rimraf: 3.0.2 - dev: true - /flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -2040,6 +1844,12 @@ packages: engines: {node: '>=16'} dev: true + /get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + /git-raw-commits@5.0.0(conventional-commits-parser@6.0.0): resolution: {integrity: sha512-I2ZXrXeOc0KrCvC7swqtIFXFN+rbjnC7b2T943tvemIOVNl+XP8YnA9UVwqFhzzLClnSA60KR/qEjLpXzs73Qg==} engines: {node: '>=18'} @@ -2078,18 +1888,6 @@ packages: is-glob: 4.0.3 dev: true - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - /glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} @@ -2102,13 +1900,6 @@ packages: once: 1.4.0 dev: true - /globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true - /globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -2190,6 +1981,20 @@ packages: resolve-from: 4.0.0 dev: true + /importx@0.3.5: + resolution: {integrity: sha512-YkIUWkeNX/sxxU6lVTxhqQH0e63iH97gZic6B+a3GgOlox7GMpJEbgu1alyEf6hU55uN+1qFXBLOzDhGlZ1Mfw==} + dependencies: + bundle-require: 4.2.1(esbuild@0.20.2) + debug: 4.3.5 + esbuild: 0.20.2 + jiti: 1.21.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + tsx: 4.14.0 + transitivePeerDependencies: + - supports-color + dev: true + /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -2326,10 +2131,20 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /isbinaryfile@5.0.2: + resolution: {integrity: sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==} + engines: {node: '>= 18.0.0'} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /jiti@1.21.3: + resolution: {integrity: sha512-uy2bNX5zQ+tESe+TiC7ilGRz8AtRGmnJH55NC5S0nSUjvvvM2hJHmefHErugGXN4pNv4Qx7vLsnNw9qJ9mtIsw==} + hasBin: true + dev: true + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2375,6 +2190,11 @@ packages: type-check: 0.4.0 dev: true + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /local-pkg@0.5.0: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} @@ -2687,11 +2507,6 @@ packages: engines: {node: '>=8'} dev: true - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2727,13 +2542,16 @@ packages: engines: {node: '>=8.6'} dev: true - /pkg-pr-new@0.0.5: - resolution: {integrity: sha512-DYt+sJ0juHWpRMuR5jmL3kmlBYFpNj/67dMOW5ZNXh8P6xShvzy3kVnd2ZvAEno/S3lwAhvA61M1+PUQdkRadw==} + /pkg-pr-new@0.0.8: + resolution: {integrity: sha512-yvpAQKGp8F2XIVY/USxd53lYjfF4UynWskFl4roL36UNdmbRlTV85sIlNXAs+6HY7hOZqqGmKXbDml+sEYKj3A==} hasBin: true dependencies: '@jsdevtools/ez-spawn': 3.0.4 '@octokit/action': 6.1.0 fast-glob: 3.3.2 + ignore: 5.3.1 + isbinaryfile: 5.0.2 + pkg-types: 1.1.1 query-registry: 3.0.0 dev: true @@ -2904,6 +2722,10 @@ packages: engines: {node: '>=4'} dev: true + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + /restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -2917,13 +2739,6 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - /rollup@4.17.2: resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -3238,6 +3053,17 @@ packages: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: true + /tsx@4.14.0: + resolution: {integrity: sha512-DsDLlJlusAPyCnz07S4y0gqJoUl8GciBeYcXQd75/5DqkZ4gfjKpvAUFUzmZf62nEotkcqC7JCWrdL8d+PXSng==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.20.2 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + dev: true + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3255,11 +3081,6 @@ packages: engines: {node: '>=10'} dev: false - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true - /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'}