fix: reuse sortLockfileKeys for env lockfile sorting (#11026)

Replace the custom sortEnvLockfile function with the shared
sortLockfileKeys, ensuring env lockfile fields are sorted
consistently with the main lockfile document.
This commit is contained in:
Zoltan Kochan
2026-03-19 13:27:29 +01:00
committed by GitHub
parent 1a09015839
commit 94ca54e20b
3 changed files with 19 additions and 30 deletions

View File

@@ -4,10 +4,10 @@ import util from 'node:util'
import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants'
import type { EnvLockfile } from '@pnpm/lockfile.types'
import { sortDirectKeys } from '@pnpm/object.key-sorting'
import yaml from 'js-yaml'
import writeFileAtomic from 'write-file-atomic'
import { sortLockfileKeys } from './sortLockfileKeys.js'
import { lockfileYamlDump } from './write.js'
import { extractMainDocument, streamReadFirstYamlDocument } from './yamlDocuments.js'
@@ -58,7 +58,7 @@ export async function readEnvLockfile (rootDir: string): Promise<EnvLockfile | n
export async function writeEnvLockfile (rootDir: string, lockfile: EnvLockfile): Promise<void> {
const lockfilePath = path.join(rootDir, WANTED_LOCKFILE)
const sorted = sortEnvLockfile(lockfile)
const sorted = sortLockfileKeys(lockfile)
const envYaml = lockfileYamlDump(sorted)
// Read existing main lockfile document to preserve it
@@ -75,20 +75,3 @@ export async function writeEnvLockfile (rootDir: string, lockfile: EnvLockfile):
const combined = `---\n${envYaml}\n---\n${mainDoc}`
return writeFileAtomic(lockfilePath, combined)
}
function sortEnvLockfile (lockfile: EnvLockfile): EnvLockfile {
const importer: EnvLockfile['importers']['.'] = {
configDependencies: sortDirectKeys(lockfile.importers['.']?.configDependencies ?? {}),
}
if (lockfile.importers['.'].packageManagerDependencies && Object.keys(lockfile.importers['.'].packageManagerDependencies).length > 0) {
importer.packageManagerDependencies = sortDirectKeys(lockfile.importers['.'].packageManagerDependencies)
}
return {
lockfileVersion: lockfile.lockfileVersion,
importers: {
'.': importer,
},
packages: sortDirectKeys(lockfile.packages),
snapshots: sortDirectKeys(lockfile.snapshots),
}
}

View File

@@ -1,4 +1,4 @@
import type { LockfileFile } from '@pnpm/lockfile.types'
import type { EnvLockfile, LockfileFile } from '@pnpm/lockfile.types'
import { sortDeepKeys, sortDirectKeys, sortKeysByPriority } from '@pnpm/object.key-sorting'
const ORDERED_KEYS = {
@@ -44,7 +44,9 @@ const ROOT_KEYS: readonly RootKey[] = [
]
const ROOT_KEYS_ORDER = Object.fromEntries(ROOT_KEYS.map((key, index) => [key, index]))
export function sortLockfileKeys (lockfile: LockfileFile): LockfileFile {
export function sortLockfileKeys (lockfile: LockfileFile): LockfileFile
export function sortLockfileKeys (lockfile: EnvLockfile): EnvLockfile
export function sortLockfileKeys (lockfile: LockfileFile | EnvLockfile): LockfileFile | EnvLockfile {
if (lockfile.importers != null) {
lockfile.importers = sortDirectKeys(lockfile.importers)
for (const [importerId, importer] of Object.entries(lockfile.importers)) {
@@ -72,15 +74,17 @@ export function sortLockfileKeys (lockfile: LockfileFile): LockfileFile {
}, pkg)
}
}
if (lockfile.catalogs != null) {
if ('catalogs' in lockfile && lockfile.catalogs != null) {
lockfile.catalogs = sortDirectKeys(lockfile.catalogs)
for (const [catalogName, catalog] of Object.entries(lockfile.catalogs)) {
lockfile.catalogs[catalogName] = sortDeepKeys(catalog)
}
}
for (const key of ['time', 'patchedDependencies'] as const) {
if (!lockfile[key]) continue
lockfile[key] = sortDirectKeys<any>(lockfile[key]) // eslint-disable-line @typescript-eslint/no-explicit-any
if ('time' in lockfile && lockfile.time != null) {
lockfile.time = sortDirectKeys(lockfile.time)
}
if ('patchedDependencies' in lockfile && lockfile.patchedDependencies != null) {
lockfile.patchedDependencies = sortDirectKeys(lockfile.patchedDependencies)
}
return sortKeysByPriority({ priority: ROOT_KEYS_ORDER }, lockfile)
}

View File

@@ -165,13 +165,15 @@ export type PackageBin = string | { [name: string]: string }
*/
export type ResolvedDependencies = Record<string, string>
export interface EnvImporterSnapshot {
configDependencies: Record<string, SpecifierAndResolution>
packageManagerDependencies?: Record<string, SpecifierAndResolution>
}
export interface EnvLockfile {
lockfileVersion: string
importers: {
'.': {
configDependencies: Record<string, SpecifierAndResolution>
packageManagerDependencies?: Record<string, SpecifierAndResolution>
}
importers: Record<string, EnvImporterSnapshot> & {
'.': EnvImporterSnapshot
}
packages: Record<string, LockfilePackageInfo>
snapshots: Record<string, LockfilePackageSnapshot>