Update npm packages (73 packages including @jqhtml 2.3.36)

Update npm registry domain from privatenpm.hanson.xyz to npm.internal.hanson.xyz

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-02-20 11:31:28 +00:00
parent d01a6179aa
commit b5eb27a827
1690 changed files with 47348 additions and 16848 deletions

View File

@@ -85,33 +85,36 @@ myResolver.resolve(
#### Resolver Options
| Field | Default | Description |
| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| alias | [] | A list of module alias configurations or an object which maps key to value |
| aliasFields | [] | A list of alias fields in description files |
| extensionAlias | {} | An object which maps extension to extension aliases |
| cachePredicate | function() { return true }; | A function which decides whether a request should be cached or not. An object is passed to the function with `path` and `request` properties. |
| cacheWithContext | true | If unsafe cache is enabled, includes `request.context` in the cache key |
| conditionNames | [] | A list of exports field condition names |
| descriptionFiles | ["package.json"] | A list of description files to read from |
| enforceExtension | false | Enforce that a extension from extensions must be used |
| exportsFields | ["exports"] | A list of exports fields in description files |
| extensions | [".js", ".json", ".node"] | A list of extensions which should be tried for files |
| fallback | [] | Same as `alias`, but only used if default resolving fails |
| fileSystem | | The file system which should be used |
| fullySpecified | false | Request passed to resolve is already fully specified and extensions or main files are not resolved for it (they are still resolved for internal requests) |
| mainFields | ["main"] | A list of main fields in description files |
| mainFiles | ["index"] | A list of main files in directories |
| modules | ["node_modules"] | A list of directories to resolve modules from, can be absolute path or folder name |
| plugins | [] | A list of additional resolve plugins which should be applied |
| resolver | undefined | A prepared Resolver to which the plugins are attached |
| resolveToContext | false | Resolve to a context instead of a file |
| preferRelative | false | Prefer to resolve module requests as relative request and fallback to resolving as module |
| preferAbsolute | false | Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots |
| restrictions | [] | A list of resolve restrictions |
| roots | [] | A list of root paths |
| symlinks | true | Whether to resolve symlinks to their symlinked location |
| unsafeCache | false | Use this cache object to unsafely cache the successful requests |
| Field | Default | Description |
| ------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| alias | [] | A list of module alias configurations or an object which maps key to value |
| aliasFields | [] | A list of alias fields in description files |
| extensionAlias | {} | An object which maps extension to extension aliases |
| cachePredicate | function() { return true }; | A function which decides whether a request should be cached or not. An object is passed to the function with `path` and `request` properties. |
| cacheWithContext | true | If unsafe cache is enabled, includes `request.context` in the cache key |
| conditionNames | [] | A list of exports field condition names |
| descriptionFiles | ["package.json"] | A list of description files to read from |
| enforceExtension | false | Enforce that a extension from extensions must be used |
| exportsFields | ["exports"] | A list of exports fields in description files |
| extensions | [".js", ".json", ".node"] | A list of extensions which should be tried for files |
| fallback | [] | Same as `alias`, but only used if default resolving fails |
| fileSystem | | The file system which should be used |
| fullySpecified | false | Request passed to resolve is already fully specified and extensions or main files are not resolved for it (they are still resolved for internal requests) |
| mainFields | ["main"] | A list of main fields in description files |
| mainFiles | ["index"] | A list of main files in directories |
| modules | ["node_modules"] | A list of directories to resolve modules from, can be absolute path or folder name |
| plugins | [] | A list of additional resolve plugins which should be applied |
| resolver | undefined | A prepared Resolver to which the plugins are attached |
| resolveToContext | false | Resolve to a context instead of a file |
| preferRelative | false | Prefer to resolve module requests as relative request and fallback to resolving as module |
| preferAbsolute | false | Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots |
| restrictions | [] | A list of resolve restrictions |
| roots | [] | A list of root paths |
| symlinks | true | Whether to resolve symlinks to their symlinked location |
| tsconfig | false | TypeScript config for paths mapping. Can be `false` (disabled), `true` (use default `tsconfig.json`), a string path to `tsconfig.json`, or an object with `configFile` and `references` options. |
| tsconfig.configFile | tsconfig.json | Path to the tsconfig.json file |
| tsconfig.references | [] | Project references. `'auto'` to load from tsconfig, or an array of paths to referenced projects |
| unsafeCache | false | Use this cache object to unsafely cache the successful requests |
## Plugins
@@ -152,7 +155,7 @@ enhanced-resolve will try to resolve requests containing `#` as path and as frag
## Tests
```sh
yarn test
npm run test
```
## Passing options from webpack

View File

@@ -16,7 +16,7 @@ const getInnerRequest = require("./getInnerRequest");
module.exports = class AliasFieldPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | Array<string>} field field
* @param {string | string[]} field field
* @param {string | ResolveStepHook} target target
*/
constructor(source, field, target) {
@@ -54,11 +54,11 @@ module.exports = class AliasFieldPlugin {
fieldData,
innerRequest,
)
? /** @type {{[Key in string]: JsonPrimitive}} */ (fieldData)[
? /** @type {{ [Key in string]: JsonPrimitive }} */ (fieldData)[
innerRequest
]
: innerRequest.startsWith("./")
? /** @type {{[Key in string]: JsonPrimitive}} */ (fieldData)[
? /** @type {{ [Key in string]: JsonPrimitive }} */ (fieldData)[
innerRequest.slice(2)
]
: undefined;

View File

@@ -5,19 +5,17 @@
"use strict";
const forEachBail = require("./forEachBail");
const { PathType, getType } = require("./util/path");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {string | Array<string> | false} Alias */
/** @typedef {{alias: Alias, name: string, onlyModule?: boolean}} AliasOption */
/** @typedef {string | string[] | false} Alias */
/** @typedef {{ alias: Alias, name: string, onlyModule?: boolean }} AliasOption */
const { aliasResolveHandler } = require("./AliasUtils");
module.exports = class AliasPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {AliasOption | Array<AliasOption>} options options
* @param {AliasOption | AliasOption[]} options options
* @param {string | ResolveStepHook} target target
*/
constructor(source, options, target) {
@@ -32,143 +30,16 @@ module.exports = class AliasPlugin {
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
/**
* @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);
};
resolver
.getHook(this.source)
.tapAsync("AliasPlugin", (request, resolveContext, callback) => {
const innerRequest = request.request || request.path;
if (!innerRequest) return callback();
forEachBail(
aliasResolveHandler(
resolver,
this.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();
},
target,
request,
resolveContext,
callback,
);
});

172
node_modules/enhanced-resolve/lib/AliasUtils.js generated vendored Normal file
View File

@@ -0,0 +1,172 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
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;

View File

@@ -59,9 +59,9 @@ const runCallbacks = (callbacks, err, result) => {
if (error) throw error;
};
// eslint-disable-next-line jsdoc/no-restricted-syntax
// eslint-disable-next-line jsdoc/reject-function-type
/** @typedef {Function} EXPECTED_FUNCTION */
// eslint-disable-next-line jsdoc/no-restricted-syntax
// eslint-disable-next-line jsdoc/reject-any-type
/** @typedef {any} EXPECTED_ANY */
class OperationMergerBackend {

View File

@@ -22,7 +22,7 @@ const forEachBail = require("./forEachBail");
/**
* @callback ErrorFirstCallback
* @param {Error|null=} error
* @param {Error | null=} error
* @param {DescriptionFileInfo=} result
*/
@@ -35,7 +35,7 @@ const forEachBail = require("./forEachBail");
/**
* @param {string} directory directory
* @returns {string|null} parent directory or null
* @returns {string | null} parent directory or null
*/
function cdUp(directory) {
if (directory === "/") return null;
@@ -50,7 +50,7 @@ function cdUp(directory) {
* @param {Resolver} resolver resolver
* @param {string} directory directory
* @param {string[]} filenames filenames
* @param {DescriptionFileInfo|undefined} oldInfo oldInfo
* @param {DescriptionFileInfo | undefined} oldInfo oldInfo
* @param {ResolveContext} resolveContext resolveContext
* @param {ErrorFirstCallback} callback callback
*/
@@ -71,7 +71,7 @@ function loadDescriptionFile(
filenames,
/**
* @param {string} filename filename
* @param {(err?: null|Error, result?: null|Result) => void} callback callback
* @param {(err?: null | Error, result?: null | Result) => void} callback callback
* @returns {void}
*/
(filename, callback) => {
@@ -172,7 +172,7 @@ function loadDescriptionFile(
/**
* @param {JsonObject} content content
* @param {string|string[]} field field
* @param {string | string[]} field field
* @returns {JsonValue | undefined} field data
*/
function getField(content, field) {

View File

@@ -64,7 +64,7 @@ module.exports = class ExportsFieldPlugin {
request.fragment
: request.request;
const exportsField =
/** @type {ExportsField|null|undefined} */
/** @type {ExportsField | null | undefined} */
(
DescriptionFileUtils.getField(
/** @type {JsonObject} */ (request.descriptionFileData),
@@ -130,7 +130,7 @@ module.exports = class ExportsFieldPlugin {
paths,
/**
* @param {string} path path
* @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
* @param {(err?: null | Error, result?: null | ResolveRequest) => void} callback callback
* @param {number} i index
* @returns {void}
*/

View File

@@ -10,7 +10,7 @@ const forEachBail = require("./forEachBail");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {{ alias: string|string[], extension: string }} ExtensionAliasOption */
/** @typedef {{ alias: string | string[], extension: string }} ExtensionAliasOption */
module.exports = class ExtensionAliasPlugin {
/**
@@ -39,7 +39,7 @@ module.exports = class ExtensionAliasPlugin {
const isAliasString = typeof alias === "string";
/**
* @param {string} alias extension alias
* @param {(err?: null | Error, result?: null|ResolveRequest) => void} callback callback
* @param {(err?: null | Error, result?: null | ResolveRequest) => void} callback callback
* @param {number=} index index
* @returns {void}
*/

View File

@@ -66,7 +66,7 @@ module.exports = class ImportsFieldPlugin {
const remainingRequest =
request.request + request.query + request.fragment;
const importsField =
/** @type {ImportsField|null|undefined} */
/** @type {ImportsField | null | undefined} */
(
DescriptionFileUtils.getField(
/** @type {JsonObject} */ (request.descriptionFileData),
@@ -127,7 +127,7 @@ module.exports = class ImportsFieldPlugin {
paths,
/**
* @param {string} path path
* @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
* @param {(err?: null | Error, result?: null | ResolveRequest) => void} callback callback
* @param {number} i index
* @returns {void}
*/
@@ -212,8 +212,8 @@ module.exports = class ImportsFieldPlugin {
}
},
/**
* @param {(null|Error)=} err error
* @param {(null|ResolveRequest)=} result result
* @param {null | Error=} err error
* @param {null | ResolveRequest=} result result
* @returns {void}
*/
(err, result) => callback(err, result || null),

View File

@@ -13,7 +13,7 @@ const DescriptionFileUtils = require("./DescriptionFileUtils");
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {{name: string|Array<string>, forceRelative: boolean}} MainFieldOptions */
/** @typedef {{ name: string | string[], forceRelative: boolean }} MainFieldOptions */
const alreadyTriedMainField = Symbol("alreadyTriedMainField");
@@ -48,7 +48,7 @@ module.exports = class MainFieldPlugin {
}
const filename = path.basename(request.descriptionFilePath);
let mainModule =
/** @type {string|null|undefined} */
/** @type {string | null | undefined} */
(
DescriptionFileUtils.getField(
/** @type {JsonObject} */ (request.descriptionFileData),

View File

@@ -5,22 +5,20 @@
"use strict";
const forEachBail = require("./forEachBail");
const getPaths = require("./getPaths");
const { modulesResolveHandler } = require("./ModulesUtils");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class ModulesInHierarchicalDirectoriesPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | Array<string>} directories directories
* @param {string | string[]} directories directories
* @param {string | ResolveStepHook} target target
*/
constructor(source, directories, target) {
this.source = source;
this.directories = /** @type {Array<string>} */ [...directories];
this.directories = /** @type {string[]} */ [...directories];
this.target = target;
}
@@ -35,54 +33,12 @@ module.exports = class ModulesInHierarchicalDirectoriesPlugin {
.tapAsync(
"ModulesInHierarchicalDirectoriesPlugin",
(request, resolveContext, callback) => {
const fs = resolver.fileSystem;
const addrs = getPaths(/** @type {string} */ (request.path))
.paths.map((path) =>
this.directories.map((directory) =>
resolver.join(path, directory),
),
)
.reduce((array, path) => {
array.push(...path);
return array;
}, []);
forEachBail(
addrs,
/**
* @param {string} addr addr
* @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
* @returns {void}
*/
(addr, callback) => {
fs.stat(addr, (err, stat) => {
if (!err && stat && stat.isDirectory()) {
/** @type {ResolveRequest} */
const obj = {
...request,
path: addr,
request: `./${request.request}`,
module: false,
};
const message = `looking for modules in ${addr}`;
return resolver.doResolve(
target,
obj,
message,
resolveContext,
callback,
);
}
if (resolveContext.log) {
resolveContext.log(
`${addr} doesn't exist or is not a directory`,
);
}
if (resolveContext.missingDependencies) {
resolveContext.missingDependencies.add(addr);
}
return callback();
});
},
modulesResolveHandler(
resolver,
this.directories,
target,
request,
resolveContext,
callback,
);
},

83
node_modules/enhanced-resolve/lib/ModulesUtils.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const forEachBail = require("./forEachBail");
const getPaths = require("./getPaths");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
/** @typedef {(err?: null | Error, result?: null | ResolveRequest) => void} InnerCallback */
/**
* @param {Resolver} resolver resolver
* @param {string[]} directories directories
* @param {ResolveStepHook} target target
* @param {ResolveRequest} request request
* @param {ResolveContext} resolveContext resolve context
* @param {InnerCallback} callback callback
* @returns {void}
*/
function modulesResolveHandler(
resolver,
directories,
target,
request,
resolveContext,
callback,
) {
const fs = resolver.fileSystem;
const addrs = getPaths(/** @type {string} */ (request.path))
.paths.map((path) =>
directories.map((directory) => resolver.join(path, directory)),
)
.reduce((array, path) => {
array.push(...path);
return array;
}, []);
forEachBail(
addrs,
/**
* @param {string} addr addr
* @param {(err?: null | Error, result?: null | ResolveRequest) => void} callback callback
* @returns {void}
*/
(addr, callback) => {
fs.stat(addr, (err, stat) => {
if (!err && stat && stat.isDirectory()) {
/** @type {ResolveRequest} */
const obj = {
...request,
path: addr,
request: `./${request.request}`,
module: false,
};
const message = `looking for modules in ${addr}`;
return resolver.doResolve(
target,
obj,
message,
resolveContext,
callback,
);
}
if (resolveContext.log) {
resolveContext.log(`${addr} doesn't exist or is not a directory`);
}
if (resolveContext.missingDependencies) {
resolveContext.missingDependencies.add(addr);
}
return callback();
});
},
callback,
);
}
module.exports = {
modulesResolveHandler,
};

View File

@@ -50,9 +50,9 @@ module.exports = class PnpPlugin {
const [packageName] = packageMatch;
const innerRequest = `.${req.slice(packageName.length)}`;
/** @type {string|undefined|null} */
/** @type {string | undefined | null} */
let resolution;
/** @type {string|undefined|null} */
/** @type {string | undefined | null} */
let apiResolution;
try {
resolution = this.pnpApi.resolveToUnqualified(packageName, issuer, {

View File

@@ -17,6 +17,15 @@ const {
/** @typedef {import("./ResolverFactory").ResolveOptions} ResolveOptions */
/**
* @typedef {object} KnownContext
* @property {string[]=} environments environments
*/
// eslint-disable-next-line jsdoc/reject-any-type
/** @typedef {KnownContext & Record<any, any>} Context */
/** @typedef {import("./AliasUtils").AliasOption} AliasOption */
/** @typedef {Error & { details?: string }} ErrorWithDetail */
/** @typedef {(err: ErrorWithDetail | null, res?: string | false, req?: ResolveRequest) => void} ResolveCallback */
@@ -127,43 +136,43 @@ const {
/**
* @typedef {{
* (path: PathOrFileDescriptor, options: ({ encoding?: null | undefined, flag?: string | undefined } & import("events").Abortable) | undefined | null, callback: BufferCallback): void;
* (path: PathOrFileDescriptor, options: ({ encoding: BufferEncoding, flag?: string | undefined } & import("events").Abortable) | BufferEncoding, callback: StringCallback): void;
* (path: PathOrFileDescriptor, options: (ObjectEncodingOptions & { flag?: string | undefined } & import("events").Abortable) | BufferEncoding | undefined | null, callback: StringOrBufferCallback): void;
* (path: PathOrFileDescriptor, callback: BufferCallback): void;
* (path: PathOrFileDescriptor, options: ({ encoding?: null | undefined, flag?: string | undefined } & import("events").Abortable) | undefined | null, callback: BufferCallback): void,
* (path: PathOrFileDescriptor, options: ({ encoding: BufferEncoding, flag?: string | undefined } & import("events").Abortable) | BufferEncoding, callback: StringCallback): void,
* (path: PathOrFileDescriptor, options: (ObjectEncodingOptions & { flag?: string | undefined } & import("events").Abortable) | BufferEncoding | undefined | null, callback: StringOrBufferCallback): void,
* (path: PathOrFileDescriptor, callback: BufferCallback): void
* }} ReadFile
*/
/**
* @typedef {'buffer'| { encoding: 'buffer' }} BufferEncodingOption
* @typedef {"buffer" | { encoding: "buffer" }} BufferEncodingOption
*/
/**
* @typedef {{
* (path: PathOrFileDescriptor, options?: { encoding?: null | undefined, flag?: string | undefined } | null): Buffer;
* (path: PathOrFileDescriptor, options: { encoding: BufferEncoding, flag?: string | undefined } | BufferEncoding): string;
* (path: PathOrFileDescriptor, options?: (ObjectEncodingOptions & { flag?: string | undefined }) | BufferEncoding | null): string | Buffer;
* (path: PathOrFileDescriptor, options?: { encoding?: null | undefined, flag?: string | undefined } | null): Buffer,
* (path: PathOrFileDescriptor, options: { encoding: BufferEncoding, flag?: string | undefined } | BufferEncoding): string,
* (path: PathOrFileDescriptor, options?: (ObjectEncodingOptions & { flag?: string | undefined }) | BufferEncoding | null): string | Buffer
* }} ReadFileSync
*/
/**
* @typedef {{
* (path: PathLike, options: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void;
* (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer', callback: (err: NodeJS.ErrnoException | null, files?: Buffer[]) => void): void;
* (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[] | Buffer[]) => void): void;
* (path: PathLike, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void;
* (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files?: Dirent<string>[]) => void): void;
* (path: PathLike, options: { encoding: 'buffer', withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files: Dirent<Buffer>[]) => void): void;
* (path: PathLike, options: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void,
* (path: PathLike, options: { encoding: "buffer", withFileTypes?: false | undefined, recursive?: boolean | undefined } | "buffer", callback: (err: NodeJS.ErrnoException | null, files?: Buffer[]) => void): void,
* (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[] | Buffer[]) => void): void,
* (path: PathLike, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void,
* (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files?: Dirent<string>[]) => void): void,
* (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files: Dirent<Buffer>[]) => void): void
* }} Readdir
*/
/**
* @typedef {{
* (path: PathLike, options?: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined; } | BufferEncoding | null): string[];
* (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer'): Buffer[];
* (path: PathLike, options?: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | null): string[] | Buffer[];
* (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }): Dirent[];
* (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }): Dirent<Buffer>[];
* (path: PathLike, options?: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | null): string[],
* (path: PathLike, options: { encoding: "buffer", withFileTypes?: false | undefined, recursive?: boolean | undefined } | "buffer"): Buffer[],
* (path: PathLike, options?: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | null): string[] | Buffer[],
* (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }): Dirent[],
* (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }): Dirent<Buffer>[]
* }} ReaddirSync
*/
@@ -177,77 +186,77 @@ const {
/**
* @typedef {{
* (path: PathLike, options: EncodingOption, callback: StringCallback): void;
* (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void;
* (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void;
* (path: PathLike, callback: StringCallback): void;
* (path: PathLike, options: EncodingOption, callback: StringCallback): void,
* (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void,
* (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void,
* (path: PathLike, callback: StringCallback): void
* }} Readlink
*/
/**
* @typedef {{
* (path: PathLike, options?: EncodingOption): string;
* (path: PathLike, options: BufferEncodingOption): Buffer;
* (path: PathLike, options?: EncodingOption): string | Buffer;
* (path: PathLike, options?: EncodingOption): string,
* (path: PathLike, options: BufferEncodingOption): Buffer,
* (path: PathLike, options?: EncodingOption): string | Buffer
* }} ReadlinkSync
*/
/**
* @typedef {{
* (path: PathLike, callback: StatsCallback): void;
* (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void;
* (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void;
* (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void;
* (path: PathLike, callback: StatsCallback): void,
* (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void,
* (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void,
* (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void
* }} LStat
*/
/**
* @typedef {{
* (path: PathLike, options?: undefined): IStats;
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined;
* (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined;
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats;
* (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
* (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats;
* (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined;
* (path: PathLike, options?: undefined): IStats,
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined,
* (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined,
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats,
* (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats,
* (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats,
* (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined
* }} LStatSync
*/
/**
* @typedef {{
* (path: PathLike, callback: StatsCallback): void;
* (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void;
* (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void;
* (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void;
* (path: PathLike, callback: StatsCallback): void,
* (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void,
* (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void,
* (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void
* }} Stat
*/
/**
* @typedef {{
* (path: PathLike, options?: undefined): IStats;
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined;
* (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined;
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats;
* (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
* (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats;
* (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined;
* (path: PathLike, options?: undefined): IStats,
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined,
* (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined,
* (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats,
* (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats,
* (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats,
* (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined
* }} StatSync
*/
/**
* @typedef {{
* (path: PathLike, options: EncodingOption, callback: StringCallback): void;
* (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void;
* (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void;
* (path: PathLike, callback: StringCallback): void;
* (path: PathLike, options: EncodingOption, callback: StringCallback): void,
* (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void,
* (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void,
* (path: PathLike, callback: StringCallback): void
* }} RealPath
*/
/**
* @typedef {{
* (path: PathLike, options?: EncodingOption): string;
* (path: PathLike, options: BufferEncodingOption): Buffer;
* (path: PathLike, options?: EncodingOption): string | Buffer;
* (path: PathLike, options?: EncodingOption): string,
* (path: PathLike, options: BufferEncodingOption): Buffer,
* (path: PathLike, options?: EncodingOption): string | Buffer
* }} RealPathSync
*/
@@ -289,8 +298,19 @@ const {
/** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */
/** @typedef {{ [Key in string]?: JsonValue | undefined }} JsonObject */
// eslint-disable-next-line jsdoc/require-property
/** @typedef {object} Context */
/**
* @typedef {object} TsconfigPathsMap
* @property {TsconfigPathsData} main main tsconfig paths data
* @property {string} mainContext main tsconfig base URL (absolute path)
* @property {{ [baseUrl: string]: TsconfigPathsData }} refs referenced tsconfig paths data mapped by baseUrl
* @property {Set<string>} fileDependencies file dependencies
*/
/**
* @typedef {object} TsconfigPathsData
* @property {AliasOption[]} alias tsconfig file data
* @property {string[]} modules tsconfig file data
*/
/**
* @typedef {object} BaseResolveRequest
@@ -299,6 +319,7 @@ const {
* @property {string=} descriptionFilePath description file path
* @property {string=} descriptionFileRoot description file root
* @property {JsonObject=} descriptionFileData description file data
* @property {TsconfigPathsMap | null | undefined=} tsconfigPathsMap tsconfig paths map
* @property {string=} relativePath relative path
* @property {boolean=} ignoreSymlinks true when need to ignore symlinks, otherwise false
* @property {boolean=} fullySpecified true when full specified, otherwise false
@@ -343,7 +364,7 @@ const {
*/
/**
* @typedef {{[key: string]: ResolveStepHook}} EnsuredHooks
* @typedef {{ [key: string]: ResolveStepHook }} EnsuredHooks
*/
/**
@@ -456,7 +477,7 @@ class Resolver {
}
/**
* @param {object} context context information object
* @param {Context} context context information object
* @param {string} path context path
* @param {string} request request string
* @returns {string | false} result
@@ -483,7 +504,7 @@ class Resolver {
}
/**
* @param {object} context context information object
* @param {Context} context context information object
* @param {string} path context path
* @param {string} request request string
* @param {ResolveContext} resolveContext resolve context
@@ -664,9 +685,9 @@ class Resolver {
/**
* @param {ResolveStepHook} hook hook
* @param {ResolveRequest} request request
* @param {null|string} message string
* @param {null | string} message string
* @param {ResolveContext} resolveContext resolver context
* @param {(err?: null|Error, result?: ResolveRequest) => void} callback callback
* @param {(err?: null | Error, result?: ResolveRequest) => void} callback callback
* @returns {void}
*/
doResolve(hook, request, message, resolveContext, callback) {
@@ -679,7 +700,7 @@ class Resolver {
if (resolveContext.stack.has(stackEntry)) {
/**
* Prevent recursion
* @type {Error & {recursion?: boolean}}
* @type {Error & { recursion?: boolean }}
*/
const recursionError = new Error(
`Recursion in resolving\nStack:\n ${[...newStack].join("\n ")}`,

View File

@@ -34,6 +34,7 @@ const SelfReferencePlugin = require("./SelfReferencePlugin");
const SymlinkPlugin = require("./SymlinkPlugin");
const SyncAsyncFileSystemDecorator = require("./SyncAsyncFileSystemDecorator");
const TryNextPlugin = require("./TryNextPlugin");
const TsconfigPathsPlugin = require("./TsconfigPathsPlugin");
const UnsafeCachePlugin = require("./UnsafeCachePlugin");
const UseFilePlugin = require("./UseFilePlugin");
const { PathType, getType } = require("./util/path");
@@ -50,9 +51,15 @@ const { PathType, getType } = require("./util/path");
/** @typedef {string | string[] | false} AliasOptionNewRequest */
/** @typedef {{ [k: string]: AliasOptionNewRequest }} AliasOptions */
/** @typedef {{ [k: string]: string|string[] }} ExtensionAliasOptions */
/** @typedef {{ [k: string]: string | string[] }} ExtensionAliasOptions */
/** @typedef {false | 0 | "" | null | undefined} Falsy */
/** @typedef {{apply: (resolver: Resolver) => void} | ((this: Resolver, resolver: Resolver) => void) | Falsy} Plugin */
/** @typedef {{ apply: (resolver: Resolver) => void } | ((this: Resolver, resolver: Resolver) => void) | Falsy} Plugin */
/**
* @typedef {object} TsconfigOptions
* @property {string=} configFile A relative path to the tsconfig file based on cwd, or an absolute path of tsconfig file
* @property {string[] | "auto"=} references References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths
*/
/**
* @typedef {object} UserResolveOptions
@@ -73,17 +80,18 @@ const { PathType, getType } = require("./util/path");
* @property {boolean=} symlinks Resolve symlinks to their symlinked location
* @property {Resolver=} resolver A prepared Resolver to which the plugins are attached
* @property {string[] | string=} modules A list of directories to resolve modules from, can be absolute path or folder name
* @property {(string | string[] | {name: string | string[], forceRelative: boolean})[]=} mainFields A list of main fields in description files
* @property {(string | string[] | { name: string | string[], forceRelative: boolean })[]=} mainFields A list of main fields in description files
* @property {string[]=} mainFiles A list of main files in directories
* @property {Plugin[]=} plugins A list of additional resolve plugins which should be applied
* @property {PnpApi | null=} pnpApi A PnP API that should be used - null is "never", undefined is "auto"
* @property {string[]=} roots A list of root paths
* @property {boolean=} fullySpecified The request is already fully specified and no extensions or directories are resolved for it
* @property {boolean=} resolveToContext Resolve to a context instead of a file
* @property {(string|RegExp)[]=} restrictions A list of resolve restrictions
* @property {(string | RegExp)[]=} restrictions A list of resolve restrictions
* @property {boolean=} useSyncFileSystemCalls Use only the sync constraints of the file system calls
* @property {boolean=} preferRelative Prefer to resolve module requests as relative requests before falling back to modules
* @property {boolean=} preferAbsolute Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots
* @property {string | boolean | TsconfigOptions=} tsconfig TypeScript config file path or config object with configFile and references
*/
/**
@@ -104,7 +112,7 @@ const { PathType, getType } = require("./util/path");
* @property {Cache | false} unsafeCache unsafe cache
* @property {boolean} symlinks symlinks
* @property {Resolver=} resolver resolver
* @property {Array<string | string[]>} modules modules
* @property {(string | string[])[]} modules modules
* @property {{ name: string[], forceRelative: boolean }[]} mainFields main fields
* @property {Set<string>} mainFiles main files
* @property {Plugin[]} plugins plugins
@@ -115,6 +123,7 @@ const { PathType, getType } = require("./util/path");
* @property {Set<string | RegExp>} restrictions restrictions
* @property {boolean} preferRelative prefer relative
* @property {boolean} preferAbsolute prefer absolute
* @property {string | boolean | TsconfigOptions} tsconfig tsconfig file path or config object
*/
/**
@@ -124,7 +133,7 @@ const { PathType, getType } = require("./util/path");
function processPnpApiOption(option) {
if (
option === undefined &&
/** @type {NodeJS.ProcessVersions & {pnp: string}} */ versions.pnp
/** @type {NodeJS.ProcessVersions & { pnp: string }} */ versions.pnp
) {
const _findPnpApi =
/** @type {(issuer: string) => PnpApi | null}} */
@@ -169,17 +178,17 @@ function normalizeAlias(alias) {
return obj;
})
: /** @type {Array<AliasOptionEntry>} */ (alias) || [];
: /** @type {AliasOptionEntry[]} */ (alias) || [];
}
/**
* Merging filtered elements
* @param {string[]} array source array
* @param {(item: string) => boolean} filter predicate
* @returns {Array<string | string[]>} merge result
* @returns {(string | string[])[]} merge result
*/
function mergeFilteredToArray(array, filter) {
/** @type {Array<string | string[]>} */
/** @type {(string | string[])[]} */
const result = [];
const set = new Set(array);
@@ -294,6 +303,8 @@ function createOptions(options) {
preferRelative: options.preferRelative || false,
preferAbsolute: options.preferAbsolute || false,
restrictions: new Set(options.restrictions),
tsconfig:
typeof options.tsconfig === "undefined" ? false : options.tsconfig,
};
}
@@ -332,6 +343,7 @@ module.exports.createResolver = function createResolver(options) {
resolver: customResolver,
restrictions,
roots,
tsconfig,
} = normalizedOptions;
const plugins = [...userPlugins];
@@ -415,11 +427,13 @@ module.exports.createResolver = function createResolver(options) {
new AliasPlugin("described-resolve", fallback, "internal-resolve"),
);
}
// raw-resolve
if (alias.length > 0) {
plugins.push(new AliasPlugin("raw-resolve", alias, "internal-resolve"));
}
if (tsconfig) {
plugins.push(new TsconfigPathsPlugin(tsconfig));
}
for (const item of aliasFields) {
plugins.push(new AliasFieldPlugin("raw-resolve", item, "internal-resolve"));
}

View File

@@ -41,7 +41,7 @@ class RootsPlugin {
this.roots,
/**
* @param {string} root root
* @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
* @param {(err?: null | Error, result?: null | ResolveRequest) => void} callback callback
* @returns {void}
*/
(root, callback) => {

View File

@@ -44,7 +44,7 @@ module.exports = class SymlinkPlugin {
paths,
/**
* @param {string} path path
* @param {(err?: null|Error, result?: null|number) => void} callback callback
* @param {(err?: null | Error, result?: null | number) => void} callback callback
* @returns {void}
*/
(path, callback) => {
@@ -69,8 +69,8 @@ module.exports = class SymlinkPlugin {
});
},
/**
* @param {(null | Error)=} err error
* @param {(null|number)=} idx result
* @param {null | Error=} err error
* @param {null | number=} idx result
* @returns {void}
*/
(err, idx) => {

View File

@@ -9,9 +9,9 @@
/** @typedef {import("./Resolver").StringCallback} StringCallback */
/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
// eslint-disable-next-line jsdoc/no-restricted-syntax
// eslint-disable-next-line jsdoc/reject-function-type
/** @typedef {Function} SyncOrAsyncFunction */
// eslint-disable-next-line jsdoc/no-restricted-syntax
// eslint-disable-next-line jsdoc/reject-any-type
/** @typedef {any} ResultOfSyncOrAsyncFunction */
/**

View File

@@ -0,0 +1,560 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Natsu @xiaoxiaojx
*/
"use strict";
const { aliasResolveHandler } = require("./AliasUtils");
const { modulesResolveHandler } = require("./ModulesUtils");
const { readJson } = require("./util/fs");
const {
PathType: _PathType,
cachedDirname: dirname,
cachedJoin: join,
isSubPath,
normalize,
} = require("./util/path");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {import("./AliasUtils").AliasOption} AliasOption */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
/** @typedef {import("./Resolver").FileSystem} FileSystem */
/** @typedef {import("./Resolver").TsconfigPathsData} TsconfigPathsData */
/** @typedef {import("./Resolver").TsconfigPathsMap} TsconfigPathsMap */
/** @typedef {import("./ResolverFactory").TsconfigOptions} TsconfigOptions */
/**
* @typedef {object} TsconfigCompilerOptions
* @property {string=} baseUrl Base URL for resolving paths
* @property {{ [key: string]: string[] }=} paths TypeScript paths mapping
*/
/**
* @typedef {object} TsconfigReference
* @property {string} path Path to the referenced project
*/
/**
* @typedef {object} Tsconfig
* @property {TsconfigCompilerOptions=} compilerOptions Compiler options
* @property {string | string[]=} extends Extended configuration paths
* @property {TsconfigReference[]=} references Project references
*/
const DEFAULT_CONFIG_FILE = "tsconfig.json";
/**
* @param {string} pattern Path pattern
* @returns {number} Length of the prefix
*/
function getPrefixLength(pattern) {
const prefixLength = pattern.indexOf("*");
if (prefixLength === -1) {
return pattern.length;
}
return pattern.slice(0, Math.max(0, prefixLength)).length;
}
/**
* Sort path patterns.
* If a module name can be matched with multiple patterns then pattern with the longest prefix will be picked.
* @param {string[]} arr Array of path patterns
* @returns {string[]} Array of path patterns sorted by longest prefix
*/
function sortByLongestPrefix(arr) {
return [...arr].sort((a, b) => getPrefixLength(b) - getPrefixLength(a));
}
/**
* Merge two tsconfig objects
* @param {Tsconfig | null} base base config
* @param {Tsconfig | null} config config to merge
* @returns {Tsconfig} merged config
*/
function mergeTsconfigs(base, config) {
base = base || {};
config = config || {};
return {
...base,
...config,
compilerOptions: {
.../** @type {TsconfigCompilerOptions} */ (base.compilerOptions),
.../** @type {TsconfigCompilerOptions} */ (config.compilerOptions),
},
};
}
/**
* Substitute ${configDir} template variable in path
* @param {string} pathValue the path value
* @param {string} configDir the config directory
* @returns {string} the path with substituted template
*/
function substituteConfigDir(pathValue, configDir) {
return pathValue.replace(/\$\{configDir\}/g, configDir);
}
/**
* Convert tsconfig paths to resolver options
* @param {string} configDir Config file directory
* @param {{ [key: string]: string[] }} paths TypeScript paths mapping
* @param {string=} baseUrl Base URL for resolving paths (relative to configDir)
* @returns {TsconfigPathsData} the resolver options
*/
function tsconfigPathsToResolveOptions(configDir, paths, baseUrl) {
// Calculate absolute base URL
const absoluteBaseUrl = !baseUrl ? configDir : join(configDir, baseUrl);
/** @type {string[]} */
const sortedKeys = sortByLongestPrefix(Object.keys(paths));
/** @type {AliasOption[]} */
const alias = [];
/** @type {string[]} */
const modules = [];
for (const pattern of sortedKeys) {
const mappings = paths[pattern];
// Substitute ${configDir} in path mappings
const absolutePaths = mappings.map((mapping) => {
const substituted = substituteConfigDir(mapping, configDir);
return join(absoluteBaseUrl, substituted);
});
if (absolutePaths.length > 0) {
if (pattern === "*") {
modules.push(
...absolutePaths
.map((dir) => {
if (/[/\\]\*$/.test(dir)) {
return dir.replace(/[/\\]\*$/, "");
}
return "";
})
.filter(Boolean),
);
} else {
alias.push({ name: pattern, alias: absolutePaths });
}
}
}
if (absoluteBaseUrl && !modules.includes(absoluteBaseUrl)) {
modules.push(absoluteBaseUrl);
}
return {
alias,
modules,
};
}
/**
* Get the base context for the current project
* @param {string} context the context
* @param {string=} baseUrl base URL for resolving paths
* @returns {string} the base context
*/
function getAbsoluteBaseUrl(context, baseUrl) {
return !baseUrl ? context : join(context, baseUrl);
}
module.exports = class TsconfigPathsPlugin {
/**
* @param {true | string | TsconfigOptions} configFileOrOptions tsconfig file path or options object
*/
constructor(configFileOrOptions) {
if (
typeof configFileOrOptions === "object" &&
configFileOrOptions !== null
) {
// Options object format
this.configFile = configFileOrOptions.configFile || DEFAULT_CONFIG_FILE;
/** @type {string[] | "auto"} */
if (Array.isArray(configFileOrOptions.references)) {
/** @type {TsconfigReference[] | "auto"} */
this.references = configFileOrOptions.references.map((ref) => ({
path: ref,
}));
} else if (configFileOrOptions.references === "auto") {
this.references = "auto";
} else {
this.references = [];
}
} else {
this.configFile =
configFileOrOptions === true
? DEFAULT_CONFIG_FILE
: /** @type {string} */ (configFileOrOptions);
/** @type {TsconfigReference[] | "auto"} */
this.references = [];
}
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const aliasTarget = resolver.ensureHook("internal-resolve");
const moduleTarget = resolver.ensureHook("module");
resolver
.getHook("raw-resolve")
.tapAsync(
"TsconfigPathsPlugin",
async (request, resolveContext, callback) => {
try {
const tsconfigPathsMap = await this._getTsconfigPathsMap(
resolver,
request,
resolveContext,
);
if (!tsconfigPathsMap) return callback();
const selectedData = this._selectPathsDataForContext(
request.path,
tsconfigPathsMap,
);
if (!selectedData) return callback();
aliasResolveHandler(
resolver,
selectedData.alias,
aliasTarget,
request,
resolveContext,
callback,
);
} catch (err) {
callback(/** @type {Error} */ (err));
}
},
);
resolver
.getHook("raw-module")
.tapAsync(
"TsconfigPathsPlugin",
async (request, resolveContext, callback) => {
try {
const tsconfigPathsMap = await this._getTsconfigPathsMap(
resolver,
request,
resolveContext,
);
if (!tsconfigPathsMap) return callback();
const selectedData = this._selectPathsDataForContext(
request.path,
tsconfigPathsMap,
);
if (!selectedData) return callback();
modulesResolveHandler(
resolver,
selectedData.modules,
moduleTarget,
request,
resolveContext,
callback,
);
} catch (err) {
callback(/** @type {Error} */ (err));
}
},
);
}
/**
* Get TsconfigPathsMap for the request (with caching)
* @param {Resolver} resolver the resolver
* @param {ResolveRequest} request the request
* @param {ResolveContext} resolveContext the resolve context
* @returns {Promise<TsconfigPathsMap | null>} the tsconfig paths map or null
*/
async _getTsconfigPathsMap(resolver, request, resolveContext) {
if (typeof request.tsconfigPathsMap === "undefined") {
try {
const absTsconfigPath = join(
request.path || process.cwd(),
this.configFile,
);
const result = await this._loadTsconfigPathsMap(
resolver.fileSystem,
absTsconfigPath,
);
request.tsconfigPathsMap = result;
} catch (err) {
request.tsconfigPathsMap = null;
throw err;
}
}
if (!request.tsconfigPathsMap) {
return null;
}
for (const fileDependency of request.tsconfigPathsMap.fileDependencies) {
if (resolveContext.fileDependencies) {
resolveContext.fileDependencies.add(fileDependency);
}
}
return request.tsconfigPathsMap;
}
/**
* Load tsconfig.json and build complete TsconfigPathsMap
* Includes main project paths and all referenced projects
* @param {FileSystem} fileSystem the file system
* @param {string} absTsconfigPath absolute path to tsconfig.json
* @returns {Promise<TsconfigPathsMap>} the complete tsconfig paths map
*/
async _loadTsconfigPathsMap(fileSystem, absTsconfigPath) {
/** @type {Set<string>} */
const fileDependencies = new Set();
const config = await this._loadTsconfig(
fileSystem,
absTsconfigPath,
fileDependencies,
);
const compilerOptions = config.compilerOptions || {};
const mainContext = dirname(absTsconfigPath);
const main = tsconfigPathsToResolveOptions(
mainContext,
compilerOptions.paths || {},
compilerOptions.baseUrl,
);
/** @type {{ [baseUrl: string]: TsconfigPathsData }} */
const refs = {};
let referencesToUse = null;
if (this.references === "auto") {
referencesToUse = config.references;
} else if (Array.isArray(this.references)) {
referencesToUse = this.references;
}
if (Array.isArray(referencesToUse)) {
await this._loadTsconfigReferences(
fileSystem,
mainContext,
referencesToUse,
fileDependencies,
refs,
);
}
return { main, mainContext, refs, fileDependencies };
}
/**
* Select the correct TsconfigPathsData based on request.path (context-aware)
* Matches the behavior of tsconfig-paths-webpack-plugin
* @param {string | false} requestPath the request path
* @param {TsconfigPathsMap} tsconfigPathsMap the tsconfig paths map
* @returns {TsconfigPathsData | null} the selected paths data
*/
_selectPathsDataForContext(requestPath, tsconfigPathsMap) {
const { main, mainContext, refs } = tsconfigPathsMap;
if (!requestPath) {
return main;
}
// Combine main and refs into a single map: context path -> TsconfigPathsData
const allContexts = {
[mainContext]: main,
...refs,
};
let longestMatch = null;
let longestMatchLength = 0;
for (const [context, data] of Object.entries(allContexts)) {
if (context === requestPath) {
return data;
}
if (
isSubPath(context, requestPath) &&
context.length > longestMatchLength
) {
longestMatch = data;
longestMatchLength = context.length;
}
}
if (longestMatch) {
return longestMatch;
}
return null;
}
/**
* Load tsconfig from extends path
* @param {FileSystem} fileSystem the file system
* @param {string} configFilePath current config file path
* @param {string} extendedConfigValue extends value
* @param {Set<string>} fileDependencies the file dependencies
* @returns {Promise<Tsconfig>} the extended tsconfig
*/
async _loadTsconfigFromExtends(
fileSystem,
configFilePath,
extendedConfigValue,
fileDependencies,
) {
const currentDir = dirname(configFilePath);
// Substitute ${configDir} in extends path
extendedConfigValue = substituteConfigDir(extendedConfigValue, currentDir);
if (
typeof extendedConfigValue === "string" &&
!extendedConfigValue.includes(".json")
) {
extendedConfigValue += ".json";
}
let extendedConfigPath = join(currentDir, extendedConfigValue);
const exists = await new Promise((resolve) => {
fileSystem.readFile(extendedConfigPath, (err) => {
resolve(!err);
});
});
if (!exists && extendedConfigValue.includes("/")) {
extendedConfigPath = join(
currentDir,
normalize(`node_modules/${extendedConfigValue}`),
);
}
const config = await this._loadTsconfig(
fileSystem,
extendedConfigPath,
fileDependencies,
);
const compilerOptions = config.compilerOptions || { baseUrl: undefined };
if (compilerOptions.baseUrl) {
const extendsDir = dirname(extendedConfigValue);
compilerOptions.baseUrl = getAbsoluteBaseUrl(
extendsDir,
compilerOptions.baseUrl,
);
}
delete config.references;
return /** @type {Tsconfig} */ (config);
}
/**
* Load referenced tsconfig projects and store in referenceMatchMap
* Simple implementation matching tsconfig-paths-webpack-plugin:
* Just load each reference and store independently
* @param {FileSystem} fileSystem the file system
* @param {string} context the context
* @param {TsconfigReference[]} references array of references
* @param {Set<string>} fileDependencies the file dependencies
* @param {{ [baseUrl: string]: TsconfigPathsData }} referenceMatchMap the map to populate
* @returns {Promise<void>}
*/
async _loadTsconfigReferences(
fileSystem,
context,
references,
fileDependencies,
referenceMatchMap,
) {
for (const ref of references) {
// Substitute ${configDir} in reference path
const refPath = substituteConfigDir(ref.path, context);
const refConfigPath = join(join(context, refPath), DEFAULT_CONFIG_FILE);
try {
const refConfig = await this._loadTsconfig(
fileSystem,
refConfigPath,
fileDependencies,
);
if (refConfig.compilerOptions && refConfig.compilerOptions.paths) {
const refContext = dirname(refConfigPath);
referenceMatchMap[refContext] = tsconfigPathsToResolveOptions(
refContext,
refConfig.compilerOptions.paths || {},
refConfig.compilerOptions.baseUrl,
);
}
if (this.references === "auto" && Array.isArray(refConfig.references)) {
await this._loadTsconfigReferences(
fileSystem,
dirname(refConfigPath),
refConfig.references,
fileDependencies,
referenceMatchMap,
);
}
} catch (_err) {
continue;
}
}
}
/**
* Load tsconfig.json with extends support
* @param {FileSystem} fileSystem the file system
* @param {string} configFilePath absolute path to tsconfig.json
* @param {Set<string>} fileDependencies the file dependencies
* @returns {Promise<Tsconfig>} the merged tsconfig
*/
async _loadTsconfig(fileSystem, configFilePath, fileDependencies) {
const config = await readJson(fileSystem, configFilePath);
fileDependencies.add(configFilePath);
let result = config;
const extendedConfig = config.extends;
if (extendedConfig) {
let base;
if (Array.isArray(extendedConfig)) {
base = {};
for (const extendedConfigElement of extendedConfig) {
const extendedTsconfig = await this._loadTsconfigFromExtends(
fileSystem,
configFilePath,
extendedConfigElement,
fileDependencies,
);
base = mergeTsconfigs(base, extendedTsconfig);
}
} else {
base = await this._loadTsconfigFromExtends(
fileSystem,
configFilePath,
extendedConfig,
fileDependencies,
);
}
result = /** @type {Tsconfig} */ (mergeTsconfigs(base, config));
}
return result;
}
};

View File

@@ -9,7 +9,7 @@
/**
* @param {ResolveContext} options options for inner context
* @param {null|string} message message to log
* @param {null | string} message message to log
* @returns {ResolveContext} inner context
*/
module.exports = function createInnerContext(options, message) {

View File

@@ -12,7 +12,7 @@
* @template Z
* @callback Iterator
* @param {T} item item
* @param {(err?: null|Error, result?: null|Z) => void} callback callback
* @param {(err?: null | Error, result?: null | Z) => void} callback callback
* @param {number} i index
* @returns {void}
*/
@@ -22,7 +22,7 @@
* @template Z
* @param {T[]} array array
* @param {Iterator<T, Z>} iterator iterator
* @param {(err?: null|Error, result?: null|Z, i?: number) => void} callback callback after all items are iterated
* @param {(err?: null | Error, result?: null | Z, i?: number) => void} callback callback after all items are iterated
* @returns {void}
*/
module.exports = function forEachBail(array, iterator, callback) {
@@ -30,7 +30,7 @@ module.exports = function forEachBail(array, iterator, callback) {
let i = 0;
const next = () => {
/** @type {boolean|undefined} */
/** @type {boolean | undefined} */
let loop;
iterator(
array[i++],

View File

@@ -21,7 +21,7 @@ module.exports = function getInnerRequest(resolver, request) {
) {
return request.__innerRequest;
}
/** @type {string|undefined} */
/** @type {string | undefined} */
let innerRequest;
if (request.request) {
innerRequest = request.request;

View File

@@ -7,7 +7,7 @@
/**
* @param {string} path path
* @returns {{paths: string[], segments: string[]}}} paths and segments
* @returns {{ paths: string[], segments: string[] }}} paths and segments
*/
module.exports = function getPaths(path) {
if (path === "/") return { paths: ["/"], segments: [""] };
@@ -33,7 +33,7 @@ module.exports = function getPaths(path) {
/**
* @param {string} path path
* @returns {string|null} basename or null
* @returns {string | null} basename or null
*/
module.exports.basename = function basename(path) {
const i = path.lastIndexOf("/");

View File

@@ -10,6 +10,7 @@ const memoize = require("./util/memoize");
/** @typedef {import("./CachedInputFileSystem").BaseFileSystem} BaseFileSystem */
/** @typedef {import("./PnpPlugin").PnpApiImpl} PnpApi */
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").Context} Context */
/** @typedef {import("./Resolver").FileSystem} FileSystem */
/** @typedef {import("./Resolver").ResolveCallback} ResolveCallback */
/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
@@ -20,17 +21,17 @@ const memoize = require("./util/memoize");
/**
* @typedef {{
* (context: object, path: string, request: string, resolveContext: ResolveContext, callback: ResolveCallback): void;
* (context: object, path: string, request: string, callback: ResolveCallback): void;
* (path: string, request: string, resolveContext: ResolveContext, callback: ResolveCallback): void;
* (path: string, request: string, callback: ResolveCallback): void;
* (context: Context, path: string, request: string, resolveContext: ResolveContext, callback: ResolveCallback): void,
* (context: Context, path: string, request: string, callback: ResolveCallback): void,
* (path: string, request: string, resolveContext: ResolveContext, callback: ResolveCallback): void,
* (path: string, request: string, callback: ResolveCallback): void
* }} ResolveFunctionAsync
*/
/**
* @typedef {{
* (context: object, path: string, request: string): string | false;
* (path: string, request: string): string | false;
* (context: Context, path: string, request: string): string | false,
* (path: string, request: string): string | false
* }} ResolveFunction
*/
@@ -102,7 +103,7 @@ const getSyncResolver = memoize(() =>
*/
const resolveSync =
/**
* @param {object|string} context context
* @param {object | string} context context
* @param {string} path path
* @param {string=} request request
* @returns {string | false} result
@@ -132,10 +133,10 @@ function create(options) {
...options,
});
/**
* @param {object|string} context Custom context
* @param {object | string} context Custom context
* @param {string} path Base path
* @param {string|ResolveContext|ResolveCallback} request String to resolve
* @param {ResolveContext|ResolveCallback=} resolveContext Resolve context
* @param {string | ResolveContext | ResolveCallback} request String to resolve
* @param {ResolveContext | ResolveCallback=} resolveContext Resolve context
* @param {ResolveCallback=} callback Result callback
*/
return function create(context, path, request, resolveContext, callback) {
@@ -219,6 +220,9 @@ module.exports = mergeExports(resolve, {
get LogInfoPlugin() {
return require("./LogInfoPlugin");
},
get TsconfigPathsPlugin() {
return require("./TsconfigPathsPlugin");
},
get forEachBail() {
return require("./forEachBail");
},

View File

@@ -7,10 +7,10 @@
const { parseIdentifier } = require("./identifier");
/** @typedef {string|(string|ConditionalMapping)[]} DirectMapping */
/** @typedef {{[k: string]: MappingValue}} ConditionalMapping */
/** @typedef {ConditionalMapping|DirectMapping|null} MappingValue */
/** @typedef {Record<string, MappingValue>|ConditionalMapping|DirectMapping} ExportsField */
/** @typedef {string | (string | ConditionalMapping)[]} DirectMapping */
/** @typedef {{ [k: string]: MappingValue }} ConditionalMapping */
/** @typedef {ConditionalMapping | DirectMapping | null} MappingValue */
/** @typedef {Record<string, MappingValue> | ConditionalMapping | DirectMapping} ExportsField */
/** @typedef {Record<string, MappingValue>} ImportsField */
/**
@@ -104,7 +104,7 @@ function patternKeyCompare(a, b) {
* Trying to match request to field
* @param {string} request request
* @param {ExportsField | ImportsField} field exports or import field
* @returns {[MappingValue, string, boolean, boolean, string]|null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
* @returns {[MappingValue, string, boolean, boolean, string] | null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
*/
function findMatch(request, field) {
if (
@@ -112,14 +112,16 @@ function findMatch(request, field) {
!request.includes("*") &&
!request.endsWith("/")
) {
const target = /** @type {{[k: string]: MappingValue}} */ (field)[request];
const target = /** @type {{ [k: string]: MappingValue }} */ (field)[
request
];
return [target, "", false, false, request];
}
/** @type {string} */
let bestMatch = "";
/** @type {string|undefined} */
/** @type {string | undefined} */
let bestMatchSubpath;
const keys = Object.getOwnPropertyNames(field);
@@ -157,7 +159,9 @@ function findMatch(request, field) {
if (bestMatch === "") return null;
const target = /** @type {{[k: string]: MappingValue}} */ (field)[bestMatch];
const target =
/** @type {{ [k: string]: MappingValue }} */
(field)[bestMatch];
const isSubpathMapping = bestMatch.endsWith("/");
const isPattern = bestMatch.includes("*");
@@ -171,7 +175,7 @@ function findMatch(request, field) {
}
/**
* @param {ConditionalMapping | DirectMapping|null} mapping mapping
* @param {ConditionalMapping | DirectMapping | null} mapping mapping
* @returns {boolean} is conditional mapping
*/
function isConditionalMapping(mapping) {
@@ -274,10 +278,10 @@ function targetMapping(
}
/**
* @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
* @param {string | undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
* @param {boolean} isPattern true, if mapping is a pattern (contains "*")
* @param {boolean} isSubpathMapping true, for subpath mappings
* @param {DirectMapping|null} mappingTarget direct export
* @param {DirectMapping | null} mappingTarget direct export
* @param {Set<string>} conditionNames condition names
* @param {(d: string, f: boolean) => void} assert asserting direct value
* @returns {string[]} mapping result

38
node_modules/enhanced-resolve/lib/util/fs.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Natsu @xiaoxiaojx
*/
"use strict";
/** @typedef {import("../Resolver").FileSystem} FileSystem */
/**
* Read and parse JSON file
* @template T
* @param {FileSystem} fileSystem the file system
* @param {string} jsonFilePath absolute path to JSON file
* @returns {Promise<T>} parsed JSON content
*/
async function readJson(fileSystem, jsonFilePath) {
const { readJson } = fileSystem;
if (readJson) {
return new Promise((resolve, reject) => {
readJson(jsonFilePath, (err, content) => {
if (err) return reject(err);
resolve(/** @type {T} */ (content));
});
});
}
const buf = await new Promise((resolve, reject) => {
fileSystem.readFile(jsonFilePath, (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
return JSON.parse(/** @type {string} */ (buf.toString()));
}
module.exports.readJson = readJson;

View File

@@ -171,6 +171,18 @@ const join = (rootPath, request) => {
return posixNormalize(rootPath);
};
/**
* @param {string} maybePath a path
* @returns {string} the directory name
*/
const dirname = (maybePath) => {
switch (getType(maybePath)) {
case PathType.AbsoluteWin:
return path.win32.dirname(maybePath);
}
return path.posix.dirname(maybePath);
};
/** @type {Map<string, Map<string, string | undefined>>} */
const joinCache = new Map();
@@ -194,10 +206,45 @@ const cachedJoin = (rootPath, request) => {
return cacheEntry;
};
/** @type {Map<string, string>} */
const dirnameCache = new Map();
/**
* @param {string} maybePath a path
* @returns {string} the directory name
*/
const cachedDirname = (maybePath) => {
const cacheEntry = dirnameCache.get(maybePath);
if (cacheEntry !== undefined) return cacheEntry;
const result = dirname(maybePath);
dirnameCache.set(maybePath, result);
return result;
};
/**
* Check if childPath is a subdirectory of parentPath
* @param {string} parentPath parent directory path
* @param {string} childPath child path to check
* @returns {boolean} true if childPath is under parentPath
*/
const isSubPath = (parentPath, childPath) => {
// Ensure parentPath ends with a separator to avoid false matches
// e.g., "/app" shouldn't match "/app-other"
const parentWithSlash =
parentPath.endsWith("/") || parentPath.endsWith("\\")
? parentPath
: normalize(`${parentPath}/`);
return childPath.startsWith(parentWithSlash);
};
module.exports.PathType = PathType;
module.exports.cachedDirname = cachedDirname;
module.exports.cachedJoin = cachedJoin;
module.exports.deprecatedInvalidSegmentRegEx = deprecatedInvalidSegmentRegEx;
module.exports.dirname = dirname;
module.exports.getType = getType;
module.exports.invalidSegmentRegEx = invalidSegmentRegEx;
module.exports.isSubPath = isSubPath;
module.exports.join = join;
module.exports.normalize = normalize;

View File

@@ -10,10 +10,8 @@ module.exports = {
* @type {Record<string, string>}
*/
versions: {},
// eslint-disable-next-line jsdoc/no-restricted-syntax
/**
* @param {Function} fn function
*/
// eslint-disable-next-line jsdoc/reject-function-type
/** @param {Function} fn function */
nextTick(fn) {
// eslint-disable-next-line prefer-rest-params
const args = Array.prototype.slice.call(arguments, 1);

View File

@@ -1,6 +1,6 @@
{
"name": "enhanced-resolve",
"version": "5.18.4",
"version": "5.19.0",
"description": "Offers a async require.resolve function. It's highly configurable.",
"homepage": "http://github.com/webpack/enhanced-resolve",
"repository": {
@@ -21,25 +21,25 @@
"LICENSE"
],
"scripts": {
"prepare": "husky install",
"lint": "yarn lint:code && yarn lint:types && yarn lint:types-test && yarn lint:special && yarn fmt:check && yarn lint:spellcheck",
"prepare": "husky",
"lint": "npm run lint:code && npm run lint:types && npm run lint:types-test && npm run lint:special && npm run fmt:check && npm run lint:spellcheck",
"lint:code": "eslint --cache .",
"lint:special": "node node_modules/tooling/lockfile-lint && node node_modules/tooling/inherit-types && node node_modules/tooling/generate-types",
"lint:special": "node node_modules/tooling/inherit-types && node node_modules/tooling/generate-types",
"lint:types": "tsc",
"lint:types-test": "tsc -p tsconfig.types.test.json",
"lint:spellcheck": "cspell --no-must-find-files \"**/*.*\"",
"fmt": "yarn fmt:base --loglevel warn --write",
"fmt:check": "yarn fmt:base --check",
"lint:spellcheck": "cspell --cache --no-must-find-files --quiet \"**/*.*\"",
"fmt": "npm run fmt:base -- --loglevel warn --write",
"fmt:check": "npm run fmt:base -- --check",
"fmt:base": "node_modules/prettier/bin/prettier.cjs --cache --ignore-unknown .",
"fix": "yarn fix:code && yarn fix:special",
"fix:code": "yarn lint:code --fix",
"fix": "npm run fix:code && npm run fix:special",
"fix:code": "npm run lint:code -- --fix",
"fix:special": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/generate-types --write",
"type-report": "rimraf coverage && yarn cover:types && yarn cover:report && open-cli coverage/lcov-report/index.html",
"pretest": "yarn lint",
"test": "yarn test:coverage",
"type-report": "rimraf coverage && npm run cover:types && npm run cover:report && open-cli coverage/lcov-report/index.html",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"test:only": "jest",
"test:watch": "yarn test:only --watch",
"test:coverage": "yarn test:only --collectCoverageFrom=\"lib/**/*.js\" --coverage"
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"lib/**/*.js\" --coverage"
},
"lint-staged": {
"*.{js,cjs,mjs}": [
@@ -52,34 +52,23 @@
},
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
"tapable": "^2.3.0"
},
"devDependencies": {
"@eslint/js": "^9.28.0",
"@eslint/markdown": "^7.1.0",
"@types/graceful-fs": "^4.1.6",
"@types/jest": "^27.5.1",
"@types/node": "^24.0.3",
"@stylistic/eslint-plugin": "^5.2.2",
"cspell": "4.2.8",
"eslint": "^9.28.0",
"eslint-config-prettier": "^10.1.5",
"eslint-config-webpack": "^4.1.2",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-jsdoc": "^52.0.2",
"eslint-plugin-n": "^17.19.0",
"eslint-plugin-prettier": "^5.4.1",
"eslint-plugin-unicorn": "^60.0.0",
"globals": "^16.2.0",
"husky": "^6.0.0",
"@types/node": "^24.10.4",
"cspell": "^9.4.0",
"eslint": "^9.39.2",
"eslint-config-webpack": "^4.9.0",
"husky": "^9.1.7",
"jest": "^27.5.1",
"lint-staged": "^10.4.0",
"memfs": "^3.2.0",
"prettier": "^3.5.3",
"lint-staged": "^16.2.7",
"memfs": "^3.5.3",
"prettier": "^3.7.4",
"prettier-2": "npm:prettier@^2",
"tooling": "webpack/tooling#v1.24.0",
"typescript": "^5.8.3"
"tooling": "webpack/tooling#v1.24.4",
"typescript": "^5.9.3"
},
"engines": {
"node": ">=10.13.0"

View File

@@ -34,7 +34,7 @@ declare interface BaseResolveRequest {
/**
* content
*/
context?: object;
context?: Context;
/**
* description file path
@@ -51,6 +51,11 @@ declare interface BaseResolveRequest {
*/
descriptionFileData?: JsonObject;
/**
* tsconfig paths map
*/
tsconfigPathsMap?: null | TsconfigPathsMap;
/**
* relative path
*/
@@ -160,6 +165,7 @@ declare class CloneBasenamePlugin {
>;
apply(resolver: Resolver): void;
}
type Context = KnownContext & Record<any, any>;
declare interface Dirent<T extends string | Buffer = string> {
/**
* true when is file, otherwise false
@@ -553,6 +559,12 @@ declare interface JsonObject {
| JsonValue[];
}
type JsonValue = null | string | number | boolean | JsonObject | JsonValue[];
declare interface KnownContext {
/**
* environments
*/
environments?: string[];
}
declare interface KnownHooks {
/**
* resolve step hook
@@ -1081,12 +1093,12 @@ declare interface ResolveContext {
yield?: (request: ResolveRequest) => void;
}
declare interface ResolveFunction {
(context: object, path: string, request: string): string | false;
(context: Context, path: string, request: string): string | false;
(path: string, request: string): string | false;
}
declare interface ResolveFunctionAsync {
(
context: object,
context: Context,
path: string,
request: string,
resolveContext: ResolveContext,
@@ -1097,7 +1109,7 @@ declare interface ResolveFunctionAsync {
) => void,
): void;
(
context: object,
context: Context,
path: string,
request: string,
callback: (
@@ -1266,6 +1278,11 @@ declare interface ResolveOptionsResolverFactoryObject_1 {
* prefer absolute
*/
preferAbsolute: boolean;
/**
* tsconfig file path or config object
*/
tsconfig: string | boolean | TsconfigOptions;
}
declare interface ResolveOptionsResolverFactoryObject_2 {
/**
@@ -1411,6 +1428,11 @@ declare interface ResolveOptionsResolverFactoryObject_2 {
* Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots
*/
preferAbsolute?: boolean;
/**
* TypeScript config file path or config object with configFile and references
*/
tsconfig?: string | boolean | TsconfigOptions;
}
type ResolveRequest = BaseResolveRequest & Partial<ParsedIdentifier>;
declare abstract class Resolver {
@@ -1439,9 +1461,9 @@ declare abstract class Resolver {
[ResolveRequest, ResolveContext],
null | ResolveRequest
>;
resolveSync(context: object, path: string, request: string): string | false;
resolveSync(context: Context, path: string, request: string): string | false;
resolve(
context: object,
context: Context,
path: string,
request: string,
resolveContext: ResolveContext,
@@ -1569,12 +1591,67 @@ declare interface SyncFileSystem {
*/
realpathSync?: RealPathSync;
}
declare interface TsconfigOptions {
/**
* A relative path to the tsconfig file based on cwd, or an absolute path of tsconfig file
*/
configFile?: string;
/**
* References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths
*/
references?: string[] | "auto";
}
declare interface TsconfigPathsData {
/**
* tsconfig file data
*/
alias: AliasOption[];
/**
* tsconfig file data
*/
modules: string[];
}
declare interface TsconfigPathsMap {
/**
* main tsconfig paths data
*/
main: TsconfigPathsData;
/**
* main tsconfig base URL (absolute path)
*/
mainContext: string;
/**
* referenced tsconfig paths data mapped by baseUrl
*/
refs: { [index: string]: TsconfigPathsData };
/**
* file dependencies
*/
fileDependencies: Set<string>;
}
declare class TsconfigPathsPlugin {
constructor(configFileOrOptions: string | true | TsconfigOptions);
configFile: string;
references: "auto" | TsconfigReference[];
apply(resolver: Resolver): void;
}
declare interface TsconfigReference {
/**
* Path to the referenced project
*/
path: string;
}
declare interface URL_url extends URL_Import {}
declare interface WriteOnlySet<T> {
add: (item: T) => void;
}
declare function exports(
context: object,
context: Context,
path: string,
request: string,
resolveContext: ResolveContext,
@@ -1585,7 +1662,7 @@ declare function exports(
) => void,
): void;
declare function exports(
context: object,
context: Context,
path: string,
request: string,
callback: (
@@ -1640,10 +1717,12 @@ declare namespace exports {
CachedInputFileSystem,
CloneBasenamePlugin,
LogInfoPlugin,
TsconfigPathsPlugin,
ResolveOptionsOptionalFS,
BaseFileSystem,
PnpApi,
Resolver,
Context,
FileSystem,
ResolveContext,
ResolveRequest,