/** * This webpack resolver is largely based on TypeScript's "paths" handling * The TypeScript license can be found here: * https://github.com/microsoft/TypeScript/blob/214df64e287804577afa1fea0184c18c40f7d1ca/LICENSE.txt */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { hasZeroOrOneAsteriskCharacter: null, pathIsRelative: null, tryParsePattern: null, findBestPatternMatch: null, matchPatternOrExact: null, isString: null, matchedText: null, patternText: null, JsConfigPathsPlugin: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { hasZeroOrOneAsteriskCharacter: function() { return hasZeroOrOneAsteriskCharacter; }, pathIsRelative: function() { return pathIsRelative; }, tryParsePattern: function() { return tryParsePattern; }, findBestPatternMatch: function() { return findBestPatternMatch; }, matchPatternOrExact: function() { return matchPatternOrExact; }, isString: function() { return isString; }, matchedText: function() { return matchedText; }, patternText: function() { return patternText; }, JsConfigPathsPlugin: function() { return JsConfigPathsPlugin; } }); const _path = /*#__PURE__*/ _interop_require_default(require("path")); const _debug = require("next/dist/compiled/debug"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const log = (0, _debug.debug)("next:jsconfig-paths-plugin"); const asterisk = 0x2a; function hasZeroOrOneAsteriskCharacter(str) { let seenAsterisk = false; for(let i = 0; i < str.length; i++){ if (str.charCodeAt(i) === asterisk) { if (!seenAsterisk) { seenAsterisk = true; } else { // have already seen asterisk return false; } } } return true; } function pathIsRelative(testPath) { return /^\.\.?($|[\\/])/.test(testPath); } function tryParsePattern(pattern) { // This should be verified outside of here and a proper error thrown. const indexOfStar = pattern.indexOf("*"); return indexOfStar === -1 ? undefined : { prefix: pattern.slice(0, indexOfStar), suffix: pattern.slice(indexOfStar + 1) }; } function isPatternMatch({ prefix, suffix }, candidate) { return candidate.length >= prefix.length + suffix.length && candidate.startsWith(prefix) && candidate.endsWith(suffix); } function findBestPatternMatch(values, getPattern, candidate) { let matchedValue; // use length of prefix as betterness criteria let longestMatchPrefixLength = -1; for (const v of values){ const pattern = getPattern(v); if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) { longestMatchPrefixLength = pattern.prefix.length; matchedValue = v; } } return matchedValue; } function matchPatternOrExact(patternStrings, candidate) { const patterns = []; for (const patternString of patternStrings){ if (!hasZeroOrOneAsteriskCharacter(patternString)) continue; const pattern = tryParsePattern(patternString); if (pattern) { patterns.push(pattern); } else if (patternString === candidate) { // pattern was matched as is - no need to search further return patternString; } } return findBestPatternMatch(patterns, (_)=>_, candidate); } function isString(text) { return typeof text === "string"; } function matchedText(pattern, candidate) { return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length); } function patternText({ prefix, suffix }) { return `${prefix}*${suffix}`; } /** * Calls the iterator function for each entry of the array * until the first result or error is reached */ function forEachBail(array, iterator, callback) { if (array.length === 0) return callback(); let i = 0; const next = ()=>{ let loop = undefined; iterator(array[i++], (err, result)=>{ if (err || result !== undefined || i >= array.length) { return callback(err, result); } if (loop === false) while(next()); loop = true; }); if (!loop) loop = false; return loop; }; while(next()); } const NODE_MODULES_REGEX = /node_modules/; class JsConfigPathsPlugin { constructor(paths, resolvedBaseUrl){ this.paths = paths; this.resolvedBaseUrl = resolvedBaseUrl; this.jsConfigPlugin = true; log("tsconfig.json or jsconfig.json paths: %O", paths); log("resolved baseUrl: %s", resolvedBaseUrl); } apply(resolver) { const target = resolver.ensureHook("resolve"); resolver.getHook("described-resolve").tapAsync("JsConfigPathsPlugin", (request, resolveContext, callback)=>{ const paths = this.paths; const pathsKeys = Object.keys(paths); // If no aliases are added bail out if (pathsKeys.length === 0) { log("paths are empty, bailing out"); return callback(); } const moduleName = request.request; // Exclude node_modules from paths support (speeds up resolving) if (request.path.match(NODE_MODULES_REGEX)) { log("skipping request as it is inside node_modules %s", moduleName); return callback(); } if (_path.default.posix.isAbsolute(moduleName) || process.platform === "win32" && _path.default.win32.isAbsolute(moduleName)) { log("skipping request as it is an absolute path %s", moduleName); return callback(); } if (pathIsRelative(moduleName)) { log("skipping request as it is a relative path %s", moduleName); return callback(); } // log('starting to resolve request %s', moduleName) // If the module name does not match any of the patterns in `paths` we hand off resolving to webpack const matchedPattern = matchPatternOrExact(pathsKeys, moduleName); if (!matchedPattern) { log("moduleName did not match any paths pattern %s", moduleName); return callback(); } const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName); const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern); let triedPaths = []; forEachBail(paths[matchedPatternText], (subst, pathCallback)=>{ const curPath = matchedStar ? subst.replace("*", matchedStar) : subst; // Ensure .d.ts is not matched if (curPath.endsWith(".d.ts")) { // try next path candidate return pathCallback(); } const candidate = _path.default.join(this.resolvedBaseUrl, curPath); const obj = Object.assign({}, request, { request: candidate }); resolver.doResolve(target, obj, `Aliased with tsconfig.json or jsconfig.json ${matchedPatternText} to ${candidate}`, resolveContext, (resolverErr, resolverResult)=>{ if (resolverErr || resolverResult === undefined) { triedPaths.push(candidate); // try next path candidate return pathCallback(); } return pathCallback(resolverErr, resolverResult); }); }, callback); }); } } //# sourceMappingURL=jsconfig-paths-plugin.js.map