🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

exsolve

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

exsolve - npm Package Compare versions

Comparing version
1.0.8
to
1.1.0
+0
-2
dist/index.d.mts

@@ -1,2 +0,1 @@

//#region src/resolve.d.ts
/**

@@ -67,3 +66,2 @@ * Options to configure module resolution.

declare function clearResolveCache(): void;
//#endregion
export { type ResolveOptions, type ResolverOptions, clearResolveCache, createResolver, resolveModulePath, resolveModuleURL };
+179
-227

@@ -6,6 +6,3 @@ import fs, { lstatSync, realpathSync, statSync } from "node:fs";

import process$1 from "node:process";
import v8 from "node:v8";
import { format, inspect } from "node:util";
//#region src/internal/builtins.ts
const nodeBuiltins = [

@@ -81,8 +78,4 @@ "_http_agent",

];
//#endregion
//#region src/internal/errors.ts
const own$1 = {}.hasOwnProperty;
const classRegExp = /^([A-Z][a-z\d]*)+$/;
const kTypes = new Set([
const kTypes = /* @__PURE__ */ new Set([
"string",

@@ -99,21 +92,17 @@ "function",

const messages = /* @__PURE__ */ new Map();
const nodeInternalPrefix = "__node_internal_";
let userStackTraceLimit;
/**
* Create a list string in the form like 'A and B' or 'A, B, ..., and Z'.
* We cannot use Intl.ListFormat because it's not available in
* --without-intl builds.
*
* @param {Array<string>} array
* An array of strings.
* @param {string} [type]
* The list type to be inserted before the last element.
* @returns {string}
*/
function formatList(array, type = "and") {
return array.length < 3 ? array.join(` ${type} `) : `${array.slice(0, -1).join(", ")}, ${type} ${array.at(-1)}`;
switch (array.length) {
case 0: return "";
case 1: return `${array[0]}`;
case 2: return `${array[0]} ${type} ${array[1]}`;
case 3: return `${array[0]}, ${array[1]}, ${type} ${array[2]}`;
default: return `${array.slice(0, -1).join(", ")}, ${type} ${array.at(-1)}`;
}
}
/**
* Utility function for registering the error codes.
*/
function getExpectedArgumentLength(message) {
let expectedLength = 0;
const regex = /%[dfijoOs]/g;
while (regex.exec(message) !== null) expectedLength++;
return expectedLength;
}
function createError(sym, value, constructor) {

@@ -123,56 +112,72 @@ messages.set(sym, value);

}
const kIsNodeError = Symbol("kIsNodeError");
function makeNodeErrorWithCode(Base, key) {
return function NodeError(...parameters) {
const limit = Error.stackTraceLimit;
if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0;
const error = new Base();
if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit;
const message = getMessage(key, parameters, error);
Object.defineProperties(error, {
message: {
value: message,
enumerable: false,
writable: true,
configurable: true
},
toString: {
value() {
const message = messages.get(key);
const expectedLength = typeof message === "string" ? getExpectedArgumentLength(message) : -1;
switch (expectedLength) {
case 0: {
class NodeError extends Base {
code = key;
constructor(...args) {
assert.ok(args.length === 0, `Code: ${key}; The provided arguments length (${args.length}) does not match the required ones (${expectedLength}).`);
super(message);
}
get ["constructor"]() {
return Base;
}
get [kIsNodeError]() {
return true;
}
toString() {
return `${this.name} [${key}]: ${this.message}`;
},
enumerable: false,
writable: true,
configurable: true
}
}
});
captureLargerStackTrace(error);
error.code = key;
return error;
};
return NodeError;
}
case -1: {
class NodeError extends Base {
code = key;
constructor(...args) {
super();
Object.defineProperty(this, "message", {
value: getMessage(key, args, this),
enumerable: false,
writable: true,
configurable: true
});
}
get ["constructor"]() {
return Base;
}
get [kIsNodeError]() {
return true;
}
toString() {
return `${this.name} [${key}]: ${this.message}`;
}
}
return NodeError;
}
default: {
class NodeError extends Base {
code = key;
constructor(...args) {
assert.ok(args.length === expectedLength, `Code: ${key}; The provided arguments length (${args.length}) does not match the required ones (${expectedLength}).`);
args.unshift(message);
super(Reflect.apply(format, null, args));
}
get ["constructor"]() {
return Base;
}
get [kIsNodeError]() {
return true;
}
toString() {
return `${this.name} [${key}]: ${this.message}`;
}
}
return NodeError;
}
}
}
function isErrorStackTraceLimitWritable() {
try {
if (v8.startupSnapshot.isBuildingSnapshot()) return false;
} catch {}
const desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit");
if (desc === void 0) return Object.isExtensible(Error);
return own$1.call(desc, "writable") && desc.writable !== void 0 ? desc.writable : desc.set !== void 0;
}
/**
* This function removes unnecessary frames from Node.js core errors.
*/
function hideStackFrames(wrappedFunction) {
const hidden = nodeInternalPrefix + wrappedFunction.name;
Object.defineProperty(wrappedFunction, "name", { value: hidden });
return wrappedFunction;
}
const captureLargerStackTrace = hideStackFrames(function(error) {
const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable();
if (stackTraceLimitIsWritable) {
userStackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = Number.POSITIVE_INFINITY;
}
Error.captureStackTrace(error);
if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit;
return error;
});
function getMessage(key, parameters, self) {

@@ -185,5 +190,3 @@ const message = messages.get(key);

}
const regex = /%[dfijoOs]/g;
let expectedLength = 0;
while (regex.exec(message) !== null) expectedLength++;
const expectedLength = getExpectedArgumentLength(message);
assert.ok(expectedLength === parameters.length, `Code: ${key}; The provided arguments length (${parameters.length}) does not match the required ones (${expectedLength}).`);

@@ -194,17 +197,34 @@ if (parameters.length === 0) return message;

}
/**
* Determine the specific type of a value for type-mismatch errors.
*/
function determineSpecificType(value) {
if (value === null || value === void 0) return String(value);
if (typeof value === "function" && value.name) return `function ${value.name}`;
if (typeof value === "object") {
if (value.constructor && value.constructor.name) return `an instance of ${value.constructor.name}`;
return `${inspect(value, { depth: -1 })}`;
if (value === null) return "null";
else if (value === void 0) return "undefined";
const type = typeof value;
switch (type) {
case "bigint": return `type bigint (${value}n)`;
case "number":
if (value === 0) return 1 / value === Number.NEGATIVE_INFINITY ? "type number (-0)" : "type number (0)";
else if (Number.isNaN(value)) return "type number (NaN)";
else if (value === Number.POSITIVE_INFINITY) return "type number (Infinity)";
else if (value === Number.NEGATIVE_INFINITY) return "type number (-Infinity)";
return `type number (${value})`;
case "boolean": return value ? "type boolean (true)" : "type boolean (false)";
case "symbol": return `type symbol (${String(value)})`;
case "function": return `function ${value.name}`;
case "object":
if (value.constructor && value.constructor.name) return `an instance of ${value.constructor.name}`;
return `${inspect(value, { depth: -1 })}`;
case "string": {
let string = value;
if (string.length > 28) string = `${string.slice(0, 25)}...`;
if (!string.includes("'")) return `type string ('${string}')`;
return `type string (${JSON.stringify(string)})`;
}
default: {
let inspected = inspect(value, { colors: false });
if (inspected.length > 28) inspected = `${inspected.slice(0, 25)}...`;
return `type ${type} (${inspected})`;
}
}
let inspected = inspect(value, { colors: false });
if (inspected.length > 28) inspected = `${inspected.slice(0, 25)}...`;
return `type ${typeof value} (${inspected})`;
}
const ERR_INVALID_ARG_TYPE = createError("ERR_INVALID_ARG_TYPE", (name, expected, actual) => {
createError("ERR_INVALID_ARG_TYPE", (name, expected, actual) => {
assert.ok(typeof name === "string", "'name' must be a string");

@@ -233,3 +253,3 @@ if (!Array.isArray(expected)) expected = [expected];

if (pos !== -1) {
types.slice(pos, 1);
types.splice(pos, 1);
instances.push("Object");

@@ -254,16 +274,7 @@ }

}, TypeError);
const ERR_INVALID_MODULE_SPECIFIER = createError(
"ERR_INVALID_MODULE_SPECIFIER",
/**
* @param {string} request
* @param {string} reason
* @param {string} [base]
*/
(request, reason, base) => {
return `Invalid module "${request}" ${reason}${base ? ` imported from ${base}` : ""}`;
},
TypeError
);
const ERR_INVALID_PACKAGE_CONFIG = createError("ERR_INVALID_PACKAGE_CONFIG", (path$1, base, message) => {
return `Invalid package config ${path$1}${base ? ` while importing ${base}` : ""}${message ? `. ${message}` : ""}`;
const ERR_INVALID_MODULE_SPECIFIER = createError("ERR_INVALID_MODULE_SPECIFIER", (request, reason, base) => {
return `Invalid module "${request}" ${reason}${base ? ` imported from ${base}` : ""}`;
}, TypeError);
const ERR_INVALID_PACKAGE_CONFIG = createError("ERR_INVALID_PACKAGE_CONFIG", (path, base, message) => {
return `Invalid package config ${path}${base ? ` while importing ${base}` : ""}${message ? `. ${message}` : ""}`;
}, Error);

@@ -278,28 +289,22 @@ const ERR_INVALID_PACKAGE_TARGET = createError("ERR_INVALID_PACKAGE_TARGET", (packagePath, key, target, isImport = false, base) => {

}, Error);
const ERR_MODULE_NOT_FOUND = createError("ERR_MODULE_NOT_FOUND", (path$1, base, exactUrl = false) => {
return `Cannot find ${exactUrl ? "module" : "package"} '${path$1}' imported from ${base}`;
const ERR_MODULE_NOT_FOUND = createError("ERR_MODULE_NOT_FOUND", function(path, base, exactUrl = false) {
if (exactUrl && typeof exactUrl === "string") this.url = `${exactUrl}`;
return `Cannot find ${exactUrl ? "module" : "package"} '${path}' imported from ${base}`;
}, Error);
const ERR_NETWORK_IMPORT_DISALLOWED = createError("ERR_NETWORK_IMPORT_DISALLOWED", "import of '%s' by %s is not supported: %s", Error);
const ERR_PACKAGE_IMPORT_NOT_DEFINED = createError("ERR_PACKAGE_IMPORT_NOT_DEFINED", (specifier, packagePath, base) => {
return `Package import specifier "${specifier}" is not defined${packagePath ? ` in package ${packagePath || ""}package.json` : ""} imported from ${base}`;
}, TypeError);
const ERR_PACKAGE_PATH_NOT_EXPORTED = createError(
"ERR_PACKAGE_PATH_NOT_EXPORTED",
/**
* @param {string} packagePath
* @param {string} subpath
* @param {string} [base]
*/
(packagePath, subpath, base) => {
if (subpath === ".") return `No "exports" main defined in ${packagePath}package.json${base ? ` imported from ${base}` : ""}`;
return `Package subpath '${subpath}' is not defined by "exports" in ${packagePath}package.json${base ? ` imported from ${base}` : ""}`;
},
Error
);
const ERR_UNSUPPORTED_DIR_IMPORT = createError("ERR_UNSUPPORTED_DIR_IMPORT", "Directory import '%s' is not supported resolving ES modules imported from %s", Error);
const ERR_PACKAGE_PATH_NOT_EXPORTED = createError("ERR_PACKAGE_PATH_NOT_EXPORTED", (packagePath, subpath, base) => {
if (subpath === ".") return `No "exports" main defined in ${packagePath}package.json${base ? ` imported from ${base}` : ""}`;
return `Package subpath '${subpath}' is not defined by "exports" in ${packagePath}package.json${base ? ` imported from ${base}` : ""}`;
}, Error);
const ERR_UNSUPPORTED_DIR_IMPORT = createError("ERR_UNSUPPORTED_DIR_IMPORT", function(path, base, exactUrl = void 0) {
this.url = exactUrl;
return `Directory import '${path}' is not supported resolving ES modules imported from ${base}`;
}, Error);
const ERR_UNSUPPORTED_RESOLVE_REQUEST = createError("ERR_UNSUPPORTED_RESOLVE_REQUEST", "Failed to resolve module specifier \"%s\" from \"%s\": Invalid relative URL or base scheme is not hierarchical.", TypeError);
const ERR_UNKNOWN_FILE_EXTENSION = createError("ERR_UNKNOWN_FILE_EXTENSION", (extension, path$1) => {
return `Unknown file extension "${extension}" for ${path$1}`;
const ERR_UNKNOWN_FILE_EXTENSION = createError("ERR_UNKNOWN_FILE_EXTENSION", (extension, path) => {
return `Unknown file extension "${extension}" for ${path}`;
}, TypeError);
const ERR_INVALID_ARG_VALUE = createError("ERR_INVALID_ARG_VALUE", (name, value, reason = "is invalid") => {
createError("ERR_INVALID_ARG_VALUE", (name, value, reason = "is invalid") => {
let inspected = inspect(value);

@@ -309,5 +314,2 @@ if (inspected.length > 128) inspected = `${inspected.slice(0, 128)}...`;

}, TypeError);
//#endregion
//#region src/internal/package-json-reader.ts
const hasOwnProperty$1 = {}.hasOwnProperty;

@@ -369,5 +371,2 @@ const cache = /* @__PURE__ */ new Map();

}
//#endregion
//#region src/internal/get-format.ts
const hasOwnProperty = {}.hasOwnProperty;

@@ -391,3 +390,3 @@ const extensionFormatMap = {

function mimeToFormat(mime) {
if (mime && /\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?/i.test(mime)) return "module";
if (mime && /^\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?$/i.test(mime)) return "module";
if (mime === "application/json") return "json";

@@ -397,3 +396,3 @@ return null;

function getDataProtocolModuleFormat(parsed) {
const { 1: mime } = /^([^/]+\/[^;,]+)[^,]*?(;base64)?,/.exec(parsed.pathname) || [
const { 1: mime } = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [
null,

@@ -405,17 +404,9 @@ null,

}
/**
* Returns the file extension from a URL.
*
* Should give similar result to
* `require('node:path').extname(require('node:url').fileURLToPath(url))`
* when used with a `file:` URL.
*
*/
const DOT_CODE = 46;
const SLASH_CODE = 47;
function extname(url) {
const pathname = url.pathname;
let index = pathname.length;
while (index--) {
const code = pathname.codePointAt(index);
if (code === 47) return "";
if (code === 46) return pathname.codePointAt(index - 1) === 47 ? "" : pathname.slice(index);
for (let i = pathname.length - 1; i > 0; i--) switch (pathname.charCodeAt(i)) {
case SLASH_CODE: return "";
case DOT_CODE: return pathname.charCodeAt(i - 1) === SLASH_CODE ? "" : pathname.slice(i);
}

@@ -433,7 +424,8 @@ return "";

const { type: packageType } = getPackageScopeConfig(url);
if (packageType === "none" || packageType === "commonjs") return "commonjs";
return "module";
if (packageType === "module") return "module";
if (packageType !== "none") return packageType;
return "commonjs";
}
const format$1 = extensionFormatMap[ext];
if (format$1) return format$1;
const format = extensionFormatMap[ext];
if (format) return format;
if (ignoreErrors) return;

@@ -447,5 +439,2 @@ throw new ERR_UNKNOWN_FILE_EXTENSION(ext, fileURLToPath(url));

}
//#endregion
//#region src/internal/resolve.ts
const RegExpPrototypeSymbolReplace = RegExp.prototype[Symbol.replace];

@@ -475,15 +464,7 @@ const own = {}.hasOwnProperty;

}
function tryStatSync(path$1) {
function tryStatSync(path) {
try {
return statSync(path$1);
return statSync(path);
} catch {}
}
/**
* Legacy CommonJS main resolution:
* 1. let M = pkg_url + (json main field)
* 2. TRY(M, M.js, M.json, M.node)
* 3. TRY(M/index.js, M/index.json, M/index.node)
* 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node)
* 5. NOT_FOUND
*/
function fileExists(url) {

@@ -499,3 +480,3 @@ const stats = statSync(url, { throwIfNoEntry: false });

if (fileExists(guess)) return guess;
const tries$1 = [
const tries = [
`./${packageConfig.main}.js`,

@@ -508,5 +489,5 @@ `./${packageConfig.main}.json`,

];
let i$1 = -1;
while (++i$1 < tries$1.length) {
guess = new URL$1(tries$1[i$1], packageJsonUrl);
let i = -1;
while (++i < tries.length) {
guess = new URL$1(tries[i], packageJsonUrl);
if (fileExists(guess)) break;

@@ -643,3 +624,3 @@ guess = void 0;

}
if (lastException === void 0 || lastException === null) return null;
if (lastException === void 0 || lastException === null) return lastException;
throw lastException;

@@ -664,3 +645,3 @@ }

}
return null;
return;
}

@@ -739,3 +720,3 @@ if (target === null) return null;

function packageImportsResolve(name, base, conditions) {
if (name === "#" || name.startsWith("#/") || name.endsWith("/")) throw new ERR_INVALID_MODULE_SPECIFIER(name, "is not a valid internal imports specifier name", fileURLToPath(base));
if (name === "#" || name.endsWith("/")) throw new ERR_INVALID_MODULE_SPECIFIER(name, "is not a valid internal imports specifier name", fileURLToPath(base));
let packageJsonUrl;

@@ -774,6 +755,2 @@ const packageConfig = getPackageScopeConfig(base);

}
/**
* @param {string} specifier
* @param {URL} base
*/
function parsePackageName(specifier, base) {

@@ -813,8 +790,8 @@ let separatorIndex = specifier.indexOf("/");

}
const packageConfig$1 = read(packageJsonPath, {
const packageConfig = read(packageJsonPath, {
base,
specifier
});
if (packageConfig$1.exports !== void 0 && packageConfig$1.exports !== null) return packageExportsResolve(packageJsonUrl, packageSubpath, packageConfig$1, base, conditions);
if (packageSubpath === ".") return legacyMainResolve(packageJsonUrl, packageConfig$1, base);
if (packageConfig.exports !== void 0 && packageConfig.exports !== null) return packageExportsResolve(packageJsonUrl, packageSubpath, packageConfig, base, conditions);
if (packageSubpath === ".") return legacyMainResolve(packageJsonUrl, packageConfig, base);
return new URL$1(packageSubpath, packageJsonUrl);

@@ -836,17 +813,2 @@ } while (packageJsonPath.length !== lastPath.length);

}
/**
* The “Resolver Algorithm Specification” as detailed in the Node docs (which is
* sync and slightly lower-level than `resolve`).
*
* @param {string} specifier
* `/example.js`, `./example.js`, `../example.js`, `some-package`, `fs`, etc.
* @param {URL} base
* Full URL (to a file) that `specifier` is resolved relative from.
* @param {Set<string>} [conditions]
* Conditions.
* @param {boolean} [preserveSymlinks]
* Keep symlinks instead of resolving them.
* @returns {URL}
* A URL object to the found thing.
*/
function moduleResolve(specifier, base, conditions, preserveSymlinks) {

@@ -878,15 +840,6 @@ const protocol = base.protocol;

}
//#endregion
//#region src/resolve.ts
const DEFAULT_CONDITIONS_SET = /* @__PURE__ */ new Set(["node", "import"]);
const isWindows = /* @__PURE__ */ (() => process.platform === "win32")();
const globalCache = /* @__PURE__ */ (() => globalThis["__EXSOLVE_CACHE__"] ||= /* @__PURE__ */ new Map())();
/**
* Synchronously resolves a module url based on the options provided.
*
* @param {string} input - The identifier or path of the module to resolve.
* @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}.
* @returns {string} The resolved URL as a string.
*/
const DEFAULT_CONDITIONS_SET = /* #__PURE__ */ new Set(["node", "import"]);
const DEFAULT_CONDITIONS_KEY = "2:6:import4:node";
const isWindows = /* #__PURE__ */ (() => process.platform === "win32")();
const globalCache = /* #__PURE__ */ (() => globalThis["__EXSOLVE_CACHE__"] ||= /* @__PURE__ */ new Map())();
function resolveModuleURL(input, options) {

@@ -956,11 +909,2 @@ const parsedInput = _parseInput(input);

}
/**
* Synchronously resolves a module then converts it to a file path
*
* (throws error if reolved path is not file:// scheme)
*
* @param {string} id - The identifier or path of the module to resolve.
* @param {ResolveOptions} [options] - Options to resolve the module. See {@link ResolveOptions}.
* @returns {string} The resolved URL as a string.
*/
function resolveModulePath(id, options) {

@@ -1025,11 +969,21 @@ const resolved = resolveModuleURL(id, options);

}
function _cacheKey(id, opts) {
return JSON.stringify([
id,
(opts?.conditions || ["node", "import"]).sort(),
opts?.extensions,
opts?.from,
opts?.suffixes
]);
function _cacheKey(id, options) {
let from;
if (Array.isArray(options?.from)) from = options.from;
else if (options?.from) from = [options.from];
return _cacheKeyValues([id]) + _conditionsKey(options?.conditions) + _cacheKeyValues(options?.extensions) + _cacheKeyValues(from) + _cacheKeyValues(options?.suffixes);
}
function _conditionsKey(conditions) {
if (!conditions) return DEFAULT_CONDITIONS_KEY;
return _cacheKeyValues([...new Set(conditions)].sort());
}
function _cacheKeyValues(values) {
if (!values) return "-";
let key = `${values.length}:`;
for (const value of values) {
const stringValue = String(value);
key += `${stringValue.length}:${stringValue}`;
}
return key;
}
function _join(a, b) {

@@ -1039,4 +993,4 @@ if (!a || !b || b === "/") return a;

}
function _normalizeWinPath(path$1) {
return path$1.replace(/\\/g, "/").replace(/^[a-z]:\//, (r) => r.toUpperCase());
function _normalizeWinPath(path) {
return path.replace(/\\/g, "/").replace(/^[a-z]:\//, (r) => r.toUpperCase());
}

@@ -1072,4 +1026,2 @@ function _isURL(input) {

}
//#endregion
export { clearResolveCache, createResolver, resolveModulePath, resolveModuleURL };
export { clearResolveCache, createResolver, resolveModulePath, resolveModuleURL };
{
"name": "exsolve",
"version": "1.0.8",
"version": "1.1.0",
"description": "Module resolution utilities based on Node.js upstream implementation.",

@@ -28,16 +28,16 @@ "repository": "unjs/exsolve",

"devDependencies": {
"@types/node": "^24.10.0",
"@vitest/coverage-v8": "^4.0.8",
"automd": "^0.4.2",
"@types/node": "^26.0.0",
"@vitest/coverage-v8": "^4.1.9",
"automd": "^0.4.3",
"changelogen": "^0.6.2",
"eslint": "^9.39.1",
"eslint-config-unjs": "^0.5.0",
"happy-dom": "^20.0.10",
"jiti": "^2.6.1",
"obuild": "^0.4.1",
"prettier": "^3.6.2",
"typescript": "^5.9.3",
"vitest": "^4.0.8"
"eslint": "^10.5.0",
"eslint-config-unjs": "^0.6.2",
"happy-dom": "^20.10.6",
"jiti": "^2.7.0",
"obuild": "^0.4.36",
"prettier": "^3.8.4",
"typescript": "^6.0.3",
"vitest": "^4.1.9"
},
"packageManager": "pnpm@10.21.0"
"packageManager": "pnpm@11.8.0"
}