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