Skip to content

Commit c940785

Browse files
authored
test: test import-x and flat config support correctly (#370)
* test: test import-x/flat config support correctly * fix: support multiple matching ts paths
1 parent c4c99b4 commit c940785

File tree

7 files changed

+110
-66
lines changed

7 files changed

+110
-66
lines changed

.changeset/beige-gorillas-hunt.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-import-resolver-typescript": patch
3+
---
4+
5+
fix: support multiple matching ts paths

.eslintrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"node": true
55
},
66
"parserOptions": {
7-
"ecmaVersion": "latest"
7+
"ecmaVersion": "latest",
8+
"sourceType": "module"
89
},
910
"extends": [
1011
"plugin:prettier/recommended",

.nvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18.20.6
1+
18.20.7

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"test:dotInclude": "eslint --ext ts,tsx tests/dotInclude --ignore-pattern \"!.dot\"",
5555
"test:dotPaths": "eslint --ext ts,tsx tests/dotPaths --ignore-pattern \"!.dot\"",
5656
"test:dotProject": "eslint --ext ts,tsx tests/dotProject --ignore-pattern \"!.dot\"",
57-
"test:importXResolverV3": "eslint --config=tests/importXResolverV3/eslint.config.js tests/importXResolverV3",
57+
"test:importXResolverV3": "cross-env ESLINT_USE_FLAT_CONFIG=true eslint --config=tests/importXResolverV3/eslint.config.js tests/importXResolverV3",
5858
"test:multipleEslintrcs": "eslint --ext ts,tsx tests/multipleEslintrcs",
5959
"test:multipleTsconfigs": "eslint --ext ts,tsx tests/multipleTsconfigs",
6060
"test:withJsExtension": "node tests/withJsExtension/test.js && eslint --ext ts,tsx tests/withJsExtension",
@@ -98,6 +98,7 @@
9898
"@types/debug": "^4.1.12",
9999
"@types/node": "^18.19.78",
100100
"@types/unist": "^2.0.11",
101+
"cross-env": "^7.0.3",
101102
"dummy.js": "link:dummy.js",
102103
"eslint": "^8.57.1",
103104
"eslint-import-resolver-typescript": "link:.",
@@ -111,7 +112,7 @@
111112
"size-limit": "^11.0.0",
112113
"size-limit-preset-node-lib": "^0.3.0",
113114
"type-coverage": "^2.27.0",
114-
"typescript": "^5.3.2"
115+
"typescript": "~5.1.0"
115116
},
116117
"resolutions": {
117118
"eslint-import-resolver-typescript": "link:.",

src/index.ts

+38-29
Original file line numberDiff line numberDiff line change
@@ -181,22 +181,30 @@ export function resolve(
181181

182182
initMappers(cachedOptions)
183183

184-
const mappedPath = getMappedPath(source, file, cachedOptions.extensions, true)
185-
if (mappedPath) {
186-
log('matched ts path:', mappedPath)
184+
let mappedPaths = getMappedPaths(source, file, cachedOptions.extensions, true)
185+
186+
if (mappedPaths.length > 0) {
187+
log('matched ts path:', ...mappedPaths)
188+
} else {
189+
mappedPaths = [source]
187190
}
188191

189192
// note that even if we map the path, we still need to do a final resolve
190-
let foundNodePath: string | null
191-
try {
192-
foundNodePath =
193-
resolver.resolveSync(
193+
let foundNodePath: string | undefined
194+
for (const mappedPath of mappedPaths) {
195+
try {
196+
const resolved = resolver.resolveSync(
194197
{},
195198
path.dirname(path.resolve(file)),
196-
mappedPath ?? source,
197-
) || null
198-
} catch {
199-
foundNodePath = null
199+
mappedPath,
200+
)
201+
if (resolved) {
202+
foundNodePath = resolved
203+
break
204+
}
205+
} catch {
206+
log('failed to resolve with', mappedPath)
207+
}
200208
}
201209

202210
// naive attempt at `@types/*` resolution,
@@ -286,16 +294,16 @@ const isModule = (modulePath?: string | undefined): modulePath is string => {
286294
* @returns The mapped path of the module or undefined
287295
*/
288296
// eslint-disable-next-line sonarjs/cognitive-complexity
289-
function getMappedPath(
297+
function getMappedPaths(
290298
source: string,
291299
file: string,
292300
extensions: string[] = defaultExtensions,
293301
retry?: boolean,
294-
): string | undefined {
302+
): string[] {
295303
const originalExtensions = extensions
296304
extensions = ['', ...extensions]
297305

298-
let paths: Array<string | undefined> | undefined = []
306+
let paths: string[] = []
299307

300308
if (RELATIVE_PATH_PATTERN.test(source)) {
301309
const resolved = path.resolve(path.dirname(file), source)
@@ -341,34 +349,35 @@ function getMappedPath(
341349
const tsExt = jsExt.replace('js', 'ts')
342350
const basename = source.replace(JS_EXT_PATTERN, '')
343351

344-
const resolved =
345-
getMappedPath(basename + tsExt, file) ||
346-
getMappedPath(
347-
basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt),
348-
file,
349-
)
352+
const mappedPaths = getMappedPaths(basename + tsExt, file)
350353

351-
if (resolved) {
354+
const resolved =
355+
mappedPaths.length > 0
356+
? mappedPaths
357+
: getMappedPaths(
358+
basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt),
359+
file,
360+
)
361+
362+
if (resolved.length > 0) {
352363
return resolved
353364
}
354365
}
355366

356367
for (const ext of extensions) {
368+
const mappedPaths = isJs ? [] : getMappedPaths(source + ext, file)
357369
const resolved =
358-
(isJs ? null : getMappedPath(source + ext, file)) ||
359-
getMappedPath(source + `/index${ext}`, file)
370+
mappedPaths.length > 0
371+
? mappedPaths
372+
: getMappedPaths(source + `/index${ext}`, file)
360373

361-
if (resolved) {
374+
if (resolved.length > 0) {
362375
return resolved
363376
}
364377
}
365378
}
366379

367-
if (paths.length > 1) {
368-
log('found multiple matching ts paths:', paths)
369-
}
370-
371-
return paths[0]
380+
return paths
372381
}
373382

374383
// eslint-disable-next-line sonarjs/cognitive-complexity
+24-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
const path = require('path')
2-
const { createTypeScriptImportResolver } = require('../../lib/index.cjs')
2+
const importX = require('eslint-plugin-import-x')
3+
4+
const { createTypeScriptImportResolver } = require('../..')
35

46
const globPattern = './packages/*/tsconfig.json'
57

68
// in normal cases this is not needed because the __dirname would be the root
79
const absoluteGlobPath = path.join(__dirname, globPattern)
810

9-
module.exports = {
10-
...require('eslint-plugin-import-x').flatConfigs.typescript,
11-
settings: {
12-
...require('eslint-plugin-import-x').flatConfigs.typescript.settings,
13-
'import-x/resolver-next': [
14-
createTypeScriptImportResolver({
15-
project: absoluteGlobPath,
16-
alwaysTryTypes: true,
17-
}),
18-
],
19-
},
20-
}
11+
const base = require('../baseEslintConfig.cjs')()
12+
13+
module.exports =
14+
// don't run on node 16 because lacking of `structuredClone`
15+
+process.versions.node.split('.')[0] <= 16
16+
? {}
17+
: {
18+
files: ['**/*.ts', '**/*.tsx'],
19+
plugins: {
20+
import: importX,
21+
},
22+
settings: {
23+
...importX.flatConfigs.typescript.settings,
24+
'import-x/resolver-next': [
25+
createTypeScriptImportResolver({
26+
project: absoluteGlobPath,
27+
}),
28+
],
29+
},
30+
rules: base.rules,
31+
}

yarn.lock

+37-20
Original file line numberDiff line numberDiff line change
@@ -2268,14 +2268,7 @@ __metadata:
22682268
languageName: node
22692269
linkType: hard
22702270

2271-
"@changesets/types@npm:^6.0.0":
2272-
version: 6.0.0
2273-
resolution: "@changesets/types@npm:6.0.0"
2274-
checksum: 214c58ff3e3da019c578b94815ec6748729a38b665d950acddf53f3a23073ac7a57dce45812c4bec0cbcd6902c84a482c804457d4c903602005b2399de8a4021
2275-
languageName: node
2276-
linkType: hard
2277-
2278-
"@changesets/types@npm:^6.1.0":
2271+
"@changesets/types@npm:^6.0.0, @changesets/types@npm:^6.1.0":
22792272
version: 6.1.0
22802273
resolution: "@changesets/types@npm:6.1.0"
22812274
checksum: 2dcd00712cb85d0c53afdd8d0e856b4bf9c0ce8dc36c838c918d44799aacd9ba8659b9ff610ff92b94fc03c8fd2b52c5b05418fcf8a1bd138cd9182414ede373
@@ -3731,16 +3724,7 @@ __metadata:
37313724
languageName: node
37323725
linkType: hard
37333726

3734-
"@types/node@npm:^18.0.0":
3735-
version: 18.19.74
3736-
resolution: "@types/node@npm:18.19.74"
3737-
dependencies:
3738-
undici-types: "npm:~5.26.4"
3739-
checksum: 2306bd0b41cdd528b890b210b96f287a5b5035c128f62636057d6616bd612b3f53d32d77f7e76ef41a9f130ea691e6980e6d5942dd625df05d3a641764fddb78
3740-
languageName: node
3741-
linkType: hard
3742-
3743-
"@types/node@npm:^18.19.78":
3727+
"@types/node@npm:^18.0.0, @types/node@npm:^18.19.78":
37443728
version: 18.19.78
37453729
resolution: "@types/node@npm:18.19.78"
37463730
dependencies:
@@ -5373,6 +5357,18 @@ __metadata:
53735357
languageName: node
53745358
linkType: hard
53755359

5360+
"cross-env@npm:^7.0.3":
5361+
version: 7.0.3
5362+
resolution: "cross-env@npm:7.0.3"
5363+
dependencies:
5364+
cross-spawn: "npm:^7.0.1"
5365+
bin:
5366+
cross-env: src/bin/cross-env.js
5367+
cross-env-shell: src/bin/cross-env-shell.js
5368+
checksum: e99911f0d31c20e990fd92d6fd001f4b01668a303221227cc5cb42ed155f086351b1b3bd2699b200e527ab13011b032801f8ce638e6f09f854bdf744095e604c
5369+
languageName: node
5370+
linkType: hard
5371+
53765372
"cross-spawn@npm:^6.0.5":
53775373
version: 6.0.5
53785374
resolution: "cross-spawn@npm:6.0.5"
@@ -5386,7 +5382,7 @@ __metadata:
53865382
languageName: node
53875383
linkType: hard
53885384

5389-
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5":
5385+
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5":
53905386
version: 7.0.6
53915387
resolution: "cross-spawn@npm:7.0.6"
53925388
dependencies:
@@ -6169,6 +6165,7 @@ __metadata:
61696165
"@types/debug": "npm:^4.1.12"
61706166
"@types/node": "npm:^18.19.78"
61716167
"@types/unist": "npm:^2.0.11"
6168+
cross-env: "npm:^7.0.3"
61726169
debug: "npm:^4.3.7"
61736170
dummy.js: "link:dummy.js"
61746171
enhanced-resolve: "npm:^5.15.0"
@@ -6188,7 +6185,7 @@ __metadata:
61886185
stable-hash: "npm:^0.0.4"
61896186
tinyglobby: "npm:^0.2.12"
61906187
type-coverage: "npm:^2.27.0"
6191-
typescript: "npm:^5.3.2"
6188+
typescript: "npm:~5.1.0"
61926189
peerDependencies:
61936190
eslint: "*"
61946191
eslint-plugin-import: "*"
@@ -13873,6 +13870,16 @@ __metadata:
1387313870
languageName: node
1387413871
linkType: hard
1387513872

13873+
"typescript@npm:~5.1.0":
13874+
version: 5.1.6
13875+
resolution: "typescript@npm:5.1.6"
13876+
bin:
13877+
tsc: bin/tsc
13878+
tsserver: bin/tsserver
13879+
checksum: f347cde665cf43dc4c1c7d9821c7d9bbec3c3914f4bdd82ee490e9fb9f6d99036ed8666463b6a192dd005eeef333c5087d5931bdd51ec853436ff9a670a7417e
13880+
languageName: node
13881+
linkType: hard
13882+
1387613883
"typescript@patch:typescript@npm%3A^4.6.4 || ^5.2.2#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.3.2#optional!builtin<compat/typescript>":
1387713884
version: 5.3.2
1387813885
resolution: "typescript@patch:typescript@npm%3A5.3.2#optional!builtin<compat/typescript>::version=5.3.2&hash=e012d7"
@@ -13883,6 +13890,16 @@ __metadata:
1388313890
languageName: node
1388413891
linkType: hard
1388513892

13893+
"typescript@patch:typescript@npm%3A~5.1.0#optional!builtin<compat/typescript>":
13894+
version: 5.1.6
13895+
resolution: "typescript@patch:typescript@npm%3A5.1.6#optional!builtin<compat/typescript>::version=5.1.6&hash=5da071"
13896+
bin:
13897+
tsc: bin/tsc
13898+
tsserver: bin/tsserver
13899+
checksum: f5481fa3ba0eee8970f46708d13c05650a865ad093b586fc9573f425c64c57ca97e3308e110bb528deb3ccebe83f6fd7b5a8ac90018038da96326a9ccdf8e77c
13900+
languageName: node
13901+
linkType: hard
13902+
1388613903
"unassert@npm:^2.0.0, unassert@npm:^2.0.2":
1388713904
version: 2.0.2
1388813905
resolution: "unassert@npm:2.0.2"

0 commit comments

Comments
 (0)