Socket
Socket
Sign inDemoInstall

enhanced-resolve

Package Overview
Dependencies
2
Maintainers
4
Versions
127
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.12.0 to 5.13.0

10

lib/Resolver.js

@@ -48,6 +48,14 @@ /*

/** @typedef {function((NodeJS.ErrnoException | null)=, (string | Buffer)[] | IDirent[]=): void} DirentArrayCallback */
/**
* @typedef {Object} ReaddirOptions
* @property {BufferEncoding | null | 'buffer'} [encoding]
* @property {boolean | undefined} [withFileTypes=false]
*/
/**
* @typedef {Object} FileSystem
* @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} readFile
* @property {(function(string, FileSystemCallback<(Buffer | string)[] | FileSystemDirent[]>): void) & function(string, object, FileSystemCallback<(Buffer | string)[] | FileSystemDirent[]>): void} readdir
* @property {function(string, (ReaddirOptions | BufferEncoding | null | undefined | 'buffer' | DirentArrayCallback)=, DirentArrayCallback=): void} readdir
* @property {((function(string, FileSystemCallback<object>): void) & function(string, object, FileSystemCallback<object>): void)=} readJson

@@ -54,0 +62,0 @@ * @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} readlink

331

lib/util/entrypoints.js

@@ -15,10 +15,2 @@ /*

/**
* @typedef {Object} PathTreeNode
* @property {Map<string, PathTreeNode>|null} children
* @property {MappingValue} folder
* @property {Map<string, MappingValue>|null} wildcards
* @property {Map<string, MappingValue>} files
*/
/**
* Processing exports/imports field

@@ -87,2 +79,3 @@ * @callback FieldProcessor

const hashCode = "#".charCodeAt(0);
const patternRegEx = /\*/g;

