|
| 1 | +import fs from 'node:fs' |
1 | 2 | import path from 'node:path'
|
2 | 3 | import { fileURLToPath } from 'node:url'
|
3 | 4 |
|
@@ -63,7 +64,8 @@ export function resolve(
|
63 | 64 | }
|
64 | 65 |
|
65 | 66 | initMappers(options)
|
66 |
| - const mappedPath = getMappedPath(source) |
| 67 | + |
| 68 | + const mappedPath = getMappedPath(source, file, true) |
67 | 69 | if (mappedPath) {
|
68 | 70 | log('matched ts path:', mappedPath)
|
69 | 71 | }
|
@@ -183,18 +185,65 @@ function removeJsExtension(id: string) {
|
183 | 185 | let mappersBuildForOptions: TsResolverOptions
|
184 | 186 | let mappers: Array<((specifier: string) => string[]) | null> | undefined
|
185 | 187 |
|
| 188 | +const JS_EXT_PATTERN = /\.([cm]js|jsx?)$/ |
| 189 | +const RELATIVE_PATH_PATTERN = /^\.{1,2}(\/.*)?$/ |
| 190 | + |
| 191 | +const isFile = (path?: string | undefined): path is string => { |
| 192 | + try { |
| 193 | + return !!path && fs.statSync(path).isFile() |
| 194 | + } catch { |
| 195 | + return false |
| 196 | + } |
| 197 | +} |
| 198 | + |
186 | 199 | /**
|
187 | 200 | * @param {string} source the module to resolve; i.e './some-module'
|
| 201 | + * @param {string} file the importing file's full path; i.e. '/usr/local/bin/file.js' |
188 | 202 | * @returns The mapped path of the module or undefined
|
189 | 203 | */
|
190 |
| -function getMappedPath(source: string) { |
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) |
| 204 | +function getMappedPath( |
| 205 | + source: string, |
| 206 | + file: string, |
| 207 | + retry?: boolean, |
| 208 | +): string | undefined { |
| 209 | + let paths: string[] | undefined = [] |
| 210 | + |
| 211 | + if (RELATIVE_PATH_PATTERN.test(source)) { |
| 212 | + const resolved = path.resolve(path.dirname(file), source) |
| 213 | + if (isFile(resolved)) { |
| 214 | + paths = [resolved] |
| 215 | + } |
| 216 | + } else { |
| 217 | + paths = mappers!.flatMap(mapper => mapper?.(source)).filter(isFile) |
| 218 | + } |
| 219 | + |
| 220 | + if (retry && paths.length === 0) { |
| 221 | + if (JS_EXT_PATTERN.test(source)) { |
| 222 | + const jsExt = path.extname(source) |
| 223 | + const tsExt = jsExt.replace('js', 'ts') |
| 224 | + const basename = source.replace(JS_EXT_PATTERN, '') |
| 225 | + return ( |
| 226 | + getMappedPath(basename + tsExt, file) || |
| 227 | + getMappedPath(source + '/index.ts', file) || |
| 228 | + getMappedPath(source + '/index.tsx', file) || |
| 229 | + getMappedPath(source + '/index.js', file) || |
| 230 | + getMappedPath( |
| 231 | + basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt), |
| 232 | + file, |
| 233 | + false, |
| 234 | + ) |
| 235 | + ) |
| 236 | + } |
| 237 | + return ( |
| 238 | + getMappedPath(source + '.ts', file) || |
| 239 | + getMappedPath(source + '.tsx', file) || |
| 240 | + getMappedPath(source + '.js', file) || |
| 241 | + getMappedPath(source + '.d.ts', file) || |
| 242 | + getMappedPath(source + '/index.ts', file) || |
| 243 | + getMappedPath(source + '/index.tsx', file) || |
| 244 | + getMappedPath(source + '/index.js', file) |
| 245 | + ) |
| 246 | + } |
198 | 247 |
|
199 | 248 | if (paths.length > 1) {
|
200 | 249 | log('found multiple matching ts paths:', paths)
|
|
0 commit comments