mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-13 11:05:52 -04:00
* chore: update all dependencies to latest versions Update all outdated dependencies across the monorepo catalog and fix breaking changes from major version bumps. Notable updates: - ESLint 9 → 10 (fix custom rule API, disable new no-useless-assignment) - @stylistic/eslint-plugin 4 → 5 (auto-fixed indent changes) - @cyclonedx/cyclonedx-library 9 → 10 (adapt to removed SPDX API) - esbuild 0.25 → 0.27 - TypeScript 5.9.2 → 5.9.3 - Various @types packages, test utilities, and build tools Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update unified/remark/mdast imports for v11/v4 API changes Update imports in get-release-text for the new ESM named exports: - mdast-util-to-string: default → { toString } - unified: default → { unified } Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve typecheck errors from dependency updates - isexe v4: use named import { sync } instead of default export - remark-parse/remark-stringify v11: add vfile as packageExtension dependency so TypeScript can resolve type declarations - get-release-text: remove unused @ts-expect-error directives Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: revert runtime dependency major version bumps Revert major version bumps for runtime dependencies that are bundled into pnpm to fix test failures where pnpm add silently fails: - bin-links: keep ^5.0.0 (was ^6.0.0) - cli-truncate: keep ^4.0.0 (was ^5.2.0) - delay: keep ^6.0.0 (was ^7.0.0) - filenamify: keep ^6.0.0 (was ^7.0.1) - find-up: keep ^7.0.0 (was ^8.0.0) - isexe: keep 2.0.0 (was 4.0.0) - normalize-newline: keep 4.1.0 (was 5.0.0) - p-queue: keep ^8.1.0 (was ^9.1.0) - ps-list: keep ^8.1.1 (was ^9.0.0) - string-length: keep ^6.0.0 (was ^7.0.1) - symlink-dir: keep ^7.0.0 (was ^9.0.0) - terminal-link: keep ^4.0.0 (was ^5.0.0) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: restore runtime dependency major version bumps Re-apply all runtime dependency major version bumps that were previously reverted. All packages maintain their default exports except isexe v4 which needs named imports. Updated runtime deps: - bin-links: ^5.0.0 → ^6.0.0 - cli-truncate: ^4.0.0 → ^5.2.0 - delay: ^6.0.0 → ^7.0.0 - filenamify: ^6.0.0 → ^7.0.1 - find-up: ^7.0.0 → ^8.0.0 - isexe: 2.0.0 → 4.0.0 (fix: use named import { sync }) - normalize-newline: 4.1.0 → 5.0.0 - p-queue: ^8.1.0 → ^9.1.0 - ps-list: ^8.1.1 → ^9.0.0 - string-length: ^6.0.0 → ^7.0.1 - symlink-dir: ^7.0.0 → ^9.0.0 - terminal-link: ^4.0.0 → ^5.0.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: revert tempy to 3.0.0 to fix bundle hang tempy 3.2.0 pulls in temp-dir 3.0.0 which uses async fs.realpath() inside its module init. When bundled by esbuild into the __esm lazy init pattern, this causes a deadlock during module initialization, making the pnpm binary hang silently on startup. Keeping tempy at 3.0.0 which uses temp-dir 2.x (sync fs.realpathSync). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add comment explaining why tempy cannot be upgraded Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: revert nock to 13.3.4 for node-fetch compatibility nock 14 changed its HTTP interception mechanism in a way that doesn't properly intercept node-fetch requests, causing audit tests to hang waiting for responses that are never intercepted. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add comment explaining why nock cannot be upgraded Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update symlink-dir imports for v10 ESM named exports symlink-dir v10 removed the default export and switched to named exports: { symlinkDir, symlinkDirSync }. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: revert @typescript/native-preview to working version Newer tsgo dev builds (>= 20260318) have a regression where @types/node cannot be resolved, breaking all node built-in types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: vulnerabilities * fix: align comment indentation in runLifecycleHook Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: pin msgpackr to 1.11.8 for TypeScript 5.9 compatibility msgpackr 1.11.9 has broken type definitions that use Iterable/Iterator without required type arguments, causing compile errors with TS 5.9. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
149 lines
4.8 KiB
TypeScript
149 lines
4.8 KiB
TypeScript
import {
|
|
LOCKFILE_VERSION,
|
|
WANTED_LOCKFILE,
|
|
} from '@pnpm/constants'
|
|
import {
|
|
createLockfileObject,
|
|
existsNonEmptyWantedLockfile,
|
|
isEmptyLockfile,
|
|
type LockfileObject,
|
|
readCurrentLockfile,
|
|
readWantedLockfile,
|
|
readWantedLockfileAndAutofixConflicts,
|
|
} from '@pnpm/lockfile.fs'
|
|
import { logger } from '@pnpm/logger'
|
|
import type { ProjectId, ProjectRootDir } from '@pnpm/types'
|
|
import { clone, equals } from 'ramda'
|
|
|
|
export interface PnpmContext {
|
|
currentLockfile: LockfileObject
|
|
existsCurrentLockfile: boolean
|
|
existsWantedLockfile: boolean
|
|
existsNonEmptyWantedLockfile: boolean
|
|
wantedLockfile: LockfileObject
|
|
}
|
|
|
|
export async function readLockfiles (
|
|
opts: {
|
|
autoInstallPeers: boolean
|
|
excludeLinksFromLockfile: boolean
|
|
peersSuffixMaxLength: number
|
|
ci?: boolean
|
|
force: boolean
|
|
frozenLockfile: boolean
|
|
projects: Array<{
|
|
id: ProjectId
|
|
rootDir: ProjectRootDir
|
|
}>
|
|
lockfileDir: string
|
|
registry: string
|
|
useLockfile: boolean
|
|
useGitBranchLockfile?: boolean
|
|
mergeGitBranchLockfiles?: boolean
|
|
internalPnpmDir: string
|
|
}
|
|
): Promise<{
|
|
currentLockfile: LockfileObject
|
|
currentLockfileIsUpToDate: boolean
|
|
existsCurrentLockfile: boolean
|
|
existsWantedLockfile: boolean
|
|
existsNonEmptyWantedLockfile: boolean
|
|
wantedLockfile: LockfileObject
|
|
wantedLockfileIsModified: boolean
|
|
lockfileHadConflicts: boolean
|
|
}> {
|
|
const wantedLockfileVersion = LOCKFILE_VERSION
|
|
// On CI, avoid breaking builds due to incompatible lockfiles by default.
|
|
// Ignore incompatible lockfiles only for non-frozen CI installs or when `force` is set;
|
|
// in frozen-lockfile mode, incompatible lockfiles should still fail.
|
|
const lockfileOpts = {
|
|
ignoreIncompatible: opts.force || (opts.ci === true && !opts.frozenLockfile),
|
|
wantedVersions: [LOCKFILE_VERSION],
|
|
useGitBranchLockfile: opts.useGitBranchLockfile,
|
|
mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles,
|
|
}
|
|
const fileReads = [] as Array<Promise<LockfileObject | undefined | null>>
|
|
let lockfileHadConflicts: boolean = false
|
|
if (opts.useLockfile) {
|
|
if (!opts.frozenLockfile) {
|
|
fileReads.push(
|
|
(async () => {
|
|
try {
|
|
const { lockfile, hadConflicts } = await readWantedLockfileAndAutofixConflicts(opts.lockfileDir, lockfileOpts)
|
|
lockfileHadConflicts = hadConflicts
|
|
return lockfile
|
|
} catch (err: any) { // eslint-disable-line
|
|
logger.warn({
|
|
message: `Ignoring broken lockfile at ${opts.lockfileDir}: ${err.message as string}`,
|
|
prefix: opts.lockfileDir,
|
|
})
|
|
return undefined
|
|
}
|
|
})()
|
|
)
|
|
} else {
|
|
fileReads.push(readWantedLockfile(opts.lockfileDir, lockfileOpts))
|
|
}
|
|
} else {
|
|
if (await existsNonEmptyWantedLockfile(opts.lockfileDir, lockfileOpts)) {
|
|
logger.warn({
|
|
message: `A ${WANTED_LOCKFILE} file exists. The current configuration prohibits to read or write a lockfile`,
|
|
prefix: opts.lockfileDir,
|
|
})
|
|
}
|
|
fileReads.push(Promise.resolve(undefined))
|
|
}
|
|
fileReads.push(
|
|
(async () => {
|
|
try {
|
|
return await readCurrentLockfile(opts.internalPnpmDir, lockfileOpts)
|
|
} catch (err: any) { // eslint-disable-line
|
|
logger.warn({
|
|
message: `Ignoring broken lockfile at ${opts.internalPnpmDir}: ${err.message as string}`,
|
|
prefix: opts.lockfileDir,
|
|
})
|
|
return undefined
|
|
}
|
|
})()
|
|
)
|
|
const files = await Promise.all<LockfileObject | null | undefined>(fileReads)
|
|
const sopts = {
|
|
autoInstallPeers: opts.autoInstallPeers,
|
|
excludeLinksFromLockfile: opts.excludeLinksFromLockfile,
|
|
lockfileVersion: wantedLockfileVersion,
|
|
peersSuffixMaxLength: opts.peersSuffixMaxLength,
|
|
}
|
|
const importerIds = opts.projects.map((importer) => importer.id)
|
|
const currentLockfile = files[1] ?? createLockfileObject(importerIds, sopts)
|
|
for (const importerId of importerIds) {
|
|
if (!currentLockfile.importers[importerId]) {
|
|
currentLockfile.importers[importerId] = {
|
|
specifiers: {},
|
|
}
|
|
}
|
|
}
|
|
const wantedLockfile = files[0] ??
|
|
(currentLockfile && clone(currentLockfile)) ??
|
|
createLockfileObject(importerIds, sopts)
|
|
let wantedLockfileIsModified = false
|
|
for (const importerId of importerIds) {
|
|
if (!wantedLockfile.importers[importerId]) {
|
|
wantedLockfileIsModified = true
|
|
wantedLockfile.importers[importerId] = {
|
|
specifiers: {},
|
|
}
|
|
}
|
|
}
|
|
const existsWantedLockfile = files[0] != null
|
|
return {
|
|
currentLockfile,
|
|
currentLockfileIsUpToDate: equals(currentLockfile, wantedLockfile),
|
|
existsCurrentLockfile: files[1] != null,
|
|
existsWantedLockfile,
|
|
existsNonEmptyWantedLockfile: existsWantedLockfile && !isEmptyLockfile(wantedLockfile),
|
|
wantedLockfile,
|
|
wantedLockfileIsModified,
|
|
lockfileHadConflicts,
|
|
}
|
|
}
|