Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
options: ResolveDependencyOptions,
): Promise {
const update = Boolean(
options.update ||
options.workspacePackages &&
wantedDepIsLocallyAvailable(options.workspacePackages, wantedDependency, { defaultTag: ctx.defaultTag, registry: ctx.registries.default }))
const proceed = update || options.proceed || !options.currentResolution
const parentIsInstallable = options.parentIsInstallable === undefined || options.parentIsInstallable
const currentLockfileContainsTheDep = options.relDepPath ? Boolean(ctx.currentLockfile.packages?.[options.relDepPath]) : undefined
const depIsLinked = Boolean(options.depPath &&
// if package is not in `node_modules/.pnpm-lock.yaml`
// we can safely assume that it doesn't exist in `node_modules`
currentLockfileContainsTheDep &&
options.relDepPath && options.dependencyLockfile &&
await exists(path.join(ctx.virtualStoreDir, `${options.depPath}/node_modules/${nameVerFromPkgSnapshot(options.relDepPath, options.dependencyLockfile).name}/package.json`)) &&
(options.currentDepth > 0 || wantedDependency.alias && await exists(path.join(ctx.modulesDir, wantedDependency.alias))))
if (!proceed && depIsLinked) {
return null
}
let pkgResponse!: PackageResponse
try {
pkgResponse = await ctx.storeController.requestPackage(wantedDependency, {
alwaysTryWorkspacePackages: options.alwaysTryWorkspacePackages,
currentPackageId: options.pkgId,
currentResolution: options.currentResolution,
defaultTag: ctx.defaultTag,
downloadPriority: -options.currentDepth,
importerDir: ctx.prefix,
lockfileDir: ctx.lockfileDir,
let useManifestInfoFromLockfile = false
let prepare!: boolean
let hasBin!: boolean
if (
!options.update && options.dependencyLockfile && options.relDepPath &&
!pkgResponse.body.updated &&
// peerDependencies field is also used for transitive peer dependencies which should not be linked
// That's why we cannot omit reading package.json of such dependencies.
// This can be removed if we implement something like peerDependenciesMeta.transitive: true
!options.dependencyLockfile.peerDependencies
) {
useManifestInfoFromLockfile = true
prepare = options.dependencyLockfile.prepare === true
hasBin = options.dependencyLockfile.hasBin === true
pkg = Object.assign(
nameVerFromPkgSnapshot(options.relDepPath, options.dependencyLockfile),
options.dependencyLockfile,
)
} else {
// tslint:disable:no-string-literal
pkg = ctx.readPackageHook
? ctx.readPackageHook(pkgResponse.body.manifest || await pkgResponse.bundledManifest!())
: pkgResponse.body.manifest || await pkgResponse.bundledManifest!()
prepare = Boolean(
pkgResponse.body.resolvedVia === 'git-repository' &&
typeof pkg.scripts?.prepare === 'string',
)
if (
options.dependencyLockfile?.deprecated &&
!pkgResponse.body.updated && !pkg.deprecated
const message = `No entry for "${relDepPath}" in ${WANTED_LOCKFILE}`
if (opts.failOnMissingDependencies) {
throw new PnpmError('LOCKFILE_MISSING_DEPENDENCY', message)
}
logger.debug(message)
continue
}
let installable!: boolean
if (!parentIsInstallable) {
installable = false
if (!ctx.pickedPackages[relDepPath]) {
opts.skipped.add(relDepPath)
}
} else {
const pkg = {
...nameVerFromPkgSnapshot(relDepPath, pkgSnapshot),
cpu: pkgSnapshot.cpu,
engines: pkgSnapshot.engines,
os: pkgSnapshot.os,
}
// TODO: relDepPath is not the package ID. Should be fixed
installable = opts.includeIncompatiblePackages || packageIsInstallable(pkgSnapshot.id || relDepPath, pkg, {
engineStrict: opts.engineStrict,
lockfileDir: opts.lockfileDir,
nodeVersion: opts.currentEngine.nodeVersion,
optional: pkgSnapshot.optional === true,
pnpmVersion: opts.currentEngine.pnpmVersion,
}) !== false
if (!installable) {
if (!ctx.pickedPackages[relDepPath]) {
opts.skipped.add(relDepPath)
}
lockfile: Lockfile,
opts: {
prefix: string,
},
) {
const relDepPath = dp.refToRelative(preferredRef, wantedDep.alias)
if (relDepPath === null) return false
const pkgSnapshot = lockfile.packages?.[relDepPath]
if (!pkgSnapshot) {
logger.warn({
message: `Could not find preferred package ${relDepPath} in lockfile`,
prefix: opts.prefix,
})
return false
}
const { version } = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot)
return semver.satisfies(version, wantedDep.pref, true)
}
return R.toPairs(deps).map(([depAlias, ref]) => {
if (importerId && ref.startsWith('link:')) {
return [depAlias, path.join(importerId, ref.substr(5))]
}
const relDepPath = refToRelative(ref, depAlias)
if (!relDepPath) return [depAlias, ref]
const { name, version, peersSuffix } = nameVerFromPkgSnapshot(relDepPath, lockfile.packages![relDepPath])
const pnpVersion = toPnPVersion(version, peersSuffix)
if (depAlias === name) {
return [depAlias, pnpVersion]
}
return [depAlias, [name, pnpVersion]]
})
}
export function getPreferredVersionsFromLockfile (snapshots: PackageSnapshots): PreferredVersions {
const preferredVersions: PreferredVersions = {}
for (const [relDepPath, snapshot] of Object.entries(snapshots)) {
const { name, version } = nameVerFromPkgSnapshot(relDepPath, snapshot)
if (!preferredVersions[name]) {
preferredVersions[name] = { [version]: 'version' }
} else {
preferredVersions[name][version] = 'version'
}
}
return preferredVersions
}
async function getDependencies (
step: LockfileWalkerStep,
depth: number,
opts: {
getIndependentPackageLocation?: (packageId: string, packageName: string) => Promise,
registries: Registries,
lockfileDir: string,
virtualStoreDir: string,
},
): Promise {
const deps: Dependency[] = []
const nextSteps: LockfileWalkerStep[] = []
for (const { pkgSnapshot, relDepPath, next } of step.dependencies) {
const absolutePath = dp.resolve(opts.registries, relDepPath)
const pkgName = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot).name
const modules = path.join(opts.virtualStoreDir, pkgIdToFilename(absolutePath, opts.lockfileDir), 'node_modules')
const independent = opts.getIndependentPackageLocation && packageIsIndependent(pkgSnapshot)
const allDeps = {
...pkgSnapshot.dependencies,
...pkgSnapshot.optionalDependencies,
}
deps.push({
absolutePath,
children: Object.keys(allDeps).reduce((children, alias) => {
children[alias] = dp.refToAbsolute(allDeps[alias], alias, opts.registries)
return children
}, {}),
depth,
location: !independent
? path.join(modules, pkgName)
: await opts.getIndependentPackageLocation!(pkgSnapshot.id || absolutePath, pkgName),
.filter((relativeDepPath) => {
const pkgLockfile = packages[relativeDepPath]
const pkgInfo = nameVerFromPkgSnapshot(relativeDepPath, pkgLockfile)
if (!pkgInfo.name) {
logger.warn({
message: `Skipping ${relativeDepPath} because cannot get the package name from ${WANTED_LOCKFILE}.
Try to run run \`pnpm update --depth 100\` to create a new ${WANTED_LOCKFILE} with all the necessary info.`,
prefix: opts.prefix,
})
return false
}
return matches(searched, pkgInfo)
})
}