Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const locator = locators[packageId];
const info = pnp.getPackageInformation(locator)!;
let linkType;
let target;
if (options.pnpifyFs) {
// In case of pnpifyFs we represent modules as symlinks to archives in NodeModulesFS
// `/home/user/project/foo` is a symlink to `/home/user/project/.yarn/.cache/foo.zip/node_modules/foo`
// To make this fs layout work with legacy tools we make
// `/home/user/project/.yarn/.cache/foo.zip/node_modules/foo/node_modules` (which normally does not exist inside archive) a symlink to:
// `/home/user/project/node_modules/foo/node_modules`, so that the tools were able to access it
target = npath.toPortablePath(info.packageLocation);
linkType = LinkType.SOFT;
} else {
const truePath = pnp.resolveVirtual && locator.reference && locator.reference.startsWith('virtual:') ? pnp.resolveVirtual(info.packageLocation) : info.packageLocation;
target = npath.toPortablePath(truePath || info.packageLocation);
linkType = info.linkType;
}
return {
locator: serializeLocator(locator),
size: packages[packageId].weight,
target,
linkType,
};
};
// 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(
ErrorCode.BUILTIN_NODE_RESOLUTION_FAILED,
`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree)\n\nRequire path: "${request}"\nRequired by: ${issuer}\n`,
{request, issuer},
);
}
return npath.toPortablePath(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.name !== null) {
// To allow programs to become gradually stricter, starting from the v2 we enforce that workspaces cannot depend on fallbacks.
// This works by having a list containing all their locators, and checking when a fallback is required whether it's one of them.
const exclusionEntry = runtimeState.fallbackExclusionList.get(issuerLocator.name);
export async function execute(command: string, args: Array = [], {
builtins = {},
cwd = npath.toPortablePath(process.cwd()),
env = process.env,
stdin = process.stdin,
stdout = process.stdout,
stderr = process.stderr,
variables = {},
}: Partial = {}) {
const normalizedEnv: {[key: string]: string} = {};
for (const [key, value] of Object.entries(env))
if (typeof value !== `undefined`)
normalizedEnv[key] = value;
const normalizedBuiltins = new Map(BUILTINS);
for (const [key, builtin] of Object.entries(builtins))
normalizedBuiltins.set(key, builtin);
// This is meant to be the equivalent of /dev/null
const makeLeafNode = (packageId: HoisterPackageId): {locator: LocatorKey, size: number, target: PortablePath, linkType: LinkType} => {
const locator = locators[packageId];
const info = pnp.getPackageInformation(locator)!;
let linkType;
let target;
if (options.pnpifyFs) {
// In case of pnpifyFs we represent modules as symlinks to archives in NodeModulesFS
// `/home/user/project/foo` is a symlink to `/home/user/project/.yarn/.cache/foo.zip/node_modules/foo`
// To make this fs layout work with legacy tools we make
// `/home/user/project/.yarn/.cache/foo.zip/node_modules/foo/node_modules` (which normally does not exist inside archive) a symlink to:
// `/home/user/project/node_modules/foo/node_modules`, so that the tools were able to access it
target = npath.toPortablePath(info.packageLocation);
linkType = LinkType.SOFT;
} else {
const truePath = pnp.resolveVirtual && locator.reference && locator.reference.startsWith('virtual:') ? pnp.resolveVirtual(info.packageLocation) : info.packageLocation;
target = npath.toPortablePath(truePath || info.packageLocation);
linkType = info.linkType;
}
return {
locator: serializeLocator(locator),
size: packages[packageId].weight,
target,
linkType,
};
};
export async function makeScriptEnv({project, lifecycleScript}: {project?: Project, lifecycleScript?: string} = {}) {
const scriptEnv: {[key: string]: string} = {};
for (const [key, value] of Object.entries(process.env))
if (typeof value !== `undefined`)
scriptEnv[key.toLowerCase() !== `path` ? key : `PATH`] = value;
const nativeBinFolder = dirSync().name;
const binFolder = npath.toPortablePath(nativeBinFolder);
// We expose the base folder in the environment so that we can later add the
// binaries for the dependencies of the active package
scriptEnv.BERRY_BIN_FOLDER = nativeBinFolder;
// Register some binaries that must be made available in all subprocesses
// spawned by Yarn (we thus ensure that they always use the right version)
await makePathWrapper(binFolder, toFilename(`node`), process.execPath);
if (YarnVersion !== null) {
await makePathWrapper(binFolder, toFilename(`run`), process.execPath, [process.argv[1], `run`]);
await makePathWrapper(binFolder, toFilename(`yarn`), process.execPath, [process.argv[1]]);
await makePathWrapper(binFolder, toFilename(`yarnpkg`), process.execPath, [process.argv[1]]);
await makePathWrapper(binFolder, toFilename(`node-gyp`), process.execPath, [process.argv[1], `run`, `--top-level`, `node-gyp`]);
}
const parseLocation = (location: PortablePath): {locationRoot: PortablePath, segments: Filename[]} => {
const allSegments = location.split(ppath.sep);
const nmIndex = allSegments.indexOf(NODE_MODULES);
const locationRoot: LocationRoot = npath.toPortablePath(allSegments.slice(0, nmIndex + 1).join(ppath.sep));
const segments = allSegments.slice(nmIndex + 1).map(x => toFilename(x));
return {locationRoot, segments};
};
function findApiPathFor(modulePath: NativePath) {
let curr: PortablePath;
let next = npath.toPortablePath(modulePath);
do {
curr = next;
const candidate = ppath.join(curr, `.pnp.js` as Filename);
if (xfs.existsSync(candidate) && xfs.statSync(candidate).isFile())
return candidate;
next = ppath.dirname(curr);
} while (curr !== PortablePath.root);
return null;
}
case SettingsType.MAP:
return parseMap(configuration, path, value, definition, folder);
}
if (value === null && !definition.isNullable && definition.default !== null)
throw new Error(`Non-nullable configuration settings "${path}" cannot be set to null`);
if (definition.type === SettingsType.BOOLEAN)
return parseBoolean(value);
if (typeof value !== `string`)
throw new Error(`Expected value to be a string`);
switch (definition.type) {
case SettingsType.ABSOLUTE_PATH:
return ppath.resolve(folder, npath.toPortablePath(value));
case SettingsType.LOCATOR_LOOSE:
return structUtils.parseLocator(value, false);
case SettingsType.LOCATOR:
return structUtils.parseLocator(value);
default:
return value;
}
}
resolveRequest: maybeLog(`resolveRequest`, (request: NativePath, issuer: NativePath | null, opts?: ResolveRequestOptions) => {
const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null;
const resolution = resolveRequest(npath.toPortablePath(request), portableIssuer, opts);
if (resolution === null)
return null;
return npath.fromPortablePath(resolution);
}),