import type { DiffArgs } from "./diff/index.js"; import type { ExpectedSchemaWithProvenance } from "./expected-schema.js"; import type { SchemaSnapshot } from "./types.js"; /** * Decides whether an object's fully-qualified name (`resolutionKey()`) is governed * by this run. Supplied by the caller as a PREDICATE so migrate-ts never carries a * second implementation of the scope-pattern grammar — `matchesScope` in * `@metaobjectsdev/sdk` is the only one, and the CLI adapts a compiled scope to * this seam. */ export type ObjectScopePredicate = (fqn: string) => boolean; export interface ScopedExpectedSchema { /** The expected schema narrowed to the governed objects. */ snapshot: SchemaSnapshot; /** * Qualified physical names (`.`) of the tables and views removed * above. Reaches `diff`'s `unmanagedNames` (MERGED with `collectUnmanagedNames`, * never replacing it) so the actual side is suppressed too — `scopedDiffInputs` * does that merge; see the module header for why omitting it inverts the feature. */ outOfScope: string[]; /** * The database schemas the UNSCOPED model declares, for `diff`'s `scopeSchemas`. * `scopedDiffInputs` threads it — see the module header: without it a scope * matching nothing hands `diff` an empty expected side, which it reads as "no * model, govern the whole database". * * `undefined` when no predicate was supplied (so `diff` derives its own set from * an untouched `expected`, exactly as before — an unscoped project's arguments are * unchanged) and also when the unscoped model declares no tables or views at all * (nothing to derive from; `diff`'s legacy whole-DB fallback is preserved). */ declaredSchemas?: string[]; } /** * Carry an out-of-scope object forward into the snapshot a run is about to commit. * * The committed snapshot is built from the metadata-expected schema, which a scoped * run has already narrowed — so accepting a scoped run DELETES every out-of-scope * entry the previous snapshot held. Widening or removing `migrate.scope` later then * proposes `CREATE TABLE` for a table that exists, and the migration fails at apply. * * `prior` is the snapshot (or introspected schema) the run diffed against, and the * entries taken from it are exactly the ones this run excluded — nothing else is * carried, so a table the model never declared is unaffected either way. An empty * `outOfScope` returns the SAME object, so an unscoped run commits a byte-identical * snapshot. */ export declare function carryForwardOutOfScope(next: SchemaSnapshot, prior: SchemaSnapshot, outOfScope: readonly string[]): SchemaSnapshot; /** * Drop the out-of-scope entries from a COMMITTED SNAPSHOT, producing the same * three-part shape `scopeExpectedSchema` produces so the result can go straight * through {@link scopedDiffInputs}. * * `verify`'s committed-snapshot gate (#292) needs this: `unmanagedNames` suppresses * only the ACTUAL side, which is right when the expected side is the metadata (it is * already scoped) and wrong here, where the expected side IS the snapshot — a * snapshot written before the scope was declared still carries the other owner's * tables, and leaving them in reports a phantom disagreement about an object this * consumer does not manage. * * `governed` is the scope decision the caller's drift comparison already made — pass * the `DriftResult` itself, which satisfies this shape. Taking `declaredSchemas` * from there rather than re-deriving it from the snapshot is what closes the last * whole-database door: a snapshot that is present but EMPTY (a never-migrated * project) declares no schemas at all, so deriving from it hands `diff` nothing and * reaches its "no model, govern the whole database" fallback — the very inversion * this module exists to prevent, at the one call site that was still re-deriving. * * An empty `outOfScope` returns the SAME snapshot object with no schema pin, so an * unscoped project's `diff` arguments are byte-for-byte what they always were. */ export declare function excludeFromSnapshot(snapshot: SchemaSnapshot, governed: GovernedScope): ScopedExpectedSchema; /** The scope decision a run made, as `DriftResult` reports it. */ export interface GovernedScope { /** Qualified physical names (`.`) the run does not govern. */ readonly outOfScope: readonly string[]; /** The schemas the run governs — `ScopedExpectedSchema.declaredSchemas`. */ readonly declaredSchemas?: readonly string[] | undefined; } /** * The three `diff` arguments a scoped run owes, as ONE value. * * The module header lists them as three separate obligations, and five call sites * re-derived them by hand — one of which had already drifted into its own guard. * Every scoped `diff` call is now * `diff({ ...scopedDiffInputs(scoped, collectUnmanagedNames(metadata)), actual, ... })`, * so the rule is enforced by the type rather than by the comment. * * `unmanaged` is the `@unmanaged`-declared set (`collectUnmanagedNames`); it is * MERGED with `outOfScope`, never replaced by it — both must reach `diff`. * `scopeSchemas` is omitted entirely when the run narrowed nothing, so an unscoped * project's arguments are unchanged. */ export declare function scopedDiffInputs(scoped: ScopedExpectedSchema, unmanaged: readonly string[]): Pick; /** * The distinct database schemas a snapshot's tables and views sit in, absent * normalized to the Postgres default — the value `diff` derives for itself when no * `scopeSchemas` is supplied. The ONE definition: any caller narrowing an expected * side must pin `diff`'s schema scope to the UNNARROWED snapshot's schemas, and a * second encoding of "absent means public" here would silently disagree with the * one inside `diff`. * * Empty in ⇒ empty out, which callers translate to "pass nothing", preserving * `diff`'s legacy whole-database fallback for a genuinely empty model. */ export declare function declaredSchemasOf(snapshot: SchemaSnapshot): string[]; /** * Narrow an expected schema to the objects inside `inScope`. * * An undefined predicate returns the input untouched — the SAME snapshot object, * not an equal copy — so a project that declares no `migrate.scope` reaches the * diff, the emitter and the committed snapshot through an unchanged value. * * A table or view with NO recorded provenance is KEPT. Scope decides on the * declaring object's FQN, and an object whose FQN is unknown was never proven to be * anyone else's; dropping it would silently un-manage it (and, worse, suppressing * its name on the actual side would hide real drift). */ export declare function scopeExpectedSchema(built: ExpectedSchemaWithProvenance, inScope: ObjectScopePredicate | undefined): ScopedExpectedSchema; //# sourceMappingURL=scope.d.ts.map