import { PackageNamePattern } from '../embedded-packages/spec.js'; export declare const DEPENDENCY_CLASSES: readonly ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]; export type DependencyClass = typeof DEPENDENCY_CLASSES[number]; /** * A per-class map: `true` selects the whole class and a pattern array * selects matching entries from it. */ export type BundlePackagesPruneClasses = { [K in DependencyClass]?: true | string[]; }; /** * A `bundle.packages.prune` array entry: a global name pattern applied to * every bundled workspace manifest, or a member-scoped object targeting * the manifests whose `name` the `member` pattern list selects (`'.'` * addresses the workspace root). A scoped entry carries exactly one of * `remove` (subtractive: matching entries are removed, composing with * global patterns in listed order) or `keep` (declarative: the member's * entire final dependency set — entries not kept are removed, classes a * class-keyed `keep` leaves unmentioned are emptied, and no other entry * can remove a kept name). */ export type BundlePackagesPruneEntry = string | { member: string | string[]; remove: string[] | BundlePackagesPruneClasses; keep?: never; } | { member: string | string[]; keep: string[] | BundlePackagesPruneClasses; remove?: never; }; /** * The `bundle.packages.prune` config surface: an entry array (name * patterns and member-scoped objects), or a per-class map where `true` * removes the whole class and a pattern array removes matching entries * from it. */ export type BundlePackagesPrune = BundlePackagesPruneEntry[] | BundlePackagesPruneClasses; /** * A member selector element: the `'.'` token addressing the workspace * root, or a name pattern matched against a member manifest's `name`. */ export type MemberPattern = { root: true; exclude: boolean; } | PackageNamePattern; /** Parsed patterns per dependency class; an absent class holds none. */ export type PruneClassPatterns = { [K in DependencyClass]?: PackageNamePattern[]; }; /** * A normalized prune entry. `true` class values inside member-scoped * `remove`/`keep` normalize to the catch-all `'**'` pattern, so ordered * entry composition needs no separate whole-class rule — unlike the * standalone class-keyed form, whose `true` keeps its structural extras * (see {@link applyPrune}). `flat` records that a `keep` was written as * one pattern list rather than keyed by class. */ export type NormalizedPruneEntry = { kind: 'global'; pattern: PackageNamePattern; } | { kind: 'remove'; member: MemberPattern[]; remove: PruneClassPatterns; } | { kind: 'keep'; member: MemberPattern[]; keep: PruneClassPatterns; flat: boolean; }; /** * Normalized form: the entry array becomes an ordered entry list, the * class-keyed map stays per class — `true` (remove all) or parsed * patterns, with an absent class left untouched. Application always goes * through {@link resolveManifestPrune} first, which reduces either form * to what applies to one concrete manifest. */ export type NormalizedPackagePrune = { form: 'entries'; entries: NormalizedPruneEntry[]; } | { form: 'classes'; classes: { [K in DependencyClass]?: true | PackageNamePattern[]; }; }; /** * Walks a `bundle.packages.prune` value, reporting every issue through * `onIssue` so that all of them surface in a single run — the config * loader turns each one into its own diagnostic. Member-scoped entry * issues are prefixed with the entry's index and class-keyed pattern * issues with the dependency class; a top-level global pattern issue * keeps its `InvalidPackageNamePatternError` class and message as-is, * since the pattern text identifies the entry. */ export declare function collectPackagePruneIssues(raw: BundlePackagesPrune | undefined, onIssue: (issue: Error) => void): void; /** * Validates and normalizes a `bundle.packages.prune` value. Returns * `undefined` when there is nothing to do — the value is absent, or every * shape it carries is empty. Throws the first issue found; the bundler * relies on that to reject a value that bypassed config validation. */ export declare function normalizePackagePrune(raw: BundlePackagesPrune | undefined): NormalizedPackagePrune | undefined; /** * The identity a manifest is matched against when resolving member-scoped * prune entries. */ export interface PruneMemberIdentity { /** * The manifest's `name`. The `Package` type declares `name: string`, * but a workspace root's manifest legitimately ships without one and * some discovery paths let that `undefined` through — such a member is * matchable solely by the `'.'` token. */ name?: string; /** Whether this is the workspace root. */ root: boolean; } /** * What a prune configuration does to one concrete manifest. In `remove` * mode each configured class holds `true` (standalone class-keyed form * only) or the combined ordered pattern list of every entry that applies * to this manifest. In `keep` mode the manifest's final dependency set is * the union of the matched `keep` selections and everything else is * removed — removals never apply to a keep-governed manifest, which is * what makes its outcome independent of entry order. */ export type ResolvedManifestPrune = { mode: 'remove'; classes: { [K in DependencyClass]?: true | PackageNamePattern[]; }; } | { mode: 'keep'; keeps: PruneClassPatterns[]; }; /** * Reduces a normalized prune to what applies to the given manifest: * global patterns and matching member-scoped `remove` selections combine * per class in listed order (so a later `!` exclusion subtracts from * earlier entries' selections), unless a `keep` entry matches the member, * in which case the keep selections govern alone. Returns `undefined` * when nothing targets the manifest. */ export declare function resolveManifestPrune(prune: NormalizedPackagePrune, member: PruneMemberIdentity): ResolvedManifestPrune | undefined; /** * Lints member-scoped prune entries. Two nets, both warnings rather than * errors because a pattern reaching nothing is legal in every other * `bundle.packages` position: a `member` selector matching no workspace * member at all (typo net), and a `keep` pattern selecting nothing in a * matched bundled member (the auto-enrollment net — a member swept in by * a wildcard later almost never declares another member's keep set, so * the gutting self-reports on the next run; a right name in the wrong * class reports the same way). The typo net is judged against the whole * discovered workspace, not the bundle: which members land in a bundle * varies per run with the check filter (`checkly test --grep`, a single * `checkly pw-test` config), and a selector for a member the current run * merely did not bundle is not a typo — that state shows up in the debug * reach log instead. The keep net runs on the bundled physical manifests * only — faux shims carry no real dependency classes — and only on ones * the caller could read, so a symlinked or unreadable manifest's own * failure warns separately. */ export declare class MemberPruneDiagnostics { #private; constructor(prune: NormalizedPackagePrune | undefined); /** * Marks the scoped entries whose member selector selects this workspace * member, bundled or not — the input of the typo net. */ observeWorkspaceMember(member: PruneMemberIdentity): void; /** * Marks the scoped entries whose member selector selects this bundled * physical manifest — the input of the debug reach log. */ observeBundledMember(member: PruneMemberIdentity): void; /** Checks matching keep selections against the manifest's contents. */ observeManifestContent(member: PruneMemberIdentity, content: string): void; /** * Logs each scoped entry's resolved member set — workspace-wide and * within this run's bundle — mirroring embed's pattern reach logging. * This is also where "the selector is fine, the member just is not in * this bundle" is visible. A separate call rather than a side effect of * {@link MemberPruneDiagnostics.warnings}: a caller that gates or drops * the warnings must not silently lose the reach log, which is the tool * for answering the very question the warnings raise. */ logMemberReach(): void; /** The accumulated lint messages, without the `Warning:` prefix. */ warnings(): string[]; } export interface PrunePackageJsonResult { content: string; /** * `class:name` labels of removed entries. Can be empty while `changed` * is true: `peerDependencies: true` on a manifest with an empty peer * section, or with only `peerDependenciesMeta`, removes no entries but * still edits the manifest. */ removed: string[]; /** Whether `content` differs from the input. */ changed: boolean; } /** * Applies a resolved per-manifest prune (see {@link resolveManifestPrune}) * to a package.json's contents. Returns the rewritten content and the * removed entries, or `undefined` when the content cannot be parsed or the * rewrite fails verification — the caller ships the original in that case. * A prune that changes nothing returns the original content with * `changed: false`, so the caller can leave the bundle entry untouched. */ export declare function prunePackageJson(content: string, resolved: ResolvedManifestPrune): PrunePackageJsonResult | undefined; /** * Asserts that a prune rewrite changed nothing but the reported entries, * by replaying the deletion on a fresh parse of the original — from the * `class:name` labels rather than the pattern matching, with each label * additionally checked against the resolved prune — so a matcher that * deleted the wrong entry, deleted from a class the prune never * configured, deleted a keep-selected entry, or strayed outside the * dependency classes fails the comparison instead of shipping. The * verification is inherently per manifest — its inputs are one manifest's * original and rewrite — so the resolved model already carries any member * scoping and the labels need no member qualifier. The structural rules * (`true` deleting a class, emptied sections and meta dropping out) are * mirrored from applyPrune rather than independently derived, so only the * per-entry path carries independent evidence; a maintainer extending the * structural rules must extend both sides. What the comparison cannot see * is a field whose value is already altered by JSON.parse itself (an * integer beyond 2^53 loses precision on both sides alike); asymmetric * serialization loss (`1e999` parses to `Infinity` but stringifies as * `null`) does fail it. The patch filtering keeps an analogous * fail-closed verifier in patched-dependencies.ts (`verifyRewrite`); * hardening either against a manifest quirk likely applies to both. */ export declare function verifyPrunedManifest(original: string, rewritten: string, resolved: ResolvedManifestPrune, removed: string[]): string | undefined;