Spaces:
Running
Running
| /* | |
| MIT License http://www.opensource.org/licenses/mit-license.php | |
| Author Tobias Koppers @sokra | |
| */ | |
| ; | |
| const forEachBail = require("./forEachBail"); | |
| const { PathType, getType } = require("./util/path"); | |
| /** @typedef {import("./Resolver")} Resolver */ | |
| /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */ | |
| /** @typedef {import("./Resolver").ResolveContext} ResolveContext */ | |
| /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ | |
| /** @typedef {import("./Resolver").ResolveCallback} ResolveCallback */ | |
| /** @typedef {string | string[] | false} Alias */ | |
| /** @typedef {{ alias: Alias, name: string, onlyModule?: boolean }} AliasOption */ | |
| /** @typedef {(err?: null | Error, result?: null | ResolveRequest) => void} InnerCallback */ | |
| /** | |
| * @param {Resolver} resolver resolver | |
| * @param {AliasOption[]} options options | |
| * @param {ResolveStepHook} target target | |
| * @param {ResolveRequest} request request | |
| * @param {ResolveContext} resolveContext resolve context | |
| * @param {InnerCallback} callback callback | |
| * @returns {void} | |
| */ | |
| function aliasResolveHandler( | |
| resolver, | |
| options, | |
| target, | |
| request, | |
| resolveContext, | |
| callback, | |
| ) { | |
| const innerRequest = request.request || request.path; | |
| if (!innerRequest) return callback(); | |
| /** | |
| * @param {string} maybeAbsolutePath path | |
| * @returns {null | string} absolute path with slash ending | |
| */ | |
| const getAbsolutePathWithSlashEnding = (maybeAbsolutePath) => { | |
| const type = getType(maybeAbsolutePath); | |
| if (type === PathType.AbsolutePosix || type === PathType.AbsoluteWin) { | |
| return resolver.join(maybeAbsolutePath, "_").slice(0, -1); | |
| } | |
| return null; | |
| }; | |
| /** | |
| * @param {string} path path | |
| * @param {string} maybeSubPath sub path | |
| * @returns {boolean} true, if path is sub path | |
| */ | |
| const isSubPath = (path, maybeSubPath) => { | |
| const absolutePath = getAbsolutePathWithSlashEnding(maybeSubPath); | |
| if (!absolutePath) return false; | |
| return path.startsWith(absolutePath); | |
| }; | |
| forEachBail( | |
| options, | |
| (item, callback) => { | |
| /** @type {boolean} */ | |
| 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) { | |
| /** | |
| * @param {Alias} alias alias | |
| * @param {(err?: null | Error, result?: null | ResolveRequest) => void} callback callback | |
| * @returns {void} | |
| */ | |
| const resolveWithAlias = (alias, callback) => { | |
| if (alias === false) { | |
| /** @type {ResolveRequest} */ | |
| 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 = alias.toString().replace("*", match); | |
| } | |
| if ( | |
| matchRequest && | |
| innerRequest !== alias && | |
| !innerRequest.startsWith(`${alias}/`) | |
| ) { | |
| /** @type {string} */ | |
| const remainingRequest = innerRequest.slice(item.name.length); | |
| newRequestStr = alias + remainingRequest; | |
| } | |
| if (newRequestStr !== undefined) { | |
| shouldStop = true; | |
| /** @type {ResolveRequest} */ | |
| 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(); | |
| }; | |
| /** | |
| * @param {(null | Error)=} err error | |
| * @param {(null | ResolveRequest)=} result result | |
| * @returns {void} | |
| */ | |
| const stoppingCallback = (err, result) => { | |
| if (err) return callback(err); | |
| if (result) return callback(null, result); | |
| // Don't allow other aliasing or raw request | |
| 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, | |
| ); | |
| } | |
| module.exports.aliasResolveHandler = aliasResolveHandler; | |