UNPKG

4.84 kBJavaScriptView Raw
1import path from 'path';
2import { createMatchPath, loadConfig, } from 'tsconfig-paths';
3import globSync from 'tiny-glob/sync';
4import isGlob from 'is-glob';
5import { isCore, sync } from 'resolve';
6import debug from 'debug';
7var log = debug('eslint-import-resolver-ts');
8var extensions = ['.ts', '.tsx', '.d.ts'].concat(
9// eslint-disable-next-line node/no-deprecated-api
10Object.keys(require.extensions), '.jsx');
11export var interfaceVersion = 2;
12/**
13 * @param {string} source the module to resolve; i.e './some-module'
14 * @param {string} file the importing file's full path; i.e. '/usr/local/bin/file.js'
15 */
16export function resolve(source, file, options) {
17 if (options === void 0) { options = {}; }
18 log('looking for:', source);
19 // don't worry about core node modules
20 if (isCore(source)) {
21 log('matched core:', source);
22 return {
23 found: true,
24 path: null,
25 };
26 }
27 initMappers(options);
28 var mappedPath = getMappedPath(source, file);
29 if (mappedPath) {
30 log('matched ts path:', mappedPath);
31 }
32 // note that even if we map the path, we still need to do a final resolve
33 var foundNodePath;
34 try {
35 foundNodePath = sync(mappedPath || source, {
36 extensions: extensions,
37 basedir: path.dirname(path.resolve(file)),
38 packageFilter: packageFilter,
39 });
40 }
41 catch (err) {
42 foundNodePath = null;
43 }
44 // naive attempt at @types/* resolution,
45 // if path is neither absolute nor relative
46 if ((/\.jsx?$/.test(foundNodePath) ||
47 (options.alwaysTryTypes && !foundNodePath)) &&
48 !/^@types[/\\]/.test(source) &&
49 !path.isAbsolute(source) &&
50 !source.startsWith('.')) {
51 var definitelyTyped = resolve('@types' + path.sep + mangleScopedPackage(source), file, options);
52 if (definitelyTyped.found) {
53 return definitelyTyped;
54 }
55 }
56 if (foundNodePath) {
57 log('matched node path:', foundNodePath);
58 return {
59 found: true,
60 path: foundNodePath,
61 };
62 }
63 log("didn't find ", source);
64 return {
65 found: false,
66 };
67}
68function packageFilter(pkg) {
69 pkg.main =
70 pkg.types || pkg.typings || pkg.module || pkg['jsnext:main'] || pkg.main;
71 return pkg;
72}
73var mappers;
74/**
75 * @param {string} source the module to resolve; i.e './some-module'
76 * @param {string} file the importing file's full path; i.e. '/usr/local/bin/file.js'
77 * @returns The mapped path of the module or undefined
78 */
79function getMappedPath(source, file) {
80 var paths = mappers
81 .map(function (mapper) { return mapper(source, file); })
82 .filter(function (path) { return !!path; });
83 if (paths.length > 1) {
84 log('found multiple matching ts paths:', paths);
85 }
86 return paths[0];
87}
88function initMappers(options) {
89 if (mappers) {
90 return;
91 }
92 var isArrayOfStrings = function (array) {
93 return Array.isArray(array) && array.every(function (o) { return typeof o === 'string'; });
94 };
95 var configPaths = typeof options.directory === 'string'
96 ? [options.directory]
97 : isArrayOfStrings(options.directory)
98 ? options.directory
99 : [process.cwd()];
100 mappers = configPaths
101 // turn glob patterns into paths
102 .reduce(function (paths, path) { return paths.concat(isGlob(path) ? globSync(path) : path); }, [])
103 .map(loadConfig)
104 .filter(isConfigLoaderSuccessResult)
105 .map(function (configLoaderResult) {
106 var matchPath = createMatchPath(configLoaderResult.absoluteBaseUrl, configLoaderResult.paths);
107 return function (source, file) {
108 // exclude files that are not part of the config base url
109 if (!file.includes(configLoaderResult.absoluteBaseUrl)) {
110 return undefined;
111 }
112 // look for files based on setup tsconfig "paths"
113 return matchPath(source, undefined, undefined, extensions);
114 };
115 });
116}
117function isConfigLoaderSuccessResult(configLoaderResult) {
118 if (configLoaderResult.resultType !== 'success') {
119 // this can happen if the user has problems with their tsconfig
120 // or if it's valid, but they don't have baseUrl set
121 log('failed to init tsconfig-paths:', configLoaderResult.message);
122 return false;
123 }
124 return true;
125}
126/**
127 * For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`.
128 */
129function mangleScopedPackage(moduleName) {
130 if (moduleName.startsWith('@')) {
131 var replaceSlash = moduleName.replace(path.sep, '__');
132 if (replaceSlash !== moduleName) {
133 return replaceSlash.slice(1); // Take off the "@"
134 }
135 }
136 return moduleName;
137}
138//# sourceMappingURL=index.js.map
\No newline at end of file