@@ -2,16 +2,10 @@ import path from 'node:path'
2
2
import { fileURLToPath } from 'node:url'
3
3
4
4
import debug from 'debug'
5
+ import { createPathsMatcher , getTsconfig } from 'get-tsconfig'
5
6
import isGlob from 'is-glob'
6
- import * as _resolve from 'resolve'
7
+ import { isCore , type PackageJSON , sync , SyncOpts } from 'resolve'
7
8
import { createSyncFn } from 'synckit'
8
- import {
9
- ConfigLoaderSuccessResult ,
10
- createMatchPath ,
11
- loadConfig ,
12
- ConfigLoaderResult ,
13
- MatchPath ,
14
- } from 'tsconfig-paths'
15
9
16
10
const IMPORTER_NAME = 'eslint-import-resolver-typescript'
17
11
@@ -26,22 +20,9 @@ const globSync = createSyncFn<typeof import('globby').globby>(
26
20
path . resolve ( _dirname , 'worker.mjs' ) ,
27
21
)
28
22
29
- /**
30
- * .mts, .cts, .d.mts, .d.cts, .mjs, .cjs are not included because .cjs and .mjs must be used explicitly.
31
- */
32
- const defaultExtensions = [
33
- '.ts' ,
34
- '.tsx' ,
35
- '.d.ts' ,
36
- '.js' ,
37
- '.jsx' ,
38
- '.json' ,
39
- '.node' ,
40
- ]
41
-
42
23
export const interfaceVersion = 2
43
24
44
- export type TsResolverOptions = _resolve . SyncOpts & {
25
+ export type TsResolverOptions = SyncOpts & {
45
26
alwaysTryTypes ?: boolean
46
27
/**
47
28
* @deprecated use `project` instead
@@ -72,7 +53,7 @@ export function resolve(
72
53
source = removeQuerystring ( source )
73
54
74
55
// don't worry about core node modules
75
- if ( _resolve . isCore ( source ) ) {
56
+ if ( isCore ( source ) ) {
76
57
log ( 'matched core:' , source )
77
58
78
59
return {
@@ -84,16 +65,14 @@ export function resolve(
84
65
initMappers ( options )
85
66
const mappedPath = getMappedPath ( source )
86
67
if ( mappedPath ) {
87
- log ( 'matched ts path:' , mappedPath . path )
68
+ log ( 'matched ts path:' , mappedPath )
88
69
}
89
70
90
71
// note that even if we map the path, we still need to do a final resolve
91
72
let foundNodePath : string | null | undefined
92
73
try {
93
- foundNodePath = tsResolve ( mappedPath ?. path ?? source , {
74
+ foundNodePath = tsResolve ( mappedPath ?? source , {
94
75
...options ,
95
- extensions :
96
- mappedPath ?. extensions ?? options . extensions ?? defaultExtensions ,
97
76
basedir : path . dirname ( path . resolve ( file ) ) ,
98
77
packageFilter : options . packageFilter ?? packageFilterDefault ,
99
78
} )
@@ -136,7 +115,7 @@ export function resolve(
136
115
}
137
116
}
138
117
139
- function packageFilterDefault ( pkg : _resolve . PackageJSON ) {
118
+ function packageFilterDefault ( pkg : PackageJSON ) {
140
119
pkg . main =
141
120
pkg . types || pkg . typings || pkg . module || pkg [ 'jsnext:main' ] || pkg . main
142
121
return pkg
@@ -172,13 +151,13 @@ function resolveExtension(id: string) {
172
151
* Like `sync` from `resolve` package, but considers that the module id
173
152
* could have a .js or .jsx extension.
174
153
*/
175
- function tsResolve ( id : string , opts : _resolve . SyncOpts ) : string {
154
+ function tsResolve ( id : string , opts : SyncOpts ) : string {
176
155
try {
177
- return _resolve . sync ( id , opts )
156
+ return sync ( id , opts )
178
157
} catch ( error ) {
179
158
const resolved = resolveExtension ( id )
180
159
if ( resolved ) {
181
- return _resolve . sync ( resolved . path , {
160
+ return sync ( resolved . path , {
182
161
...opts ,
183
162
extensions : resolved . extensions ?? opts . extensions ,
184
163
} )
@@ -202,24 +181,20 @@ function removeJsExtension(id: string) {
202
181
}
203
182
204
183
let mappersBuildForOptions : TsResolverOptions
205
- let mappers :
206
- | Array <
207
- ( source : string ) =>
208
- | {
209
- path : string
210
- extensions ?: string [ ]
211
- }
212
- | undefined
213
- >
214
- | undefined
184
+ let mappers : Array < ( ( specifier : string ) => string [ ] ) | null > | undefined
215
185
216
186
/**
217
187
* @param {string } source the module to resolve; i.e './some-module'
218
- * @param {string } file the importing file's full path; i.e. '/usr/local/bin/file.js'
219
188
* @returns The mapped path of the module or undefined
220
189
*/
221
190
function getMappedPath ( source : string ) {
222
- const paths = mappers ! . map ( mapper => mapper ( source ) ) . filter ( path => ! ! path )
191
+ const paths = mappers !
192
+ . map ( mapper => mapper ?.( source ) )
193
+ . filter ( path => ! ! path )
194
+ . flat ( )
195
+
196
+ console . log ( 'source:' , source )
197
+ console . log ( 'paths:' , paths )
223
198
224
199
if ( paths . length > 1 ) {
225
200
log ( 'found multiple matching ts paths:' , paths )
@@ -228,51 +203,6 @@ function getMappedPath(source: string) {
228
203
return paths [ 0 ]
229
204
}
230
205
231
- /**
232
- * Like `createMatchPath` from `tsconfig-paths` package, but considers
233
- * that the module id could have a .mjs, .cjs, .js or .jsx extension.
234
- *
235
- * The default resolved path does not include the extension, so we need to return it for reusing,
236
- * otherwise `.mts`, `.cts`, `.d.mts`, `.d.cts` will not be used by default, see also @link {defaultExtensions}.
237
- */
238
- const createExtendedMatchPath : (
239
- ...createArgs : Parameters < typeof createMatchPath >
240
- ) => ( ...matchArgs : Parameters < MatchPath > ) =>
241
- | {
242
- path : string
243
- extensions ?: string [ ]
244
- }
245
- | undefined = ( ...createArgs ) => {
246
- const matchPath = createMatchPath ( ...createArgs )
247
-
248
- return ( id , readJson , fileExists , extensions ) => {
249
- const match = matchPath ( id , readJson , fileExists , extensions )
250
-
251
- if ( match != null ) {
252
- return {
253
- path : match ,
254
- }
255
- }
256
-
257
- const resolved = resolveExtension ( id )
258
-
259
- if ( resolved ) {
260
- const match = matchPath (
261
- resolved . path ,
262
- readJson ,
263
- fileExists ,
264
- resolved . extensions ?? extensions ,
265
- )
266
- if ( match ) {
267
- return {
268
- path : match ,
269
- extensions : resolved . extensions ,
270
- }
271
- }
272
- }
273
- }
274
- }
275
-
276
206
function initMappers ( options : TsResolverOptions ) {
277
207
if ( mappers && mappersBuildForOptions === options ) {
278
208
return
@@ -307,40 +237,14 @@ function initMappers(options: TsResolverOptions) {
307
237
] ) ,
308
238
]
309
239
310
- mappers = projectPaths
311
- . map ( loadConfig )
312
- . filter ( isConfigLoaderSuccessResult )
313
- . map ( configLoaderResult => {
314
- const matchPath = createExtendedMatchPath (
315
- configLoaderResult . absoluteBaseUrl ,
316
- configLoaderResult . paths ,
317
- )
318
-
319
- return ( source : string ) =>
320
- // look for files based on setup tsconfig "paths"
321
- matchPath (
322
- source ,
323
- undefined ,
324
- undefined ,
325
- options . extensions ?? defaultExtensions ,
326
- )
327
- } )
240
+ mappers = projectPaths . map ( projectPath => {
241
+ const tsconfigResult = getTsconfig ( projectPath )
242
+ return tsconfigResult && createPathsMatcher ( tsconfigResult )
243
+ } )
328
244
329
245
mappersBuildForOptions = options
330
246
}
331
247
332
- function isConfigLoaderSuccessResult (
333
- configLoaderResult : ConfigLoaderResult ,
334
- ) : configLoaderResult is ConfigLoaderSuccessResult {
335
- if ( configLoaderResult . resultType !== 'success' ) {
336
- // this can happen if the user has problems with their tsconfig
337
- // or if it's valid, but they don't have baseUrl set
338
- log ( 'failed to init tsconfig-paths:' , configLoaderResult . message )
339
- return false
340
- }
341
- return true
342
- }
343
-
344
248
/**
345
249
* For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`.
346
250
*/
0 commit comments