import type { ColumnNamingStrategy, MetaData } from "@metaobjectsdev/metadata"; import type { Dialect, SchemaSnapshot } from "./types.js"; import { type ExpectedViewColumnInput } from "./view-column-types.js"; export interface BuildExpectedSchemaOptions { /** * If set, normalize column SqlTypes for the target dialect so the diff * matches what introspection will see. For sqlite (and d1, which is SQLite * at the SQL level) this collapses boolean → integer{64} and * timestamp/date/time → text, since sqlite has no native boolean/timestamp * affinity and Drizzle's `integer(..., {mode:"boolean"})` / `text("ts")` * patterns produce INTEGER / TEXT in the actual DB. */ dialect?: Dialect; /** * Column-naming strategy for fields with no `@column` override. Defaults to * `"snake_case"`. Must match the runtime's `ObjectManager` strategy — a * mismatch yields a schema whose columns the runtime can't address. */ columnNamingStrategy?: ColumnNamingStrategy; /** * Expected views (projection → CREATE VIEW body), computed by the caller via * codegen-ts's `buildProjectionViews` and threaded in. migrate-ts does NOT * generate view DDL itself (it stays dependency-pure — never importing the * code generator); view SQL has a single source, `emitViewDdl` in codegen-ts. * Defaults to none. * * The caller supplies each view's output columns PHYSICALLY but untyped * (codegen-ts knows nothing of SqlType); Pass 4 resolves them against the * expected tables and computes the view's fingerprint. */ views?: readonly ExpectedViewInput[]; } /** * A view as the caller (codegen-ts `buildProjectionViews`) produces it — structurally * an `ExpectedView`. It becomes a full `ViewDescriptor` in Pass 4, which is where the * fingerprint is computed and the column types are resolved. */ export interface ExpectedViewInput { name: string; schema?: string; sql?: string; dependsOn?: readonly string[]; columns?: readonly ExpectedViewColumnInput[]; /** * `resolutionKey()` of the object that declared this view — its PROVENANCE. * Recorded in the provenance map and deliberately NEVER copied onto the * `ViewDescriptor`: descriptors are serialized into the committed snapshot, and * a descriptor that gains a field owes a `SNAPSHOT_FORMAT_VERSION` bump, which * hard-fails every older reader. Optional — a caller that supplies no FQN gets a * view with no provenance, which `scopeExpectedSchema` keeps (never guesses). */ fqn?: string; } /** * Qualified physical name (`qualifiedDbName`) → the `resolutionKey()` of the * metadata object that declared it. The ONLY sound basis for a per-command scope * decision: a SQL name cannot be reversed into an FQN (naming strategies, `@table` * overrides and TPH folding are all lossy), and a second metadata walk would have * to re-implement Pass 1's skip rules — abstract, TPH subtype, no writable source, * `@unmanaged` — and would drift from them. */ export type SchemaProvenance = ReadonlyMap; export interface ExpectedSchemaWithProvenance { snapshot: SchemaSnapshot; provenance: SchemaProvenance; } /** * The expected schema as every existing caller wants it. Thin wrapper over * {@link buildExpectedSchemaWithProvenance}; byte-identical output. */ export declare function buildExpectedSchema(root: MetaData, opts?: BuildExpectedSchemaOptions): SchemaSnapshot; /** * The expected schema PLUS the declaring FQN of every table and view in it. * * Provenance is threaded out of the passes that already hold the declaring node — * Pass 2 has each table's entity, Pass 4 each view's input — so there is exactly * one walk and one set of skip rules. Callers that filter by scope * (`scopeExpectedSchema`) consume it; callers that don't use the wrapper above. */ export declare function buildExpectedSchemaWithProvenance(root: MetaData, opts?: BuildExpectedSchemaOptions): ExpectedSchemaWithProvenance; /** The resolved `@intValueMap` as a plain record, or undefined when absent. */ export declare function intValueMapOf(field: MetaData): Record | undefined; //# sourceMappingURL=expected-schema.d.ts.map