Skip to content

Commit 60312ee

Browse files
SukkaWCopilot
andauthored
chore: prepare for ESLint 10 more (#458)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1da4043 commit 60312ee

14 files changed

Lines changed: 1984 additions & 1682 deletions

‎.changeset/hungry-owls-start.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-import-x": patch
3+
---
4+
5+
Bump peer deps version range to include ESLint 10 support

‎.github/workflows/ci.yml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ jobs:
2121
- 18
2222
- 20
2323
- 22
24-
# https://github.com/nodejs/node/issues/59480
25-
- 24.5
24+
- 24
2625
eslint:
2726
- 8.56
2827
- 8
2928
- 9
29+
- 10
3030

3131
include:
3232
- executeLint: true
@@ -37,6 +37,9 @@ jobs:
3737
node: lts/*
3838
eslint: 9
3939
os: ubuntu-latest
40+
exclude:
41+
- eslint: 10
42+
node: 18 # ESLint 10 drops Node.js 18 support
4043
fail-fast: false
4144

4245
runs-on: ${{ matrix.os }}
@@ -49,6 +52,7 @@ jobs:
4952
with:
5053
node-version: ${{ matrix.node }}
5154
cache: yarn
55+
check-latest: true
5256

5357
- name: Install ESLint ${{ matrix.eslint }}
5458
if: ${{ matrix.eslint != 9 }}

‎package.json‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@
6262
"watch": "yarn test --watch"
6363
},
6464
"peerDependencies": {
65-
"@typescript-eslint/utils": "^8.0.0",
66-
"eslint": "^8.57.0 || ^9.0.0",
65+
"@typescript-eslint/utils": "^8.56.0",
66+
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
6767
"eslint-import-resolver-node": "*"
6868
},
6969
"peerDependenciesMeta": {
@@ -76,7 +76,7 @@
7676
},
7777
"dependencies": {
7878
"@package-json/types": "^0.0.12",
79-
"@typescript-eslint/types": "^8.35.0",
79+
"@typescript-eslint/types": "^8.56.0",
8080
"comment-parser": "^1.4.1",
8181
"debug": "^4.4.1",
8282
"eslint-import-context": "^0.1.9",
@@ -93,9 +93,9 @@
9393
"@1stg/remark-preset": "^3.1.2",
9494
"@1stg/simple-git-hooks": "^2.1.0",
9595
"@1stg/tsconfig": "^3.0.3",
96-
"@angular-eslint/template-parser": "^20.1.1",
96+
"@angular-eslint/template-parser": "^21.3.0",
9797
"@babel/core": "^7.27.4",
98-
"@babel/eslint-parser": "^7.27.5",
98+
"@babel/eslint-parser": "^7.28.6",
9999
"@babel/plugin-proposal-decorators": "^7.27.1",
100100
"@babel/plugin-proposal-export-default-from": "^7.27.1",
101101
"@babel/preset-env": "^7.27.2",
@@ -123,11 +123,12 @@
123123
"@types/node": "^22.15.33",
124124
"@types/pnpapi": "^0.0.5",
125125
"@types/tmp": "^0.2.6",
126-
"@typescript-eslint/eslint-plugin": "^8.35.0",
127-
"@typescript-eslint/parser": "^8.35.0",
128-
"@typescript-eslint/rule-tester": "^8.35.0",
129-
"@typescript-eslint/utils": "^8.35.0",
126+
"@typescript-eslint/eslint-plugin": "^8.56.0",
127+
"@typescript-eslint/parser": "^8.56.0",
128+
"@typescript-eslint/rule-tester": "^8.56.0",
129+
"@typescript-eslint/utils": "^8.56.0",
130130
"@unts/patch-package": "^8.1.1",
131+
"babel-eslint-parser-8-cjs": "^0.0.1-babel-8-0-0-rc-2",
131132
"clean-pkg-json": "^1.3.0",
132133
"eslint": "^9.29.0",
133134
"eslint-config-prettier": "^10.1.5",
@@ -144,10 +145,11 @@
144145
"eslint-plugin-prettier": "^5.5.1",
145146
"eslint-plugin-unicorn": "^59.0.1",
146147
"eslint-plugin-yml": "^1.18.0",
148+
"eslint10": "npm:eslint@^10.0.1",
147149
"eslint8.56": "npm:eslint@~8.56.0",
148150
"eslint9": "npm:eslint@^9.28.0",
149151
"globals": "^16.2.0",
150-
"hermes-eslint": "^0.29.0",
152+
"hermes-eslint": "^0.33.3",
151153
"jest": "^30.0.3",
152154
"klaw-sync": "^7.0.0",
153155
"nano-staged": "^0.8.0",
@@ -162,11 +164,11 @@
162164
"ts-node": "^10.9.2",
163165
"tsdown": "^0.12.9",
164166
"typescript": "^5.8.3",
165-
"typescript-eslint": "^8.35.0",
167+
"typescript-eslint": "^8.56.0",
166168
"yarn-berry-deduplicate": "^6.1.3"
167169
},
168170
"resolutions": {
169-
"@typescript-eslint/utils": "^8.34.0",
171+
"@typescript-eslint/utils": "^8.56.0",
170172
"prettier": "^3.5.3"
171173
},
172174
"eslintIgnore": [

‎src/utils/apply-default.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ export function applyDefault<
1212
User extends readonly unknown[],
1313
Default extends User,
1414
>(
15-
defaultOptions: Readonly<Default>,
15+
defaultOptions: Readonly<Default> | undefined,
1616
userOptions: Readonly<User> | null,
1717
): Default {
1818
// clone defaults
19-
const options = structuredClone(defaultOptions) as AsMutable<Default>
19+
const options = structuredClone(defaultOptions ?? []) as AsMutable<Default>
2020

2121
if (userOptions == null) {
2222
return options

‎test/cli.spec.ts‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import path from 'node:path'
44
import { fileURLToPath } from 'node:url'
55

66
// eslint-disable-next-line import-x/default -- incorrect types , commonjs actually
7-
import eslintUnsupportedApi from 'eslint/use-at-your-own-risk'
7+
import eslintUnsupportedApi from 'eslint9/use-at-your-own-risk'
88

9-
import importPlugin from 'eslint-plugin-import-x'
9+
import { isESLint10 } from './utils.js'
1010

11-
// eslint-disable-next-line import-x/no-named-as-default-member -- incorrect types , commonjs actually
12-
const { LegacyESLint } = eslintUnsupportedApi
11+
import importPlugin from 'eslint-plugin-import-x'
12+
;(isESLint10 ? describe.skip : describe)('CLI regression tests', () => {
13+
// eslint-disable-next-line import-x/no-named-as-default-member -- incorrect types , commonjs actually
14+
const { LegacyESLint } = eslintUnsupportedApi
1315

14-
describe('CLI regression tests', () => {
1516
const testDir = path.resolve(fileURLToPath(import.meta.url), '..')
1617

1718
describe('issue #210', () => {

‎test/fixtures/.eslintrc.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ const supportsArbitraryModuleNamespaceIdentifierNames = semver.satisfies(
55
eslintPkg.version,
66
'>= 8.7',
77
)
8+
const isESLint10 = semver.satisfies(eslintPkg.version, '>=10')
89

910
const config = {
1011
root: true,
11-
parser: '@babel/eslint-parser',
12+
parser: isESLint10 ? 'babel-eslint-parser-8-cjs' : '@babel/eslint-parser',
1213
parserOptions: {
1314
sourceType: 'module',
1415
ecmaVersion: 8,

‎test/rules/consistent-type-specifier-style.spec.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { RuleTester as TSESLintRuleTester } from '@typescript-eslint/rule-tester'
22
import { AST_NODE_TYPES } from '@typescript-eslint/utils'
33

4-
import { parsers, createRuleTestCaseFunctions } from '../utils.js'
4+
import { parsers, createRuleTestCaseFunctions, isESLint10 } from '../utils.js'
55
import type { RuleRunTests } from '../utils.js'
66

77
import { cjsRequire } from 'eslint-plugin-import-x'
@@ -406,7 +406,8 @@ describe('TypeScript', () => {
406406
})
407407
})
408408

409-
describe('Babel/Flow', () => {
409+
// TODO: babel 8 appears to remove import typeof support
410+
;(isESLint10 ? describe.skip : describe)('Babel/Flow', () => {
410411
const ruleTester = new TSESLintRuleTester({
411412
languageOptions: {
412413
parser: cjsRequire(parsers.BABEL),
@@ -428,7 +429,8 @@ describe('Babel/Flow', () => {
428429
})
429430
})
430431

431-
describe('Hermes/Flow', () => {
432+
// TODO: hermes-eslint doesn't support ESLint 10 yet
433+
;(isESLint10 ? describe.skip : describe)('Hermes/Flow', () => {
432434
const ruleTester = new TSESLintRuleTester({
433435
languageOptions: {
434436
parser: cjsRequire(parsers.HERMES),

‎test/rules/group-exports.spec.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { RuleTester as TSESLintRuleTester } from '@typescript-eslint/rule-tester'
22

3-
import { createRuleTestCaseFunctions, parsers } from '../utils.js'
3+
import { createRuleTestCaseFunctions, isESLint10, parsers } from '../utils.js'
44

55
import { cjsRequire } from 'eslint-plugin-import-x'
66
import rule from 'eslint-plugin-import-x/rules/group-exports'
@@ -13,7 +13,7 @@ const ruleTester = new TSESLintRuleTester({
1313
babelOptions: {
1414
configFile: false,
1515
babelrc: false,
16-
presets: ['@babel/flow'],
16+
presets: ['@babel/preset-flow'],
1717
},
1818
},
1919
},
@@ -153,6 +153,7 @@ ruleTester.run('group-exports', rule, {
153153
`,
154154
}),
155155
tValid({
156+
skip: isESLint10,
156157
code: `
157158
type firstType = {
158159
propType: string
@@ -163,6 +164,7 @@ ruleTester.run('group-exports', rule, {
163164
`,
164165
}),
165166
tValid({
167+
skip: isESLint10,
166168
code: `
167169
type firstType = {
168170
propType: string
@@ -174,6 +176,7 @@ ruleTester.run('group-exports', rule, {
174176
`,
175177
}),
176178
tValid({
179+
skip: isESLint10,
177180
code: `
178181
export type { type1A, type1B } from './module-1'
179182
export { method1 } from './module-1'
@@ -308,6 +311,7 @@ ruleTester.run('group-exports', rule, {
308311
],
309312
}),
310313
tInvalid({
314+
skip: isESLint10,
311315
code: `
312316
type firstType = {
313317
propType: string
@@ -326,6 +330,7 @@ ruleTester.run('group-exports', rule, {
326330
],
327331
}),
328332
tInvalid({
333+
skip: isESLint10,
329334
code: `
330335
export type { type1 } from './module-1'
331336
export type { type2 } from './module-1'

‎test/rules/no-empty-named-blocks.spec.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,11 @@ ruleTester.run('no-empty-named-blocks', rule, {
5050
tValid({
5151
code: `import type { Named } from 'mod';`,
5252
}),
53+
5354
tValid({
5455
code: `import type Default, { Named } from 'mod';`,
56+
// TS Parse Error: A type-only import can specify a default import or named bindings, but not both.
57+
languageOptions: { parser: require(parsers.BABEL) },
5558
}),
5659
tValid({
5760
code: `import type * as Namespace from 'mod';`,
@@ -113,6 +116,9 @@ ruleTester.run('no-empty-named-blocks', rule, {
113116
code: `import type Default, {} from 'mod';`,
114117
output: `import type Default from 'mod';`,
115118

119+
// TS Parse Error: A type-only import can specify a default import or named bindings, but not both.
120+
languageOptions: { parser: require(parsers.BABEL) },
121+
116122
errors: [{ messageId: 'emptyNamed' }],
117123
}),
118124

0 commit comments

Comments
 (0)