@@ -3,9 +3,15 @@ import path from 'node:path'
33import { fileURLToPath } from 'node:url'
44
55import debug from 'debug'
6+ import {
7+ FileSystem ,
8+ ResolveOptions ,
9+ Resolver ,
10+ ResolverFactory ,
11+ } from 'enhanced-resolve'
612import { createPathsMatcher , getTsconfig } from 'get-tsconfig'
13+ import isCore from 'is-core-module'
714import isGlob from 'is-glob'
8- import { isCore , type PackageJSON , sync , SyncOpts } from 'resolve'
915import { createSyncFn } from 'synckit'
1016
1117const IMPORTER_NAME = 'eslint-import-resolver-typescript'
@@ -21,15 +27,37 @@ const globSync = createSyncFn<typeof import('globby').globby>(
2127 path . resolve ( _dirname , 'worker.mjs' ) ,
2228)
2329
30+ /**
31+ * .mts, .cts, .d.mts, .d.cts, .mjs, .cjs are not included because .cjs and .mjs must be used explicitly.
32+ */
33+ const defaultExtensions = [
34+ '.ts' ,
35+ '.tsx' ,
36+ '.d.ts' ,
37+ '.js' ,
38+ '.jsx' ,
39+ '.json' ,
40+ '.node' ,
41+ ]
42+
43+ const defaultMainFields = [ 'types' , 'typings' , 'module' , 'jsnext:main' , 'main' ]
44+
2445export const interfaceVersion = 2
2546
26- export type TsResolverOptions = SyncOpts & {
47+ export interface TsResolverOptions
48+ extends Omit < ResolveOptions , 'fileSystem' | 'useSyncFileSystemCalls' > {
2749 alwaysTryTypes ?: boolean
2850 project ?: string [ ] | string
2951 extensions ?: string [ ]
3052 packageFilter ?: ( pkg : Record < string , string > ) => Record < string , string >
3153}
3254
55+ const fileSystem = fs as FileSystem
56+
57+ let mappersBuildForOptions : TsResolverOptions
58+ let mappers : Array < ( ( specifier : string ) => string [ ] ) | null > | undefined
59+ let resolver : Resolver
60+
3361/**
3462 * @param {string } source the module to resolve; i.e './some-module'
3563 * @param {string } file the importing file's full path; i.e. '/usr/local/bin/file.js'
@@ -38,12 +66,20 @@ export type TsResolverOptions = SyncOpts & {
3866export function resolve (
3967 source : string ,
4068 file : string ,
41- options : TsResolverOptions | null ,
69+ options ? : TsResolverOptions | null ,
4270) : {
4371 found : boolean
4472 path ?: string | null
4573} {
46- options = options ?? { }
74+ const opts : ResolveOptions & TsResolverOptions = {
75+ ...options ,
76+ extensions : options ?. extensions ?? defaultExtensions ,
77+ mainFields : options ?. mainFields ?? defaultMainFields ,
78+ fileSystem,
79+ useSyncFileSystemCalls : true ,
80+ }
81+
82+ resolver = ResolverFactory . createResolver ( opts )
4783
4884 log ( 'looking for:' , source )
4985
@@ -59,7 +95,7 @@ export function resolve(
5995 }
6096 }
6197
62- initMappers ( options )
98+ initMappers ( opts )
6399
64100 const mappedPath = getMappedPath ( source , file , true )
65101 if ( mappedPath ) {
@@ -69,11 +105,9 @@ export function resolve(
69105 // note that even if we map the path, we still need to do a final resolve
70106 let foundNodePath : string | null | undefined
71107 try {
72- foundNodePath = tsResolve ( mappedPath ?? source , {
73- ...options ,
74- basedir : path . dirname ( path . resolve ( file ) ) ,
75- packageFilter : options . packageFilter ?? packageFilterDefault ,
76- } )
108+ foundNodePath =
109+ tsResolve ( mappedPath ?? source , path . dirname ( path . resolve ( file ) ) , opts ) ||
110+ null
77111 } catch {
78112 foundNodePath = null
79113 }
@@ -82,7 +116,7 @@ export function resolve(
82116 // if path is neither absolute nor relative
83117 if (
84118 ( / \. j s x ? $ / . test ( foundNodePath ! ) ||
85- ( options . alwaysTryTypes && ! foundNodePath ) ) &&
119+ ( opts . alwaysTryTypes && ! foundNodePath ) ) &&
86120 ! / ^ @ t y p e s [ / \\ ] / . test ( source ) &&
87121 ! path . isAbsolute ( source ) &&
88122 ! source . startsWith ( '.' )
@@ -113,12 +147,6 @@ export function resolve(
113147 }
114148}
115149
116- function packageFilterDefault ( pkg : PackageJSON ) {
117- pkg . main =
118- pkg . types || pkg . typings || pkg . module || pkg [ 'jsnext:main' ] || pkg . main
119- return pkg
120- }
121-
122150function resolveExtension ( id : string ) {
123151 const idWithoutJsExt = removeJsExtension ( id )
124152
@@ -149,16 +177,21 @@ function resolveExtension(id: string) {
149177 * Like `sync` from `resolve` package, but considers that the module id
150178 * could have a .js or .jsx extension.
151179 */
152- function tsResolve ( id : string , opts : SyncOpts ) : string {
180+ function tsResolve (
181+ source : string ,
182+ base : string ,
183+ options : ResolveOptions ,
184+ ) : string | false {
153185 try {
154- return sync ( id , opts )
186+ return resolver . resolveSync ( { } , base , source )
155187 } catch ( error ) {
156- const resolved = resolveExtension ( id )
188+ const resolved = resolveExtension ( source )
157189 if ( resolved ) {
158- return sync ( resolved . path , {
159- ...opts ,
160- extensions : resolved . extensions ?? opts . extensions ,
190+ const resolver = ResolverFactory . createResolver ( {
191+ ...options ,
192+ extensions : resolved . extensions ?? options . extensions ,
161193 } )
194+ return resolver . resolveSync ( { } , base , resolved . path )
162195 }
163196 throw error
164197 }
@@ -178,9 +211,6 @@ function removeJsExtension(id: string) {
178211 return id . replace ( / \. ( [ c m ] j s | j s x ? ) $ / , '' )
179212}
180213
181- let mappersBuildForOptions : TsResolverOptions
182- let mappers : Array < ( ( specifier : string ) => string [ ] ) | null > | undefined
183-
184214const JS_EXT_PATTERN = / \. ( [ c m ] j s | j s x ? ) $ /
185215const RELATIVE_PATH_PATTERN = / ^ \. { 1 , 2 } ( \/ .* ) ? $ /
186216
0 commit comments