Ajout de promotion et de commande
This commit is contained in:
+641
File diff suppressed because it is too large
Load Diff
+12
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
var $Error = require('es-errors');
|
||||
|
||||
module.exports = function () {
|
||||
// see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
|
||||
var origPrepareStackTrace = $Error.prepareStackTrace;
|
||||
$Error.prepareStackTrace = function (_, stack) { return stack; };
|
||||
var stack = (new $Error()).stack;
|
||||
$Error.prepareStackTrace = origPrepareStackTrace;
|
||||
return stack[2].getFileName();
|
||||
};
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
'use strict';
|
||||
|
||||
var objectKeys = require('object-keys');
|
||||
var $Error = require('es-errors');
|
||||
|
||||
// Check if an exports map key looks like a subpath (starts with '.')
|
||||
function isSubpathKey(key) {
|
||||
return key.length > 0 && key.charAt(0) === '.';
|
||||
}
|
||||
|
||||
// Normalize the exports field into a map of subpath -> target
|
||||
function normalizeExports(exportsField) {
|
||||
if (typeof exportsField === 'string') {
|
||||
return { __proto__: null, '.': exportsField };
|
||||
}
|
||||
if (Array.isArray(exportsField)) {
|
||||
return { __proto__: null, '.': exportsField };
|
||||
}
|
||||
if (typeof exportsField === 'object' && exportsField !== null) {
|
||||
var keys = objectKeys(exportsField);
|
||||
if (keys.length === 0) {
|
||||
return { __proto__: null };
|
||||
}
|
||||
// If any key starts with '.', it's a subpath map
|
||||
// If no key starts with '.', it's a conditions object for '.'
|
||||
var hasSubpath = false;
|
||||
for (var i = 0; !hasSubpath && i < keys.length; i++) {
|
||||
if (isSubpathKey(keys[i])) {
|
||||
hasSubpath = true;
|
||||
}
|
||||
}
|
||||
// Copy to new object with null prototype
|
||||
var result = { __proto__: null };
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
result[keys[j]] = exportsField[keys[j]];
|
||||
}
|
||||
if (hasSubpath) {
|
||||
return result;
|
||||
}
|
||||
return { __proto__: null, '.': result };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve a target value through conditions
|
||||
// conditions: array of condition strings, or null (broken: string/array only)
|
||||
function resolveTarget(target, conditions) {
|
||||
if (typeof target === 'string') {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (target === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Array.isArray(target)) {
|
||||
for (var i = 0; i < target.length; i++) {
|
||||
var resolved = resolveTarget(target[i], conditions);
|
||||
if (resolved !== null && typeof resolved !== 'undefined') {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof target === 'object') {
|
||||
// If no conditions supported (broken category), can't resolve objects
|
||||
if (conditions === null) {
|
||||
return null;
|
||||
}
|
||||
var keys = objectKeys(target);
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
var key = keys[j];
|
||||
for (var k = 0; k < conditions.length; k++) {
|
||||
if (key === conditions[k]) {
|
||||
var result = resolveTarget(target[key], conditions);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate a resolved path
|
||||
function validateTarget(target) {
|
||||
if (typeof target !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (target.slice(0, 2) !== './') {
|
||||
return false;
|
||||
}
|
||||
if (target.indexOf('/node_modules/') !== -1) {
|
||||
return false;
|
||||
}
|
||||
// Check for '..' path traversal
|
||||
var parts = target.split('/');
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
if (parts[i] === '..') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the best pattern match for a subpath among keys with '*'
|
||||
function findPatternMatch(subpath, exportsMap, allowPatternTrailers) {
|
||||
var keys = objectKeys(exportsMap);
|
||||
var bestKey = null;
|
||||
var bestPrefixLen = -1;
|
||||
var bestMatch = '';
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var starIndex = key.indexOf('*');
|
||||
// Key must have exactly one '*'
|
||||
if (starIndex !== -1 && key.indexOf('*', starIndex + 1) === -1) {
|
||||
var prefix = key.slice(0, starIndex);
|
||||
var suffix = key.slice(starIndex + 1);
|
||||
|
||||
// Pattern trailers: if suffix is non-empty after *, need allowPatternTrailers
|
||||
if (suffix.length === 0 || allowPatternTrailers) {
|
||||
if (
|
||||
subpath.length >= prefix.length + suffix.length
|
||||
&& subpath.slice(0, prefix.length) === prefix
|
||||
&& (suffix.length === 0 || subpath.slice(subpath.length - suffix.length) === suffix)
|
||||
) {
|
||||
// Longest prefix wins
|
||||
if (prefix.length > bestPrefixLen) {
|
||||
bestPrefixLen = prefix.length;
|
||||
bestKey = key;
|
||||
bestMatch = subpath.slice(prefix.length, subpath.length - suffix.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestKey !== null) {
|
||||
return {
|
||||
__proto__: null, key: bestKey, match: bestMatch
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find directory slash match (for categories that support it)
|
||||
function findDirSlashMatch(subpath, exportsMap) {
|
||||
var keys = objectKeys(exportsMap);
|
||||
var bestKey = null;
|
||||
var bestPrefixLen = -1;
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
if (key.charAt(key.length - 1) === '/') {
|
||||
if (subpath.slice(0, key.length) === key && key.length > bestPrefixLen) {
|
||||
bestPrefixLen = key.length;
|
||||
bestKey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestKey !== null) {
|
||||
return {
|
||||
__proto__: null, key: bestKey, remainder: subpath.slice(bestKey.length)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Replace '*' in target string with match value
|
||||
function substitutePattern(target, match) {
|
||||
if (typeof target === 'string') {
|
||||
return target.split('*').join(match);
|
||||
}
|
||||
if (Array.isArray(target)) {
|
||||
var result = [];
|
||||
for (var i = 0; i < target.length; i++) {
|
||||
result.push(substitutePattern(target[i], match));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (typeof target === 'object' && target !== null) {
|
||||
var obj = { __proto__: null };
|
||||
var keys = objectKeys(target);
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
obj[keys[j]] = substitutePattern(target[keys[j]], match);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
// Main exports resolution function
|
||||
// exportsField: the value of package.json "exports"
|
||||
// subpath: the subpath to resolve (e.g., "." or "./foo/bar")
|
||||
// conditions: array of condition strings, or null for broken category
|
||||
// options: { patterns: boolean, patternTrailers: boolean, dirSlash: boolean }
|
||||
// Returns: resolved relative path string, or null if no exports field
|
||||
// Throws: when exports field exists but subpath is not exported
|
||||
module.exports = function resolveExports(exportsField, subpath, conditions, options) {
|
||||
if (typeof exportsField === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var exportsMap = normalizeExports(exportsField);
|
||||
if (!exportsMap) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var allowPatterns = options && options.patterns;
|
||||
var allowPatternTrailers = options && options.patternTrailers;
|
||||
var allowDirSlash = options && options.dirSlash;
|
||||
|
||||
// 1. Exact key match
|
||||
if (typeof exportsMap[subpath] !== 'undefined') {
|
||||
var resolved = resolveTarget(exportsMap[subpath], conditions);
|
||||
if (resolved !== null && typeof resolved !== 'undefined') {
|
||||
if (!validateTarget(resolved)) {
|
||||
var invalidError = new $Error('Invalid "exports" target "' + resolved + '" for subpath "' + subpath + '"');
|
||||
invalidError.code = 'ERR_INVALID_PACKAGE_CONFIG';
|
||||
throw invalidError;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
// Target exists but resolved to null (explicitly not exported)
|
||||
var notExportedError = new $Error('Package subpath "' + subpath + '" is not defined by "exports"');
|
||||
notExportedError.code = 'ERR_PACKAGE_PATH_NOT_EXPORTED';
|
||||
throw notExportedError;
|
||||
}
|
||||
|
||||
// 2. Pattern match (keys with '*')
|
||||
if (allowPatterns) {
|
||||
var patternResult = findPatternMatch(subpath, exportsMap, allowPatternTrailers);
|
||||
if (patternResult) {
|
||||
var substituted = substitutePattern(exportsMap[patternResult.key], patternResult.match);
|
||||
var patternResolved = resolveTarget(substituted, conditions);
|
||||
if (patternResolved !== null && typeof patternResolved !== 'undefined') {
|
||||
if (!validateTarget(patternResolved)) {
|
||||
var patternInvalidError = new $Error('Invalid "exports" target "' + patternResolved + '" for subpath "' + subpath + '"');
|
||||
patternInvalidError.code = 'ERR_INVALID_PACKAGE_CONFIG';
|
||||
throw patternInvalidError;
|
||||
}
|
||||
return patternResolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Directory slash match (for older categories)
|
||||
if (allowDirSlash) {
|
||||
var dirResult = findDirSlashMatch(subpath, exportsMap);
|
||||
if (dirResult) {
|
||||
var dirTarget = resolveTarget(exportsMap[dirResult.key], conditions);
|
||||
if (dirTarget !== null && typeof dirTarget !== 'undefined' && typeof dirTarget === 'string') {
|
||||
var dirResolved = dirTarget + dirResult.remainder;
|
||||
if (!validateTarget(dirResolved)) {
|
||||
var dirInvalidError = new $Error('Invalid "exports" target "' + dirResolved + '" for subpath "' + subpath + '"');
|
||||
dirInvalidError.code = 'ERR_INVALID_PACKAGE_CONFIG';
|
||||
throw dirInvalidError;
|
||||
}
|
||||
return dirResolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var err = new $Error('Package subpath "' + subpath + '" is not defined by "exports"');
|
||||
err.code = 'ERR_PACKAGE_PATH_NOT_EXPORTED';
|
||||
throw err;
|
||||
};
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
var isCategory = require('node-exports-info/isCategory');
|
||||
var getCategoriesForRange = require('node-exports-info/getCategoriesForRange');
|
||||
var $TypeError = require('es-errors/type');
|
||||
|
||||
var selectMostRestrictive = require('./select-most-restrictive');
|
||||
|
||||
// Determine the active exports category from resolve options
|
||||
// Returns null if no exports resolution should be applied
|
||||
// Returns 'engines' if engines: true (needs consumer package.json lookup)
|
||||
// Throws TypeError if invalid options are provided
|
||||
/** @type {(opts?: { exportsCategory?: import('node-exports-info/getCategory').Category, engines?: boolean | string }) => null | import('node-exports-info/getCategory').Category} */
|
||||
module.exports = function getExportsCategory(opts) {
|
||||
if (!opts) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hasCategory = typeof opts.exportsCategory !== 'undefined';
|
||||
var engines = opts.engines;
|
||||
var hasEngines = typeof engines !== 'undefined' && engines !== false;
|
||||
|
||||
if (hasCategory && hasEngines) {
|
||||
throw new $TypeError('`exportsCategory` and `engines` are mutually exclusive.');
|
||||
}
|
||||
|
||||
if (hasCategory) {
|
||||
if (!isCategory(opts.exportsCategory)) {
|
||||
var catError = new $TypeError('Invalid exports category: "' + opts.exportsCategory + '"');
|
||||
catError.code = 'INVALID_EXPORTS_CATEGORY';
|
||||
throw catError;
|
||||
}
|
||||
return opts.exportsCategory;
|
||||
}
|
||||
|
||||
if (hasEngines) {
|
||||
// engines: true means read from consumer's package.json
|
||||
if (engines === true) {
|
||||
return 'engines';
|
||||
}
|
||||
|
||||
// engines must be a non-empty string (semver range)
|
||||
if (typeof engines !== 'string' || engines === '') {
|
||||
throw new $TypeError('`engines` must be `true`, `false`, or a non-empty string semver range.');
|
||||
}
|
||||
|
||||
var categories = getCategoriesForRange(engines);
|
||||
return selectMostRestrictive(categories);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
var os = require('os');
|
||||
|
||||
// adapted from https://github.com/sindresorhus/os-homedir/blob/11e089f4754db38bb535e5a8416320c4446e8cfd/index.js
|
||||
|
||||
module.exports = os.homedir || function homedir() {
|
||||
var home = process.env.HOME;
|
||||
var user = process.env.LOGNAME || process.env.USER || process.env.LNAME || process.env.USERNAME;
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
return process.env.USERPROFILE || process.env.HOMEDRIVE + process.env.HOMEPATH || home || null;
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
return home || (user ? '/Users/' + user : null);
|
||||
}
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
return home || (process.getuid() === 0 ? '/root' : (user ? '/home/' + user : null));
|
||||
}
|
||||
|
||||
return home || null;
|
||||
};
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
var path = require('path');
|
||||
var parse = path.parse || require('path-parse'); // eslint-disable-line global-require
|
||||
|
||||
var driveLetterRegex = /^([A-Za-z]:)/;
|
||||
var uncPathRegex = /^\\\\/;
|
||||
|
||||
function getNodeModulesDirs(absoluteStart, modules) {
|
||||
var prefix = '/';
|
||||
if (driveLetterRegex.test(absoluteStart)) {
|
||||
prefix = '';
|
||||
} else if (uncPathRegex.test(absoluteStart)) {
|
||||
prefix = '\\\\';
|
||||
}
|
||||
|
||||
var paths = [absoluteStart];
|
||||
var parsed = parse(absoluteStart);
|
||||
while (parsed.dir !== paths[paths.length - 1]) {
|
||||
paths.push(parsed.dir);
|
||||
parsed = parse(parsed.dir);
|
||||
}
|
||||
|
||||
return paths.reduce(function (dirs, aPath) {
|
||||
return dirs.concat(modules.map(function (moduleDir) {
|
||||
return path.resolve(prefix, aPath, moduleDir);
|
||||
}));
|
||||
}, []);
|
||||
}
|
||||
|
||||
module.exports = function nodeModulesPaths(start, opts, request) {
|
||||
var modules = opts && opts.moduleDirectory
|
||||
? [].concat(opts.moduleDirectory)
|
||||
: ['node_modules'];
|
||||
|
||||
if (opts && typeof opts.paths === 'function') {
|
||||
return opts.paths(
|
||||
request,
|
||||
start,
|
||||
function () { return getNodeModulesDirs(start, modules); },
|
||||
opts
|
||||
);
|
||||
}
|
||||
|
||||
var dirs = getNodeModulesDirs(start, modules);
|
||||
return opts && opts.paths ? dirs.concat(opts.paths) : dirs;
|
||||
};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
module.exports = function (x, opts) {
|
||||
/**
|
||||
* This file is purposefully a passthrough. It's expected that third-party
|
||||
* environments will override it at runtime in order to inject special logic
|
||||
* into `resolve` (by manipulating the options). One such example is the PnP
|
||||
* code path in Yarn.
|
||||
*/
|
||||
|
||||
return opts || {};
|
||||
};
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
/** @type {(x: string) => { __proto__: null, name: string, subpath: string }} */
|
||||
module.exports = function parsePackageSpecifier(x) {
|
||||
if (x.charAt(0) === '@') {
|
||||
var slashIndex = x.indexOf('/');
|
||||
if (slashIndex === -1) {
|
||||
return {
|
||||
__proto__: null, name: x, subpath: '.'
|
||||
};
|
||||
}
|
||||
var secondSlash = x.indexOf('/', slashIndex + 1);
|
||||
if (secondSlash === -1) {
|
||||
return {
|
||||
__proto__: null, name: x, subpath: '.'
|
||||
};
|
||||
}
|
||||
return {
|
||||
__proto__: null, name: x.slice(0, secondSlash), subpath: '.' + x.slice(secondSlash)
|
||||
};
|
||||
}
|
||||
var firstSlash = x.indexOf('/');
|
||||
if (firstSlash === -1) {
|
||||
return {
|
||||
__proto__: null, name: x, subpath: '.'
|
||||
};
|
||||
}
|
||||
return {
|
||||
__proto__: null, name: x.slice(0, firstSlash), subpath: '.' + x.slice(firstSlash)
|
||||
};
|
||||
};
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
// Category ranking from most restrictive (lowest rank) to least restrictive (highest rank)
|
||||
// Lower rank = more restrictive = fewer features supported
|
||||
var categoryRank = /** @type {const} */ {
|
||||
__proto__: null,
|
||||
'pre-exports': /** @type {const} */ (0),
|
||||
broken: /** @type {const} */ (1),
|
||||
experimental: /** @type {const} */ (2),
|
||||
conditions: /** @type {const} */ (3),
|
||||
'broken-dir-slash-conditions': /** @type {const} */ (4),
|
||||
patterns: /** @type {const} */ (5),
|
||||
'pattern-trailers': /** @type {const} */ (6),
|
||||
'pattern-trailers+json-imports': /** @type {const} */ (7),
|
||||
'pattern-trailers-no-dir-slash': /** @type {const} */ (8),
|
||||
'pattern-trailers-no-dir-slash+json-imports': /** @type {const} */ (9),
|
||||
'require-esm': /** @type {const} */ (10),
|
||||
'strips-types': /** @type {const} */ (11),
|
||||
'subpath-imports-slash': /** @type {const} */ (12)
|
||||
};
|
||||
|
||||
// Select the most restrictive category from an array of categories
|
||||
/** @type {(categories?: ReturnType<import('node-exports-info/getCategory')>[]) => import('node-exports-info/getCategory').Category | null} */
|
||||
module.exports = function selectMostRestrictive(categories) {
|
||||
if (!categories || categories.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var mostRestrictive = null;
|
||||
var lowestRank = Infinity;
|
||||
|
||||
for (var i = 0; i < categories.length; i++) {
|
||||
var cat = categories[i];
|
||||
var rank = categoryRank[cat];
|
||||
if (typeof rank === 'number' && rank < lowestRank) {
|
||||
lowestRank = rank;
|
||||
mostRestrictive = cat;
|
||||
}
|
||||
}
|
||||
|
||||
return mostRestrictive;
|
||||
};
|
||||
+418
@@ -0,0 +1,418 @@
|
||||
var isCore = require('is-core-module');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var $Error = require('es-errors');
|
||||
var $TypeError = require('es-errors/type');
|
||||
|
||||
var getHomedir = require('./homedir');
|
||||
var caller = require('./caller');
|
||||
var nodeModulesPaths = require('./node-modules-paths');
|
||||
var normalizeOptions = require('./normalize-options');
|
||||
var resolveExports = require('./exports-resolve');
|
||||
var parsePackageSpecifier = require('./parse-package-specifier');
|
||||
var getExportsCategory = require('./get-exports-category');
|
||||
var getCategoryInfo = require('node-exports-info/getCategoryInfo');
|
||||
var getCategoriesForRange = require('node-exports-info/getCategoriesForRange');
|
||||
var selectMostRestrictive = require('./select-most-restrictive');
|
||||
|
||||
var realpathFS = process.platform !== 'win32' && fs.realpathSync && typeof fs.realpathSync.native === 'function' ? fs.realpathSync.native : fs.realpathSync;
|
||||
|
||||
var relativePathRegex = /^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/;
|
||||
var windowsDriveRegex = /^\w:[/\\]*$/;
|
||||
var nodeModulesRegex = /[/\\]node_modules[/\\]*$/;
|
||||
|
||||
var homedir = getHomedir();
|
||||
function defaultPaths() {
|
||||
return [
|
||||
path.join(homedir, '.node_modules'),
|
||||
path.join(homedir, '.node_libraries')
|
||||
];
|
||||
}
|
||||
|
||||
var defaultIsFile = function isFile(file) {
|
||||
try {
|
||||
var stat = fs.statSync(file, { throwIfNoEntry: false });
|
||||
} catch (e) {
|
||||
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
|
||||
throw e;
|
||||
}
|
||||
return !!stat && (stat.isFile() || stat.isFIFO());
|
||||
};
|
||||
|
||||
var defaultIsDir = function isDirectory(dir) {
|
||||
try {
|
||||
var stat = fs.statSync(dir, { throwIfNoEntry: false });
|
||||
} catch (e) {
|
||||
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
|
||||
throw e;
|
||||
}
|
||||
return !!stat && stat.isDirectory();
|
||||
};
|
||||
|
||||
var defaultRealpathSync = function realpathSync(x) {
|
||||
try {
|
||||
return realpathFS(x);
|
||||
} catch (realpathErr) {
|
||||
if (realpathErr.code !== 'ENOENT') {
|
||||
throw realpathErr;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
};
|
||||
|
||||
function maybeRealpathSync(realpathSync, x, opts) {
|
||||
if (!opts || !opts.preserveSymlinks) {
|
||||
return realpathSync(x);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
function defaultReadPackageSync(readFileSync, pkgfile) {
|
||||
return JSON.parse(readFileSync(pkgfile));
|
||||
}
|
||||
|
||||
function getPackageCandidates(x, start, opts) {
|
||||
var dirs = nodeModulesPaths(start, opts, x);
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
dirs[i] = path.join(dirs[i], x);
|
||||
}
|
||||
return dirs;
|
||||
}
|
||||
|
||||
function findConsumerPackageSync(startDir, isFile, readPackageSync, readFileSync) {
|
||||
var dir = path.resolve(startDir);
|
||||
while (true) {
|
||||
var pkgfile = path.join(dir, 'package.json');
|
||||
if (isFile(pkgfile)) {
|
||||
try {
|
||||
return readPackageSync(readFileSync, pkgfile);
|
||||
} catch (e) {
|
||||
if (!(e instanceof SyntaxError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
var parentDir = path.dirname(dir);
|
||||
if (parentDir === dir) {
|
||||
return null;
|
||||
}
|
||||
dir = parentDir;
|
||||
}
|
||||
}
|
||||
|
||||
function findPackageWithDirSync(startDir, isFile, readPackageSync, readFileSync) {
|
||||
var dir = path.resolve(startDir);
|
||||
while (true) {
|
||||
// Stop at node_modules boundaries - can't self-reference across node_modules
|
||||
if (nodeModulesRegex.test(dir)) {
|
||||
return null;
|
||||
}
|
||||
var pkgfile = path.join(dir, 'package.json');
|
||||
if (isFile(pkgfile)) {
|
||||
try {
|
||||
var pkg = readPackageSync(readFileSync, pkgfile);
|
||||
return {
|
||||
__proto__: null, pkg: pkg, dir: dir
|
||||
};
|
||||
} catch (e) {
|
||||
if (!(e instanceof SyntaxError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
var parentDir = path.dirname(dir);
|
||||
if (parentDir === dir) {
|
||||
return null;
|
||||
}
|
||||
dir = parentDir;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function resolveSync(x, options) {
|
||||
if (typeof x !== 'string') {
|
||||
throw new $TypeError('Path must be a string.');
|
||||
}
|
||||
var opts = normalizeOptions(x, options);
|
||||
|
||||
var isFile = opts.isFile || defaultIsFile;
|
||||
var isDirectory = opts.isDirectory || defaultIsDir;
|
||||
var readFileSync = opts.readFileSync || fs.readFileSync;
|
||||
var realpathSync = opts.realpathSync || defaultRealpathSync;
|
||||
var readPackageSync = opts.readPackageSync || defaultReadPackageSync;
|
||||
if (opts.readFileSync && opts.readPackageSync) {
|
||||
throw new $TypeError('`readFileSync` and `readPackageSync` are mutually exclusive.');
|
||||
}
|
||||
var packageIterator = opts.packageIterator;
|
||||
|
||||
var extensions = opts.extensions || ['.js'];
|
||||
var includeCoreModules = opts.includeCoreModules !== false;
|
||||
var basedir = opts.basedir || path.dirname(caller());
|
||||
var parent = opts.filename || basedir;
|
||||
|
||||
opts.paths = opts.paths || defaultPaths();
|
||||
|
||||
// Determine exports category
|
||||
var exportsCategory = getExportsCategory(opts);
|
||||
if (exportsCategory === 'engines') {
|
||||
// Read consumer's package.json to get engines.node
|
||||
var consumerPkg = findConsumerPackageSync(basedir, isFile, readPackageSync, readFileSync);
|
||||
if (consumerPkg && consumerPkg.engines && consumerPkg.engines.node) {
|
||||
var categories = getCategoriesForRange(consumerPkg.engines.node);
|
||||
exportsCategory = selectMostRestrictive(categories);
|
||||
} else {
|
||||
exportsCategory = null;
|
||||
}
|
||||
}
|
||||
|
||||
var useExports = exportsCategory !== null && exportsCategory !== 'pre-exports';
|
||||
|
||||
// ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory
|
||||
var absoluteStart = maybeRealpathSync(realpathSync, path.resolve(basedir), opts);
|
||||
|
||||
if (opts.basedir && !isDirectory(absoluteStart)) {
|
||||
var dirError = new $TypeError('Provided basedir "' + opts.basedir + '" is not a directory' + (opts.preserveSymlinks ? '' : ', or a symlink to a directory'));
|
||||
dirError.code = 'INVALID_BASEDIR';
|
||||
throw dirError;
|
||||
}
|
||||
|
||||
if (relativePathRegex.test(x)) {
|
||||
var res = path.resolve(absoluteStart, x);
|
||||
if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/';
|
||||
var m = loadAsFileSync(res) || loadAsDirectorySync(res);
|
||||
if (m) return maybeRealpathSync(realpathSync, m, opts);
|
||||
} else if (includeCoreModules && isCore(x)) {
|
||||
return x;
|
||||
} else if (useExports) {
|
||||
// Try self-reference resolution first
|
||||
var selfRef = resolveSelfReferenceSync(x, absoluteStart);
|
||||
if (selfRef) return maybeRealpathSync(realpathSync, selfRef, opts);
|
||||
var nE = loadNodeModulesWithExportsSync(x, absoluteStart);
|
||||
if (nE) return maybeRealpathSync(realpathSync, nE, opts);
|
||||
} else {
|
||||
var n = loadNodeModulesSync(x, absoluteStart);
|
||||
if (n) return maybeRealpathSync(realpathSync, n, opts);
|
||||
}
|
||||
|
||||
var err = new $Error("Cannot find module '" + x + "' from '" + parent + "'");
|
||||
err.code = 'MODULE_NOT_FOUND';
|
||||
throw err;
|
||||
|
||||
function resolveSelfReferenceSync(x, startDir) {
|
||||
var parsed = parsePackageSpecifier(x);
|
||||
var pkgInfo = findPackageWithDirSync(startDir, isFile, readPackageSync, readFileSync);
|
||||
|
||||
if (!pkgInfo || !pkgInfo.pkg || pkgInfo.pkg.name !== parsed.name) {
|
||||
return null; // Not a self-reference
|
||||
}
|
||||
|
||||
var pkg = pkgInfo.pkg;
|
||||
var pkgDir = pkgInfo.dir;
|
||||
|
||||
if (opts.packageFilter) {
|
||||
pkg = opts.packageFilter(pkg, path.join(pkgDir, 'package.json'), pkgDir);
|
||||
}
|
||||
|
||||
// If package has exports field, resolve via exports
|
||||
if (typeof pkg.exports !== 'undefined') {
|
||||
var categoryInfo = getCategoryInfo(exportsCategory, 'require');
|
||||
var conditions = opts.conditions || categoryInfo.conditions;
|
||||
var resolved = resolveExports(pkg.exports, parsed.subpath, conditions, categoryInfo.flags);
|
||||
if (resolved) {
|
||||
var resolvedPath = path.resolve(pkgDir, resolved);
|
||||
if (isFile(resolvedPath)) {
|
||||
return resolvedPath;
|
||||
}
|
||||
}
|
||||
// exports field exists but didn't resolve - this is an error per Node semantics
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// No exports field - fall back to traditional resolution for self-reference
|
||||
// (Note: this matches Node's behavior where self-ref without exports uses main)
|
||||
if (parsed.subpath === '.') {
|
||||
return loadAsDirectorySync(pkgDir);
|
||||
}
|
||||
var subPath = path.join(pkgDir, parsed.subpath.slice(1));
|
||||
var sm = loadAsFileSync(subPath);
|
||||
if (sm) return sm;
|
||||
return loadAsDirectorySync(subPath);
|
||||
}
|
||||
|
||||
function loadAsFileSync(x) {
|
||||
var pkg = loadpkg(path.dirname(x));
|
||||
|
||||
if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) {
|
||||
var rfile = path.relative(pkg.dir, x);
|
||||
var r = opts.pathFilter(pkg.pkg, x, rfile);
|
||||
if (r) {
|
||||
x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign
|
||||
}
|
||||
}
|
||||
|
||||
if (isFile(x)) {
|
||||
return x;
|
||||
}
|
||||
|
||||
for (var i = 0; i < extensions.length; i++) {
|
||||
var file = x + extensions[i];
|
||||
if (isFile(file)) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadpkg(dir) {
|
||||
if (dir === '' || dir === '/') return;
|
||||
if (process.platform === 'win32' && windowsDriveRegex.test(dir)) {
|
||||
return;
|
||||
}
|
||||
if (nodeModulesRegex.test(dir)) return;
|
||||
|
||||
var pkgfile = path.join(isDirectory(dir) ? maybeRealpathSync(realpathSync, dir, opts) : dir, 'package.json');
|
||||
|
||||
if (!isFile(pkgfile)) {
|
||||
return loadpkg(path.dirname(dir));
|
||||
}
|
||||
|
||||
var pkg;
|
||||
try {
|
||||
pkg = readPackageSync(readFileSync, pkgfile);
|
||||
} catch (e) {
|
||||
if (!(e instanceof SyntaxError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (pkg && opts.packageFilter) {
|
||||
pkg = opts.packageFilter(pkg, pkgfile, dir);
|
||||
}
|
||||
|
||||
return { pkg: pkg, dir: dir };
|
||||
}
|
||||
|
||||
function loadAsDirectorySync(x) {
|
||||
var pkgfile = path.join(isDirectory(x) ? maybeRealpathSync(realpathSync, x, opts) : x, '/package.json');
|
||||
if (isFile(pkgfile)) {
|
||||
try {
|
||||
var pkg = readPackageSync(readFileSync, pkgfile);
|
||||
} catch (e) {}
|
||||
|
||||
if (pkg && opts.packageFilter) {
|
||||
pkg = opts.packageFilter(pkg, pkgfile, x);
|
||||
}
|
||||
|
||||
if (pkg && pkg.main) {
|
||||
if (typeof pkg.main !== 'string') {
|
||||
var mainError = new $TypeError('package “' + pkg.name + '” `main` must be a string');
|
||||
mainError.code = 'INVALID_PACKAGE_MAIN';
|
||||
throw mainError;
|
||||
}
|
||||
if (pkg.main === '.' || pkg.main === './') {
|
||||
pkg.main = 'index';
|
||||
}
|
||||
try {
|
||||
var mainPath = path.resolve(x, pkg.main);
|
||||
var m = loadAsFileSync(mainPath);
|
||||
if (m) return m;
|
||||
var n = loadAsDirectorySync(mainPath);
|
||||
if (n) return n;
|
||||
var checkIndex = loadAsFileSync(path.resolve(x, 'index'));
|
||||
if (checkIndex) return checkIndex;
|
||||
} catch (e) { }
|
||||
var incorrectMainError = new $Error("Cannot find module '" + path.resolve(x, pkg.main) + "'. Please verify that the package.json has a valid \"main\" entry");
|
||||
incorrectMainError.code = 'INCORRECT_PACKAGE_MAIN';
|
||||
throw incorrectMainError;
|
||||
}
|
||||
}
|
||||
|
||||
return loadAsFileSync(path.join(x, '/index'));
|
||||
}
|
||||
|
||||
function loadNodeModulesSync(x, start) {
|
||||
var thunk = function () { return getPackageCandidates(x, start, opts); };
|
||||
var dirs = packageIterator ? packageIterator(x, start, thunk, opts) : thunk();
|
||||
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
var dir = dirs[i];
|
||||
if (isDirectory(path.dirname(dir))) {
|
||||
var m = loadAsFileSync(dir);
|
||||
if (m) return m;
|
||||
var n = loadAsDirectorySync(dir);
|
||||
if (n) return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadNodeModulesWithExportsSync(x, start) {
|
||||
var parsed = parsePackageSpecifier(x);
|
||||
var categoryInfo = getCategoryInfo(exportsCategory, 'require');
|
||||
var conditions = opts.conditions || categoryInfo.conditions;
|
||||
|
||||
// Get candidate directories for the package name
|
||||
var thunk = function () { return getPackageCandidates(parsed.name, start, opts); };
|
||||
var dirs = packageIterator ? packageIterator(parsed.name, start, thunk, opts) : thunk();
|
||||
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
var pkgDir = dirs[i];
|
||||
if (isDirectory(pkgDir)) {
|
||||
var pkgfile = path.join(pkgDir, 'package.json');
|
||||
if (isFile(pkgfile)) {
|
||||
var pkg;
|
||||
try {
|
||||
pkg = readPackageSync(readFileSync, pkgfile);
|
||||
} catch (e) {
|
||||
if (!(e instanceof SyntaxError)) {
|
||||
throw e;
|
||||
}
|
||||
pkg = null;
|
||||
}
|
||||
|
||||
if (pkg) {
|
||||
if (opts.packageFilter) {
|
||||
pkg = opts.packageFilter(pkg, pkgfile, pkgDir);
|
||||
}
|
||||
|
||||
// If package has exports field, use exports resolution
|
||||
if (typeof pkg.exports !== 'undefined') {
|
||||
var resolved = resolveExports(pkg.exports, parsed.subpath, conditions, categoryInfo.flags);
|
||||
if (resolved) {
|
||||
var resolvedPath = path.resolve(pkgDir, resolved);
|
||||
if (isFile(resolvedPath)) {
|
||||
return resolvedPath;
|
||||
}
|
||||
}
|
||||
// exports field exists but didn't resolve - this is an error per Node semantics
|
||||
// (don't fall through to main/index)
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// No exports field, fall back to traditional resolution
|
||||
if (parsed.subpath === '.') {
|
||||
var result = loadAsDirectorySync(pkgDir);
|
||||
if (result) { return result; }
|
||||
} else {
|
||||
var subPath = path.join(pkgDir, parsed.subpath.slice(1));
|
||||
var sm = loadAsFileSync(subPath);
|
||||
if (sm) { return sm; }
|
||||
var sn = loadAsDirectorySync(subPath);
|
||||
if (sn) { return sn; }
|
||||
}
|
||||
}
|
||||
} else if (parsed.subpath === '.') {
|
||||
// No package.json, fall back to file/directory resolution
|
||||
var m = loadAsFileSync(pkgDir);
|
||||
if (m) { return m; }
|
||||
var n = loadAsDirectorySync(pkgDir);
|
||||
if (n) { return n; }
|
||||
} else {
|
||||
// No package.json, fall back to file/directory resolution for subpath
|
||||
var fullPath = path.join(pkgDir, parsed.subpath.slice(1));
|
||||
var m2 = loadAsFileSync(fullPath);
|
||||
if (m2) { return m2; }
|
||||
var n2 = loadAsDirectorySync(fullPath);
|
||||
if (n2) { return n2; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user