/** * The directory pnpm's own `pnpm patch-commit` writes patches to, relative to * the workspace root. Shared so that the auto-include that bundles patches and * the filtering that removes them cannot drift apart: widening one without the * other would silently leave orphaned patch files in every bundle. */ export declare const PNPM_PATCHES_DIR = "patches"; /** * Whether an archive path names a patch file the filtering may remove from a * bundle: a `.patch` directly under {@link PNPM_PATCHES_DIR}. A declaration * may point anywhere, including at a file bundled for an unrelated reason, so * only the conventional location is removable. */ export declare function isRemovablePatchPath(archivePath: string): boolean; /** * Where a pnpm project can declare `patchedDependencies`. Both are live: * pnpm 10 reads the `package.json` field (and prefers it over * `pnpm-workspace.yaml` when both are populated), while pnpm 11 ignores it * and reads only `pnpm-workspace.yaml`. */ export type PatchConfigKind = 'pnpm-workspace.yaml' | 'package.json'; /** One of the bundle's declaring config files. */ export interface PatchConfigFile { /** Posix path of the file within the archive, e.g. `pnpm-workspace.yaml`. */ archivePath: string; kind: PatchConfigKind; content: string; } export interface RewrittenFile { archivePath: string; content: string; } /** * A complete, ready-to-apply description of the patch declarations to remove * from a bundle. Everything is computed up front so that applying it is pure * map mutation: a half-applied filter ships a bundle whose config and lockfile * disagree, which fails the remote install outright. */ export interface PatchFilterPlan { /** The `patchedDependencies` keys that no longer apply to anything. */ unusedKeys: string[]; /** The declaring config, rewritten without those keys. */ rewrittenConfig: RewrittenFile; /** * Archive paths of patch files that only the removed declarations * referenced. Paths resolving outside the workspace root are never listed. */ droppedPatchPaths: string[]; /** The pruned lockfile, rewritten without those keys. */ lockfileContent: string; } export interface PlanPatchFilterOptions { configs: PatchConfigFile[]; /** The workspace's own lockfile, as committed — before pruning. */ originalLockfileContent: string; /** * The lockfile the prune regenerated. Must come from a prune that passed the * pruner's own verification (see `verifyPrunedLockfile`): that check is what * guarantees the two lockfiles spell `patch_hash=` markers comparably, which * is the premise the used/unused decision rests on. Handed an unverified * regeneration — one written by a pnpm that disagrees about which * declaration site is live — the comparison could read a patch that is * genuinely in force as no longer applied. */ prunedLockfileContent: string; } interface PatchDeclaration { key: string; /** The patch file path exactly as the config spells it. */ patchPath: string; } /** * Reads a config's `patchedDependencies` map. Returns an empty map when the * config declares none, and `undefined` when the file cannot be parsed or the * map is not shaped as expected — callers treat that as "do not filter". */ export declare function readPatchedDependencies(config: PatchConfigFile): PatchDeclaration[] | undefined; /** * Reads a lockfile's `patchedDependencies` section as key → patch hash. * pnpm 10 records `{ hash, path }` objects and pnpm 11 a bare hash string; * both are accepted. Returns `undefined` when the lockfile cannot be parsed. * A pnpm 12 environment document, if present, is skipped. */ export declare function readLockfilePatchHashes(lockfileContent: string): Map | undefined; /** * Computes the patch declarations a bundle should stop shipping, together with * the rewritten files that carry the removal. Returns `undefined` whenever the * evidence is incomplete or an edit cannot be verified — the caller then ships * the bundle unchanged, which is always safe. */ export declare function planPatchFilter(options: PlanPatchFilterOptions): PatchFilterPlan | undefined; /** * Removes keys from a single YAML document's top-level `patchedDependencies` * map, dropping the map itself once it empties. Used for `pnpm-workspace.yaml` * directly and for `pnpm-lock.yaml` through {@link rewriteLockfileSection}; * both files' sections have the same shape. * * The result is verified structurally before it is returned: a serializer that * reformatted or dropped anything else would ship silently, and for the * lockfile it would also invalidate the verification the pruner already ran * over the bytes it produced. * * A `pnpm-lock.yaml` may carry a leading environment document, which * {@link rewriteLockfileSection} strips first; `pnpm-workspace.yaml` is * passed as-is, since a leading `---` there is an ordinary document-start * marker and not a separate document. */ export declare function rewriteYamlSection(content: string, removed: Set): string | undefined; /** * {@link rewriteYamlSection} for `pnpm-lock.yaml`. A pnpm 12 lockfile may * lead with an environment document; only the application document is * edited and verified, and the environment document is carried over verbatim * so pnpm still finds it in the bundled lockfile. */ export declare function rewriteLockfileSection(content: string, removed: Set): string | undefined; /** * Asserts that a rewrite changed nothing but the intended keys, by comparing * the reparsed result against the reparsed original with those keys deleted. * A config can carry anything else pnpm understands — `catalog:`, `overrides`, * `onlyBuiltDependencies` — and nothing downstream would notice it being * mangled, so the check is what makes the edit safe to ship. * * Exported so that the rejection path — which no legitimate serializer output * reaches, and which therefore cannot be driven through the callers — is * directly testable. * * Package pruning keeps an analogous fail-closed verifier in * package-prune.ts (`verifyPrunedManifest`); hardening either against a * manifest quirk likely applies to both. */ export declare function verifyRewrite(original: string, rewritten: string, removed: Set, parse: (content: string) => any): string | undefined; export interface FindUnrepairedPatchKeysOptions { configs: PatchConfigFile[]; originalLockfileContent: string; /** The lockfile the bundle is about to ship. */ shippedLockfileContent: string; } /** * Reports declarations the shipped bundle still carries but its shipped * lockfile no longer records — the precondition for the remote install failing * with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`. * * Scoped to keys the project's original lockfile recorded, so a declaration * the project's own pnpm never honoured is not reported as a bundling problem. */ export declare function findUnrepairedPatchKeys(options: FindUnrepairedPatchKeysOptions): string[]; export {};