@dependabot/yarn-lib
Version:
📦🐈 Fast, reliable, and secure dependency management.
871 lines (671 loc) • 31.7 kB
JavaScript
#!$$SHEBANG
'use strict';
/* eslint-disable max-len, flowtype/require-valid-file-annotation, flowtype/require-return-type */
/* global packageInformationStores, $$BLACKLIST, $$SETUP_STATIC_TABLES */
// Used for the resolveUnqualified part of the resolution (ie resolving folder/index.js & file extensions)
// Deconstructed so that they aren't affected by any fs monkeypatching occuring later during the execution
var _require = require('fs');
const statSync = _require.statSync,
lstatSync = _require.lstatSync,
readlinkSync = _require.readlinkSync,
readFileSync = _require.readFileSync,
existsSync = _require.existsSync,
realpathSync = _require.realpathSync;
const Module = require('module');
const path = require('path');
const StringDecoder = require('string_decoder');
const ignorePattern = $$BLACKLIST ? new RegExp($$BLACKLIST) : null;
const pnpFile = path.resolve(__dirname, __filename);
const builtinModules = new Set(Module.builtinModules || Object.keys(process.binding('natives')));
const topLevelLocator = { name: null, reference: null };
const blacklistedLocator = { name: NaN, reference: NaN };
// Used for compatibility purposes - cf setupCompatibilityLayer
const patchedModules = [];
const fallbackLocators = [topLevelLocator];
// Matches backslashes of Windows paths
const backwardSlashRegExp = /\\/g;
// Matches if the path must point to a directory (ie ends with /)
const isDirRegExp = /\/$/;
// Matches if the path starts with a valid path qualifier (./, ../, /)
// eslint-disable-next-line no-unused-vars
const isStrictRegExp = /^\.{0,2}\//;
// Splits a require request into its components, or return null if the request is a file path
const pathRegExp = /^(?![a-zA-Z]:[\\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^\/]+\/)?[^\/]+)\/?(.*|)$/;
// Keep a reference around ("module" is a common name in this context, so better rename it to something more significant)
const pnpModule = module;
/**
* Used to disable the resolution hooks (for when we want to fallback to the previous resolution - we then need
* a way to "reset" the environment temporarily)
*/
let enableNativeHooks = true;
/**
* Simple helper function that assign an error code to an error, so that it can more easily be caught and used
* by third-parties.
*/
function makeError(code, message, data = {}) {
const error = new Error(message);
return Object.assign(error, { code, data });
}
/**
* Ensures that the returned locator isn't a blacklisted one.
*
* Blacklisted packages are packages that cannot be used because their dependencies cannot be deduced. This only
* happens with peer dependencies, which effectively have different sets of dependencies depending on their parents.
*
* In order to deambiguate those different sets of dependencies, the Yarn implementation of PnP will generate a
* symlink for each combination of <package name>/<package version>/<dependent package> it will find, and will
* blacklist the target of those symlinks. By doing this, we ensure that files loaded through a specific path
* will always have the same set of dependencies, provided the symlinks are correctly preserved.
*
* Unfortunately, some tools do not preserve them, and when it happens PnP isn't able anymore to deduce the set of
* dependencies based on the path of the file that makes the require calls. But since we've blacklisted those paths,
* we're able to print a more helpful error message that points out that a third-party package is doing something
* incompatible!
*/
// eslint-disable-next-line no-unused-vars
function blacklistCheck(locator) {
if (locator === blacklistedLocator) {
throw makeError(`BLACKLISTED`, [`A package has been resolved through a blacklisted path - this is usually caused by one of your tools calling`, `"realpath" on the return value of "require.resolve". Since the returned values use symlinks to disambiguate`, `peer dependencies, they must be passed untransformed to "require".`].join(` `));
}
return locator;
}
$$SETUP_STATIC_TABLES();
/**
* Returns the module that should be used to resolve require calls. It's usually the direct parent, except if we're
* inside an eval expression.
*/
function getIssuerModule(parent) {
let issuer = parent;
while (issuer && (issuer.id === '[eval]' || issuer.id === '<repl>' || !issuer.filename)) {
issuer = issuer.parent;
}
return issuer;
}
/**
* Returns information about a package in a safe way (will throw if they cannot be retrieved)
*/
function getPackageInformationSafe(packageLocator) {
const packageInformation = exports.getPackageInformation(packageLocator);
if (!packageInformation) {
throw makeError(`INTERNAL`, `Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)`);
}
return packageInformation;
}
/**
* Implements the node resolution for folder access and extension selection
*/
function applyNodeExtensionResolution(unqualifiedPath, { extensions }) {
// We use this "infinite while" so that we can restart the process as long as we hit package folders
while (true) {
let stat;
try {
stat = statSync(unqualifiedPath);
} catch (error) {}
// If the file exists and is a file, we can stop right there
if (stat && !stat.isDirectory()) {
// If the very last component of the resolved path is a symlink to a file, we then resolve it to a file. We only
// do this first the last component, and not the rest of the path! This allows us to support the case of bin
// symlinks, where a symlink in "/xyz/pkg-name/.bin/bin-name" will point somewhere else (like "/xyz/pkg-name/index.js").
// In such a case, we want relative requires to be resolved relative to "/xyz/pkg-name/" rather than "/xyz/pkg-name/.bin/".
//
// Also note that the reason we must use readlink on the last component (instead of realpath on the whole path)
// is that we must preserve the other symlinks, in particular those used by pnp to deambiguate packages using
// peer dependencies. For example, "/xyz/.pnp/local/pnp-01234569/.bin/bin-name" should see its relative requires
// be resolved relative to "/xyz/.pnp/local/pnp-0123456789/" rather than "/xyz/pkg-with-peers/", because otherwise
// we would lose the information that would tell us what are the dependencies of pkg-with-peers relative to its
// ancestors.
if (lstatSync(unqualifiedPath).isSymbolicLink()) {
unqualifiedPath = path.normalize(path.resolve(path.dirname(unqualifiedPath), readlinkSync(unqualifiedPath)));
}
return unqualifiedPath;
}
// If the file is a directory, we must check if it contains a package.json with a "main" entry
if (stat && stat.isDirectory()) {
let pkgJson;
try {
pkgJson = JSON.parse(readFileSync(`${unqualifiedPath}/package.json`, 'utf-8'));
} catch (error) {}
let nextUnqualifiedPath;
if (pkgJson && pkgJson.main) {
nextUnqualifiedPath = path.resolve(unqualifiedPath, pkgJson.main);
}
// If the "main" field changed the path, we start again from this new location
if (nextUnqualifiedPath && nextUnqualifiedPath !== unqualifiedPath) {
const resolution = applyNodeExtensionResolution(nextUnqualifiedPath, { extensions });
if (resolution !== null) {
return resolution;
}
}
}
// Otherwise we check if we find a file that match one of the supported extensions
const qualifiedPath = extensions.map(extension => {
return `${unqualifiedPath}${extension}`;
}).find(candidateFile => {
return existsSync(candidateFile);
});
if (qualifiedPath) {
return qualifiedPath;
}
// Otherwise, we check if the path is a folder - in such a case, we try to use its index
if (stat && stat.isDirectory()) {
const indexPath = extensions.map(extension => {
return `${unqualifiedPath}/index${extension}`;
}).find(candidateFile => {
return existsSync(candidateFile);
});
if (indexPath) {
return indexPath;
}
}
// Otherwise there's nothing else we can do :(
return null;
}
}
/**
* This function creates fake modules that can be used with the _resolveFilename function.
* Ideally it would be nice to be able to avoid this, since it causes useless allocations
* and cannot be cached efficiently (we recompute the nodeModulePaths every time).
*
* Fortunately, this should only affect the fallback, and there hopefully shouldn't be a
* lot of them.
*/
function makeFakeModule(path) {
const fakeModule = new Module(path, false);
fakeModule.filename = path;
fakeModule.paths = Module._nodeModulePaths(path);
return fakeModule;
}
/**
* Normalize path to posix format.
*/
function normalizePath(fsPath) {
fsPath = path.normalize(fsPath);
if (process.platform === 'win32') {
fsPath = fsPath.replace(backwardSlashRegExp, '/');
}
return fsPath;
}
/**
* Forward the resolution to the next resolver (usually the native one)
*/
function callNativeResolution(request, issuer) {
if (issuer.endsWith('/')) {
issuer += 'internal.js';
}
try {
enableNativeHooks = false;
// Since we would need to create a fake module anyway (to call _resolveLookupPath that
// would give us the paths to give to _resolveFilename), we can as well not use
// the {paths} option at all, since it internally makes _resolveFilename create another
// fake module anyway.
return Module._resolveFilename(request, makeFakeModule(issuer), false);
} finally {
enableNativeHooks = true;
}
}
/**
* This key indicates which version of the standard is implemented by this resolver. The `std` key is the
* Plug'n'Play standard, and any other key are third-party extensions. Third-party extensions are not allowed
* to override the standard, and can only offer new methods.
*
* If an new version of the Plug'n'Play standard is released and some extensions conflict with newly added
* functions, they'll just have to fix the conflicts and bump their own version number.
*/
exports.VERSIONS = { std: 1 };
/**
* Useful when used together with getPackageInformation to fetch information about the top-level package.
*/
exports.topLevel = { name: null, reference: null };
/**
* Gets the package information for a given locator. Returns null if they cannot be retrieved.
*/
exports.getPackageInformation = function getPackageInformation({ name, reference }) {
const packageInformationStore = packageInformationStores.get(name);
if (!packageInformationStore) {
return null;
}
const packageInformation = packageInformationStore.get(reference);
if (!packageInformation) {
return null;
}
return packageInformation;
};
/**
* Transforms a request (what's typically passed as argument to the require function) into an unqualified path.
* This path is called "unqualified" because it only changes the package name to the package location on the disk,
* which means that the end result still cannot be directly accessed (for example, it doesn't try to resolve the
* file extension, or to resolve directories to their "index.js" content). Use the "resolveUnqualified" function
* to convert them to fully-qualified paths, or just use "resolveRequest" that do both operations in one go.
*
* Note that it is extremely important that the `issuer` path ends with a forward slash if the issuer is to be
* treated as a folder (ie. "/tmp/foo/" rather than "/tmp/foo" if "foo" is a directory). Otherwise relative
* imports won't be computed correctly (they'll get resolved relative to "/tmp/" instead of "/tmp/foo/").
*/
exports.resolveToUnqualified = function resolveToUnqualified(request, issuer, { considerBuiltins = true } = {}) {
// The 'pnpapi' request is reserved and will always return the path to the PnP file, from everywhere
if (request === `pnpapi`) {
return pnpFile;
}
// Bailout if the request is a native module
if (considerBuiltins && builtinModules.has(request)) {
return null;
}
// We allow disabling the pnp resolution for some subpaths. This is because some projects, often legacy,
// contain multiple levels of dependencies (ie. a yarn.lock inside a subfolder of a yarn.lock). This is
// typically solved using workspaces, but not all of them have been converted already.
if (ignorePattern && ignorePattern.test(normalizePath(issuer))) {
const result = callNativeResolution(request, issuer);
if (result === false) {
throw makeError(`BUILTIN_NODE_RESOLUTION_FAIL`, `The builtin node resolution algorithm was unable to resolve the module referenced by "${request}" and requested from "${issuer}" (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp "$$BLACKLIST")`, {
request,
issuer
});
}
return result;
}
let unqualifiedPath;
// If the request is a relative or absolute path, we just return it normalized
const dependencyNameMatch = request.match(pathRegExp);
if (!dependencyNameMatch) {
if (path.isAbsolute(request)) {
unqualifiedPath = path.normalize(request);
} else if (issuer.match(isDirRegExp)) {
unqualifiedPath = path.normalize(path.resolve(issuer, request));
} else {
unqualifiedPath = path.normalize(path.resolve(path.dirname(issuer), request));
}
}
// Things are more hairy if it's a package require - we then need to figure out which package is needed, and in
// particular the exact version for the given location on the dependency tree
if (dependencyNameMatch) {
const dependencyName = dependencyNameMatch[1],
subPath = dependencyNameMatch[2];
const issuerLocator = exports.findPackageLocator(issuer);
// If the issuer file doesn't seem to be owned by a package managed through pnp, then we resort to using the next
// resolution algorithm in the chain, usually the native Node resolution one
if (!issuerLocator) {
const result = callNativeResolution(request, issuer);
if (result === false) {
throw makeError(`BUILTIN_NODE_RESOLUTION_FAIL`, `The builtin node resolution algorithm was unable to resolve the module referenced by "${request}" and requested from "${issuer}" (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree)`, {
request,
issuer
});
}
return result;
}
const issuerInformation = getPackageInformationSafe(issuerLocator);
// We obtain the dependency reference in regard to the package that request it
let dependencyReference = issuerInformation.packageDependencies.get(dependencyName);
// If we can't find it, we check if we can potentially load it from the packages that have been defined as potential fallbacks.
// It's a bit of a hack, but it improves compatibility with the existing Node ecosystem. Hopefully we should eventually be able
// to kill this logic and become stricter once pnp gets enough traction and the affected packages fix themselves.
if (issuerLocator !== topLevelLocator) {
for (let t = 0, T = fallbackLocators.length; dependencyReference === undefined && t < T; ++t) {
const fallbackInformation = getPackageInformationSafe(fallbackLocators[t]);
dependencyReference = fallbackInformation.packageDependencies.get(dependencyName);
}
}
// If we can't find the path, and if the package making the request is the top-level, we can offer nicer error messages
if (!dependencyReference) {
if (dependencyReference === null) {
if (issuerLocator === topLevelLocator) {
throw makeError(`MISSING_PEER_DEPENDENCY`, `You seem to be requiring a peer dependency ("${dependencyName}"), but it is not installed (which might be because you're the top-level package)`, { request, issuer, dependencyName });
} else {
throw makeError(`MISSING_PEER_DEPENDENCY`, `Package "${issuerLocator.name}@${issuerLocator.reference}" is trying to access a peer dependency ("${dependencyName}") that should be provided by its direct ancestor but isn't`, { request, issuer, issuerLocator: Object.assign({}, issuerLocator), dependencyName });
}
} else {
if (issuerLocator === topLevelLocator) {
throw makeError(`UNDECLARED_DEPENDENCY`, `You cannot require a package ("${dependencyName}") that is not declared in your dependencies (via "${issuer}")`, { request, issuer, dependencyName });
} else {
const candidates = Array.from(issuerInformation.packageDependencies.keys());
throw makeError(`UNDECLARED_DEPENDENCY`, `Package "${issuerLocator.name}@${issuerLocator.reference}" (via "${issuer}") is trying to require the package "${dependencyName}" (via "${request}") without it being listed in its dependencies (${candidates.join(`, `)})`, { request, issuer, issuerLocator: Object.assign({}, issuerLocator), dependencyName, candidates });
}
}
}
// We need to check that the package exists on the filesystem, because it might not have been installed
const dependencyLocator = { name: dependencyName, reference: dependencyReference };
const dependencyInformation = exports.getPackageInformation(dependencyLocator);
const dependencyLocation = path.resolve(__dirname, dependencyInformation.packageLocation);
if (!dependencyLocation) {
throw makeError(`MISSING_DEPENDENCY`, `Package "${dependencyLocator.name}@${dependencyLocator.reference}" is a valid dependency, but hasn't been installed and thus cannot be required (it might be caused if you install a partial tree, such as on production environments)`, { request, issuer, dependencyLocator: Object.assign({}, dependencyLocator) });
}
// Now that we know which package we should resolve to, we only have to find out the file location
if (subPath) {
unqualifiedPath = path.resolve(dependencyLocation, subPath);
} else {
unqualifiedPath = dependencyLocation;
}
}
return path.normalize(unqualifiedPath);
};
/**
* Transforms an unqualified path into a qualified path by using the Node resolution algorithm (which automatically
* appends ".js" / ".json", and transforms directory accesses into "index.js").
*/
exports.resolveUnqualified = function resolveUnqualified(unqualifiedPath, { extensions = Object.keys(Module._extensions) } = {}) {
const qualifiedPath = applyNodeExtensionResolution(unqualifiedPath, { extensions });
if (qualifiedPath) {
return path.normalize(qualifiedPath);
} else {
throw makeError(`QUALIFIED_PATH_RESOLUTION_FAILED`, `Couldn't find a suitable Node resolution for unqualified path "${unqualifiedPath}"`, { unqualifiedPath });
}
};
/**
* Transforms a request into a fully qualified path.
*
* Note that it is extremely important that the `issuer` path ends with a forward slash if the issuer is to be
* treated as a folder (ie. "/tmp/foo/" rather than "/tmp/foo" if "foo" is a directory). Otherwise relative
* imports won't be computed correctly (they'll get resolved relative to "/tmp/" instead of "/tmp/foo/").
*/
exports.resolveRequest = function resolveRequest(request, issuer, { considerBuiltins, extensions } = {}) {
let unqualifiedPath;
try {
unqualifiedPath = exports.resolveToUnqualified(request, issuer, { considerBuiltins });
} catch (originalError) {
// If we get a BUILTIN_NODE_RESOLUTION_FAIL error there, it means that we've had to use the builtin node
// resolution, which usually shouldn't happen. It might be because the user is trying to require something
// from a path loaded through a symlink (which is not possible, because we need something normalized to
// figure out which package is making the require call), so we try to make the same request using a fully
// resolved issuer and throws a better and more actionable error if it works.
if (originalError.code === `BUILTIN_NODE_RESOLUTION_FAIL`) {
let realIssuer;
try {
realIssuer = realpathSync(issuer);
} catch (error) {}
if (realIssuer) {
if (issuer.endsWith(`/`)) {
realIssuer = realIssuer.replace(/\/?$/, `/`);
}
try {
exports.resolveToUnqualified(request, realIssuer, { considerBuiltins });
} catch (error) {
// If an error was thrown, the problem doesn't seem to come from a path not being normalized, so we
// can just throw the original error which was legit.
throw originalError;
}
// If we reach this stage, it means that resolveToUnqualified didn't fail when using the fully resolved
// file path, which is very likely caused by a module being invoked through Node with a path not being
// correctly normalized (ie you should use "node $(realpath script.js)" instead of "node script.js").
throw makeError(`SYMLINKED_PATH_DETECTED`, `A pnp module ("${request}") has been required from what seems to be a symlinked path ("${issuer}"). This is not possible, you must ensure that your modules are invoked through their fully resolved path on the filesystem (in this case "${realIssuer}").`, {
request,
issuer,
realIssuer
});
}
}
throw originalError;
}
if (unqualifiedPath === null) {
return null;
}
try {
return exports.resolveUnqualified(unqualifiedPath, { extensions });
} catch (resolutionError) {
if (resolutionError.code === 'QUALIFIED_PATH_RESOLUTION_FAILED') {
Object.assign(resolutionError.data, { request, issuer });
}
throw resolutionError;
}
};
/**
* Setups the hook into the Node environment.
*
* From this point on, any call to `require()` will go through the "resolveRequest" function, and the result will
* be used as path of the file to load.
*/
exports.setup = function setup() {
// A small note: we don't replace the cache here (and instead use the native one). This is an effort to not
// break code similar to "delete require.cache[require.resolve(FOO)]", where FOO is a package located outside
// of the Yarn dependency tree. In this case, we defer the load to the native loader. If we were to replace the
// cache by our own, the native loader would populate its own cache, which wouldn't be exposed anymore, so the
// delete call would be broken.
const originalModuleLoad = Module._load;
Module._load = function (request, parent, isMain) {
if (!enableNativeHooks) {
return originalModuleLoad.call(Module, request, parent, isMain);
}
// Builtins are managed by the regular Node loader
if (builtinModules.has(request)) {
try {
enableNativeHooks = false;
return originalModuleLoad.call(Module, request, parent, isMain);
} finally {
enableNativeHooks = true;
}
}
// The 'pnpapi' name is reserved to return the PnP api currently in use by the program
if (request === `pnpapi`) {
return pnpModule.exports;
}
// Request `Module._resolveFilename` (ie. `resolveRequest`) to tell us which file we should load
const modulePath = Module._resolveFilename(request, parent, isMain);
// Check if the module has already been created for the given file
const cacheEntry = Module._cache[modulePath];
if (cacheEntry) {
return cacheEntry.exports;
}
// Create a new module and store it into the cache
const module = new Module(modulePath, parent);
Module._cache[modulePath] = module;
// The main module is exposed as global variable
if (isMain) {
process.mainModule = module;
module.id = '.';
}
// Try to load the module, and remove it from the cache if it fails
let hasThrown = true;
try {
module.load(modulePath);
hasThrown = false;
} finally {
if (hasThrown) {
delete Module._cache[modulePath];
}
}
// Some modules might have to be patched for compatibility purposes
for (var _iterator = patchedModules, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref2;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref2 = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref2 = _i.value;
}
const _ref = _ref2;
const filter = _ref[0];
const patchFn = _ref[1];
if (filter.test(request)) {
module.exports = patchFn(exports.findPackageLocator(parent.filename), module.exports);
}
}
return module.exports;
};
const originalModuleResolveFilename = Module._resolveFilename;
Module._resolveFilename = function (request, parent, isMain, options) {
if (!enableNativeHooks) {
return originalModuleResolveFilename.call(Module, request, parent, isMain, options);
}
let issuers;
if (options) {
const optionNames = new Set(Object.keys(options));
optionNames.delete('paths');
if (optionNames.size > 0) {
throw makeError(`UNSUPPORTED`, `Some options passed to require() aren't supported by PnP yet (${Array.from(optionNames).join(', ')})`);
}
if (options.paths) {
issuers = options.paths.map(entry => `${path.normalize(entry)}/`);
}
}
if (!issuers) {
const issuerModule = getIssuerModule(parent);
const issuer = issuerModule ? issuerModule.filename : `${process.cwd()}/`;
issuers = [issuer];
}
let firstError;
for (var _iterator2 = issuers, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref3;
if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref3 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref3 = _i2.value;
}
const issuer = _ref3;
let resolution;
try {
resolution = exports.resolveRequest(request, issuer);
} catch (error) {
firstError = firstError || error;
continue;
}
return resolution !== null ? resolution : request;
}
throw firstError;
};
const originalFindPath = Module._findPath;
Module._findPath = function (request, paths, isMain) {
if (!enableNativeHooks) {
return originalFindPath.call(Module, request, paths, isMain);
}
for (var _iterator3 = paths || [], _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref4;
if (_isArray3) {
if (_i3 >= _iterator3.length) break;
_ref4 = _iterator3[_i3++];
} else {
_i3 = _iterator3.next();
if (_i3.done) break;
_ref4 = _i3.value;
}
const path = _ref4;
let resolution;
try {
resolution = exports.resolveRequest(request, path);
} catch (error) {
continue;
}
if (resolution) {
return resolution;
}
}
return false;
};
process.versions.pnp = String(exports.VERSIONS.std);
};
exports.setupCompatibilityLayer = () => {
// ESLint currently doesn't have any portable way for shared configs to specify their own
// plugins that should be used (https://github.com/eslint/eslint/issues/10125). This will
// likely get fixed at some point, but it'll take time and in the meantime we'll just add
// additional fallback entries for common shared configs.
var _arr = [`react-scripts`];
for (var _i4 = 0; _i4 < _arr.length; _i4++) {
const name = _arr[_i4];
const packageInformationStore = packageInformationStores.get(name);
if (packageInformationStore) {
for (var _iterator4 = packageInformationStore.keys(), _isArray4 = Array.isArray(_iterator4), _i5 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref5;
if (_isArray4) {
if (_i5 >= _iterator4.length) break;
_ref5 = _iterator4[_i5++];
} else {
_i5 = _iterator4.next();
if (_i5.done) break;
_ref5 = _i5.value;
}
const reference = _ref5;
fallbackLocators.push({ name, reference });
}
}
}
// Modern versions of `resolve` support a specific entry point that custom resolvers can use
// to inject a specific resolution logic without having to patch the whole package.
//
// Cf: https://github.com/browserify/resolve/pull/174
patchedModules.push([/^\.\/normalize-options\.js$/, (issuer, normalizeOptions) => {
if (!issuer || issuer.name !== 'resolve') {
return normalizeOptions;
}
return (request, opts) => {
opts = opts || {};
if (opts.forceNodeResolution) {
return opts;
}
opts.preserveSymlinks = true;
opts.paths = function (request, basedir, getNodeModulesDir, opts) {
// Extract the name of the package being requested (1=full name, 2=scope name, 3=local name)
const parts = request.match(/^((?:(@[^\/]+)\/)?([^\/]+))/);
// make sure that basedir ends with a slash
if (basedir.charAt(basedir.length - 1) !== '/') {
basedir = path.join(basedir, '/');
}
// This is guaranteed to return the path to the "package.json" file from the given package
const manifestPath = exports.resolveToUnqualified(`${parts[1]}/package.json`, basedir);
// The first dirname strips the package.json, the second strips the local named folder
let nodeModules = path.dirname(path.dirname(manifestPath));
// Strips the scope named folder if needed
if (parts[2]) {
nodeModules = path.dirname(nodeModules);
}
return [nodeModules];
};
return opts;
};
}]);
};
if (module.parent && module.parent.id === 'internal/preload') {
exports.setupCompatibilityLayer();
exports.setup();
}
if (process.mainModule === module) {
exports.setupCompatibilityLayer();
const reportError = (code, message, data) => {
process.stdout.write(`${JSON.stringify([{ code, message, data }, null])}\n`);
};
const reportSuccess = resolution => {
process.stdout.write(`${JSON.stringify([null, resolution])}\n`);
};
const processResolution = (request, issuer) => {
try {
reportSuccess(exports.resolveRequest(request, issuer));
} catch (error) {
reportError(error.code, error.message, error.data);
}
};
const processRequest = data => {
try {
var _JSON$parse = JSON.parse(data);
const request = _JSON$parse[0],
issuer = _JSON$parse[1];
processResolution(request, issuer);
} catch (error) {
reportError(`INVALID_JSON`, error.message, error.data);
}
};
if (process.argv.length > 2) {
if (process.argv.length !== 4) {
process.stderr.write(`Usage: ${process.argv[0]} ${process.argv[1]} <request> <issuer>\n`);
process.exitCode = 64; /* EX_USAGE */
} else {
processResolution(process.argv[2], process.argv[3]);
}
} else {
let buffer = '';
const decoder = new StringDecoder.StringDecoder();
process.stdin.on('data', chunk => {
buffer += decoder.write(chunk);
do {
const index = buffer.indexOf('\n');
if (index === -1) {
break;
}
const line = buffer.slice(0, index);
buffer = buffer.slice(index + 1);
processRequest(line);
} while (true);
});
}
}