eslint-import-resolver-typescript
Version:
This plugin adds `TypeScript` support to `eslint-plugin-import`
135 lines • 5.01 kB
JavaScript
import { isBuiltin } from 'node:module';
import path from 'node:path';
import { createFilesMatcher, parseTsconfig, } from 'get-tsconfig';
import { isBunBuiltin } from 'is-bun-module';
import { stableHash } from 'stable-hash';
import { ResolverFactory } from 'unrs-resolver';
import { IMPORT_RESOLVER_NAME, JS_EXT_PATTERN, TSCONFIG_NOT_FOUND_REGEXP, } from './constants.js';
import { mangleScopedPackage, removeQuerystring, sortProjectsByAffinity, } from './helpers.js';
import { log } from './logger.js';
import { normalizeOptions } from './normalize-options.js';
export * from './constants.js';
export * from './helpers.js';
export * from './normalize-options.js';
const resolverCache = new Map();
const tsconfigCache = new Map();
const matcherCache = new Map();
const unrsResolve = (source, file, resolver) => {
const result = resolver.sync(path.dirname(file), source);
if (result.path) {
return {
found: true,
path: result.path,
};
}
if (result.error) {
log('oxc resolve error:', result.error);
if (TSCONFIG_NOT_FOUND_REGEXP.test(result.error)) {
throw new Error(result.error);
}
}
return {
found: false,
};
};
const isBun = !!process.versions.bun;
export const resolve = (source, file, options, resolver) => {
options ||= {};
if (isBun || options.bun ? isBunBuiltin(source) : isBuiltin(source)) {
log('matched core:', source);
return { found: true, path: null };
}
source = removeQuerystring(source);
if (!resolver) {
const optionsHash = stableHash(options);
const cwd = process.cwd();
options = normalizeOptions(options, cwd);
const cacheKey = `${optionsHash}:${cwd}`;
let cached = resolverCache.get(cacheKey);
if (!cached && !options.project) {
resolverCache.set(cacheKey, (cached = new ResolverFactory(options)));
}
resolver = cached;
}
createResolver: if (!resolver) {
const project = options.project;
for (const tsconfigPath of project) {
const resolverCached = resolverCache.get(tsconfigPath);
if (resolverCached) {
resolver = resolverCached;
break createResolver;
}
let tsconfigCached = tsconfigCache.get(tsconfigPath);
if (!tsconfigCached) {
tsconfigCache.set(tsconfigPath, (tsconfigCached = parseTsconfig(tsconfigPath)));
}
let matcherCached = matcherCache.get(tsconfigPath);
if (!matcherCached) {
matcherCache.set(tsconfigPath, (matcherCached = createFilesMatcher({
config: tsconfigCached,
path: tsconfigPath,
})));
}
const tsconfig = matcherCached(file);
if (!tsconfig) {
log('tsconfig', tsconfigPath, 'does not match', file);
continue;
}
log('matched tsconfig at:', tsconfigPath, 'for', file);
options = {
...options,
tsconfig: {
references: 'auto',
...options.tsconfig,
configFile: tsconfigPath,
},
};
resolver = new ResolverFactory(options);
resolverCache.set(tsconfigPath, resolver);
break createResolver;
}
log('no tsconfig matched', file, 'with', ...project, ', trying from the the nearest one');
for (const p of sortProjectsByAffinity(project, file)) {
const resolved = resolve(source, file, { ...options, project: p }, resolver);
if (resolved.found) {
return resolved;
}
}
}
if (!resolver) {
return {
found: false,
};
}
const resolved = unrsResolve(source, file, resolver);
const foundPath = resolved.path;
if (((foundPath && JS_EXT_PATTERN.test(foundPath)) ||
(options.alwaysTryTypes !== false && !foundPath)) &&
!/^@types[/\\]/.test(source) &&
!path.isAbsolute(source) &&
!source.startsWith('.')) {
const definitelyTyped = unrsResolve('@types/' + mangleScopedPackage(source), file, resolver);
if (definitelyTyped.found) {
return definitelyTyped;
}
}
if (foundPath) {
log('matched path:', foundPath);
}
else {
log("didn't find", source, 'with', options.tsconfig?.configFile || options.project);
}
return resolved;
};
export const createTypeScriptImportResolver = (options) => {
options = normalizeOptions(options);
const resolver = options.project ? null : new ResolverFactory(options);
return {
interfaceVersion: 3,
name: IMPORT_RESOLVER_NAME,
resolve(source, file) {
return resolve(source, file, options, resolver);
},
};
};
//# sourceMappingURL=index.js.map