You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					346 lines
				
				11 KiB
			
		
		
			
		
	
	
					346 lines
				
				11 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Translate the old options to the new Resolver functionality.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const fs = require('fs');
							 | 
						||
| 
								 | 
							
								const nmod = require('module');
							 | 
						||
| 
								 | 
							
								const {EventEmitter} = require('events');
							 | 
						||
| 
								 | 
							
								const util = require('util');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const {
							 | 
						||
| 
								 | 
							
									Resolver,
							 | 
						||
| 
								 | 
							
									DefaultResolver
							 | 
						||
| 
								 | 
							
								} = require('./resolver');
							 | 
						||
| 
								 | 
							
								const {VMScript} = require('./script');
							 | 
						||
| 
								 | 
							
								const {VM} = require('./vm');
							 | 
						||
| 
								 | 
							
								const {VMError} = require('./bridge');
							 | 
						||
| 
								 | 
							
								const {DefaultFileSystem} = require('./filesystem');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Require wrapper to be able to annotate require with webpackIgnore.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @private
							 | 
						||
| 
								 | 
							
								 * @param {string} moduleName - Name of module to load.
							 | 
						||
| 
								 | 
							
								 * @return {*} Module exports.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function defaultRequire(moduleName) {
							 | 
						||
| 
								 | 
							
									// Set module.parser.javascript.commonjsMagicComments=true in your webpack config.
							 | 
						||
| 
								 | 
							
									// eslint-disable-next-line global-require
							 | 
						||
| 
								 | 
							
									return require(/* webpackIgnore: true */ moduleName);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
							 | 
						||
| 
								 | 
							
								function escapeRegExp(string) {
							 | 
						||
| 
								 | 
							
									return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function makeExternalMatcherRegex(obj) {
							 | 
						||
| 
								 | 
							
									return escapeRegExp(obj).replace(/\\\\|\//g, '[\\\\/]')
							 | 
						||
| 
								 | 
							
										.replace(/\\\*\\\*/g, '.*').replace(/\\\*/g, '[^\\\\/]*').replace(/\\\?/g, '[^\\\\/]');
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function makeExternalMatcher(obj) {
							 | 
						||
| 
								 | 
							
									const regexString = makeExternalMatcherRegex(obj);
							 | 
						||
| 
								 | 
							
									return new RegExp(`[\\\\/]node_modules[\\\\/]${regexString}(?:[\\\\/](?!(?:.*[\\\\/])?node_modules[\\\\/]).*)?$`);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LegacyResolver extends DefaultResolver {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor(fileSystem, builtinModules, checkPath, globalPaths, pathContext, customResolver, hostRequire, compiler, strict, externals, allowTransitive) {
							 | 
						||
| 
								 | 
							
										super(fileSystem, builtinModules, checkPath, globalPaths, pathContext, customResolver, hostRequire, compiler, strict);
							 | 
						||
| 
								 | 
							
										this.externals = externals;
							 | 
						||
| 
								 | 
							
										this.currMod = undefined;
							 | 
						||
| 
								 | 
							
										this.trustedMods = new WeakMap();
							 | 
						||
| 
								 | 
							
										this.allowTransitive = allowTransitive;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									isPathAllowed(path) {
							 | 
						||
| 
								 | 
							
										return this.isPathAllowedForModule(path, this.currMod);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									isPathAllowedForModule(path, mod) {
							 | 
						||
| 
								 | 
							
										if (!super.isPathAllowed(path)) return false;
							 | 
						||
| 
								 | 
							
										if (mod) {
							 | 
						||
| 
								 | 
							
											if (mod.allowTransitive) return true;
							 | 
						||
| 
								 | 
							
											if (path.startsWith(mod.path)) {
							 | 
						||
| 
								 | 
							
												const rem = path.slice(mod.path.length);
							 | 
						||
| 
								 | 
							
												if (!/(?:^|[\\\\/])node_modules(?:$|[\\\\/])/.test(rem)) return true;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return this.externals.some(regex => regex.test(path));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									registerModule(mod, filename, path, parent, direct) {
							 | 
						||
| 
								 | 
							
										const trustedParent = this.trustedMods.get(parent);
							 | 
						||
| 
								 | 
							
										this.trustedMods.set(mod, {
							 | 
						||
| 
								 | 
							
											filename,
							 | 
						||
| 
								 | 
							
											path,
							 | 
						||
| 
								 | 
							
											paths: this.genLookupPaths(path),
							 | 
						||
| 
								 | 
							
											allowTransitive: this.allowTransitive &&
							 | 
						||
| 
								 | 
							
												((direct && trustedParent && trustedParent.allowTransitive) || this.externals.some(regex => regex.test(filename)))
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									resolveFull(mod, x, options, ext, direct) {
							 | 
						||
| 
								 | 
							
										this.currMod = undefined;
							 | 
						||
| 
								 | 
							
										if (!direct) return super.resolveFull(mod, x, options, ext, false);
							 | 
						||
| 
								 | 
							
										const trustedMod = this.trustedMods.get(mod);
							 | 
						||
| 
								 | 
							
										if (!trustedMod || mod.path !== trustedMod.path) return super.resolveFull(mod, x, options, ext, false);
							 | 
						||
| 
								 | 
							
										const paths = [...mod.paths];
							 | 
						||
| 
								 | 
							
										if (paths.length === trustedMod.length) {
							 | 
						||
| 
								 | 
							
											for (let i = 0; i < paths.length; i++) {
							 | 
						||
| 
								 | 
							
												if (paths[i] !== trustedMod.paths[i]) {
							 | 
						||
| 
								 | 
							
													return super.resolveFull(mod, x, options, ext, false);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const extCopy = Object.assign({__proto__: null}, ext);
							 | 
						||
| 
								 | 
							
										try {
							 | 
						||
| 
								 | 
							
											this.currMod = trustedMod;
							 | 
						||
| 
								 | 
							
											return super.resolveFull(trustedMod, x, undefined, extCopy, true);
							 | 
						||
| 
								 | 
							
										} finally {
							 | 
						||
| 
								 | 
							
											this.currMod = undefined;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									checkAccess(mod, filename) {
							 | 
						||
| 
								 | 
							
										const trustedMod = this.trustedMods.get(mod);
							 | 
						||
| 
								 | 
							
										if ((!trustedMod || trustedMod.filename !== filename) && !this.isPathAllowedForModule(filename, undefined)) {
							 | 
						||
| 
								 | 
							
											throw new VMError(`Module '${filename}' is not allowed to be required. The path is outside the border!`, 'EDENIED');
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									loadJS(vm, mod, filename) {
							 | 
						||
| 
								 | 
							
										filename = this.pathResolve(filename);
							 | 
						||
| 
								 | 
							
										this.checkAccess(mod, filename);
							 | 
						||
| 
								 | 
							
										if (this.pathContext(filename, 'js') === 'sandbox') {
							 | 
						||
| 
								 | 
							
											const trustedMod = this.trustedMods.get(mod);
							 | 
						||
| 
								 | 
							
											const script = this.readScript(filename);
							 | 
						||
| 
								 | 
							
											vm.run(script, {filename, strict: true, module: mod, wrapper: 'none', dirname: trustedMod ? trustedMod.path : mod.path});
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											const m = this.hostRequire(filename);
							 | 
						||
| 
								 | 
							
											mod.exports = vm.readonly(m);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function defaultBuiltinLoader(resolver, vm, id) {
							 | 
						||
| 
								 | 
							
									const mod = resolver.hostRequire(id);
							 | 
						||
| 
								 | 
							
									return vm.readonly(mod);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const eventsModules = new WeakMap();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function defaultBuiltinLoaderEvents(resolver, vm, id) {
							 | 
						||
| 
								 | 
							
									return eventsModules.get(vm);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let cacheBufferScript;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function defaultBuiltinLoaderBuffer(resolver, vm, id) {
							 | 
						||
| 
								 | 
							
									if (!cacheBufferScript) {
							 | 
						||
| 
								 | 
							
										cacheBufferScript = new VMScript('return buffer=>({Buffer: buffer});', {__proto__: null, filename: 'buffer.js'});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									const makeBuffer = vm.run(cacheBufferScript, {__proto__: null, strict: true, wrapper: 'none'});
							 | 
						||
| 
								 | 
							
									return makeBuffer(Buffer);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let cacheUtilScript;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function defaultBuiltinLoaderUtil(resolver, vm, id) {
							 | 
						||
| 
								 | 
							
									if (!cacheUtilScript) {
							 | 
						||
| 
								 | 
							
										cacheUtilScript = new VMScript(`return function inherits(ctor, superCtor) {
							 | 
						||
| 
								 | 
							
											ctor.super_ = superCtor;
							 | 
						||
| 
								 | 
							
											Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
							 | 
						||
| 
								 | 
							
										}`, {__proto__: null, filename: 'util.js'});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									const inherits = vm.run(cacheUtilScript, {__proto__: null, strict: true, wrapper: 'none'});
							 | 
						||
| 
								 | 
							
									const copy = Object.assign({}, util);
							 | 
						||
| 
								 | 
							
									copy.inherits = inherits;
							 | 
						||
| 
								 | 
							
									return vm.readonly(copy);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const BUILTIN_MODULES = (nmod.builtinModules || Object.getOwnPropertyNames(process.binding('natives'))).filter(s=>!s.startsWith('internal/'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let EventEmitterReferencingAsyncResourceClass = null;
							 | 
						||
| 
								 | 
							
								if (EventEmitter.EventEmitterAsyncResource) {
							 | 
						||
| 
								 | 
							
									// eslint-disable-next-line global-require
							 | 
						||
| 
								 | 
							
									const {AsyncResource} = require('async_hooks');
							 | 
						||
| 
								 | 
							
									const kEventEmitter = Symbol('kEventEmitter');
							 | 
						||
| 
								 | 
							
									class EventEmitterReferencingAsyncResource extends AsyncResource {
							 | 
						||
| 
								 | 
							
										constructor(ee, type, options) {
							 | 
						||
| 
								 | 
							
											super(type, options);
							 | 
						||
| 
								 | 
							
											this[kEventEmitter] = ee;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										get eventEmitter() {
							 | 
						||
| 
								 | 
							
											return this[kEventEmitter];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									EventEmitterReferencingAsyncResourceClass = EventEmitterReferencingAsyncResource;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let cacheEventsScript;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const SPECIAL_MODULES = {
							 | 
						||
| 
								 | 
							
									events(vm) {
							 | 
						||
| 
								 | 
							
										if (!cacheEventsScript) {
							 | 
						||
| 
								 | 
							
											const eventsSource = fs.readFileSync(`${__dirname}/events.js`, 'utf8');
							 | 
						||
| 
								 | 
							
											cacheEventsScript = new VMScript(`(function (fromhost) { const module = {}; module.exports={};{ ${eventsSource}
							 | 
						||
| 
								 | 
							
								} return module.exports;})`, {filename: 'events.js'});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const closure = VM.prototype.run.call(vm, cacheEventsScript);
							 | 
						||
| 
								 | 
							
										const eventsInstance = closure(vm.readonly({
							 | 
						||
| 
								 | 
							
											kErrorMonitor: EventEmitter.errorMonitor,
							 | 
						||
| 
								 | 
							
											once: EventEmitter.once,
							 | 
						||
| 
								 | 
							
											on: EventEmitter.on,
							 | 
						||
| 
								 | 
							
											getEventListeners: EventEmitter.getEventListeners,
							 | 
						||
| 
								 | 
							
											EventEmitterReferencingAsyncResource: EventEmitterReferencingAsyncResourceClass
							 | 
						||
| 
								 | 
							
										}));
							 | 
						||
| 
								 | 
							
										eventsModules.set(vm, eventsInstance);
							 | 
						||
| 
								 | 
							
										vm._addProtoMapping(EventEmitter.prototype, eventsInstance.EventEmitter.prototype);
							 | 
						||
| 
								 | 
							
										return defaultBuiltinLoaderEvents;
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
									buffer(vm) {
							 | 
						||
| 
								 | 
							
										return defaultBuiltinLoaderBuffer;
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
									util(vm) {
							 | 
						||
| 
								 | 
							
										return defaultBuiltinLoaderUtil;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function addDefaultBuiltin(builtins, key, vm) {
							 | 
						||
| 
								 | 
							
									if (builtins[key]) return;
							 | 
						||
| 
								 | 
							
									const special = SPECIAL_MODULES[key];
							 | 
						||
| 
								 | 
							
									builtins[key] = special ? special(vm) : defaultBuiltinLoader;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function genBuiltinsFromOptions(vm, builtinOpt, mockOpt, override) {
							 | 
						||
| 
								 | 
							
									const builtins = {__proto__: null};
							 | 
						||
| 
								 | 
							
									if (mockOpt) {
							 | 
						||
| 
								 | 
							
										const keys = Object.getOwnPropertyNames(mockOpt);
							 | 
						||
| 
								 | 
							
										for (let i = 0; i < keys.length; i++) {
							 | 
						||
| 
								 | 
							
											const key = keys[i];
							 | 
						||
| 
								 | 
							
											builtins[key] = (resolver, tvm, id) => tvm.readonly(mockOpt[key]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (override) {
							 | 
						||
| 
								 | 
							
										const keys = Object.getOwnPropertyNames(override);
							 | 
						||
| 
								 | 
							
										for (let i = 0; i < keys.length; i++) {
							 | 
						||
| 
								 | 
							
											const key = keys[i];
							 | 
						||
| 
								 | 
							
											builtins[key] = override[key];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (Array.isArray(builtinOpt)) {
							 | 
						||
| 
								 | 
							
										const def = builtinOpt.indexOf('*') >= 0;
							 | 
						||
| 
								 | 
							
										if (def) {
							 | 
						||
| 
								 | 
							
											for (let i = 0; i < BUILTIN_MODULES.length; i++) {
							 | 
						||
| 
								 | 
							
												const name = BUILTIN_MODULES[i];
							 | 
						||
| 
								 | 
							
												if (builtinOpt.indexOf(`-${name}`) === -1) {
							 | 
						||
| 
								 | 
							
													addDefaultBuiltin(builtins, name, vm);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											for (let i = 0; i < BUILTIN_MODULES.length; i++) {
							 | 
						||
| 
								 | 
							
												const name = BUILTIN_MODULES[i];
							 | 
						||
| 
								 | 
							
												if (builtinOpt.indexOf(name) !== -1) {
							 | 
						||
| 
								 | 
							
													addDefaultBuiltin(builtins, name, vm);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else if (builtinOpt) {
							 | 
						||
| 
								 | 
							
										for (let i = 0; i < BUILTIN_MODULES.length; i++) {
							 | 
						||
| 
								 | 
							
											const name = BUILTIN_MODULES[i];
							 | 
						||
| 
								 | 
							
											if (builtinOpt[name]) {
							 | 
						||
| 
								 | 
							
												addDefaultBuiltin(builtins, name, vm);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return builtins;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function defaultCustomResolver() {
							 | 
						||
| 
								 | 
							
									return undefined;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const DEFAULT_FS = new DefaultFileSystem();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const DENY_RESOLVER = new Resolver(DEFAULT_FS, {__proto__: null}, [], id => {
							 | 
						||
| 
								 | 
							
									throw new VMError(`Access denied to require '${id}'`, 'EDENIED');
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function resolverFromOptions(vm, options, override, compiler) {
							 | 
						||
| 
								 | 
							
									if (!options) {
							 | 
						||
| 
								 | 
							
										if (!override) return DENY_RESOLVER;
							 | 
						||
| 
								 | 
							
										const builtins = genBuiltinsFromOptions(vm, undefined, undefined, override);
							 | 
						||
| 
								 | 
							
										return new Resolver(DEFAULT_FS, builtins, [], defaultRequire);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const {
							 | 
						||
| 
								 | 
							
										builtin: builtinOpt,
							 | 
						||
| 
								 | 
							
										mock: mockOpt,
							 | 
						||
| 
								 | 
							
										external: externalOpt,
							 | 
						||
| 
								 | 
							
										root: rootPaths,
							 | 
						||
| 
								 | 
							
										resolve: customResolver,
							 | 
						||
| 
								 | 
							
										customRequire: hostRequire = defaultRequire,
							 | 
						||
| 
								 | 
							
										context = 'host',
							 | 
						||
| 
								 | 
							
										strict = true,
							 | 
						||
| 
								 | 
							
										fs: fsOpt = DEFAULT_FS,
							 | 
						||
| 
								 | 
							
									} = options;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const builtins = genBuiltinsFromOptions(vm, builtinOpt, mockOpt, override);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (!externalOpt) return new Resolver(fsOpt, builtins, [], hostRequire);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									let checkPath;
							 | 
						||
| 
								 | 
							
									if (rootPaths) {
							 | 
						||
| 
								 | 
							
										const checkedRootPaths = (Array.isArray(rootPaths) ? rootPaths : [rootPaths]).map(f => fsOpt.resolve(f));
							 | 
						||
| 
								 | 
							
										checkPath = (filename) => {
							 | 
						||
| 
								 | 
							
											return checkedRootPaths.some(path => {
							 | 
						||
| 
								 | 
							
												if (!filename.startsWith(path)) return false;
							 | 
						||
| 
								 | 
							
												const len = path.length;
							 | 
						||
| 
								 | 
							
												if (filename.length === len || (len > 0 && fsOpt.isSeparator(path[len-1]))) return true;
							 | 
						||
| 
								 | 
							
												return fsOpt.isSeparator(filename[len]);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										checkPath = () => true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									let newCustomResolver = defaultCustomResolver;
							 | 
						||
| 
								 | 
							
									let externals = undefined;
							 | 
						||
| 
								 | 
							
									let external = undefined;
							 | 
						||
| 
								 | 
							
									if (customResolver) {
							 | 
						||
| 
								 | 
							
										let externalCache;
							 | 
						||
| 
								 | 
							
										newCustomResolver = (resolver, x, path, extList) => {
							 | 
						||
| 
								 | 
							
											if (external && !(resolver.pathIsAbsolute(x) || resolver.pathIsRelative(x))) {
							 | 
						||
| 
								 | 
							
												if (!externalCache) {
							 | 
						||
| 
								 | 
							
													externalCache = external.map(ext => new RegExp(makeExternalMatcherRegex(ext)));
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if (!externalCache.some(regex => regex.test(x))) return undefined;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											const resolved = customResolver(x, path);
							 | 
						||
| 
								 | 
							
											if (!resolved) return undefined;
							 | 
						||
| 
								 | 
							
											if (externals) externals.push(new RegExp('^' + escapeRegExp(resolved)));
							 | 
						||
| 
								 | 
							
											return resolver.loadAsFileOrDirecotry(resolved, extList);
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (typeof externalOpt !== 'object') {
							 | 
						||
| 
								 | 
							
										return new DefaultResolver(fsOpt, builtins, checkPath, [], () => context, newCustomResolver, hostRequire, compiler, strict);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									let transitive = false;
							 | 
						||
| 
								 | 
							
									if (Array.isArray(externalOpt)) {
							 | 
						||
| 
								 | 
							
										external = externalOpt;
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										external = externalOpt.modules;
							 | 
						||
| 
								 | 
							
										transitive = context === 'sandbox' && externalOpt.transitive;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									externals = external.map(makeExternalMatcher);
							 | 
						||
| 
								 | 
							
									return new LegacyResolver(fsOpt, builtins, checkPath, [], () => context, newCustomResolver, hostRequire, compiler, strict, externals, transitive);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.resolverFromOptions = resolverFromOptions;
							 |