|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"use strict"; |
|
|
|
|
|
const forEachBail = require("./forEachBail"); |
|
|
const { PathType, getType } = require("./util/path"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = class AliasPlugin { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(source, options, target) { |
|
|
this.source = source; |
|
|
this.options = Array.isArray(options) ? options : [options]; |
|
|
this.target = target; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apply(resolver) { |
|
|
const target = resolver.ensureHook(this.target); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getAbsolutePathWithSlashEnding = (maybeAbsolutePath) => { |
|
|
const type = getType(maybeAbsolutePath); |
|
|
if (type === PathType.AbsolutePosix || type === PathType.AbsoluteWin) { |
|
|
return resolver.join(maybeAbsolutePath, "_").slice(0, -1); |
|
|
} |
|
|
return null; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isSubPath = (path, maybeSubPath) => { |
|
|
const absolutePath = getAbsolutePathWithSlashEnding(maybeSubPath); |
|
|
if (!absolutePath) return false; |
|
|
return path.startsWith(absolutePath); |
|
|
}; |
|
|
resolver |
|
|
.getHook(this.source) |
|
|
.tapAsync("AliasPlugin", (request, resolveContext, callback) => { |
|
|
const innerRequest = request.request || request.path; |
|
|
if (!innerRequest) return callback(); |
|
|
|
|
|
forEachBail( |
|
|
this.options, |
|
|
(item, callback) => { |
|
|
|
|
|
let shouldStop = false; |
|
|
|
|
|
const matchRequest = |
|
|
innerRequest === item.name || |
|
|
(!item.onlyModule && |
|
|
(request.request |
|
|
? innerRequest.startsWith(`${item.name}/`) |
|
|
: isSubPath(innerRequest, item.name))); |
|
|
|
|
|
const splitName = item.name.split("*"); |
|
|
const matchWildcard = !item.onlyModule && splitName.length === 2; |
|
|
|
|
|
if (matchRequest || matchWildcard) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const resolveWithAlias = (alias, callback) => { |
|
|
if (alias === false) { |
|
|
|
|
|
const ignoreObj = { |
|
|
...request, |
|
|
path: false, |
|
|
}; |
|
|
if (typeof resolveContext.yield === "function") { |
|
|
resolveContext.yield(ignoreObj); |
|
|
return callback(null, null); |
|
|
} |
|
|
return callback(null, ignoreObj); |
|
|
} |
|
|
|
|
|
let newRequestStr; |
|
|
|
|
|
const [prefix, suffix] = splitName; |
|
|
if ( |
|
|
matchWildcard && |
|
|
innerRequest.startsWith(prefix) && |
|
|
innerRequest.endsWith(suffix) |
|
|
) { |
|
|
const match = innerRequest.slice( |
|
|
prefix.length, |
|
|
innerRequest.length - suffix.length, |
|
|
); |
|
|
newRequestStr = item.alias.toString().replace("*", match); |
|
|
} |
|
|
|
|
|
if ( |
|
|
matchRequest && |
|
|
innerRequest !== alias && |
|
|
!innerRequest.startsWith(`${alias}/`) |
|
|
) { |
|
|
|
|
|
const remainingRequest = innerRequest.slice(item.name.length); |
|
|
newRequestStr = alias + remainingRequest; |
|
|
} |
|
|
|
|
|
if (newRequestStr !== undefined) { |
|
|
shouldStop = true; |
|
|
|
|
|
const obj = { |
|
|
...request, |
|
|
request: newRequestStr, |
|
|
fullySpecified: false, |
|
|
}; |
|
|
return resolver.doResolve( |
|
|
target, |
|
|
obj, |
|
|
`aliased with mapping '${item.name}': '${alias}' to '${newRequestStr}'`, |
|
|
resolveContext, |
|
|
(err, result) => { |
|
|
if (err) return callback(err); |
|
|
if (result) return callback(null, result); |
|
|
return callback(); |
|
|
}, |
|
|
); |
|
|
} |
|
|
return callback(); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const stoppingCallback = (err, result) => { |
|
|
if (err) return callback(err); |
|
|
|
|
|
if (result) return callback(null, result); |
|
|
|
|
|
if (shouldStop) return callback(null, null); |
|
|
return callback(); |
|
|
}; |
|
|
|
|
|
if (Array.isArray(item.alias)) { |
|
|
return forEachBail( |
|
|
item.alias, |
|
|
resolveWithAlias, |
|
|
stoppingCallback, |
|
|
); |
|
|
} |
|
|
return resolveWithAlias(item.alias, stoppingCallback); |
|
|
} |
|
|
|
|
|
return callback(); |
|
|
}, |
|
|
callback, |
|
|
); |
|
|
}); |
|
|
} |
|
|
}; |
|
|
|