aboutsummaryrefslogtreecommitdiff
path: root/node_modules/enhanced-resolve/lib/Resolver.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/enhanced-resolve/lib/Resolver.js')
-rw-r--r--node_modules/enhanced-resolve/lib/Resolver.js499
1 files changed, 301 insertions, 198 deletions
diff --git a/node_modules/enhanced-resolve/lib/Resolver.js b/node_modules/enhanced-resolve/lib/Resolver.js
index 5994d5d61..814704037 100644
--- a/node_modules/enhanced-resolve/lib/Resolver.js
+++ b/node_modules/enhanced-resolve/lib/Resolver.js
@@ -1,198 +1,301 @@
-/*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
-*/
-var Tapable = require("tapable");
-var createInnerCallback = require("./createInnerCallback");
-
-function Resolver(fileSystem) {
- Tapable.call(this);
- this.fileSystem = fileSystem;
-}
-module.exports = Resolver;
-
-Resolver.prototype = Object.create(Tapable.prototype);
-
-Resolver.prototype.constructor = Resolver;
-
-Resolver.prototype.resolveSync = function resolveSync(context, path, request) {
- var err, result, sync = false;
- this.resolve(context, path, request, function(e, r) {
- err = e;
- result = r;
- sync = true;
- });
- if(!sync) throw new Error("Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!");
- if(err) throw err;
- return result;
-};
-
-Resolver.prototype.resolve = function resolve(context, path, request, callback) {
- if(arguments.length === 3) {
- throw new Error("Signature changed: context parameter added");
- }
- var resolver = this;
- var obj = {
- context: context,
- path: path,
- request: request
- };
-
- var localMissing;
- var log;
- var message = "resolve '" + request + "' in '" + path + "'";
-
- function writeLog(msg) {
- log.push(msg);
- }
-
- function logAsString() {
- return log.join("\n");
- }
-
- function onError(err, result) {
- if(callback.log) {
- for(var i = 0; i < log.length; i++)
- callback.log(log[i]);
- }
-
- if(err) return callback(err);
-
- var error = new Error("Can't " + message);
- error.details = logAsString();
- error.missing = localMissing;
- resolver.applyPlugins("no-resolve", obj, error);
- return callback(error);
- }
-
- function onResolve(err, result) {
- if(!err && result) {
- return callback(null, result.path === false ? false : result.path + (result.query || ""), result);
- }
-
- localMissing = [];
- log = [];
-
- return resolver.doResolve("resolve", obj, message, createInnerCallback(onError, {
- log: writeLog,
- missing: localMissing,
- stack: callback.stack
- }));
- }
-
- onResolve.missing = callback.missing;
- onResolve.stack = callback.stack;
-
- return this.doResolve("resolve", obj, message, onResolve);
-};
-
-Resolver.prototype.doResolve = function doResolve(type, request, message, callback) {
- var resolver = this;
- var stackLine = type + ": (" + request.path + ") " +
- (request.request || "") + (request.query || "") +
- (request.directory ? " directory" : "") +
- (request.module ? " module" : "");
- var newStack = [stackLine];
- if(callback.stack) {
- newStack = callback.stack.concat(newStack);
- if(callback.stack.indexOf(stackLine) >= 0) {
- // Prevent recursion
- var recursionError = new Error("Recursion in resolving\nStack:\n " + newStack.join("\n "));
- recursionError.recursion = true;
- if(callback.log) callback.log("abort resolving because of recursion");
- return callback(recursionError);
- }
- }
- resolver.applyPlugins("resolve-step", type, request);
-
- resolver.applyPluginsAsyncSeriesBailResult1("before-" + type, request, createInnerCallback(beforeInnerCallback, {
- log: callback.log,
- missing: callback.missing,
- stack: newStack
- }, message && ("before " + message), true));
-
- function beforeInnerCallback(err, result) {
- if(arguments.length > 0) {
- if(err) return callback(err);
- if(result) return callback(null, result);
- return callback();
- }
- return resolver.applyPluginsParallelBailResult1(type, request, createInnerCallback(innerCallback, {
- log: callback.log,
- missing: callback.missing,
- stack: newStack
- }, message));
- }
-
- function innerCallback(err, result) {
- if(arguments.length > 0) {
- if(err) return callback(err);
- if(result) return callback(null, result);
- return callback();
- }
- return resolver.applyPluginsAsyncSeriesBailResult1("after-" + type, request, createInnerCallback(afterInnerCallback, {
- log: callback.log,
- missing: callback.missing,
- stack: newStack
- }, message && ("after " + message), true));
- }
-
- function afterInnerCallback(err, result) {
- if(arguments.length > 0) {
- if(err) return callback(err);
- if(result) return callback(null, result);
- return callback();
- }
- return callback();
- }
-};
-
-Resolver.prototype.parse = function parse(identifier) {
- if(identifier === "") return null;
- var part = {
- request: "",
- query: "",
- module: false,
- directory: false,
- file: false
- };
- var idxQuery = identifier.indexOf("?");
- if(idxQuery === 0) {
- part.query = identifier;
- } else if(idxQuery > 0) {
- part.request = identifier.slice(0, idxQuery);
- part.query = identifier.slice(idxQuery);
- } else {
- part.request = identifier;
- }
- if(part.request) {
- part.module = this.isModule(part.request);
- part.directory = this.isDirectory(part.request);
- if(part.directory) {
- part.request = part.request.substr(0, part.request.length - 1);
- }
- }
- return part;
-};
-
-var notModuleRegExp = /^\.$|^\.[\\\/]|^\.\.$|^\.\.[\/\\]|^\/|^[A-Z]:[\\\/]/i;
-Resolver.prototype.isModule = function isModule(path) {
- return !notModuleRegExp.test(path);
-};
-
-var directoryRegExp = /[\/\\]$/i;
-Resolver.prototype.isDirectory = function isDirectory(path) {
- return directoryRegExp.test(path);
-};
-
-var memoryFsJoin = require("memory-fs/lib/join");
-var memoizedJoin = {};
-Resolver.prototype.join = function(path, request) {
- var memoizeKey = path + "|$" + request;
- if(!memoizedJoin[memoizeKey]) {
- memoizedJoin[memoizeKey] = memoryFsJoin(path, request);
- }
- return memoizedJoin[memoizeKey];
-};
-
-Resolver.prototype.normalize = require("memory-fs/lib/normalize");
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+"use strict";
+
+const util = require("util");
+
+const Tapable = require("tapable/lib/Tapable");
+const SyncHook = require("tapable/lib/SyncHook");
+const AsyncSeriesBailHook = require("tapable/lib/AsyncSeriesBailHook");
+const AsyncSeriesHook = require("tapable/lib/AsyncSeriesHook");
+const createInnerContext = require("./createInnerContext");
+
+const REGEXP_NOT_MODULE = /^\.$|^\.[\\\/]|^\.\.$|^\.\.[\/\\]|^\/|^[A-Z]:[\\\/]/i;
+const REGEXP_DIRECTORY = /[\/\\]$/i;
+
+const memoryFsJoin = require("memory-fs/lib/join");
+const memoizedJoin = new Map();
+const memoryFsNormalize = require("memory-fs/lib/normalize");
+
+function withName(name, hook) {
+ hook.name = name;
+ return hook;
+}
+
+function toCamelCase(str) {
+ return str.replace(/-([a-z])/g, str => str.substr(1).toUpperCase());
+}
+
+const deprecatedPushToMissing = util.deprecate((set, item) => {
+ set.add(item);
+}, "Resolver: 'missing' is now a Set. Use add instead of push.");
+
+const deprecatedResolveContextInCallback = util.deprecate((x) => {
+ return x;
+}, "Resolver: The callback argument was splitted into resolveContext and callback.");
+
+const deprecatedHookAsString = util.deprecate((x) => {
+ return x;
+}, "Resolver#doResolve: The type arguments (string) is now a hook argument (Hook). Pass a reference to the hook instead.");
+
+class Resolver extends Tapable {
+ constructor(fileSystem) {
+ super();
+ this.fileSystem = fileSystem;
+ this.hooks = {
+ resolveStep: withName("resolveStep", new SyncHook(["hook", "request"])),
+ noResolve: withName("noResolve", new SyncHook(["request", "error"])),
+ resolve: withName("resolve", new AsyncSeriesBailHook(["request", "resolveContext"])),
+ result: new AsyncSeriesHook(["result", "resolveContext"])
+ };
+ this._pluginCompat.tap("Resolver: before/after", options => {
+ if(/^before-/.test(options.name)) {
+ options.name = options.name.substr(7);
+ options.stage = -10;
+ } else if(/^after-/.test(options.name)) {
+ options.name = options.name.substr(6);
+ options.stage = 10;
+ }
+ });
+ this._pluginCompat.tap("Resolver: step hooks", options => {
+ const name = options.name;
+ const stepHook = !/^resolve(-s|S)tep$|^no(-r|R)esolve$/.test(name);
+ if(stepHook) {
+ options.async = true;
+ this.ensureHook(name);
+ const fn = options.fn;
+ options.fn = (request, resolverContext, callback) => {
+ const innerCallback = (err, result) => {
+ if(err) return callback(err);
+ if(result !== undefined) return callback(null, result);
+ callback();
+ };
+ for(const key in resolverContext) {
+ innerCallback[key] = resolverContext[key];
+ }
+ fn.call(this, request, innerCallback);
+ };
+ }
+ });
+ }
+
+ ensureHook(name) {
+ if(typeof name !== "string") return name;
+ name = toCamelCase(name);
+ if(/^before/.test(name)) {
+ return this.ensureHook(name[6].toLowerCase() + name.substr(7)).withOptions({
+ stage: -10
+ });
+ }
+ if(/^after/.test(name)) {
+ return this.ensureHook(name[5].toLowerCase() + name.substr(6)).withOptions({
+ stage: 10
+ });
+ }
+ const hook = this.hooks[name];
+ if(!hook) {
+ return this.hooks[name] = withName(name, new AsyncSeriesBailHook(["request", "resolveContext"]));
+ }
+ return hook;
+ }
+
+ getHook(name) {
+ if(typeof name !== "string") return name;
+ name = toCamelCase(name);
+ if(/^before/.test(name)) {
+ return this.getHook(name[6].toLowerCase() + name.substr(7)).withOptions({
+ stage: -10
+ });
+ }
+ if(/^after/.test(name)) {
+ return this.getHook(name[5].toLowerCase() + name.substr(6)).withOptions({
+ stage: 10
+ });
+ }
+ const hook = this.hooks[name];
+ if(!hook) {
+ throw new Error(`Hook ${name} doesn't exist`);
+ }
+ return hook;
+ }
+
+ resolveSync(context, path, request) {
+ let err, result, sync = false;
+ this.resolve(context, path, request, {}, (e, r) => {
+ err = e;
+ result = r;
+ sync = true;
+ });
+ if(!sync) throw new Error("Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!");
+ if(err) throw err;
+ return result;
+ }
+
+ resolve(context, path, request, resolveContext, callback) {
+ // TODO remove in enhanced-resolve 5
+ // For backward compatiblity START
+ if(typeof callback !== "function") {
+ callback = deprecatedResolveContextInCallback(resolveContext);
+ // resolveContext is a function containing additional properties
+ // It's now used for resolveContext and callback
+ }
+ // END
+ const obj = {
+ context: context,
+ path: path,
+ request: request
+ };
+
+ const message = "resolve '" + request + "' in '" + path + "'";
+
+ // Try to resolve assuming there is no error
+ // We don't log stuff in this case
+ return this.doResolve(this.hooks.resolve, obj, message, {
+ missing: resolveContext.missing,
+ stack: resolveContext.stack
+ }, (err, result) => {
+ if(!err && result) {
+ return callback(null, result.path === false ? false : result.path + (result.query || ""), result);
+ }
+
+ const localMissing = new Set();
+ // TODO remove in enhanced-resolve 5
+ localMissing.push = item => deprecatedPushToMissing(localMissing, item);
+ const log = [];
+
+ return this.doResolve(this.hooks.resolve, obj, message, {
+ log: msg => {
+ if(resolveContext.log) {
+ resolveContext.log(msg);
+ }
+ log.push(msg);
+ },
+ missing: localMissing,
+ stack: resolveContext.stack
+ }, (err, result) => {
+ if(err) return callback(err);
+
+ const error = new Error("Can't " + message);
+ error.details = log.join("\n");
+ error.missing = Array.from(localMissing);
+ this.hooks.noResolve.call(obj, error);
+ return callback(error);
+ });
+ });
+ }
+
+ doResolve(hook, request, message, resolveContext, callback) {
+ // TODO remove in enhanced-resolve 5
+ // For backward compatiblity START
+ if(typeof callback !== "function") {
+ callback = deprecatedResolveContextInCallback(resolveContext);
+ // resolveContext is a function containing additional properties
+ // It's now used for resolveContext and callback
+ }
+ if(typeof hook === "string") {
+ const name = toCamelCase(hook);
+ hook = deprecatedHookAsString(this.hooks[name]);
+ if(!hook) {
+ throw new Error(`Hook "${name}" doesn't exist`);
+ }
+ }
+ // END
+ if(typeof callback !== "function") throw new Error("callback is not a function " + Array.from(arguments));
+ if(!resolveContext) throw new Error("resolveContext is not an object " + Array.from(arguments));
+
+ const stackLine = hook.name + ": (" + request.path + ") " +
+ (request.request || "") + (request.query || "") +
+ (request.directory ? " directory" : "") +
+ (request.module ? " module" : "");
+
+ let newStack;
+ if(resolveContext.stack) {
+ newStack = new Set(resolveContext.stack);
+ if(resolveContext.stack.has(stackLine)) {
+ // Prevent recursion
+ const recursionError = new Error("Recursion in resolving\nStack:\n " + Array.from(newStack).join("\n "));
+ recursionError.recursion = true;
+ if(resolveContext.log) resolveContext.log("abort resolving because of recursion");
+ return callback(recursionError);
+ }
+ newStack.add(stackLine);
+ } else {
+ newStack = new Set([stackLine]);
+ }
+ this.hooks.resolveStep.call(hook, request);
+
+ if(hook.isUsed()) {
+ const innerContext = createInnerContext({
+ log: resolveContext.log,
+ missing: resolveContext.missing,
+ stack: newStack
+ }, message);
+ return hook.callAsync(request, innerContext, (err, result) => {
+ if(err) return callback(err);
+ if(result) return callback(null, result);
+ callback();
+ });
+ } else {
+ callback();
+ }
+ }
+
+ parse(identifier) {
+ if(identifier === "") return null;
+ const part = {
+ request: "",
+ query: "",
+ module: false,
+ directory: false,
+ file: false
+ };
+ const idxQuery = identifier.indexOf("?");
+ if(idxQuery === 0) {
+ part.query = identifier;
+ } else if(idxQuery > 0) {
+ part.request = identifier.slice(0, idxQuery);
+ part.query = identifier.slice(idxQuery);
+ } else {
+ part.request = identifier;
+ }
+ if(part.request) {
+ part.module = this.isModule(part.request);
+ part.directory = this.isDirectory(part.request);
+ if(part.directory) {
+ part.request = part.request.substr(0, part.request.length - 1);
+ }
+ }
+ return part;
+ }
+
+ isModule(path) {
+ return !REGEXP_NOT_MODULE.test(path);
+ }
+
+ isDirectory(path) {
+ return REGEXP_DIRECTORY.test(path);
+ }
+
+ join(path, request) {
+ let cacheEntry;
+ let pathCache = memoizedJoin.get(path);
+ if(typeof pathCache === "undefined") {
+ memoizedJoin.set(path, pathCache = new Map());
+ } else {
+ cacheEntry = pathCache.get(request);
+ if(typeof cacheEntry !== "undefined")
+ return cacheEntry;
+ }
+ cacheEntry = memoryFsJoin(path, request);
+ pathCache.set(request, cacheEntry);
+ return cacheEntry;
+ }
+
+ normalize(path) {
+ return memoryFsNormalize(path);
+ }
+}
+
+module.exports = Resolver;