1 | 'use strict';
|
2 |
|
3 | function path() {
|
4 | const data = _interopRequireWildcard(require('path'));
|
5 |
|
6 | path = function () {
|
7 | return data;
|
8 | };
|
9 |
|
10 | return data;
|
11 | }
|
12 |
|
13 | function _realpathNative() {
|
14 | const data = require('realpath-native');
|
15 |
|
16 | _realpathNative = function () {
|
17 | return data;
|
18 | };
|
19 |
|
20 | return data;
|
21 | }
|
22 |
|
23 | function _chalk() {
|
24 | const data = _interopRequireDefault(require('chalk'));
|
25 |
|
26 | _chalk = function () {
|
27 | return data;
|
28 | };
|
29 |
|
30 | return data;
|
31 | }
|
32 |
|
33 | var _nodeModulesPaths = _interopRequireDefault(require('./nodeModulesPaths'));
|
34 |
|
35 | var _isBuiltinModule = _interopRequireDefault(require('./isBuiltinModule'));
|
36 |
|
37 | var _defaultResolver = _interopRequireWildcard(require('./defaultResolver'));
|
38 |
|
39 | var _ModuleNotFoundError = _interopRequireDefault(
|
40 | require('./ModuleNotFoundError')
|
41 | );
|
42 |
|
43 | function _interopRequireDefault(obj) {
|
44 | return obj && obj.__esModule ? obj : {default: obj};
|
45 | }
|
46 |
|
47 | function _getRequireWildcardCache() {
|
48 | if (typeof WeakMap !== 'function') return null;
|
49 | var cache = new WeakMap();
|
50 | _getRequireWildcardCache = function () {
|
51 | return cache;
|
52 | };
|
53 | return cache;
|
54 | }
|
55 |
|
56 | function _interopRequireWildcard(obj) {
|
57 | if (obj && obj.__esModule) {
|
58 | return obj;
|
59 | }
|
60 | if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
|
61 | return {default: obj};
|
62 | }
|
63 | var cache = _getRequireWildcardCache();
|
64 | if (cache && cache.has(obj)) {
|
65 | return cache.get(obj);
|
66 | }
|
67 | var newObj = {};
|
68 | var hasPropertyDescriptor =
|
69 | Object.defineProperty && Object.getOwnPropertyDescriptor;
|
70 | for (var key in obj) {
|
71 | if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
72 | var desc = hasPropertyDescriptor
|
73 | ? Object.getOwnPropertyDescriptor(obj, key)
|
74 | : null;
|
75 | if (desc && (desc.get || desc.set)) {
|
76 | Object.defineProperty(newObj, key, desc);
|
77 | } else {
|
78 | newObj[key] = obj[key];
|
79 | }
|
80 | }
|
81 | }
|
82 | newObj.default = obj;
|
83 | if (cache) {
|
84 | cache.set(obj, newObj);
|
85 | }
|
86 | return newObj;
|
87 | }
|
88 |
|
89 | function _defineProperty(obj, key, value) {
|
90 | if (key in obj) {
|
91 | Object.defineProperty(obj, key, {
|
92 | value: value,
|
93 | enumerable: true,
|
94 | configurable: true,
|
95 | writable: true
|
96 | });
|
97 | } else {
|
98 | obj[key] = value;
|
99 | }
|
100 | return obj;
|
101 | }
|
102 |
|
103 | const NATIVE_PLATFORM = 'native';
|
104 |
|
105 | const cwd = process.cwd();
|
106 | const resolvedCwd = (0, _realpathNative().sync)(cwd) || cwd;
|
107 | const {NODE_PATH} = process.env;
|
108 | const nodePaths = NODE_PATH
|
109 | ? NODE_PATH.split(path().delimiter)
|
110 | .filter(Boolean)
|
111 | .map(p => path().resolve(resolvedCwd, p))
|
112 | : undefined;
|
113 |
|
114 |
|
115 | class Resolver {
|
116 | constructor(moduleMap, options) {
|
117 | _defineProperty(this, '_options', void 0);
|
118 |
|
119 | _defineProperty(this, '_moduleMap', void 0);
|
120 |
|
121 | _defineProperty(this, '_moduleIDCache', void 0);
|
122 |
|
123 | _defineProperty(this, '_moduleNameCache', void 0);
|
124 |
|
125 | _defineProperty(this, '_modulePathCache', void 0);
|
126 |
|
127 | _defineProperty(this, '_supportsNativePlatform', void 0);
|
128 |
|
129 | this._options = {
|
130 | browser: options.browser,
|
131 | defaultPlatform: options.defaultPlatform,
|
132 | extensions: options.extensions,
|
133 | hasCoreModules:
|
134 | options.hasCoreModules === undefined ? true : options.hasCoreModules,
|
135 | moduleDirectories: options.moduleDirectories || ['node_modules'],
|
136 | moduleNameMapper: options.moduleNameMapper,
|
137 | modulePaths: options.modulePaths,
|
138 | platforms: options.platforms,
|
139 | resolver: options.resolver,
|
140 | rootDir: options.rootDir
|
141 | };
|
142 | this._supportsNativePlatform = options.platforms
|
143 | ? options.platforms.includes(NATIVE_PLATFORM)
|
144 | : false;
|
145 | this._moduleMap = moduleMap;
|
146 | this._moduleIDCache = new Map();
|
147 | this._moduleNameCache = new Map();
|
148 | this._modulePathCache = new Map();
|
149 | }
|
150 |
|
151 | static tryCastModuleNotFoundError(error) {
|
152 | if (error instanceof _ModuleNotFoundError.default) {
|
153 | return error;
|
154 | }
|
155 |
|
156 | const casted = error;
|
157 |
|
158 | if (casted.code === 'MODULE_NOT_FOUND') {
|
159 | return _ModuleNotFoundError.default.duckType(casted);
|
160 | }
|
161 |
|
162 | return null;
|
163 | }
|
164 |
|
165 | static clearDefaultResolverCache() {
|
166 | (0, _defaultResolver.clearDefaultResolverCache)();
|
167 | }
|
168 |
|
169 | static findNodeModule(path, options) {
|
170 | const resolver = options.resolver
|
171 | ? require(options.resolver)
|
172 | : _defaultResolver.default;
|
173 | const paths = options.paths;
|
174 |
|
175 | try {
|
176 | return resolver(path, {
|
177 | basedir: options.basedir,
|
178 | browser: options.browser,
|
179 | defaultResolver: _defaultResolver.default,
|
180 | extensions: options.extensions,
|
181 | moduleDirectory: options.moduleDirectory,
|
182 | paths: paths ? (nodePaths || []).concat(paths) : nodePaths,
|
183 | rootDir: options.rootDir
|
184 | });
|
185 | } catch (e) {
|
186 | if (options.throwIfNotFound) {
|
187 | throw e;
|
188 | }
|
189 | }
|
190 |
|
191 | return null;
|
192 | }
|
193 |
|
194 | resolveModuleFromDirIfExists(dirname, moduleName, options) {
|
195 | const paths = (options && options.paths) || this._options.modulePaths;
|
196 | const moduleDirectory = this._options.moduleDirectories;
|
197 | const key = dirname + path().delimiter + moduleName;
|
198 | const defaultPlatform = this._options.defaultPlatform;
|
199 |
|
200 | const extensions = this._options.extensions.slice();
|
201 |
|
202 | let module;
|
203 |
|
204 | if (this._supportsNativePlatform) {
|
205 | extensions.unshift(
|
206 | ...this._options.extensions.map(ext => '.' + NATIVE_PLATFORM + ext)
|
207 | );
|
208 | }
|
209 |
|
210 | if (defaultPlatform) {
|
211 | extensions.unshift(
|
212 | ...this._options.extensions.map(ext => '.' + defaultPlatform + ext)
|
213 | );
|
214 | }
|
215 |
|
216 |
|
217 | const cacheResult = this._moduleNameCache.get(key);
|
218 |
|
219 | if (cacheResult) {
|
220 | return cacheResult;
|
221 | }
|
222 |
|
223 | module = this.getModule(moduleName);
|
224 |
|
225 | if (module) {
|
226 | this._moduleNameCache.set(key, module);
|
227 |
|
228 | return module;
|
229 | }
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 | const skipResolution =
|
237 | options && options.skipNodeResolution && !moduleName.includes(path().sep);
|
238 |
|
239 | const resolveNodeModule = (name, throwIfNotFound = false) =>
|
240 | Resolver.findNodeModule(name, {
|
241 | basedir: dirname,
|
242 | browser: this._options.browser,
|
243 | extensions,
|
244 | moduleDirectory,
|
245 | paths,
|
246 | resolver: this._options.resolver,
|
247 | rootDir: this._options.rootDir,
|
248 | throwIfNotFound
|
249 | });
|
250 |
|
251 | if (!skipResolution) {
|
252 |
|
253 | module = resolveNodeModule(moduleName, Boolean(process.versions.pnp));
|
254 |
|
255 | if (module) {
|
256 | this._moduleNameCache.set(key, module);
|
257 |
|
258 | return module;
|
259 | }
|
260 | }
|
261 |
|
262 |
|
263 | const parts = moduleName.split('/');
|
264 | const hastePackage = this.getPackage(parts.shift());
|
265 |
|
266 | if (hastePackage) {
|
267 | try {
|
268 | const module = path().join.apply(
|
269 | path(),
|
270 | [path().dirname(hastePackage)].concat(parts)
|
271 | );
|
272 |
|
273 |
|
274 | const resolvedModule =
|
275 | resolveNodeModule(module) || require.resolve(module);
|
276 |
|
277 | this._moduleNameCache.set(key, resolvedModule);
|
278 |
|
279 | return resolvedModule;
|
280 | } catch (ignoredError) {}
|
281 | }
|
282 |
|
283 | return null;
|
284 | }
|
285 |
|
286 | resolveModule(from, moduleName, options) {
|
287 | const dirname = path().dirname(from);
|
288 | const module =
|
289 | this.resolveStubModuleName(from, moduleName) ||
|
290 | this.resolveModuleFromDirIfExists(dirname, moduleName, options);
|
291 | if (module) return module;
|
292 |
|
293 |
|
294 |
|
295 | const relativePath = path().relative(dirname, from);
|
296 | throw new _ModuleNotFoundError.default(
|
297 | `Cannot find module '${moduleName}' from '${relativePath || '.'}'`,
|
298 | moduleName
|
299 | );
|
300 | }
|
301 |
|
302 | _isAliasModule(moduleName) {
|
303 | const moduleNameMapper = this._options.moduleNameMapper;
|
304 |
|
305 | if (!moduleNameMapper) {
|
306 | return false;
|
307 | }
|
308 |
|
309 | return moduleNameMapper.some(({regex}) => regex.test(moduleName));
|
310 | }
|
311 |
|
312 | isCoreModule(moduleName) {
|
313 | return (
|
314 | this._options.hasCoreModules &&
|
315 | (0, _isBuiltinModule.default)(moduleName) &&
|
316 | !this._isAliasModule(moduleName)
|
317 | );
|
318 | }
|
319 |
|
320 | getModule(name) {
|
321 | return this._moduleMap.getModule(
|
322 | name,
|
323 | this._options.defaultPlatform,
|
324 | this._supportsNativePlatform
|
325 | );
|
326 | }
|
327 |
|
328 | getModulePath(from, moduleName) {
|
329 | if (moduleName[0] !== '.' || path().isAbsolute(moduleName)) {
|
330 | return moduleName;
|
331 | }
|
332 |
|
333 | return path().normalize(path().dirname(from) + '/' + moduleName);
|
334 | }
|
335 |
|
336 | getPackage(name) {
|
337 | return this._moduleMap.getPackage(
|
338 | name,
|
339 | this._options.defaultPlatform,
|
340 | this._supportsNativePlatform
|
341 | );
|
342 | }
|
343 |
|
344 | getMockModule(from, name) {
|
345 | const mock = this._moduleMap.getMockModule(name);
|
346 |
|
347 | if (mock) {
|
348 | return mock;
|
349 | } else {
|
350 | const moduleName = this.resolveStubModuleName(from, name);
|
351 |
|
352 | if (moduleName) {
|
353 | return this.getModule(moduleName) || moduleName;
|
354 | }
|
355 | }
|
356 |
|
357 | return null;
|
358 | }
|
359 |
|
360 | getModulePaths(from) {
|
361 | const cachedModule = this._modulePathCache.get(from);
|
362 |
|
363 | if (cachedModule) {
|
364 | return cachedModule;
|
365 | }
|
366 |
|
367 | const moduleDirectory = this._options.moduleDirectories;
|
368 | const paths = (0, _nodeModulesPaths.default)(from, {
|
369 | moduleDirectory
|
370 | });
|
371 |
|
372 | if (paths[paths.length - 1] === undefined) {
|
373 |
|
374 | paths.pop();
|
375 | }
|
376 |
|
377 | this._modulePathCache.set(from, paths);
|
378 |
|
379 | return paths;
|
380 | }
|
381 |
|
382 | getModuleID(virtualMocks, from, _moduleName) {
|
383 | const moduleName = _moduleName || '';
|
384 | const key = from + path().delimiter + moduleName;
|
385 |
|
386 | const cachedModuleID = this._moduleIDCache.get(key);
|
387 |
|
388 | if (cachedModuleID) {
|
389 | return cachedModuleID;
|
390 | }
|
391 |
|
392 | const moduleType = this._getModuleType(moduleName);
|
393 |
|
394 | const absolutePath = this._getAbsolutePath(virtualMocks, from, moduleName);
|
395 |
|
396 | const mockPath = this._getMockPath(from, moduleName);
|
397 |
|
398 | const sep = path().delimiter;
|
399 | const id =
|
400 | moduleType +
|
401 | sep +
|
402 | (absolutePath ? absolutePath + sep : '') +
|
403 | (mockPath ? mockPath + sep : '');
|
404 |
|
405 | this._moduleIDCache.set(key, id);
|
406 |
|
407 | return id;
|
408 | }
|
409 |
|
410 | _getModuleType(moduleName) {
|
411 | return this.isCoreModule(moduleName) ? 'node' : 'user';
|
412 | }
|
413 |
|
414 | _getAbsolutePath(virtualMocks, from, moduleName) {
|
415 | if (this.isCoreModule(moduleName)) {
|
416 | return moduleName;
|
417 | }
|
418 |
|
419 | return this._isModuleResolved(from, moduleName)
|
420 | ? this.getModule(moduleName)
|
421 | : this._getVirtualMockPath(virtualMocks, from, moduleName);
|
422 | }
|
423 |
|
424 | _getMockPath(from, moduleName) {
|
425 | return !this.isCoreModule(moduleName)
|
426 | ? this.getMockModule(from, moduleName)
|
427 | : null;
|
428 | }
|
429 |
|
430 | _getVirtualMockPath(virtualMocks, from, moduleName) {
|
431 | const virtualMockPath = this.getModulePath(from, moduleName);
|
432 | return virtualMocks[virtualMockPath]
|
433 | ? virtualMockPath
|
434 | : moduleName
|
435 | ? this.resolveModule(from, moduleName)
|
436 | : from;
|
437 | }
|
438 |
|
439 | _isModuleResolved(from, moduleName) {
|
440 | return !!(
|
441 | this.getModule(moduleName) || this.getMockModule(from, moduleName)
|
442 | );
|
443 | }
|
444 |
|
445 | resolveStubModuleName(from, moduleName) {
|
446 | const dirname = path().dirname(from);
|
447 | const paths = this._options.modulePaths;
|
448 |
|
449 | const extensions = this._options.extensions.slice();
|
450 |
|
451 | const moduleDirectory = this._options.moduleDirectories;
|
452 | const moduleNameMapper = this._options.moduleNameMapper;
|
453 | const resolver = this._options.resolver;
|
454 | const defaultPlatform = this._options.defaultPlatform;
|
455 |
|
456 | if (this._supportsNativePlatform) {
|
457 | extensions.unshift(
|
458 | ...this._options.extensions.map(ext => '.' + NATIVE_PLATFORM + ext)
|
459 | );
|
460 | }
|
461 |
|
462 | if (defaultPlatform) {
|
463 | extensions.unshift(
|
464 | ...this._options.extensions.map(ext => '.' + defaultPlatform + ext)
|
465 | );
|
466 | }
|
467 |
|
468 | if (moduleNameMapper) {
|
469 | for (const {moduleName: mappedModuleName, regex} of moduleNameMapper) {
|
470 | if (regex.test(moduleName)) {
|
471 |
|
472 |
|
473 | const matches = moduleName.match(regex);
|
474 | const mapModuleName = matches
|
475 | ? moduleName =>
|
476 | moduleName.replace(
|
477 | /\$([0-9]+)/g,
|
478 | (_, index) => matches[parseInt(index, 10)]
|
479 | )
|
480 | : moduleName => moduleName;
|
481 | const possibleModuleNames = Array.isArray(mappedModuleName)
|
482 | ? mappedModuleName
|
483 | : [mappedModuleName];
|
484 | let module = null;
|
485 |
|
486 | for (const possibleModuleName of possibleModuleNames) {
|
487 | const updatedName = mapModuleName(possibleModuleName);
|
488 | module =
|
489 | this.getModule(updatedName) ||
|
490 | Resolver.findNodeModule(updatedName, {
|
491 | basedir: dirname,
|
492 | browser: this._options.browser,
|
493 | extensions,
|
494 | moduleDirectory,
|
495 | paths,
|
496 | resolver,
|
497 | rootDir: this._options.rootDir
|
498 | });
|
499 |
|
500 | if (module) {
|
501 | break;
|
502 | }
|
503 | }
|
504 |
|
505 | if (!module) {
|
506 | throw createNoMappedModuleFoundError(
|
507 | moduleName,
|
508 | mapModuleName,
|
509 | mappedModuleName,
|
510 | regex,
|
511 | resolver
|
512 | );
|
513 | }
|
514 |
|
515 | return module;
|
516 | }
|
517 | }
|
518 | }
|
519 |
|
520 | return null;
|
521 | }
|
522 | }
|
523 |
|
524 | _defineProperty(Resolver, 'ModuleNotFoundError', _ModuleNotFoundError.default);
|
525 |
|
526 | const createNoMappedModuleFoundError = (
|
527 | moduleName,
|
528 | mapModuleName,
|
529 | mappedModuleName,
|
530 | regex,
|
531 | resolver
|
532 | ) => {
|
533 | const mappedAs = Array.isArray(mappedModuleName)
|
534 | ? JSON.stringify(mappedModuleName.map(mapModuleName), null, 2)
|
535 | : mappedModuleName;
|
536 | const original = Array.isArray(mappedModuleName)
|
537 | ? JSON.stringify(mappedModuleName, null, 6)
|
538 | .slice(0, -1) + ' ]'
|
539 | : mappedModuleName;
|
540 | const error = new Error(
|
541 | _chalk().default.red(`${_chalk().default.bold('Configuration error')}:
|
542 |
|
543 | Could not locate module ${_chalk().default.bold(moduleName)} mapped as:
|
544 | ${_chalk().default.bold(mappedAs)}.
|
545 |
|
546 | Please check your configuration for these entries:
|
547 | {
|
548 | "moduleNameMapper": {
|
549 | "${regex.toString()}": "${_chalk().default.bold(original)}"
|
550 | },
|
551 | "resolver": ${_chalk().default.bold(String(resolver))}
|
552 | }`)
|
553 | );
|
554 | error.name = '';
|
555 | return error;
|
556 | };
|
557 |
|
558 | module.exports = Resolver;
|