UNPKG

@dependabot/yarn-lib

Version:

📦🐈 Fast, reliable, and secure dependency management.

871 lines (671 loc) 31.7 kB
#!$$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); }); } }