@@ -97,3 +90,4 @@ /**

return createFieldProcessor(
buildExportsFieldPathTree(exportsField),
buildExportsField(exportsField),
request => (request.length === 0 ? "." : "./" + request),
assertExportsFieldRequest,

@@ -112,3 +106,4 @@ assertExportTarget

return createFieldProcessor(
buildImportsFieldPathTree(importsField),
buildImportsField(importsField),
request => "#" + request,
assertImportsFieldRequest,

@@ -120,3 +115,4 @@ assertImportTarget

/**
* @param {PathTreeNode} treeRoot root
* @param {ExportsField | ImportsField} field root
* @param {(s: string) => string} normalizeRequest Normalize request, for `imports` field it adds `#`, for `exports` field it adds `.` or `./`
* @param {(s: string) => string} assertRequest assertRequest

@@ -126,11 +122,16 @@ * @param {(s: string, f: boolean) => void} assertTarget assertTarget

*/
function createFieldProcessor(treeRoot, assertRequest, assertTarget) {
function createFieldProcessor(
field,
normalizeRequest,
assertRequest,
assertTarget
) {
return function fieldProcessor(request, conditionNames) {
request = assertRequest(request);
const match = findMatch(request, treeRoot);
const match = findMatch(normalizeRequest(request), field);
if (match === null) return [];
const [mapping, remainRequestIndex] = match;
const [mapping, remainingRequest, isSubpathMapping, isPattern] = match;

@@ -152,12 +153,6 @@ /** @type {DirectMapping|null} */

const remainingRequest =
remainRequestIndex === request.length + 1
? undefined
: remainRequestIndex < 0
? request.slice(-remainRequestIndex - 1)
: request.slice(remainRequestIndex);
return directMapping(
remainingRequest,
remainRequestIndex < 0,
isPattern,
isSubpathMapping,
direct,

@@ -261,97 +256,83 @@ conditionNames,

function patternKeyCompare(a, b) {
const aPatternIndex = a.indexOf("*");
const bPatternIndex = b.indexOf("*");
const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1;
const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1;
if (baseLenA > baseLenB) return -1;
if (baseLenB > baseLenA) return 1;
if (aPatternIndex === -1) return 1;
if (bPatternIndex === -1) return -1;
if (a.length > b.length) return -1;
if (b.length > a.length) return 1;
return 0;
}
/**
* Trying to match request to field
* @param {string} request request
* @param {PathTreeNode} treeRoot path tree root
* @returns {[MappingValue, number]|null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
* @param {ExportsField | ImportsField} field exports or import field
* @returns {[MappingValue, string, boolean, boolean]|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, treeRoot) {
if (request.length === 0) {
const value = treeRoot.files.get("");
return value ? [value, 1] : null;
}
function findMatch(request, field) {
if (
treeRoot.children === null &&
treeRoot.folder === null &&
treeRoot.wildcards === null
Object.prototype.hasOwnProperty.call(field, request) &&
!request.includes("*") &&
!request.endsWith("/")
) {
const value = treeRoot.files.get(request);
const target = field[request];
return value ? [value, request.length + 1] : null;
return [target, "", false, false];
}
let node = treeRoot;
let lastNonSlashIndex = 0;
let slashIndex = request.indexOf("/", 0);
let bestMatch = "";
let bestMatchSubpath;
/** @type {[MappingValue, number]|null} */
let lastFolderMatch = null;
const keys = Object.getOwnPropertyNames(field);
const applyFolderMapping = () => {
const folderMapping = node.folder;
if (folderMapping) {
if (lastFolderMatch) {
lastFolderMatch[0] = folderMapping;
lastFolderMatch[1] = -lastNonSlashIndex - 1;
} else {
lastFolderMatch = [folderMapping, -lastNonSlashIndex - 1];
}
}
};
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const patternIndex = key.indexOf("*");
const applyWildcardMappings = (wildcardMappings, remainingRequest) => {
if (wildcardMappings) {
for (const [key, target] of wildcardMappings) {
if (remainingRequest.startsWith(key)) {
if (!lastFolderMatch) {
lastFolderMatch = [target, lastNonSlashIndex + key.length];
} else if (lastFolderMatch[1] < lastNonSlashIndex + key.length) {
lastFolderMatch[0] = target;
lastFolderMatch[1] = lastNonSlashIndex + key.length;
}
}
if (patternIndex !== -1 && request.startsWith(key.slice(0, patternIndex))) {
const patternTrailer = key.slice(patternIndex + 1);
if (
request.length >= key.length &&
request.endsWith(patternTrailer) &&
patternKeyCompare(bestMatch, key) === 1 &&
key.lastIndexOf("*") === patternIndex
) {
bestMatch = key;
bestMatchSubpath = request.slice(
patternIndex,
request.length - patternTrailer.length
);
}
}
};
while (slashIndex !== -1) {
applyFolderMapping();
const wildcardMappings = node.wildcards;
if (!wildcardMappings && node.children === null) return lastFolderMatch;
const folder = request.slice(lastNonSlashIndex, slashIndex);
applyWildcardMappings(wildcardMappings, folder);
if (node.children === null) return lastFolderMatch;
const newNode = node.children.get(folder);
if (!newNode) {
return lastFolderMatch;
// For legacy `./foo/`
else if (
key[key.length - 1] === "/" &&
request.startsWith(key) &&
patternKeyCompare(bestMatch, key) === 1
) {
bestMatch = key;
bestMatchSubpath = request.slice(key.length);
}
node = newNode;
lastNonSlashIndex = slashIndex + 1;
slashIndex = request.indexOf("/", lastNonSlashIndex);
}
const remainingRequest =
lastNonSlashIndex > 0 ? request.slice(lastNonSlashIndex) : request;
if (bestMatch === "") return null;
const value = node.files.get(remainingRequest);
const target = field[bestMatch];
const isSubpathMapping = bestMatch.endsWith("/");
const isPattern = bestMatch.includes("*");
if (value) {
return [value, request.length + 1];
}
applyFolderMapping();
applyWildcardMappings(node.wildcards, remainingRequest);
return lastFolderMatch;
return [
target,
/** @type {string} */ (bestMatchSubpath),
isSubpathMapping,
isPattern
];
}

@@ -371,3 +352,4 @@

* @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
* @param {boolean} subpathMapping true, for subpath mappings
* @param {boolean} isPattern true, if mapping is a pattern (contains "*")
* @param {boolean} isSubpathMapping true, for subpath mappings
* @param {DirectMapping|null} mappingTarget direct export

@@ -380,3 +362,4 @@ * @param {Set<string>} conditionNames condition names

remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
mappingTarget,

@@ -390,3 +373,9 @@ conditionNames,

return [
targetMapping(remainingRequest, subpathMapping, mappingTarget, assert)
targetMapping(
remainingRequest,
isPattern,
isSubpathMapping,
mappingTarget,
assert
)
];

@@ -400,3 +389,9 @@ }

targets.push(
targetMapping(remainingRequest, subpathMapping, exp, assert)
targetMapping(
remainingRequest,
isPattern,
isSubpathMapping,
exp,
assert
)
);

@@ -410,3 +405,4 @@ continue;

remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
mapping,

@@ -426,3 +422,4 @@ conditionNames,

* @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
* @param {boolean} subpathMapping true, for subpath mappings
* @param {boolean} isPattern true, if mapping is a pattern (contains "*")
* @param {boolean} isSubpathMapping true, for subpath mappings
* @param {string} mappingTarget direct export

@@ -434,3 +431,4 @@ * @param {(d: string, f: boolean) => void} assert asserting direct value

remainingRequest,
subpathMapping,
isPattern,
isSubpathMapping,
mappingTarget,

@@ -441,10 +439,24 @@ assert

assert(mappingTarget, false);
return mappingTarget;
}
if (subpathMapping) {
if (isSubpathMapping) {
assert(mappingTarget, true);
return mappingTarget + remainingRequest;
}
assert(mappingTarget, false);
return mappingTarget.replace(/\*/g, remainingRequest.replace(/\$/g, "$$"));
let result = mappingTarget;
if (isPattern) {
result = result.replace(
patternRegEx,
remainingRequest.replace(/\$/g, "$$")
);
}
return result;
}

@@ -507,88 +519,9 @@

/**
* Internal helper to create path tree node
* to ensure that each node gets the same hidden class
* @returns {PathTreeNode} node
*/
function createNode() {
return {
children: null,
folder: null,
wildcards: null,
files: new Map()
};
}
/**
* Internal helper for building path tree
* @param {PathTreeNode} root root
* @param {string} path path
* @param {MappingValue} target target
*/
function walkPath(root, path, target) {
if (path.length === 0) {
root.folder = target;
return;
}
let node = root;
// Typical path tree can looks like
// root
// - files: ["a.js", "b.js"]
// - children:
// node1:
// - files: ["a.js", "b.js"]
let lastNonSlashIndex = 0;
let slashIndex = path.indexOf("/", 0);
while (slashIndex !== -1) {
const folder = path.slice(lastNonSlashIndex, slashIndex);
let newNode;
if (node.children === null) {
newNode = createNode();
node.children = new Map();
node.children.set(folder, newNode);
} else {
newNode = node.children.get(folder);
if (!newNode) {
newNode = createNode();
node.children.set(folder, newNode);
}
}
node = newNode;
lastNonSlashIndex = slashIndex + 1;
slashIndex = path.indexOf("/", lastNonSlashIndex);
}
if (lastNonSlashIndex >= path.length) {
node.folder = target;
} else {
const file = lastNonSlashIndex > 0 ? path.slice(lastNonSlashIndex) : path;
if (file.endsWith("*")) {
if (node.wildcards === null) node.wildcards = new Map();
node.wildcards.set(file.slice(0, -1), target);
} else {
node.files.set(file, target);
}
}
}
/**
* @param {ExportsField} field exports field
* @returns {PathTreeNode} tree root
* @returns {ExportsField} normalized exports field
*/
function buildExportsFieldPathTree(field) {
const root = createNode();
function buildExportsField(field) {
// handle syntax sugar, if exports field is direct mapping for "."
if (typeof field === "string") {
root.files.set("", field);
return root;
} else if (Array.isArray(field)) {
root.files.set("", field.slice());
return root;
if (typeof field === "string" || Array.isArray(field)) {
return { ".": field };
}

@@ -616,4 +549,3 @@

root.files.set("", field);
return root;
return { ".": field };
}

@@ -629,3 +561,2 @@

if (key.length === 1) {
root.files.set("", field[key]);
continue;

@@ -641,7 +572,5 @@ }

}
walkPath(root, key.slice(2), field[key]);
}
return root;
return field;
}

@@ -651,7 +580,5 @@

* @param {ImportsField} field imports field
* @returns {PathTreeNode} root
* @returns {ImportsField} normalized imports field
*/
function buildImportsFieldPathTree(field) {
const root = createNode();
function buildImportsField(field) {
const keys = Object.keys(field);

@@ -683,7 +610,5 @@

}
walkPath(root, key.slice(1), field[key]);
}
return root;
return field;
}
{
"name": "enhanced-resolve",
"version": "5.12.0",
"version": "5.13.0",
"author": "Tobias Koppers @sokra",

@@ -5,0 +5,0 @@ "description": "Offers a async require.resolve function. It's highly configurable.",

@@ -66,6 +66,6 @@ # enhanced-resolve

const context = {};
const resolveContext = {};
const lookupStartPath = "/Users/webpack/some/root/dir";
const request = "./path/to-look-up.js";
myResolver.resolve({}, lookupStartPath, request, resolveContext, (
const resolveContext = {};
myResolver.resolve(context, lookupStartPath, request, resolveContext, (
err /*Error*/,

@@ -87,3 +87,3 @@ filepath /*string*/

| cacheWithContext | true | If unsafe cache is enabled, includes `request.context` in the cache key |
| conditionNames | ["node"] | A list of exports field condition names |
| conditionNames | [] | A list of exports field condition names |
| descriptionFiles | ["package.json"] | A list of description files to read from |

@@ -90,0 +90,0 @@ | enforceExtension | false | Enforce that a extension from extensions must be used |

@@ -48,13 +48,27 @@ /*

statSync: (arg0: string, arg1?: object) => FileSystemStats;
readdir: {
(
arg0: string,
arg1: FileSystemCallback<(string | Buffer)[] | FileSystemDirent[]>
): void;
(
arg0: string,
arg1: object,
arg2: FileSystemCallback<(string | Buffer)[] | FileSystemDirent[]>
): void;
};
readdir: (
arg0: string,
arg1?:
| null
| ((
arg0?: null | NodeJS.ErrnoException,
arg1?: (string | Buffer)[] | any[]
) => void)
| ReaddirOptions
| "ascii"
| "utf8"
| "utf-8"
| "utf16le"
| "ucs2"
| "ucs-2"
| "base64"
| "latin1"
| "binary"
| "hex"
| "buffer",
arg2?: (
arg0?: null | NodeJS.ErrnoException,
arg1?: (string | Buffer)[] | any[]
) => void
) => void;
readdirSync: (

@@ -111,13 +125,27 @@ arg0: string,

};
readdir: {
(
arg0: string,
arg1: FileSystemCallback<(string | Buffer)[] | FileSystemDirent[]>
): void;
(
arg0: string,
arg1: object,
arg2: FileSystemCallback<(string | Buffer)[] | FileSystemDirent[]>
): void;
};
readdir: (
arg0: string,
arg1?:
| null
| ((
arg0?: null | NodeJS.ErrnoException,
arg1?: (string | Buffer)[] | any[]
) => void)
| ReaddirOptions
| "ascii"
| "utf8"
| "utf-8"
| "utf16le"
| "ucs2"
| "ucs-2"
| "base64"
| "latin1"
| "binary"
| "hex"
| "buffer",
arg2?: (
arg0?: null | NodeJS.ErrnoException,
arg1?: (string | Buffer)[] | any[]
) => void
) => void;
readJson?: {

@@ -190,2 +218,18 @@ (arg0: string, arg1: FileSystemCallback<object>): void;

}
declare interface ReaddirOptions {
encoding?:
| null
| "ascii"
| "utf8"
| "utf-8"
| "utf16le"
| "ucs2"
| "ucs-2"
| "base64"
| "latin1"
| "binary"
| "hex"
| "buffer";
withFileTypes?: boolean;
}

@@ -192,0 +236,0 @@ /**

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc