@schemic/postgres 0.1.0-alpha.1 → 0.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -652,6 +652,9 @@ var PgTableDef = class _PgTableDef {
|
|
|
652
652
|
this.fields = fields;
|
|
653
653
|
this.config = config;
|
|
654
654
|
}
|
|
655
|
+
name;
|
|
656
|
+
fields;
|
|
657
|
+
config;
|
|
655
658
|
/** Composite / custom PRIMARY KEY (overrides the implicit `id`). */
|
|
656
659
|
primaryKey(...cols) {
|
|
657
660
|
return new _PgTableDef(this.name, this.fields, {
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/emit.ts","../src/kinds.ts","../src/lower.ts","../src/authoring.ts"],"sourcesContent":["// The POSTGRES driver — driver #2, the spike's proof the seam holds for a very different database\n// (see docs/MULTI-DB-SPIKE.md, Milestone 3). It produces/consumes the PORTABLE IR natively: `emit`\n// translates portable types to `CREATE TABLE`, `introspect` reads `information_schema` back into the\n// portable IR, and `normalize` PROJECTS the portable IR onto what Postgres can actually represent.\n//\n// The execution engine is PGlite (embedded Postgres in WASM) — a real engine, so the round-trip is\n// genuine, and it doubles as the driver's `shadow` capability (the \"embedded engine\" option the\n// design calls out for DBs that can't spin an in-process throwaway the way SurrealDB can).\n//\n// KNOWN CAPABILITY GAPS (deliberate, documented — not silent loss):\n// - `option<T>` and `T | null` BOTH collapse to a nullable column: Postgres has no column-level\n// notion of \"absent\" distinct from NULL, so `normalize` folds option -> nullable. This is the\n// portable model working as designed — a rich superset projected down per dialect.\n// - Nested objects map to a single `jsonb` column; the dotted sub-fields are folded in (dropped by\n// `normalize`), mirroring how the Surreal IR auto-creates `x.*` elements.\n// - Surreal-only constructs (events, access, db functions, relations, changefeed, permissions) have\n// no Postgres analogue and are dropped by `normalize` with no DDL emitted.\n\nimport type {\n ApplyOptions,\n ConnectionConfigBase,\n ConnectionEntry,\n ConnectionInput,\n ConnectionOverrides,\n Definable,\n Diff,\n Driver,\n MigrationDirection,\n MigrationRecord,\n MigrationStore,\n PortableField,\n PortableObject,\n PortableType,\n ResolveContext,\n ResolvedConfig,\n ScalarName,\n ShadowCapability,\n} from \"@schemic/core/driver\";\nimport {\n connectionEntry,\n nullable,\n registerDriver,\n} from \"@schemic/core/driver\";\nimport type { PgTableDef } from \"./authoring\";\nimport { escId, type PgIndexInfo, type PgTable } from \"./emit\";\nimport { registry, splitTables } from \"./kinds\";\nimport { pgLower } from \"./lower\";\n\n// The pg-native authoring surface (`s.*`, defineTable, PgField, $postgres escape hatch, …).\nexport * from \"./authoring\";\n\n// A minimal structural view of a PGlite/node-postgres connection (so core needs no hard pg dep).\nexport interface PgConn {\n query<T = Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<{ rows: T[] }>;\n exec(sql: string): Promise<unknown>;\n close(): Promise<void>;\n}\n\n// --- introspect: information_schema -> portable IR ----------------------------------------------\n\ninterface ColRow {\n table_name: string;\n column_name: string;\n data_type: string;\n udt_name: string;\n is_nullable: string;\n is_identity: string;\n identity_generation: string | null;\n character_maximum_length: number | null;\n numeric_precision: number | null;\n numeric_scale: number | null;\n}\ninterface FkRow {\n table_name: string;\n column_name: string;\n foreign_table_name: string;\n delete_rule: string;\n update_rule: string;\n}\ninterface PkRow {\n table_name: string;\n column_name: string;\n}\ninterface IdxRow {\n table_name: string;\n index_name: string;\n column_name: string;\n is_unique: boolean;\n}\n\nconst nativeT = (name: string, params?: (string | number)[]): PortableType =>\n params && params.length > 0\n ? { t: \"native\", db: \"postgres\", name, params }\n : { t: \"native\", db: \"postgres\", name };\nconst scalarT = (name: ScalarName): PortableType => ({ t: \"scalar\", name });\n\n/** information_schema data_type -> the CANONICAL portable scalar (mirrors lower's CANON, reversed). */\nconst DATATYPE_TO_SCALAR: Record<string, ScalarName> = {\n text: \"string\",\n integer: \"int\",\n \"double precision\": \"float\",\n boolean: \"bool\",\n uuid: \"uuid\",\n bytea: \"bytes\",\n interval: \"duration\",\n};\n/** data_type spellings that differ from our pg-type token (so a native node matches what lower made). */\nconst DATATYPE_TO_NATIVE: Record<string, string> = {\n \"time without time zone\": \"time\",\n \"time with time zone\": \"timetz\",\n};\n\n/** A column row -> portable type, INVERSE of lower's token->portable (canonical -> scalar, else native+params). */\nfunction introspectType(c: ColRow): PortableType {\n const dt = c.data_type;\n if (dt === \"ARRAY\") {\n // udt_name is the element type prefixed with `_` (e.g. `_int4`, `_text`).\n return { t: \"array\", elem: pgScalarFromUdt(c.udt_name.replace(/^_/, \"\")) };\n }\n if (dt === \"jsonb\") return { t: \"object\", fields: {} };\n if (dt === \"json\") return nativeT(\"json\");\n if (dt === \"character varying\")\n return c.character_maximum_length != null\n ? nativeT(\"varchar\", [c.character_maximum_length])\n : nativeT(\"varchar\");\n if (dt === \"character\")\n return c.character_maximum_length != null\n ? nativeT(\"char\", [c.character_maximum_length])\n : nativeT(\"char\");\n if (dt === \"numeric\")\n return c.numeric_precision != null\n ? nativeT(\"numeric\", [c.numeric_precision, c.numeric_scale ?? 0])\n : scalarT(\"decimal\");\n if (dt === \"timestamp without time zone\") return nativeT(\"timestamp\");\n if (dt === \"timestamp with time zone\") return scalarT(\"datetime\");\n const sc = DATATYPE_TO_SCALAR[dt];\n if (sc) return scalarT(sc);\n return nativeT(DATATYPE_TO_NATIVE[dt] ?? dt);\n}\n\n// Array element udt -> portable scalar (CANONICAL only; non-canonical elements ride as native, which\n// may not match lower's type name -> arrays of native types are a documented round-trip gap).\nconst UDT_TO_SCALAR: Record<string, ScalarName> = {\n text: \"string\",\n int4: \"int\",\n float8: \"float\",\n numeric: \"decimal\",\n bool: \"bool\",\n timestamptz: \"datetime\",\n uuid: \"uuid\",\n bytea: \"bytes\",\n interval: \"duration\",\n};\nfunction pgScalarFromUdt(udt: string): PortableType {\n const name = UDT_TO_SCALAR[udt];\n return name\n ? { t: \"scalar\", name }\n : { t: \"native\", db: \"postgres\", name: udt };\n}\n\nasync function pgIntrospect(\n conn: PgConn,\n exclude: Set<string> = new Set(),\n): Promise<PgTable[]> {\n // Also skip the companion lock table this driver creates for any excluded (bookkeeping) table.\n const skip = new Set(exclude);\n for (const t of exclude) skip.add(`${t}_lock`);\n const { rows: cols } = await conn.query<ColRow>(\n `SELECT table_name, column_name, data_type, udt_name, is_nullable,\n is_identity, identity_generation,\n character_maximum_length, numeric_precision, numeric_scale\n FROM information_schema.columns\n WHERE table_schema = 'public'\n ORDER BY table_name, ordinal_position`,\n );\n const { rows: fks } = await conn.query<FkRow>(\n `SELECT tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name,\n rc.delete_rule, rc.update_rule\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema\n JOIN information_schema.constraint_column_usage ccu\n ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema\n JOIN information_schema.referential_constraints rc\n ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.table_schema\n WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = 'public'`,\n );\n const { rows: pks } = await conn.query<PkRow>(\n `SELECT tc.table_name, kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = 'public'\n ORDER BY kcu.ordinal_position`,\n );\n // Secondary indexes this driver can author — plain btree over real columns, UNIQUE or not (the ones\n // emitted via $unique / .index([...])). Excludes the PK's implicit index, partial indexes\n // (indpred), expression indexes (indexprs), and non-btree methods (gin/gist/…), which the driver\n // can't emit — reading those back would phantom-REMOVE. `is_unique` distinguishes the two forms.\n // Required so the `index` kind ROUND-TRIPS: the registry diffs by presence, so an un-introspected\n // index phantom-adds and a non-emittable one phantom-removes.\n const { rows: idxs } = await conn.query<IdxRow>(\n `SELECT t.relname AS table_name, i.relname AS index_name, a.attname AS column_name,\n ix.indisunique AS is_unique\n FROM pg_class t\n JOIN pg_namespace n ON n.oid = t.relnamespace AND n.nspname = 'public'\n JOIN pg_index ix ON ix.indrelid = t.oid AND NOT ix.indisprimary\n AND ix.indpred IS NULL AND ix.indexprs IS NULL\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_am am ON am.oid = i.relam AND am.amname = 'btree'\n JOIN LATERAL unnest(string_to_array(ix.indkey::text, ' ')::int[])\n WITH ORDINALITY AS k(attnum, ord) ON true\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum\n WHERE t.relkind = 'r'\n ORDER BY t.relname, i.relname, k.ord`,\n );\n\n const fkBy = new Map<string, FkRow>();\n for (const f of fks) fkBy.set(`${f.table_name}.${f.column_name}`, f);\n const pkBy = new Map<string, string[]>();\n for (const p of pks) {\n const list = pkBy.get(p.table_name) ?? [];\n list.push(p.column_name);\n pkBy.set(p.table_name, list);\n }\n // The `id` column per table (to tell the IMPLICIT id apart from an overridden one).\n const idColBy = new Map<string, ColRow>();\n for (const c of cols)\n if (c.column_name === \"id\") idColBy.set(c.table_name, c);\n // The implicit key is the EXACT `id text` PK pgEmit adds (no PK authored). A lone `id` PK whose\n // column was overridden — uuid / serial (identity) / bigint / etc. — is a real authored column that\n // must round-trip, so it is NOT implicit (kept as a column + recorded as the table's primaryKey).\n const isImplicit = (table: string) => {\n const pk = pkBy.get(table);\n if (!(pk?.length === 1 && pk[0] === \"id\")) return false;\n const id = idColBy.get(table);\n return !!id && id.data_type === \"text\" && id.is_identity !== \"YES\";\n };\n\n const seen = new Set<string>();\n const byTable = new Map<string, PortableField[]>();\n for (const c of cols) {\n if (skip.has(c.table_name)) continue;\n seen.add(c.table_name);\n if (c.column_name === \"id\" && isImplicit(c.table_name)) continue;\n const fk = fkBy.get(`${c.table_name}.${c.column_name}`);\n let type: PortableType = fk\n ? { t: \"record\", tables: [fk.foreign_table_name] }\n : introspectType(c);\n if (c.is_nullable === \"YES\") type = nullable(type);\n const pf: PortableField = {\n name: c.column_name,\n table: c.table_name,\n type,\n };\n if (c.is_identity === \"YES\")\n pf.identity =\n c.identity_generation === \"ALWAYS\" ? \"always\" : \"by-default\";\n if (fk) {\n const ref: { on_delete?: string; on_update?: string } = {};\n if (fk.delete_rule && fk.delete_rule !== \"NO ACTION\")\n ref.on_delete = fk.delete_rule;\n if (fk.update_rule && fk.update_rule !== \"NO ACTION\")\n ref.on_update = fk.update_rule;\n if (ref.on_delete !== undefined || ref.on_update !== undefined)\n pf.reference = ref;\n }\n const list = byTable.get(c.table_name) ?? [];\n list.push(pf);\n byTable.set(c.table_name, list);\n }\n\n // Group index rows -> PgIndexInfo[] per table (columns in index order, dedup by index name).\n const idxBy = new Map<string, Map<string, PgIndexInfo>>();\n for (const r of idxs) {\n if (skip.has(r.table_name)) continue;\n const byName = idxBy.get(r.table_name) ?? new Map<string, PgIndexInfo>();\n const ix = byName.get(r.index_name) ?? {\n name: r.index_name,\n cols: [],\n unique: r.is_unique,\n };\n ix.cols.push(r.column_name);\n byName.set(r.index_name, ix);\n idxBy.set(r.table_name, byName);\n }\n\n return [...seen].map((name) => {\n const t: PgTable = {\n name,\n fields: byTable.get(name) ?? [],\n indexes: [...(idxBy.get(name)?.values() ?? [])],\n };\n if (!isImplicit(name)) {\n const pk = pkBy.get(name);\n if (pk && pk.length > 0) t.primaryKey = pk;\n }\n return t;\n });\n}\n\n// --- connection (PGlite, embedded) --------------------------------------------------------------\n\nasync function newPglite(dataDir?: string): Promise<PgConn> {\n const pkg: string = \"@electric-sql/pglite\"; // non-literal so it stays an optional dep.\n let PGlite: (new (dir?: string) => PgConn) | undefined;\n try {\n const mod = (await import(pkg)) as {\n PGlite?: new (dir?: string) => PgConn;\n };\n PGlite = mod.PGlite;\n } catch {\n PGlite = undefined;\n }\n if (!PGlite) {\n throw new Error(\n \"postgres driver needs `@electric-sql/pglite` (embedded) — install it, or wire a node-postgres client.\",\n );\n }\n return new PGlite(dataDir);\n}\n\nconst shadow: ShadowCapability<PgConn> = {\n // A throwaway in-memory PGlite IS the shadow: apply the DDL, read it back as kind objects, done (no\n // drop needed — the instance is discarded). This is the \"embedded engine\" canonicalization path.\n async roundTrip(_conn, _config, ddl): Promise<PortableObject[]> {\n const scratch = await newPglite();\n try {\n if (ddl.trim()) await scratch.exec(ddl);\n return splitTables(await pgIntrospect(scratch));\n } finally {\n await scratch.close();\n }\n },\n async ephemeral() {\n const conn = await newPglite();\n return { conn, stop: () => conn.close() };\n },\n};\n\n// --- pgSql: a safe tagged-template query builder (the Postgres analogue of `surql`) -------------\n\n/** A bound Postgres query: text with positional `$1..$n` placeholders + the values bound to them. */\nexport interface BoundPgQuery {\n query: string;\n params: unknown[];\n}\n\n/** A raw SQL fragment spliced VERBATIM into a `pgSql` template (NOT parameterized — caller-trusted). */\ninterface PgFragment {\n readonly __pgRaw: string;\n}\nconst isFragment = (v: unknown): v is PgFragment =>\n typeof v === \"object\" && v !== null && \"__pgRaw\" in v;\nconst isBound = (v: unknown): v is BoundPgQuery =>\n typeof v === \"object\" &&\n v !== null &&\n typeof (v as BoundPgQuery).query === \"string\" &&\n Array.isArray((v as BoundPgQuery).params);\n\n/** Splice a raw SQL string verbatim (NOT parameterized — only for caller-trusted SQL). */\nexport function raw(sql: string): PgFragment {\n return { __pgRaw: sql };\n}\n\n/** A safely double-quoted identifier (table/column) to splice into a `pgSql` template. */\nexport function identifier(name: string): PgFragment {\n return { __pgRaw: escId(name) };\n}\n\n/**\n * Tagged-template SQL builder — the Postgres analogue of SurrealDB's `surql`. Interpolated values\n * become positional bind params (`$1..$n`), so values are never string-interpolated (injection-safe).\n * Wrap a value in {@link raw} / {@link identifier} to splice SQL STRUCTURE instead of a param, and a\n * nested `pgSql` composes (its placeholders renumber, its params merge). Returns a {@link BoundPgQuery}\n * — it does NOT execute; pass it to `postgresDriver.query` / `conn.query`, or nest it in another `pgSql`.\n *\n * pgSql`SELECT * FROM ${identifier(\"user\")} WHERE id = ${id}`\n * // -> { query: 'SELECT * FROM \"user\" WHERE id = $1', params: [id] }\n */\nexport function pgSql(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): BoundPgQuery {\n let query = \"\";\n const params: unknown[] = [];\n strings.forEach((str, i) => {\n query += str;\n if (i >= values.length) return;\n const v = values[i];\n if (isFragment(v)) {\n query += v.__pgRaw;\n } else if (isBound(v)) {\n // Compose: renumber the nested query's $n by the params already collected, then merge.\n query += v.query.replace(\n /\\$(\\d+)/g,\n (_m, n) => `$${params.length + Number(n)}`,\n );\n params.push(...v.params);\n } else {\n params.push(v);\n query += `$${params.length}`;\n }\n });\n return { query, params };\n}\n\n// --- postgresConnection: the multi-connection authoring factory ---------------------------------\n\n/** Postgres connection params, on top of the dialect-neutral base ({schema, key?, migrations?}). */\nexport interface PostgresConnectionConfig extends ConnectionConfigBase {\n /**\n * Where to connect. `file:<dir>` (or a bare path) -> embedded PGlite data dir; empty/omitted ->\n * in-memory PGlite. A `postgres://` URL is reserved for a future node-postgres client.\n */\n url?: string;\n}\n\n/**\n * Typed `postgresConnection(...)` factory — the only thing a config's `connections` map accepts for\n * this driver. Wraps {@link connectionEntry} with the Postgres connection shape. Pass a static config,\n * a resolver yielding one config, or a resolver yielding a keyed COLLECTION (each entry needs `key`).\n */\nexport function postgresConnection(\n config: PostgresConnectionConfig,\n): ConnectionEntry;\nexport function postgresConnection(\n resolver: (\n ctx: ResolveContext,\n ) => PostgresConnectionConfig | Promise<PostgresConnectionConfig>,\n): ConnectionEntry;\nexport function postgresConnection(\n resolver: (\n ctx: ResolveContext,\n ) =>\n | (PostgresConnectionConfig & { key: string })[]\n | Promise<(PostgresConnectionConfig & { key: string })[]>,\n): ConnectionEntry;\nexport function postgresConnection(\n input: ConnectionInput<PostgresConnectionConfig>,\n): ConnectionEntry {\n return connectionEntry(\"postgres\", input);\n}\n\n// --- migration bookkeeping (apply-time SQL behind migrate/rollback/status) ----------------------\n\nconst MIG_UP = \"-- schemic:up\";\nconst MIG_DOWN = \"-- schemic:down\";\n\n/** Render a diff to a Postgres migration file: marker-delimited `up` and `down` DDL sections. */\nfunction renderMigration(_tag: string, diff: Diff): string {\n return `${MIG_UP}\\n${diff.up.join(\"\\n\")}\\n\\n${MIG_DOWN}\\n${diff.down.join(\"\\n\")}\\n`;\n}\n\n/** Extract the `up` or `down` DDL section from a migration file body. */\nfunction migSection(content: string, direction: MigrationDirection): string {\n const up = content.indexOf(MIG_UP);\n const down = content.indexOf(MIG_DOWN);\n if (up === -1 || down === -1) return direction === \"up\" ? content : \"\";\n return direction === \"up\"\n ? content.slice(up + MIG_UP.length, down)\n : content.slice(down + MIG_DOWN.length);\n}\n\nconst sqlStr = (v: string) => `'${v.replace(/'/g, \"''\")}'`;\nconst lockTableOf = (table: string) => `${table}_lock`;\n\nasync function ensureMigTable(conn: PgConn, table: string): Promise<void> {\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS ${escId(table)} (\n ${escId(\"tag\")} text PRIMARY KEY,\n ${escId(\"file\")} text NOT NULL,\n ${escId(\"checksum\")} text NOT NULL,\n ${escId(\"applied_at\")} timestamptz NOT NULL DEFAULT now()\n);`,\n );\n}\n\nconst recordInsert = (table: string, r: MigrationRecord) =>\n `INSERT INTO ${escId(table)} (${escId(\"tag\")}, ${escId(\"file\")}, ${escId(\"checksum\")}) VALUES (${sqlStr(r.tag)}, ${sqlStr(r.file)}, ${sqlStr(r.checksum)});`;\n\nconst migrations: MigrationStore<PgConn> = {\n extension: \".sql\",\n render: renderMigration,\n ensure: ensureMigTable,\n\n async applied(conn, table) {\n const { rows } = await conn.query<{ tag: string; checksum: string }>(\n `SELECT ${escId(\"tag\")}, ${escId(\"checksum\")} FROM ${escId(table)};`,\n );\n return new Map(rows.map((r) => [r.tag, r.checksum]));\n },\n\n // Postgres runs DDL inside a transaction, so the migration's section + its bookkeeping write commit\n // atomically — the record lands iff the DDL applied.\n async apply(conn, table, { content, direction, record }) {\n const ddl = migSection(content, direction).trim();\n const book =\n direction === \"up\"\n ? recordInsert(table, record)\n : `DELETE FROM ${escId(table)} WHERE ${escId(\"tag\")} = ${sqlStr(record.tag)};`;\n await conn.exec(`BEGIN;\\n${ddl ? `${ddl}\\n` : \"\"}${book}\\nCOMMIT;`);\n },\n\n async record(conn, table, record) {\n await ensureMigTable(conn, table);\n await conn.exec(recordInsert(table, record));\n },\n\n async clear(conn, table) {\n await conn.exec(`DELETE FROM ${escId(table)};`);\n },\n\n // A persisted lock ROW (survives across separate CLI runs on a file-based PGlite, unlike a session\n // advisory lock). The PK collision on a held lock is the \"already locked\" signal.\n async lock(conn, table) {\n const lt = lockTableOf(table);\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS ${escId(lt)} (${escId(\"id\")} int PRIMARY KEY);`,\n );\n try {\n await conn.exec(`INSERT INTO ${escId(lt)} (${escId(\"id\")}) VALUES (1);`);\n } catch {\n throw new Error(\n \"Migrations are locked — another run is in progress. If it's stale, run `schemic unlock`.\",\n );\n }\n },\n\n async unlock(conn, table) {\n const lt = lockTableOf(table);\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS ${escId(lt)} (${escId(\"id\")} int PRIMARY KEY);\\nDELETE FROM ${escId(lt)} WHERE ${escId(\"id\")} = 1;`,\n );\n },\n};\n\nexport const postgresDriver: Driver<PgConn> = {\n name: \"postgres\",\n\n // The kind registry (table/index/constraint) — core runs lower/diff/emit/order generically over it.\n registry,\n\n // Authoring (pg-native `defineTable` -> PgTableDef) -> kinded Definables: lower each table to the\n // driver's `PgTable` IR (./lower.ts), then split it into [table, ...index, ...constraint] objects\n // (./kinds.ts splitTable). Core then runs lowerSchema(registry, explode(...)). pg has no standalone\n // defs, so `defs` is unused.\n explode: (tables): Definable[] =>\n splitTables(pgLower(tables as unknown as PgTableDef[])),\n\n // One information_schema/pg_catalog read -> ALL kind objects, canonicalized identically to lowering\n // (a clean apply round-trips to a zero diff) and complete (table + index + FK), so no phantom diffs.\n introspectAll: async (conn, exclude) =>\n splitTables(await pgIntrospect(conn, exclude)),\n\n /**\n * Raw READ query for connection RESOLVERS + seed (returns rows opaquely). Postgres binds\n * POSITIONALLY, so the uniform `vars` record is mapped onto `$1..$n`: a string with NAMED `$name`\n * placeholders + `vars` is rewritten to positional `$1..$n` with `vars` bound by name (never\n * string-interpolated); native numeric `$1` is left untouched; no `vars` -> run as-is. To build a\n * query safely from interpolated values, use {@link pgSql} (positional) and run it via the raw\n * connection: `conn.query(q.query, q.params)` — that also avoids rewriting `$` inside string literals.\n */\n async query<T = unknown>(\n conn: PgConn,\n sql: string,\n vars?: Record<string, unknown>,\n ): Promise<T[]> {\n if (!vars || Object.keys(vars).length === 0) {\n return (await conn.query<T>(sql)).rows;\n }\n const params: unknown[] = [];\n const text = sql.replace(\n /\\$([A-Za-z_][A-Za-z0-9_]*)/g,\n (_m, name: string) => {\n if (!(name in vars)) {\n throw new Error(`postgres query: no binding for $${name}`);\n }\n params.push(vars[name]);\n return `$${params.length}`;\n },\n );\n return (await conn.query<T>(text, params)).rows;\n },\n\n connect(\n config: ResolvedConfig,\n _over?: ConnectionOverrides,\n ): Promise<PgConn> {\n // The neutral ResolvedConfig carries the driver-specific connection bag in `params` (our\n // PostgresConnectionConfig minus the neutral schema/migrations/key). PGlite is embedded; treat a\n // `file:`/path url as a data dir, else in-memory.\n const url = typeof config.params.url === \"string\" ? config.params.url : \"\";\n const dir = url.startsWith(\"file:\") ? url.slice(\"file:\".length) : undefined;\n return newPglite(dir);\n },\n\n async apply(\n conn: PgConn,\n statements: string[],\n opts?: ApplyOptions,\n ): Promise<void> {\n if (!statements.length) return;\n const body = statements.join(\"\\n\");\n if (opts?.transactional === false) {\n await conn.exec(body);\n return;\n }\n await conn.exec(`BEGIN;\\n${body}\\nCOMMIT;`);\n },\n\n close(conn: PgConn): Promise<void> {\n return conn.close();\n },\n\n // Apply-time migration bookkeeping (the `_migrations` table SQL behind migrate/rollback/status).\n migrations,\n\n // `schemic init --driver postgres` scaffolds a real connections-only pg project from these files\n // (the CLI adds the neutral migration snapshot).\n initScaffold: () => ({\n \"schemic.config.ts\": INIT_CONFIG_TS,\n \"database/schema/tables.ts\": INIT_SCHEMA_TS,\n \"database/seed.ts\": INIT_SEED_TS,\n \".env.example\": INIT_ENV,\n }),\n\n // `schemic new <kind> <name>` -> the starter authoring module for a new entity. pg's only\n // standalone definable is the `table`; indexes/FKs are authored INSIDE a table, so those kinds\n // throw with guidance. The CLI writes the returned text under registry.display(kind).folder.\n scaffoldEntity: (kind, name) => scaffoldPgEntity(kind, name),\n\n shadow,\n};\n\n// --- `schemic init` scaffold templates ----------------------------------------------------------\n\nconst INIT_CONFIG_TS = `import { defineConfig } from \"@schemic/core/config\";\nimport { postgresConnection } from \"@schemic/postgres\";\n\n// Connections-only config: a map of named connections, each from a driver factory. Values are\n// explicit — read env yourself (no magic env vars).\nexport default defineConfig({\n connections: {\n default: postgresConnection({\n schema: \"./database/schema\",\n // PGlite (embedded): \\`file:<dir>\\` is a persistent data dir; \"\" is in-memory. Point\n // DATABASE_URL at a real server (\\`postgres://…\\`) once the node-postgres client lands.\n url: process.env.DATABASE_URL ?? \"file:./.pgdata\",\n }),\n },\n});\n`;\n\nconst INIT_SCHEMA_TS = `import { defineTable, s, sqlExpr } from \"@schemic/postgres\";\n\nexport const user = defineTable(\"user\", {\n email: s.varchar(255).$unique(),\n name: s.text(),\n age: s.smallint().optional(),\n createdAt: s.timestamptz().$default(sqlExpr(\"now()\")),\n});\n`;\n\nconst INIT_SEED_TS = `// Seed script — run with \\`schemic seed\\`. Receives the live connection(s).\nexport default async function seed() {\n // await conn.query(\"INSERT INTO ...\");\n}\n`;\n\nconst INIT_ENV = `# A real Postgres server (uncomment to use instead of embedded PGlite):\n# DATABASE_URL=postgres://user:pass@localhost:5432/app\n`;\n\n// --- `schemic new <kind> <name>` entity scaffolding ---------------------------------------------\n\n/** A valid JS identifier from an entity name (snake_case kept; other separators -> camelCase; digit-led -> `_`). */\nfunction toIdentifier(name: string): string {\n const camel = name.replace(\n /[^a-zA-Z0-9_$]+([a-zA-Z0-9])?/g,\n (_m, c?: string) => (c ? c.toUpperCase() : \"\"),\n );\n return /^[0-9]/.test(camel) ? `_${camel}` : camel || \"entity\";\n}\n\n/** A starter `defineTable` module for a new table — full templating: commented examples of every clause. */\nfunction scaffoldTable(name: string): string {\n const ident = toIdentifier(name);\n return `import { defineTable, s, sqlExpr } from \"@schemic/postgres\";\n\n// \\`sc new table ${name}\\` scaffolded this. Author your columns, then \\`sc gen\\`.\nexport const ${ident} = defineTable(${JSON.stringify(name)}, {\n // An implicit \\`\"id\" text PRIMARY KEY\\` is added unless you declare a PK below.\n name: s.text(),\n // email: s.varchar(255).$unique(), // -> UNIQUE INDEX\n // age: s.smallint().optional(), // -> nullable column\n // status: s.text().$check(\"status in ('active', 'archived')\"), // -> CHECK constraint\n // owner: s.references(\"other_table\", { onDelete: \"cascade\" }), // -> FOREIGN KEY\n createdAt: s.timestamptz().$default(sqlExpr(\"now()\")),\n});\n// Table-level options (chain onto defineTable(...) above):\n// .primaryKey(\"a\", \"b\") composite PK (drops the implicit id)\n// .check(\"age >= 0\") table-level CHECK\n// .index([\"name\"]) secondary index (add { unique: true } for UNIQUE)\n`;\n}\n\n/**\n * Author a new entity module for `kind`. Postgres' only standalone definable is the `table`; indexes\n * and foreign keys are authored INSIDE a table (`.index([...])` / `s.references(...)`), so those kinds\n * throw with guidance rather than scaffolding a meaningless standalone file. Unknown kinds throw too.\n */\nfunction scaffoldPgEntity(kind: string, name: string): string {\n switch (kind) {\n case \"table\":\n return scaffoldTable(name);\n case \"index\":\n case \"constraint\":\n throw new Error(\n `postgres: \"${kind}\" isn't a standalone entity — indexes and foreign keys are authored inside a table (defineTable(...).index([...]) / s.references(...)). Run \\`sc new table <name>\\`.`,\n );\n default:\n throw new Error(\n `postgres: unknown entity kind \"${kind}\" — pg scaffolds: table.`,\n );\n }\n}\n\nregisterDriver(postgresDriver as Driver<unknown>);\n","// Pure Postgres DDL + type helpers — the shared emit primitives the kind engines (./kinds.ts) +\n// authoring lower (./lower.ts) + introspection (./index.ts) build on, so a table's CREATE/ALTER DDL\n// is produced by ONE set of functions (no drift). No Driver/connection state here: just IR -> pg DDL\n// string transforms. The field/type SUBSTRATE (`PortableField`/`PortableType`) is core's; the table-\n// level container is this driver's own (`PgTable`) — `PortableTable` retired at the kind-registry flip.\n\nimport type {\n PortableField,\n PortableType,\n ScalarName,\n} from \"@schemic/core/driver\";\nimport { nullable } from \"@schemic/core/driver\";\n\n/** A secondary index over one table's columns (this driver emits UNIQUE; others tracked for parity). */\nexport interface PgIndexInfo {\n name: string;\n cols: string[];\n unique: boolean;\n}\n\n/** The driver-private table shape (replaces the retired `PortableTable`): columns + PK + CHECKs + idx. */\nexport interface PgTable {\n name: string;\n fields: PortableField[];\n indexes: PgIndexInfo[];\n primaryKey?: string[];\n checks?: string[];\n}\n\n/** Just what `createTableDdl` needs (a `PgTable` is a structural superset). */\nexport type PgCreateInput = Omit<PgTable, \"indexes\">;\n\nexport const escId = (name: string) => `\"${name.replace(/\"/g, '\"\"')}\"`;\n\n// --- Type mapping (portable <-> Postgres) -------------------------------------------------------\n\nconst SCALAR_TO_PG: Partial<Record<ScalarName, string>> = {\n string: \"text\",\n int: \"integer\",\n float: \"double precision\",\n decimal: \"numeric\",\n number: \"double precision\",\n bool: \"boolean\",\n datetime: \"timestamp with time zone\",\n uuid: \"uuid\",\n bytes: \"bytea\",\n duration: \"interval\",\n};\n\n/** A portable column type and how it lands in Postgres: base SQL type, nullability, and FK target. */\nexport interface PgColumn {\n sql: string;\n nullable: boolean;\n /** A `record<table>` link -> a FK to that table (single-target only; spike scope). */\n references?: string;\n}\n\nexport function pgColumn(type: PortableType): PgColumn {\n // Peel option/nullable: Postgres represents both as a nullable column (the documented collapse).\n if (type.t === \"option\" || type.t === \"nullable\") {\n return { ...pgColumn(type.inner), nullable: true };\n }\n if (type.t === \"scalar\") {\n const sql = SCALAR_TO_PG[type.name];\n if (!sql) throw new Error(`postgres: unsupported scalar \"${type.name}\"`);\n return { sql, nullable: false };\n }\n if (type.t === \"literal\") {\n // A single literal -> its base scalar (PG has no singleton types). Enums (literal unions) below.\n const base =\n typeof type.value === \"number\"\n ? \"double precision\"\n : typeof type.value === \"boolean\"\n ? \"boolean\"\n : \"text\";\n return { sql: base, nullable: false };\n }\n if (type.t === \"union\") {\n // A union of string literals -> text (an enum-ish column; a CHECK could be added later).\n if (\n type.members.every(\n (m) => m.t === \"literal\" && typeof m.value === \"string\",\n )\n ) {\n return { sql: \"text\", nullable: false };\n }\n throw new Error(\"postgres: non-enum unions are unsupported\");\n }\n if (type.t === \"array\" || type.t === \"set\") {\n const elem = pgColumn(type.elem);\n return { sql: `${elem.sql}[]`, nullable: false };\n }\n if (type.t === \"object\") {\n return { sql: \"jsonb\", nullable: false };\n }\n if (type.t === \"record\") {\n if (type.tables.length !== 1) {\n // Multi-target links would need a polymorphic FK; out of spike scope -> plain text id.\n return { sql: \"text\", nullable: false };\n }\n return { sql: \"text\", nullable: false, references: type.tables[0] };\n }\n if (type.t === \"geometry\") {\n // Would map to PostGIS `geometry`; without the extension, store GeoJSON as jsonb.\n return { sql: \"jsonb\", nullable: false };\n }\n if (type.t === \"native\") {\n if (type.db !== \"postgres\") {\n throw new Error(\n `postgres: native type \"${type.name}\" belongs to driver \"${type.db}\"`,\n );\n }\n // params are order-significant: varchar -> (n), numeric -> (p[, s]).\n const params = type.params as (string | number)[] | undefined;\n const sql =\n params && params.length > 0\n ? `${type.name}(${params.join(\", \")})`\n : type.name;\n return { sql, nullable: false };\n }\n throw new Error(`postgres: cannot emit type ${JSON.stringify(type)}`);\n}\n\n// --- normalize: project the portable IR onto what Postgres represents ---------------------------\n\n/** Collapse option -> nullable (Postgres can't distinguish absence from NULL). Idempotent. */\nexport function pgCanonType(type: PortableType): PortableType {\n if (type.t === \"option\") return nullable(pgCanonType(type.inner));\n if (type.t === \"nullable\") return nullable(pgCanonType(type.inner));\n if (type.t === \"array\")\n return {\n t: \"array\",\n elem: pgCanonType(type.elem),\n ...(type.size !== undefined ? { size: type.size } : {}),\n };\n if (type.t === \"set\")\n return {\n t: \"set\",\n elem: pgCanonType(type.elem),\n ...(type.size !== undefined ? { size: type.size } : {}),\n };\n // A nested object becomes an opaque jsonb column -> canonical empty object (sub-keys not tracked).\n if (type.t === \"object\") return { t: \"object\", fields: {} };\n return type;\n}\n\n/** Uppercase a referential action so authored `cascade` matches introspected `CASCADE`; drop NO ACTION (default). */\nexport function normAction(a?: string): string | undefined {\n const u = a?.toUpperCase();\n return u && u !== \"NO ACTION\" ? u : undefined;\n}\n\n/**\n * A field reduced to its EQUALITY-relevant shape: canonical type + the STRUCTURAL clauses Postgres\n * round-trips (identity, FK referential actions). EXPRESSION clauses (`default`/`check`/`computed`/\n * `comment`) are dropped here: Postgres rewrites them on read (`0` -> `0`, `'x'` -> `'x'::text`,\n * `a>0` -> `(a > 0)`), so they emit faithfully but can't round-trip to an exact match — a documented\n * capability gap, not an equality difference (see docs/COVERAGE.md).\n */\nexport function canonField(f: PortableField, table: string): PortableField {\n const out: PortableField = { name: f.name, table, type: pgCanonType(f.type) };\n if (f.identity !== undefined) out.identity = f.identity;\n if (f.reference) {\n const ref: { on_delete?: string; on_update?: string } = {};\n const od = normAction(f.reference.on_delete);\n const ou = normAction(f.reference.on_update);\n if (od) ref.on_delete = od;\n if (ou) ref.on_update = ou;\n if (ref.on_delete !== undefined || ref.on_update !== undefined)\n out.reference = ref;\n }\n return out;\n}\n\n/** Fields ready for emit: drop dotted sub-fields, canonicalize the type, KEEP all DDL clauses, sort. */\nexport function pgEmitFields(t: PgCreateInput): PortableField[] {\n return t.fields\n .filter((f) => !f.name.includes(\".\"))\n .map((f) => ({ ...f, table: t.name, type: pgCanonType(f.type) }))\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\n// --- column + table DDL -------------------------------------------------------------------------\n\n/** `ON DELETE …`/`ON UPDATE …` suffix for a FK constraint (empty when no actions). */\nexport function fkActions(ref?: {\n on_delete?: string;\n on_update?: string;\n}): string {\n let s = \"\";\n if (ref?.on_delete) s += ` ON DELETE ${ref.on_delete}`;\n if (ref?.on_update) s += ` ON UPDATE ${ref.on_update}`;\n return s;\n}\n\n/** A column body for CREATE TABLE: type + NOT NULL + identity/default/generated/check clauses. */\nexport function fieldColumnDdl(f: PortableField): string {\n const col = pgColumn(f.type);\n let s = `${escId(f.name)} ${col.sql}`;\n if (!col.nullable) s += \" NOT NULL\";\n if (f.identity)\n s += ` GENERATED ${f.identity === \"always\" ? \"ALWAYS\" : \"BY DEFAULT\"} AS IDENTITY`;\n if (f.default !== undefined) s += ` DEFAULT ${f.default}`;\n if (f.computed !== undefined)\n s += ` GENERATED ALWAYS AS (${f.computed}) STORED`;\n if (f.check !== undefined) s += ` CHECK (${f.check})`;\n return s;\n}\n\n/**\n * The `CREATE TABLE (...)` statement body for a table — the implicit `id` PK (or a custom/composite\n * PRIMARY KEY), every column with its clauses, and table-level CHECKs. The single source for table\n * creation DDL, used by the `table` kind's `emit`/`canonical`.\n */\nexport function createTableDdl(t: PgCreateInput): string {\n const fields = pgEmitFields(t);\n const custom = !!(t.primaryKey && t.primaryKey.length > 0);\n const cols: string[] = [];\n if (!custom) cols.push(`${escId(\"id\")} text PRIMARY KEY`); // implicit id (mirrors Surreal).\n for (const f of fields) cols.push(fieldColumnDdl(f));\n if (custom) cols.push(`PRIMARY KEY (${t.primaryKey?.map(escId).join(\", \")})`);\n for (const c of t.checks ?? []) cols.push(`CHECK (${c})`);\n return `CREATE TABLE ${escId(t.name)} (\\n ${cols.join(\",\\n \")}\\n);`;\n}\n\n// --- column-level ALTER helpers (used by the field-level diff + the table kind's overwrite) ------\n\n/** A column definition body (`\"name\" type [NOT NULL]`) for ADD COLUMN / CREATE TABLE. */\nexport function colDef(f: PortableField): string {\n const c = pgColumn(f.type);\n return `${escId(f.name)} ${c.sql}${c.nullable ? \"\" : \" NOT NULL\"}`;\n}\nexport const fkName = (table: string, field: string) =>\n `${table}_${field}_fkey`;\nexport const addColSql = (table: string, f: PortableField) =>\n `ALTER TABLE ${escId(table)} ADD COLUMN ${colDef(f)};`;\nexport const dropColSql = (table: string, field: string) =>\n `ALTER TABLE ${escId(table)} DROP COLUMN IF EXISTS ${escId(field)};`;\nexport const dropTableSql = (table: string) =>\n `DROP TABLE IF EXISTS ${escId(table)} CASCADE;`;\n\n/** `ALTER TABLE … ADD CONSTRAINT … FOREIGN KEY …` for a single-column FK to `ref(id)`. */\nexport const addFkSql = (\n table: string,\n field: string,\n ref: string,\n actions = \"\",\n) =>\n `ALTER TABLE ${escId(table)} ADD CONSTRAINT ${escId(fkName(table, field))} FOREIGN KEY (${escId(field)}) REFERENCES ${escId(ref)} (${escId(\"id\")})${actions};`;\n\n/** Drop a FK constraint by its generated name. */\nexport const dropFkSql = (table: string, field: string) =>\n `ALTER TABLE ${escId(table)} DROP CONSTRAINT IF EXISTS ${escId(fkName(table, field))};`;\n","// The POSTGRES kind registry (core-v2). Core no longer hard-codes object kinds; each driver registers\n// its KINDS on a per-driver KindRegistry and core orchestrates generically (lowerSchema / planKinds /\n// buildKindDiff / emitKinds). See packages/core/docs/kind-registry-contract.md.\n//\n// Postgres registers THREE kinds (coarse-to-fine, registration order == ordinal):\n// table — the structured kind: columns (substrate) + PK + table CHECKs; CREATE TABLE; field-\n// level overwrite. A FK COLUMN stays a plain `text` column here; the FK CONSTRAINT is\n// its own kind (below) so the dependency graph can break mutual-FK cycles.\n// index — own kind, deps -> its table (no `owner`); CREATE [UNIQUE] INDEX.\n// constraint — own kind (FK first), deps -> [its table, the referenced table]; ALTER ADD CONSTRAINT.\n//\n// index/constraint DECLINE `owner` (opt-in clustering): without it the spine falls back to ordinal+name,\n// so the emit order is all tables -> all indexes -> all constraints (pg's rank-grouped convention),\n// not clustered per-table. Cross-table FK still emits after both tables (deps); a genuine mutual FK is\n// broken because constraints depend on tables, not each other.\n//\n// `splitTable` turns the driver's table IR (`PgTable`, from ./lower for authoring or ./index's\n// pgIntrospect for a live DB) into these kind objects. The Driver feeds it through both seams:\n// `explode = splitTables(pgLower(...))` (authoring) and `introspectAll = splitTables(pgIntrospect(...))`\n// (live), and core runs the generic spine (lowerSchema/buildKindDiff/emitKinds) over the result. Per\n// the contract, kinds are pg's own — never cross-driver.\n\nimport {\n type KindEngine,\n KindRegistry,\n type PortableObject,\n type Ref,\n} from \"@schemic/core\";\nimport type { DiffItem, PortableField } from \"@schemic/core/driver\";\nimport {\n addFkSql,\n canonField,\n createTableDdl,\n dropFkSql,\n dropTableSql,\n escId,\n fieldColumnDdl,\n fkActions,\n fkName,\n normAction,\n type PgTable,\n pgColumn,\n pgEmitFields,\n} from \"./emit\";\n\n// --- the kinds' portable objects ----------------------------------------------------------------\n\n/** The `table` kind's portable form: emit-ready columns (substrate) + composite PK + table CHECKs. */\nexport interface PgTablePortable extends PortableObject {\n kind: \"table\";\n name: string;\n fields: PortableField[];\n primaryKey?: string[];\n checks?: string[];\n}\n\n/** The `index` kind's portable form (a secondary/unique index over one table's columns). */\nexport interface PgIndexPortable extends PortableObject {\n kind: \"index\";\n name: string;\n table: string;\n cols: string[];\n unique: boolean;\n}\n\n/** The `constraint` kind's portable form (FK only for now; deps -> table + referenced table). */\nexport interface PgConstraintPortable extends PortableObject {\n kind: \"constraint\";\n name: string;\n table: string;\n ctype: \"fk\";\n column: string;\n refTable: string;\n onDelete?: string;\n onUpdate?: string;\n}\n\nconst tableRef = (name: string): Ref => ({ kind: \"table\", name });\n\n// --- table kind ---------------------------------------------------------------------------------\n\n/** Column-level `COMMENT ON COLUMN` lines for a table's commented fields (emit-only; not introspected). */\nfunction commentLines(t: PgTablePortable): string[] {\n return t.fields\n .filter((f) => f.comment !== undefined)\n .map(\n (f) =>\n `COMMENT ON COLUMN ${escId(t.name)}.${escId(f.name)} IS '${(f.comment ?? \"\").replace(/'/g, \"''\")}';`,\n );\n}\n\n/** Clauses pg cannot ALTER in place (need a drop+recreate): identity, generated, field CHECK. */\nconst hasHardClause = (f: PortableField) =>\n f.identity !== undefined || f.computed !== undefined || f.check !== undefined;\n\nconst sameArr = (a?: string[], b?: string[]) =>\n JSON.stringify(a ?? []) === JSON.stringify(b ?? []);\n\n/** Structural equality of two emit-ready fields (the table kind's change unit). */\nconst sameField = (a: PortableField, b: PortableField) =>\n JSON.stringify(a) === JSON.stringify(b);\n\nconst fieldKey = (table: string, name: string) => `field:${table}:${name}`;\nconst createInput = (t: PgTablePortable) => ({\n name: t.name,\n fields: t.fields,\n ...(t.primaryKey ? { primaryKey: t.primaryKey } : {}),\n ...(t.checks ? { checks: t.checks } : {}),\n});\n\n/**\n * Per-FIELD display items for a table change (Manuel's per-field decision): each carries its owner\n * `table` so the CLI groups them under it. `(prev,next)` diffs columns -> add/change/remove; an added\n * table `(undefined,next)` lists every column as an add (the `--full` projection); a dropped table\n * `(prev,undefined)` lists every column as a remove. A change with no column delta (a PK / table-CHECK\n * only change) falls back to a single whole-table item so it's never silently empty. DISPLAY ONLY.\n */\nfunction fieldDisplayItems(\n prev: PgTablePortable | undefined,\n next: PgTablePortable | undefined,\n): DiffItem[] {\n const table = (next ?? prev)?.name ?? \"\";\n const before = new Map((prev?.fields ?? []).map((f) => [f.name, f]));\n const after = new Map((next?.fields ?? []).map((f) => [f.name, f]));\n const items: DiffItem[] = [];\n for (const f of next?.fields ?? [])\n if (!before.has(f.name))\n items.push({\n op: \"add\",\n key: fieldKey(table, f.name),\n kind: \"field\",\n table,\n ddl: fieldColumnDdl(f),\n });\n for (const f of next?.fields ?? []) {\n const b = before.get(f.name);\n if (!b) continue;\n if (fieldColumnDdl(b) !== fieldColumnDdl(f) || b.comment !== f.comment)\n items.push({\n op: \"change\",\n key: fieldKey(table, f.name),\n kind: \"field\",\n table,\n before: fieldColumnDdl(b),\n after: fieldColumnDdl(f),\n });\n }\n for (const f of prev?.fields ?? [])\n if (!after.has(f.name))\n items.push({\n op: \"remove\",\n key: fieldKey(table, f.name),\n kind: \"field\",\n table,\n ddl: `ALTER TABLE ${escId(table)} DROP COLUMN IF EXISTS ${escId(f.name)};`,\n old: fieldColumnDdl(f),\n });\n if (items.length === 0 && prev && next)\n items.push({\n op: \"change\",\n key: `table:${table}:${table}`,\n kind: \"table\",\n table,\n before: createTableDdl(createInput(prev)),\n after: createTableDdl(createInput(next)),\n });\n return items;\n}\n\nconst tableEngine: KindEngine<PgTablePortable, PgTablePortable> = {\n // Objects arrive already in this kind's portable shape (from `explode`/`introspectAll` via splitTable\n // / lowerSchema). `lower` is the identity — the split already produced the normalized portable object.\n lower: (t) => t,\n\n // CREATE TABLE (columns + PK + table CHECKs) followed by any column COMMENTs.\n emit: (t) => [\n createTableDdl({\n name: t.name,\n fields: t.fields,\n ...(t.primaryKey ? { primaryKey: t.primaryKey } : {}),\n ...(t.checks ? { checks: t.checks } : {}),\n }),\n ...commentLines(t),\n ],\n\n // Change-detection key (NOT the emitted DDL): the equality-relevant shape only — canonField keeps\n // type/nullability/identity/FK-actions and DROPS the rewrite-prone/non-introspected clauses\n // (DEFAULT/CHECK/GENERATED/COMMENT), and table-level CHECKs are omitted too. So those clauses stay\n // faithful in `emit` (fresh apply) but never count as a change -> no phantom-diff of a freshly\n // applied schema vs introspect (PG rewrites exprs on read; comments aren't introspected). This is\n // the fixed-slot driver's emit/equal asymmetry, restored at the kind seam.\n canonical: (t) =>\n createTableDdl({\n name: t.name,\n fields: t.fields.map((f) => canonField(f, t.name)),\n ...(t.primaryKey ? { primaryKey: t.primaryKey } : {}),\n }),\n\n // Per-FIELD display items (Manuel's decision: field-level changes grouped under their table). Each\n // carries `table` so the CLI groups them hierarchically. DISPLAY ONLY — never affects up/down DDL.\n // (prev,next): diff the columns; (undefined,next): list all columns as adds (the --full projection).\n displayItems: (prev, next) => fieldDisplayItems(prev, next),\n\n remove: (t) => [dropTableSql(t.name)],\n\n // In-place column ALTERs (add/drop/type/nullability/default/comment). A structural change pg can't\n // ALTER (PK, table CHECK, or a column's identity/generated/field-CHECK) falls back to drop+recreate.\n overwrite: (prev, next) => {\n const before = new Map(prev.fields.map((f) => [f.name, f]));\n const after = new Map(next.fields.map((f) => [f.name, f]));\n\n // Hard structural deltas -> recreate (coarse, destructive — but correct; pg has no in-place form).\n const changedHard = next.fields.some((f) => {\n const b = before.get(f.name);\n return b && (hasHardClause(f) || hasHardClause(b)) && !sameField(b, f);\n });\n const addedHard = next.fields.some(\n (f) => !before.has(f.name) && hasHardClause(f),\n );\n const removedHard = prev.fields.some(\n (f) => !after.has(f.name) && hasHardClause(f),\n );\n if (\n !sameArr(prev.primaryKey, next.primaryKey) ||\n !sameArr(prev.checks, next.checks) ||\n changedHard ||\n addedHard ||\n removedHard\n ) {\n return [...tableEngine.remove(prev), ...tableEngine.emit(next)];\n }\n\n const out: string[] = [];\n const t = next.name;\n // added columns (full column DDL — plain columns match the fixed-slot ADD COLUMN byte-for-byte)\n for (const f of next.fields)\n if (!before.has(f.name))\n out.push(`ALTER TABLE ${escId(t)} ADD COLUMN ${fieldColumnDdl(f)};`);\n // changed columns: type, nullability, default, comment\n for (const f of next.fields) {\n const b = before.get(f.name);\n if (!b) continue;\n const ca = pgColumn(f.type);\n const cb = pgColumn(b.type);\n if (ca.sql !== cb.sql)\n out.push(\n `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} TYPE ${ca.sql};`,\n );\n if (ca.nullable !== cb.nullable)\n out.push(\n `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} ${ca.nullable ? \"DROP NOT NULL\" : \"SET NOT NULL\"};`,\n );\n if (f.default !== b.default)\n out.push(\n f.default === undefined\n ? `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} DROP DEFAULT;`\n : `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} SET DEFAULT ${f.default};`,\n );\n if (f.comment !== b.comment)\n out.push(\n f.comment === undefined\n ? `COMMENT ON COLUMN ${escId(t)}.${escId(f.name)} IS NULL;`\n : `COMMENT ON COLUMN ${escId(t)}.${escId(f.name)} IS '${f.comment.replace(/'/g, \"''\")}';`,\n );\n }\n // dropped columns\n for (const f of prev.fields)\n if (!after.has(f.name))\n out.push(\n `ALTER TABLE ${escId(t)} DROP COLUMN IF EXISTS ${escId(f.name)};`,\n );\n return out;\n },\n};\n\n// --- index kind ---------------------------------------------------------------------------------\n\nconst indexEngine: KindEngine<PgIndexPortable, PgIndexPortable> = {\n lower: (i) => i,\n emit: (i) => [\n `CREATE ${i.unique ? \"UNIQUE \" : \"\"}INDEX ${escId(i.name)} ON ${escId(i.table)} (${i.cols.map(escId).join(\", \")});`,\n ],\n remove: (i) => [`DROP INDEX IF EXISTS ${escId(i.name)};`],\n // An index emits AFTER its table (deps), but NO `owner` -> no clustering: the spine then falls back\n // to ordinal+name, so all indexes emit as a rank group after all tables (pg's emit convention),\n // rather than clustered next to each table. owner is opt-in readability we deliberately decline.\n deps: (i) => [tableRef(i.table)],\n // no overwrite: an index change is a drop+recreate (the spine's default).\n};\n\n// --- constraint kind (FK) -----------------------------------------------------------------------\n\nconst constraintEngine: KindEngine<PgConstraintPortable, PgConstraintPortable> =\n {\n lower: (c) => c,\n emit: (c) => [\n addFkSql(\n c.table,\n c.column,\n c.refTable,\n fkActions({ on_delete: c.onDelete, on_update: c.onUpdate }),\n ),\n ],\n remove: (c) => [dropFkSql(c.table, c.column)],\n // A FK emits AFTER both its own table and the referenced table — this is what breaks mutual-FK\n // cycles (tables have no deps, so they create first, then the constraints between them). NO\n // `owner`: like the index kind, constraints emit as a rank group after all tables (pg convention).\n deps: (c) =>\n c.refTable === c.table\n ? [tableRef(c.table)]\n : [tableRef(c.table), tableRef(c.refTable)],\n // no overwrite: a FK change is drop+recreate (the spine's default).\n };\n\n// --- the registry -------------------------------------------------------------------------------\n\nexport const registry = new KindRegistry();\nregistry.define({\n name: \"table\",\n build: (t: PgTablePortable) => t,\n ...tableEngine,\n});\nregistry.define({\n name: \"index\",\n build: (i: PgIndexPortable) => i,\n ...indexEngine,\n});\nregistry.define({\n name: \"constraint\",\n build: (c: PgConstraintPortable) => c,\n ...constraintEngine,\n});\n\n// --- splitTable: the driver's table IR -> the registry's kind objects ----------------------------\n\n/**\n * Split one `PgTable` (from `lowerTable` for authoring, or `pgIntrospect` for a live DB) into the\n * registry's portable objects: the `table` (columns substrate + PK + table CHECKs, with FK columns kept\n * as plain `text` columns) plus its `index` and `constraint` (FK) objects. The single seam both\n * `explode` (authoring) and `introspectAll` (live) go through, so a clean apply round-trips to a zero\n * diff. Replaces the old PortableDb<->objects facade adapter.\n */\nexport function splitTable(t: PgTable): PortableObject[] {\n const out: PortableObject[] = [];\n const fields = pgEmitFields(t);\n const table: PgTablePortable = {\n kind: \"table\",\n name: t.name,\n fields,\n ...(t.primaryKey && t.primaryKey.length > 0\n ? { primaryKey: t.primaryKey }\n : {}),\n ...(t.checks && t.checks.length > 0 ? { checks: t.checks } : {}),\n };\n out.push(table);\n\n for (const ix of t.indexes) {\n const index: PgIndexPortable = {\n kind: \"index\",\n name: ix.name,\n table: t.name,\n cols: ix.cols,\n unique: ix.unique,\n };\n out.push(index);\n }\n\n for (const f of fields) {\n const ref = pgColumn(f.type).references;\n if (!ref) continue;\n const onDelete = normAction(f.reference?.on_delete);\n const onUpdate = normAction(f.reference?.on_update);\n const fk: PgConstraintPortable = {\n kind: \"constraint\",\n name: fkName(t.name, f.name),\n table: t.name,\n ctype: \"fk\",\n column: f.name,\n refTable: ref,\n ...(onDelete ? { onDelete } : {}),\n ...(onUpdate ? { onUpdate } : {}),\n };\n out.push(fk);\n }\n return out;\n}\n\n/** Split many `PgTable`s into the flat kind-object list (the `explode`/`introspectAll` shape). */\nexport const splitTables = (tables: PgTable[]): PortableObject[] =>\n tables.flatMap(splitTable);\n","// lower: the pg `s.*` authoring objects (./authoring.ts) -> the driver's table IR (`PgTable`). The\n// driver's `explode` then splits each PgTable into kind objects (table/index/constraint); `emit` turns\n// those into pg DDL and `introspectAll` reads DDL back into the same kind objects, so author -> lower\n// -> explode -> emit -> introspect -> diff round-trips. Field TYPE comes from the Zod schema's\n// structural wrappers (optional/nullable/array) combined with the PgMeta pg-type token; DDL clauses\n// (default/check/generated/identity/comment/reference) ride PgMeta into the field's clause slots.\n\nimport type {\n PortableField,\n PortableType,\n ScalarName,\n} from \"@schemic/core/driver\";\nimport type { PgField, PgMeta, PgTableDef } from \"./authoring\";\nimport type { PgIndexInfo, PgTable } from \"./emit\";\n\n/** Minimal view of a Zod schema's internal def (zod v4) — enough to peel structural wrappers. */\ninterface ZodDef {\n type: string;\n innerType?: { _zod: { def: ZodDef } };\n element?: { _zod: { def: ZodDef } };\n}\nconst defOf = (schema: { _zod: { def: ZodDef } }): ZodDef => schema._zod.def;\n\n/** Canonical pg types that map to a PORTABLE scalar (so they port cross-dialect). Others -> native. */\nconst CANON: Record<string, ScalarName> = {\n text: \"string\",\n integer: \"int\",\n \"double precision\": \"float\",\n numeric: \"decimal\",\n boolean: \"bool\",\n timestamptz: \"datetime\",\n uuid: \"uuid\",\n bytea: \"bytes\",\n interval: \"duration\",\n};\n\n/** A pg type token (+ params) -> portable leaf type: canonical -> scalar, parameterized/other -> native. */\nfunction tokenToPortable(\n type: string,\n params?: (string | number)[],\n): PortableType {\n if (type === \"jsonb\") return { t: \"object\", fields: {} };\n if (params && params.length > 0)\n return { t: \"native\", db: \"postgres\", name: type, params };\n const scalar = CANON[type];\n return scalar\n ? { t: \"scalar\", name: scalar }\n : { t: \"native\", db: \"postgres\", name: type };\n}\n\n/** Peel the Zod structural wrappers (optional/nullable/array; default/prefault/catch/readonly are transparent). */\nfunction structure(schema: PgField[\"schema\"]): {\n wrappers: (\"option\" | \"nullable\" | \"array\")[];\n leaf: { _zod: { def: ZodDef } };\n} {\n const wrappers: (\"option\" | \"nullable\" | \"array\")[] = [];\n let cur: { _zod: { def: ZodDef } } = schema;\n for (;;) {\n const def = defOf(cur);\n if (def.type === \"optional\" && def.innerType) {\n wrappers.push(\"option\");\n cur = def.innerType;\n } else if (def.type === \"nullable\" && def.innerType) {\n wrappers.push(\"nullable\");\n cur = def.innerType;\n } else if (def.type === \"array\" && def.element) {\n wrappers.push(\"array\");\n cur = def.element;\n } else if (\n (def.type === \"default\" ||\n def.type === \"prefault\" ||\n def.type === \"catch\" ||\n def.type === \"readonly\") &&\n def.innerType\n ) {\n cur = def.innerType; // App-land wrappers, transparent to the column type\n } else {\n break;\n }\n }\n return { wrappers, leaf: cur };\n}\n\n/** The leaf portable type from the field's pg metadata (FK -> record; else the pg-type token). */\nfunction leafPortable(meta: PgMeta): PortableType {\n if (meta.references) return { t: \"record\", tables: [meta.references.table] };\n if (!meta.pg) return { t: \"scalar\", name: \"string\" };\n return tokenToPortable(meta.pg.type, meta.pg.params);\n}\n\n/** Combine the structural wrappers (outermost-first) around the leaf type. */\nfunction portableType(\n meta: PgMeta,\n wrappers: (\"option\" | \"nullable\" | \"array\")[],\n): PortableType {\n let type = leafPortable(meta);\n for (let i = wrappers.length - 1; i >= 0; i--) {\n const w = wrappers[i];\n type =\n w === \"array\"\n ? { t: \"array\", elem: type }\n : w === \"option\"\n ? { t: \"option\", inner: type }\n : { t: \"nullable\", inner: type };\n }\n return type;\n}\n\n/** One pg field -> a portable field, carrying its DDL clauses into the IR's clause slots. */\nfunction lowerField(\n name: string,\n table: string,\n field: PgField,\n): PortableField {\n const meta = field.native;\n const { wrappers } = structure(field.schema);\n const pf: PortableField = {\n name,\n table,\n type: portableType(meta, wrappers),\n };\n if (meta.default !== undefined) pf.default = meta.default;\n if (meta.check !== undefined) pf.check = meta.check;\n if (meta.generated !== undefined) pf.computed = meta.generated;\n if (meta.identity !== undefined) pf.identity = meta.identity;\n if (meta.comment !== undefined) pf.comment = meta.comment;\n if (meta.references) {\n const ref: { on_delete?: string; on_update?: string } = {};\n if (meta.references.onDelete) ref.on_delete = meta.references.onDelete;\n if (meta.references.onUpdate) ref.on_update = meta.references.onUpdate;\n if (ref.on_delete !== undefined || ref.on_update !== undefined)\n pf.reference = ref;\n }\n return pf;\n}\n\n/** One pg table definition -> the driver's table IR (fields + composite PK + table CHECKs + indexes). */\nexport function lowerTable(def: PgTableDef): PgTable {\n const fields: PortableField[] = [];\n const indexes: PgIndexInfo[] = [];\n const pkCols: string[] = [...(def.config.primaryKey ?? [])];\n\n for (const [name, field] of Object.entries(def.fields)) {\n fields.push(lowerField(name, def.name, field));\n if (field.native.unique)\n indexes.push({\n name: `${def.name}_${name}_key`,\n cols: [name],\n unique: true,\n });\n if (field.native.primaryKey && !pkCols.includes(name)) pkCols.push(name);\n }\n for (const ix of def.config.indexes ?? []) {\n indexes.push({\n name: ix.name ?? `${def.name}_${ix.cols.join(\"_\")}_idx`,\n cols: ix.cols,\n unique: !!ix.unique,\n });\n }\n\n const table: PgTable = { name: def.name, fields, indexes };\n if (pkCols.length > 0) table.primaryKey = pkCols;\n if (def.config.checks && def.config.checks.length > 0)\n table.checks = def.config.checks;\n return table;\n}\n\n/** Lower the authored pg tables (+ standalone defs — none in the pg surface yet) to the table IR. */\nexport function pgLower(tables: PgTableDef[]): PgTable[] {\n return tables.map(lowerTable);\n}\n","// The POSTGRES native authoring surface — `s.*` in pg vocabulary, built on the neutral core base\n// (@schemic/core/authoring). A pg project authors with THESE types (pg lingo: text/varchar/numeric/\n// timestamptz/jsonb/serial/...) and the driver lowers them to the portable IR (see ./lower.ts), then\n// emits pg DDL. Per the multi-DB decision (every driver owns its own `s.*`), this mirrors\n// @schemic/surrealdb's surface but in Postgres terms.\n//\n// Design constraints (Manuel):\n// - LAYER ON ZOD: every field IS a Zod schema (`PgField extends SFieldBase`); pg-native metadata\n// rides the field's opaque `native` slot (PgMeta), never patching Zod internals.\n// - ESCAPE HATCH: `s.$postgres(pgType, codec)` for any type not representable on the wire — a Zod\n// codec (encode/decode) App-side, stored as the given pg type (mirrors surreal's `$surreal`).\n// - DX FIRST: native types + `$`-methods ($default/$check/$generated/$identity/$unique/$primaryKey/\n// $references/$comment) + the full Zod wrapper/passthrough chain, all type-preserving.\n\nimport {\n type AnyField,\n type SchemaOf,\n SFieldBase,\n toZod,\n} from \"@schemic/core/authoring\";\nimport * as z from \"zod\";\n\n// --- PgMeta: the pg-native metadata bag carried on every field ----------------------------------\n\n/** A pg column type token + optional params (`varchar`/[255], `numeric`/[10,2]); the leaf factory sets it. */\nexport interface PgTypeRef {\n type: string;\n params?: (string | number)[];\n}\n\n/** Postgres-native field metadata (the `native` slot of {@link PgField}). All optional; merged by `$`-methods. */\nexport interface PgMeta {\n /** The pg base type (sans option/nullable/array wrappers, which live on the Zod schema). */\n pg?: PgTypeRef;\n /** `DEFAULT <expr>` (verbatim SQL). */\n default?: string;\n /** Field-level `CHECK (<expr>)` (verbatim SQL boolean expr). */\n check?: string;\n /** `GENERATED ALWAYS AS (<expr>) STORED` (verbatim SQL expr). */\n generated?: string;\n /** `GENERATED {ALWAYS|BY DEFAULT} AS IDENTITY` (also how `serial` is modeled). */\n identity?: \"always\" | \"by-default\";\n /** Column-level `UNIQUE`. */\n unique?: boolean;\n /** Column is (part of) the PRIMARY KEY. */\n primaryKey?: boolean;\n /** A foreign key to `table(id)` with optional referential actions. */\n references?: { table: string; onDelete?: string; onUpdate?: string };\n /** `COMMENT ON COLUMN`. */\n comment?: string;\n}\n\nconst blankMeta = (): PgMeta => ({});\n\n/** A raw SQL expression marker for DDL clauses (`$default`/`$check`/`$generated`) — spliced verbatim. */\nexport interface SqlExpr {\n readonly __sql: string;\n}\n/** Mark a string as a raw SQL expression (vs a literal value) for a DDL clause: `s.timestamptz().$default(sqlExpr(\"now()\"))`. */\nexport const sqlExpr = (sql: string): SqlExpr => ({ __sql: sql });\nconst isSqlExpr = (v: unknown): v is SqlExpr =>\n typeof v === \"object\" && v !== null && \"__sql\" in v;\n\n/** Render a JS literal as a Postgres literal (numbers/bools bare, strings single-quoted, null -> NULL). */\nfunction pgLiteral(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"number\") return String(v);\n if (typeof v === \"boolean\") return v ? \"true\" : \"false\";\n return `'${v.replace(/'/g, \"''\")}'`;\n}\nconst toExpr = (v: string | number | boolean | null | SqlExpr): string =>\n isSqlExpr(v) ? v.__sql : pgLiteral(v);\n\n// --- PgField: the dialect subclass -------------------------------------------------------------\n\n/**\n * A Postgres field: a Zod schema (App/Wire typing) + {@link PgMeta} (pg-native DDL metadata). Extends\n * the neutral {@link SFieldBase}, which supplies the codecs, the Zod wrappers, and the `z.*` passthrough;\n * this subclass re-types the wrappers so a chain stays a `PgField`, and adds the pg `$`-methods.\n */\nexport class PgField<\n S extends z.ZodType = z.ZodType,\n Flags extends string = never,\n> extends SFieldBase<S, Flags, PgMeta> {\n protected rebuild<S2 extends z.ZodType, F2 extends string>(\n schema: S2,\n native: PgMeta,\n ): PgField<S2, F2> {\n return new PgField<S2, F2>(schema, native);\n }\n protected blank(): PgMeta {\n return blankMeta();\n }\n\n // Type-only narrowing of the inherited portable wrappers (runtime impl is the base's, which builds a\n // PgField via rebuild) — so a mixed chain like `s.text().$default(\"x\").optional()` stays a PgField.\n declare optional: () => PgField<z.ZodOptional<S>, Flags>;\n declare nullable: () => PgField<z.ZodNullable<S>, Flags>;\n declare nullish: () => PgField<z.ZodOptional<z.ZodNullable<S>>, Flags>;\n declare array: () => PgField<z.ZodArray<S>, Flags>;\n declare default: (value: z.input<S>) => PgField<z.ZodDefault<S>, Flags>;\n declare prefault: (value: z.input<S>) => PgField<z.ZodPrefault<S>, Flags>;\n declare catch: (value: z.output<S>) => PgField<z.ZodCatch<S>, Flags>;\n\n private with(meta: Partial<PgMeta>): PgField<S, Flags> {\n return new PgField<S, Flags>(this.schema, { ...this.native, ...meta });\n }\n\n // --- pg-native `$`-methods (DDL authoring) ---\n /** `DEFAULT <value>` — a JS literal, or `sqlExpr(\"now()\")` for a raw SQL default. */\n $default(value: z.input<S> | SqlExpr): PgField<S, Flags> {\n return this.with({ default: toExpr(value as never) });\n }\n /** Field-level `CHECK (<expr>)`. */\n $check(expr: string | SqlExpr): PgField<S, Flags> {\n return this.with({ check: isSqlExpr(expr) ? expr.__sql : expr });\n }\n /** `GENERATED ALWAYS AS (<expr>) STORED` — a computed column. */\n $generated(expr: string | SqlExpr): PgField<S, Flags> {\n return this.with({ generated: isSqlExpr(expr) ? expr.__sql : expr });\n }\n /** `GENERATED {ALWAYS|BY DEFAULT} AS IDENTITY` (auto-increment). */\n $identity(mode: \"always\" | \"by-default\" = \"by-default\"): PgField<S, Flags> {\n return this.with({ identity: mode });\n }\n /** Column-level `UNIQUE`. */\n $unique(): PgField<S, Flags> {\n return this.with({ unique: true });\n }\n /** Mark this column (part of) the PRIMARY KEY. */\n $primaryKey(): PgField<S, Flags> {\n return this.with({ primaryKey: true });\n }\n /** Foreign key to `table(id)` with optional `ON DELETE`/`ON UPDATE` actions. */\n $references(\n table: string,\n opts?: { onDelete?: string; onUpdate?: string },\n ): PgField<S, Flags> {\n return this.with({ references: { table, ...(opts ?? {}) } });\n }\n /** `COMMENT ON COLUMN`. */\n $comment(text: string): PgField<S, Flags> {\n return this.with({ comment: text });\n }\n\n /**\n * ESCAPE HATCH (chainable form) — teach the driver how to STORE this field's value in Postgres:\n * give the **wire type** as an `s.*`/Zod field (its pg column type is taken from it) plus a codec\n * (`encode`: app -> wire, `decode`: wire -> app). This turns an otherwise-unmappable App value\n * (e.g. `s.instanceof(Money)`) into a real pg column. Omit the codec for an identity mapping (the\n * app value is stored as-is). Mirrors SurrealDB's `.$surreal(wire, codec)`; the standalone\n * {@link s.$postgres} factory is the from-scratch equivalent. `$`-prefixed to avoid clashing with Zod.\n */\n $postgres<WF extends AnyField | z.ZodType, A = z.output<S>>(\n wire: WF,\n codec?: {\n encode: (app: A) => z.output<SchemaOf<WF>>;\n decode: (wire: z.output<SchemaOf<WF>>) => A;\n },\n ): PgField<z.ZodCodec<SchemaOf<WF>, S>, Flags> {\n const wireSchema = toZod(wire) as SchemaOf<WF>;\n const c = z.codec(wireSchema, this.schema, {\n decode: (w) => (codec ? codec.decode(w as never) : w) as never,\n encode: (a) => (codec ? codec.encode(a as A) : a) as never,\n });\n // The stored pg type comes from the WIRE field (its column type); App typing comes from `this`.\n const wirePg = wire instanceof PgField ? wire.native.pg : undefined;\n return new PgField<z.ZodCodec<SchemaOf<WF>, S>, Flags>(c, {\n ...this.native,\n ...(wirePg ? { pg: wirePg } : {}),\n });\n }\n}\n\n// --- the `s` vocabulary (pg lingo) -------------------------------------------------------------\n\nconst mk = (\n type: string,\n schema: z.ZodType,\n params?: (string | number)[],\n): PgField => new PgField(schema, { pg: params ? { type, params } : { type } });\n\n/** The Postgres authoring namespace. Zod drop-ins (string/number/…) + native pg types + `$postgres`. */\nexport const s = {\n // Zod drop-ins (the canonical superset; each maps to a sensible pg default). Native aliases below\n // (text/varchar/int/numeric/…) give precise control.\n string: () => mk(\"text\", z.string()),\n number: () => mk(\"double precision\", z.number()),\n // text\n text: () => mk(\"text\", z.string()),\n varchar: (n?: number) =>\n n === undefined\n ? mk(\"varchar\", z.string())\n : mk(\"varchar\", z.string().max(n), [n]),\n char: (n?: number) =>\n n === undefined ? mk(\"char\", z.string()) : mk(\"char\", z.string(), [n]),\n citext: () => mk(\"citext\", z.string()),\n // numeric\n smallint: () => mk(\"smallint\", z.int().gte(-32768).lte(32767)),\n integer: () => mk(\"integer\", z.int()),\n int: () => mk(\"integer\", z.int()),\n bigint: () => mk(\"bigint\", z.int()),\n serial: () => mk(\"integer\", z.int()).$identity(\"by-default\"),\n bigserial: () => mk(\"bigint\", z.int()).$identity(\"by-default\"),\n numeric: (precision?: number, scale?: number) =>\n precision === undefined\n ? mk(\"numeric\", z.number())\n : // Postgres stores `numeric(p)` as `numeric(p,0)`; keep scale explicit so it round-trips.\n mk(\"numeric\", z.number(), [precision, scale ?? 0]),\n decimal: (precision?: number, scale?: number) => s.numeric(precision, scale),\n real: () => mk(\"real\", z.number()),\n doublePrecision: () => mk(\"double precision\", z.number()),\n float: () => mk(\"double precision\", z.number()),\n money: () => mk(\"money\", z.string()),\n // boolean\n boolean: () => mk(\"boolean\", z.boolean()),\n bool: () => mk(\"boolean\", z.boolean()),\n // temporal\n timestamptz: () => mk(\"timestamptz\", z.date()),\n timestamp: () => mk(\"timestamp\", z.date()),\n date: () => mk(\"date\", z.date()),\n time: () => mk(\"time\", z.string()),\n timetz: () => mk(\"timetz\", z.string()),\n interval: () => mk(\"interval\", z.string()),\n // identity / network / uuid / bytes\n uuid: () => mk(\"uuid\", z.uuid()),\n bytea: () => mk(\"bytea\", z.instanceof(Uint8Array)),\n inet: () => mk(\"inet\", z.string()),\n cidr: () => mk(\"cidr\", z.string()),\n macaddr: () => mk(\"macaddr\", z.string()),\n // json\n jsonb: <T extends z.ZodType = z.ZodUnknown>(shape?: T) =>\n mk(\"jsonb\", shape ?? z.unknown()),\n json: <T extends z.ZodType = z.ZodUnknown>(shape?: T) =>\n mk(\"json\", shape ?? z.unknown()),\n // enum (string-literal union -> text) and single literal\n enum: <const T extends readonly [string, ...string[]]>(values: T) =>\n mk(\"text\", z.enum(values)),\n literal: <const V extends string | number | boolean>(value: V) =>\n mk(\n typeof value === \"number\"\n ? \"double precision\"\n : typeof value === \"boolean\"\n ? \"boolean\"\n : \"text\",\n z.literal(value),\n ),\n // object -> jsonb (opaque on disk). Accepts field OR raw-Zod values (a Zod drop-in superset).\n object: (shape: Record<string, AnyField | z.ZodType>) =>\n mk(\n \"jsonb\",\n z.object(\n Object.fromEntries(\n Object.entries(shape).map(([k, v]) => [k, toZod(v)]),\n ),\n ),\n ),\n // array(elem) -> `<elem>[]`; carries the element's pg metadata so it lowers to an array of that type.\n array: (elem: AnyField | z.ZodType): PgField =>\n new PgField(\n z.array(toZod(elem)),\n elem instanceof PgField ? elem.native : {},\n ),\n // foreign key: `text` column + FK to `table(id)`\n references: (\n table: string,\n opts?: { onDelete?: string; onUpdate?: string },\n ): PgField =>\n new PgField(z.string(), {\n pg: { type: \"text\" },\n references: { table, ...(opts ?? {}) },\n }),\n /**\n * ESCAPE HATCH — a pg type with no portable meaning, stored via a Zod codec (encode/decode). The\n * column is emitted as `pgType`; App-side reads/writes go through `codec`. Mirrors surreal `$surreal`.\n */\n $postgres: <C extends z.ZodType>(pgType: string, codec: C): PgField<C> =>\n new PgField<C>(codec, { pg: { type: pgType } }),\n};\n\n// --- defineTable: a pg table builder producing an `Authored` object -----------------------------\n\n/** Table-level pg config: composite PK, table CHECKs, and secondary indexes. */\nexport interface PgTableConfig {\n primaryKey?: string[];\n checks?: string[];\n indexes?: { name?: string; cols: string[]; unique?: boolean }[];\n}\n\n/**\n * A Postgres table definition — the `Authored` object the driver's `lower` reads. Structurally a\n * `{ name }` (the neutral `Authored` bound); also carries its `fields` (a `{ col: PgField }` map) and\n * table-level config. Chainable: `.primaryKey(...)`, `.check(expr)`, `.index([...])`.\n */\nexport class PgTableDef<\n Name extends string = string,\n F extends Record<string, PgField> = Record<string, PgField>,\n> {\n constructor(\n readonly name: Name,\n readonly fields: F,\n readonly config: PgTableConfig = {},\n ) {}\n\n /** Composite / custom PRIMARY KEY (overrides the implicit `id`). */\n primaryKey(...cols: (keyof F & string)[]): PgTableDef<Name, F> {\n return new PgTableDef(this.name, this.fields, {\n ...this.config,\n primaryKey: cols,\n });\n }\n /** A table-level `CHECK (<expr>)`. */\n check(expr: string): PgTableDef<Name, F> {\n return new PgTableDef(this.name, this.fields, {\n ...this.config,\n checks: [...(this.config.checks ?? []), expr],\n });\n }\n /** A secondary index over `cols` (optionally `UNIQUE`). */\n index(\n cols: (keyof F & string)[],\n opts?: { name?: string; unique?: boolean },\n ): PgTableDef<Name, F> {\n return new PgTableDef(this.name, this.fields, {\n ...this.config,\n indexes: [...(this.config.indexes ?? []), { cols, ...(opts ?? {}) }],\n });\n }\n\n /**\n * A foreign-key field referencing THIS table (for use in another table's shape):\n * `author: user.record({ onDelete: \"cascade\" })`. Also satisfies the CLI's structural table check.\n */\n record(opts?: { onDelete?: string; onUpdate?: string }): PgField {\n return s.references(this.name, opts);\n }\n}\n\n/** Declare a Postgres table: `export const user = defineTable(\"user\", { name: s.text(), age: s.integer().optional() })`. */\nexport function defineTable<\n Name extends string,\n F extends Record<string, PgField>,\n>(name: Name, fields: F, config?: PgTableConfig): PgTableDef<Name, F> {\n return new PgTableDef(name, fields, config ?? {});\n}\n\n// --- App/Wire type inference (DX) --------------------------------------------------------------\n\n/** The decoded (App-land) row type of a table — `z.output` of each field's schema. */\nexport type App<T extends PgTableDef> = {\n [K in keyof T[\"fields\"]]: z.output<T[\"fields\"][K][\"schema\"]>;\n};\n/** The encoded (wire) row type of a table — `z.input` of each field's schema. */\nexport type Wire<T extends PgTableDef> = {\n [K in keyof T[\"fields\"]]: z.input<T[\"fields\"][K][\"schema\"]>;\n};\n"],"mappings":"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","names":["nullable","s","codec","nullable"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/emit.ts","../src/kinds.ts","../src/lower.ts","../src/authoring.ts"],"sourcesContent":["// The POSTGRES driver — driver #2, the spike's proof the seam holds for a very different database\n// (see docs/MULTI-DB-SPIKE.md, Milestone 3). It produces/consumes the PORTABLE IR natively: `emit`\n// translates portable types to `CREATE TABLE`, `introspect` reads `information_schema` back into the\n// portable IR, and `normalize` PROJECTS the portable IR onto what Postgres can actually represent.\n//\n// The execution engine is PGlite (embedded Postgres in WASM) — a real engine, so the round-trip is\n// genuine, and it doubles as the driver's `shadow` capability (the \"embedded engine\" option the\n// design calls out for DBs that can't spin an in-process throwaway the way SurrealDB can).\n//\n// KNOWN CAPABILITY GAPS (deliberate, documented — not silent loss):\n// - `option<T>` and `T | null` BOTH collapse to a nullable column: Postgres has no column-level\n// notion of \"absent\" distinct from NULL, so `normalize` folds option -> nullable. This is the\n// portable model working as designed — a rich superset projected down per dialect.\n// - Nested objects map to a single `jsonb` column; the dotted sub-fields are folded in (dropped by\n// `normalize`), mirroring how the Surreal IR auto-creates `x.*` elements.\n// - Surreal-only constructs (events, access, db functions, relations, changefeed, permissions) have\n// no Postgres analogue and are dropped by `normalize` with no DDL emitted.\n\nimport type {\n ApplyOptions,\n ConnectionConfigBase,\n ConnectionEntry,\n ConnectionInput,\n ConnectionOverrides,\n Definable,\n Diff,\n Driver,\n MigrationDirection,\n MigrationRecord,\n MigrationStore,\n PortableField,\n PortableObject,\n PortableType,\n ResolveContext,\n ResolvedConfig,\n ScalarName,\n ShadowCapability,\n} from \"@schemic/core/driver\";\nimport {\n connectionEntry,\n nullable,\n registerDriver,\n} from \"@schemic/core/driver\";\nimport type { PgTableDef } from \"./authoring\";\nimport { escId, type PgIndexInfo, type PgTable } from \"./emit\";\nimport { registry, splitTables } from \"./kinds\";\nimport { pgLower } from \"./lower\";\n\n// The pg-native authoring surface (`s.*`, defineTable, PgField, $postgres escape hatch, …).\nexport * from \"./authoring\";\n\n// A minimal structural view of a PGlite/node-postgres connection (so core needs no hard pg dep).\nexport interface PgConn {\n query<T = Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<{ rows: T[] }>;\n exec(sql: string): Promise<unknown>;\n close(): Promise<void>;\n}\n\n// --- introspect: information_schema -> portable IR ----------------------------------------------\n\ninterface ColRow {\n table_name: string;\n column_name: string;\n data_type: string;\n udt_name: string;\n is_nullable: string;\n is_identity: string;\n identity_generation: string | null;\n character_maximum_length: number | null;\n numeric_precision: number | null;\n numeric_scale: number | null;\n}\ninterface FkRow {\n table_name: string;\n column_name: string;\n foreign_table_name: string;\n delete_rule: string;\n update_rule: string;\n}\ninterface PkRow {\n table_name: string;\n column_name: string;\n}\ninterface IdxRow {\n table_name: string;\n index_name: string;\n column_name: string;\n is_unique: boolean;\n}\n\nconst nativeT = (name: string, params?: (string | number)[]): PortableType =>\n params && params.length > 0\n ? { t: \"native\", db: \"postgres\", name, params }\n : { t: \"native\", db: \"postgres\", name };\nconst scalarT = (name: ScalarName): PortableType => ({ t: \"scalar\", name });\n\n/** information_schema data_type -> the CANONICAL portable scalar (mirrors lower's CANON, reversed). */\nconst DATATYPE_TO_SCALAR: Record<string, ScalarName> = {\n text: \"string\",\n integer: \"int\",\n \"double precision\": \"float\",\n boolean: \"bool\",\n uuid: \"uuid\",\n bytea: \"bytes\",\n interval: \"duration\",\n};\n/** data_type spellings that differ from our pg-type token (so a native node matches what lower made). */\nconst DATATYPE_TO_NATIVE: Record<string, string> = {\n \"time without time zone\": \"time\",\n \"time with time zone\": \"timetz\",\n};\n\n/** A column row -> portable type, INVERSE of lower's token->portable (canonical -> scalar, else native+params). */\nfunction introspectType(c: ColRow): PortableType {\n const dt = c.data_type;\n if (dt === \"ARRAY\") {\n // udt_name is the element type prefixed with `_` (e.g. `_int4`, `_text`).\n return { t: \"array\", elem: pgScalarFromUdt(c.udt_name.replace(/^_/, \"\")) };\n }\n if (dt === \"jsonb\") return { t: \"object\", fields: {} };\n if (dt === \"json\") return nativeT(\"json\");\n if (dt === \"character varying\")\n return c.character_maximum_length != null\n ? nativeT(\"varchar\", [c.character_maximum_length])\n : nativeT(\"varchar\");\n if (dt === \"character\")\n return c.character_maximum_length != null\n ? nativeT(\"char\", [c.character_maximum_length])\n : nativeT(\"char\");\n if (dt === \"numeric\")\n return c.numeric_precision != null\n ? nativeT(\"numeric\", [c.numeric_precision, c.numeric_scale ?? 0])\n : scalarT(\"decimal\");\n if (dt === \"timestamp without time zone\") return nativeT(\"timestamp\");\n if (dt === \"timestamp with time zone\") return scalarT(\"datetime\");\n const sc = DATATYPE_TO_SCALAR[dt];\n if (sc) return scalarT(sc);\n return nativeT(DATATYPE_TO_NATIVE[dt] ?? dt);\n}\n\n// Array element udt -> portable scalar (CANONICAL only; non-canonical elements ride as native, which\n// may not match lower's type name -> arrays of native types are a documented round-trip gap).\nconst UDT_TO_SCALAR: Record<string, ScalarName> = {\n text: \"string\",\n int4: \"int\",\n float8: \"float\",\n numeric: \"decimal\",\n bool: \"bool\",\n timestamptz: \"datetime\",\n uuid: \"uuid\",\n bytea: \"bytes\",\n interval: \"duration\",\n};\nfunction pgScalarFromUdt(udt: string): PortableType {\n const name = UDT_TO_SCALAR[udt];\n return name\n ? { t: \"scalar\", name }\n : { t: \"native\", db: \"postgres\", name: udt };\n}\n\nasync function pgIntrospect(\n conn: PgConn,\n exclude: Set<string> = new Set(),\n): Promise<PgTable[]> {\n // Also skip the companion lock table this driver creates for any excluded (bookkeeping) table.\n const skip = new Set(exclude);\n for (const t of exclude) skip.add(`${t}_lock`);\n const { rows: cols } = await conn.query<ColRow>(\n `SELECT table_name, column_name, data_type, udt_name, is_nullable,\n is_identity, identity_generation,\n character_maximum_length, numeric_precision, numeric_scale\n FROM information_schema.columns\n WHERE table_schema = 'public'\n ORDER BY table_name, ordinal_position`,\n );\n const { rows: fks } = await conn.query<FkRow>(\n `SELECT tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name,\n rc.delete_rule, rc.update_rule\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema\n JOIN information_schema.constraint_column_usage ccu\n ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema\n JOIN information_schema.referential_constraints rc\n ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.table_schema\n WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = 'public'`,\n );\n const { rows: pks } = await conn.query<PkRow>(\n `SELECT tc.table_name, kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = 'public'\n ORDER BY kcu.ordinal_position`,\n );\n // Secondary indexes this driver can author — plain btree over real columns, UNIQUE or not (the ones\n // emitted via $unique / .index([...])). Excludes the PK's implicit index, partial indexes\n // (indpred), expression indexes (indexprs), and non-btree methods (gin/gist/…), which the driver\n // can't emit — reading those back would phantom-REMOVE. `is_unique` distinguishes the two forms.\n // Required so the `index` kind ROUND-TRIPS: the registry diffs by presence, so an un-introspected\n // index phantom-adds and a non-emittable one phantom-removes.\n const { rows: idxs } = await conn.query<IdxRow>(\n `SELECT t.relname AS table_name, i.relname AS index_name, a.attname AS column_name,\n ix.indisunique AS is_unique\n FROM pg_class t\n JOIN pg_namespace n ON n.oid = t.relnamespace AND n.nspname = 'public'\n JOIN pg_index ix ON ix.indrelid = t.oid AND NOT ix.indisprimary\n AND ix.indpred IS NULL AND ix.indexprs IS NULL\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_am am ON am.oid = i.relam AND am.amname = 'btree'\n JOIN LATERAL unnest(string_to_array(ix.indkey::text, ' ')::int[])\n WITH ORDINALITY AS k(attnum, ord) ON true\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum\n WHERE t.relkind = 'r'\n ORDER BY t.relname, i.relname, k.ord`,\n );\n\n const fkBy = new Map<string, FkRow>();\n for (const f of fks) fkBy.set(`${f.table_name}.${f.column_name}`, f);\n const pkBy = new Map<string, string[]>();\n for (const p of pks) {\n const list = pkBy.get(p.table_name) ?? [];\n list.push(p.column_name);\n pkBy.set(p.table_name, list);\n }\n // The `id` column per table (to tell the IMPLICIT id apart from an overridden one).\n const idColBy = new Map<string, ColRow>();\n for (const c of cols)\n if (c.column_name === \"id\") idColBy.set(c.table_name, c);\n // The implicit key is the EXACT `id text` PK pgEmit adds (no PK authored). A lone `id` PK whose\n // column was overridden — uuid / serial (identity) / bigint / etc. — is a real authored column that\n // must round-trip, so it is NOT implicit (kept as a column + recorded as the table's primaryKey).\n const isImplicit = (table: string) => {\n const pk = pkBy.get(table);\n if (!(pk?.length === 1 && pk[0] === \"id\")) return false;\n const id = idColBy.get(table);\n return !!id && id.data_type === \"text\" && id.is_identity !== \"YES\";\n };\n\n const seen = new Set<string>();\n const byTable = new Map<string, PortableField[]>();\n for (const c of cols) {\n if (skip.has(c.table_name)) continue;\n seen.add(c.table_name);\n if (c.column_name === \"id\" && isImplicit(c.table_name)) continue;\n const fk = fkBy.get(`${c.table_name}.${c.column_name}`);\n let type: PortableType = fk\n ? { t: \"record\", tables: [fk.foreign_table_name] }\n : introspectType(c);\n if (c.is_nullable === \"YES\") type = nullable(type);\n const pf: PortableField = {\n name: c.column_name,\n table: c.table_name,\n type,\n };\n if (c.is_identity === \"YES\")\n pf.identity =\n c.identity_generation === \"ALWAYS\" ? \"always\" : \"by-default\";\n if (fk) {\n const ref: { on_delete?: string; on_update?: string } = {};\n if (fk.delete_rule && fk.delete_rule !== \"NO ACTION\")\n ref.on_delete = fk.delete_rule;\n if (fk.update_rule && fk.update_rule !== \"NO ACTION\")\n ref.on_update = fk.update_rule;\n if (ref.on_delete !== undefined || ref.on_update !== undefined)\n pf.reference = ref;\n }\n const list = byTable.get(c.table_name) ?? [];\n list.push(pf);\n byTable.set(c.table_name, list);\n }\n\n // Group index rows -> PgIndexInfo[] per table (columns in index order, dedup by index name).\n const idxBy = new Map<string, Map<string, PgIndexInfo>>();\n for (const r of idxs) {\n if (skip.has(r.table_name)) continue;\n const byName = idxBy.get(r.table_name) ?? new Map<string, PgIndexInfo>();\n const ix = byName.get(r.index_name) ?? {\n name: r.index_name,\n cols: [],\n unique: r.is_unique,\n };\n ix.cols.push(r.column_name);\n byName.set(r.index_name, ix);\n idxBy.set(r.table_name, byName);\n }\n\n return [...seen].map((name) => {\n const t: PgTable = {\n name,\n fields: byTable.get(name) ?? [],\n indexes: [...(idxBy.get(name)?.values() ?? [])],\n };\n if (!isImplicit(name)) {\n const pk = pkBy.get(name);\n if (pk && pk.length > 0) t.primaryKey = pk;\n }\n return t;\n });\n}\n\n// --- connection (PGlite, embedded) --------------------------------------------------------------\n\nasync function newPglite(dataDir?: string): Promise<PgConn> {\n const pkg: string = \"@electric-sql/pglite\"; // non-literal so it stays an optional dep.\n let PGlite: (new (dir?: string) => PgConn) | undefined;\n try {\n const mod = (await import(pkg)) as {\n PGlite?: new (dir?: string) => PgConn;\n };\n PGlite = mod.PGlite;\n } catch {\n PGlite = undefined;\n }\n if (!PGlite) {\n throw new Error(\n \"postgres driver needs `@electric-sql/pglite` (embedded) — install it, or wire a node-postgres client.\",\n );\n }\n return new PGlite(dataDir);\n}\n\nconst shadow: ShadowCapability<PgConn> = {\n // A throwaway in-memory PGlite IS the shadow: apply the DDL, read it back as kind objects, done (no\n // drop needed — the instance is discarded). This is the \"embedded engine\" canonicalization path.\n async roundTrip(_conn, _config, ddl): Promise<PortableObject[]> {\n const scratch = await newPglite();\n try {\n if (ddl.trim()) await scratch.exec(ddl);\n return splitTables(await pgIntrospect(scratch));\n } finally {\n await scratch.close();\n }\n },\n async ephemeral() {\n const conn = await newPglite();\n return { conn, stop: () => conn.close() };\n },\n};\n\n// --- pgSql: a safe tagged-template query builder (the Postgres analogue of `surql`) -------------\n\n/** A bound Postgres query: text with positional `$1..$n` placeholders + the values bound to them. */\nexport interface BoundPgQuery {\n query: string;\n params: unknown[];\n}\n\n/** A raw SQL fragment spliced VERBATIM into a `pgSql` template (NOT parameterized — caller-trusted). */\ninterface PgFragment {\n readonly __pgRaw: string;\n}\nconst isFragment = (v: unknown): v is PgFragment =>\n typeof v === \"object\" && v !== null && \"__pgRaw\" in v;\nconst isBound = (v: unknown): v is BoundPgQuery =>\n typeof v === \"object\" &&\n v !== null &&\n typeof (v as BoundPgQuery).query === \"string\" &&\n Array.isArray((v as BoundPgQuery).params);\n\n/** Splice a raw SQL string verbatim (NOT parameterized — only for caller-trusted SQL). */\nexport function raw(sql: string): PgFragment {\n return { __pgRaw: sql };\n}\n\n/** A safely double-quoted identifier (table/column) to splice into a `pgSql` template. */\nexport function identifier(name: string): PgFragment {\n return { __pgRaw: escId(name) };\n}\n\n/**\n * Tagged-template SQL builder — the Postgres analogue of SurrealDB's `surql`. Interpolated values\n * become positional bind params (`$1..$n`), so values are never string-interpolated (injection-safe).\n * Wrap a value in {@link raw} / {@link identifier} to splice SQL STRUCTURE instead of a param, and a\n * nested `pgSql` composes (its placeholders renumber, its params merge). Returns a {@link BoundPgQuery}\n * — it does NOT execute; pass it to `postgresDriver.query` / `conn.query`, or nest it in another `pgSql`.\n *\n * pgSql`SELECT * FROM ${identifier(\"user\")} WHERE id = ${id}`\n * // -> { query: 'SELECT * FROM \"user\" WHERE id = $1', params: [id] }\n */\nexport function pgSql(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): BoundPgQuery {\n let query = \"\";\n const params: unknown[] = [];\n strings.forEach((str, i) => {\n query += str;\n if (i >= values.length) return;\n const v = values[i];\n if (isFragment(v)) {\n query += v.__pgRaw;\n } else if (isBound(v)) {\n // Compose: renumber the nested query's $n by the params already collected, then merge.\n query += v.query.replace(\n /\\$(\\d+)/g,\n (_m, n) => `$${params.length + Number(n)}`,\n );\n params.push(...v.params);\n } else {\n params.push(v);\n query += `$${params.length}`;\n }\n });\n return { query, params };\n}\n\n// --- postgresConnection: the multi-connection authoring factory ---------------------------------\n\n/** Postgres connection params, on top of the dialect-neutral base ({schema, key?, migrations?}). */\nexport interface PostgresConnectionConfig extends ConnectionConfigBase {\n /**\n * Where to connect. `file:<dir>` (or a bare path) -> embedded PGlite data dir; empty/omitted ->\n * in-memory PGlite. A `postgres://` URL is reserved for a future node-postgres client.\n */\n url?: string;\n}\n\n/**\n * Typed `postgresConnection(...)` factory — the only thing a config's `connections` map accepts for\n * this driver. Wraps {@link connectionEntry} with the Postgres connection shape. Pass a static config,\n * a resolver yielding one config, or a resolver yielding a keyed COLLECTION (each entry needs `key`).\n */\nexport function postgresConnection(\n config: PostgresConnectionConfig,\n): ConnectionEntry;\nexport function postgresConnection(\n resolver: (\n ctx: ResolveContext,\n ) => PostgresConnectionConfig | Promise<PostgresConnectionConfig>,\n): ConnectionEntry;\nexport function postgresConnection(\n resolver: (\n ctx: ResolveContext,\n ) =>\n | (PostgresConnectionConfig & { key: string })[]\n | Promise<(PostgresConnectionConfig & { key: string })[]>,\n): ConnectionEntry;\nexport function postgresConnection(\n input: ConnectionInput<PostgresConnectionConfig>,\n): ConnectionEntry {\n return connectionEntry(\"postgres\", input);\n}\n\n// --- migration bookkeeping (apply-time SQL behind migrate/rollback/status) ----------------------\n\nconst MIG_UP = \"-- schemic:up\";\nconst MIG_DOWN = \"-- schemic:down\";\n\n/** Render a diff to a Postgres migration file: marker-delimited `up` and `down` DDL sections. */\nfunction renderMigration(_tag: string, diff: Diff): string {\n return `${MIG_UP}\\n${diff.up.join(\"\\n\")}\\n\\n${MIG_DOWN}\\n${diff.down.join(\"\\n\")}\\n`;\n}\n\n/** Extract the `up` or `down` DDL section from a migration file body. */\nfunction migSection(content: string, direction: MigrationDirection): string {\n const up = content.indexOf(MIG_UP);\n const down = content.indexOf(MIG_DOWN);\n if (up === -1 || down === -1) return direction === \"up\" ? content : \"\";\n return direction === \"up\"\n ? content.slice(up + MIG_UP.length, down)\n : content.slice(down + MIG_DOWN.length);\n}\n\nconst sqlStr = (v: string) => `'${v.replace(/'/g, \"''\")}'`;\nconst lockTableOf = (table: string) => `${table}_lock`;\n\nasync function ensureMigTable(conn: PgConn, table: string): Promise<void> {\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS ${escId(table)} (\n ${escId(\"tag\")} text PRIMARY KEY,\n ${escId(\"file\")} text NOT NULL,\n ${escId(\"checksum\")} text NOT NULL,\n ${escId(\"applied_at\")} timestamptz NOT NULL DEFAULT now()\n);`,\n );\n}\n\nconst recordInsert = (table: string, r: MigrationRecord) =>\n `INSERT INTO ${escId(table)} (${escId(\"tag\")}, ${escId(\"file\")}, ${escId(\"checksum\")}) VALUES (${sqlStr(r.tag)}, ${sqlStr(r.file)}, ${sqlStr(r.checksum)});`;\n\nconst migrations: MigrationStore<PgConn> = {\n extension: \".sql\",\n render: renderMigration,\n ensure: ensureMigTable,\n\n async applied(conn, table) {\n const { rows } = await conn.query<{ tag: string; checksum: string }>(\n `SELECT ${escId(\"tag\")}, ${escId(\"checksum\")} FROM ${escId(table)};`,\n );\n return new Map(rows.map((r) => [r.tag, r.checksum]));\n },\n\n // Postgres runs DDL inside a transaction, so the migration's section + its bookkeeping write commit\n // atomically — the record lands iff the DDL applied.\n async apply(conn, table, { content, direction, record }) {\n const ddl = migSection(content, direction).trim();\n const book =\n direction === \"up\"\n ? recordInsert(table, record)\n : `DELETE FROM ${escId(table)} WHERE ${escId(\"tag\")} = ${sqlStr(record.tag)};`;\n await conn.exec(`BEGIN;\\n${ddl ? `${ddl}\\n` : \"\"}${book}\\nCOMMIT;`);\n },\n\n async record(conn, table, record) {\n await ensureMigTable(conn, table);\n await conn.exec(recordInsert(table, record));\n },\n\n async clear(conn, table) {\n await conn.exec(`DELETE FROM ${escId(table)};`);\n },\n\n // A persisted lock ROW (survives across separate CLI runs on a file-based PGlite, unlike a session\n // advisory lock). The PK collision on a held lock is the \"already locked\" signal.\n async lock(conn, table) {\n const lt = lockTableOf(table);\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS ${escId(lt)} (${escId(\"id\")} int PRIMARY KEY);`,\n );\n try {\n await conn.exec(`INSERT INTO ${escId(lt)} (${escId(\"id\")}) VALUES (1);`);\n } catch {\n throw new Error(\n \"Migrations are locked — another run is in progress. If it's stale, run `schemic unlock`.\",\n );\n }\n },\n\n async unlock(conn, table) {\n const lt = lockTableOf(table);\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS ${escId(lt)} (${escId(\"id\")} int PRIMARY KEY);\\nDELETE FROM ${escId(lt)} WHERE ${escId(\"id\")} = 1;`,\n );\n },\n};\n\nexport const postgresDriver: Driver<PgConn> = {\n name: \"postgres\",\n\n // The kind registry (table/index/constraint) — core runs lower/diff/emit/order generically over it.\n registry,\n\n // Authoring (pg-native `defineTable` -> PgTableDef) -> kinded Definables: lower each table to the\n // driver's `PgTable` IR (./lower.ts), then split it into [table, ...index, ...constraint] objects\n // (./kinds.ts splitTable). Core then runs lowerSchema(registry, explode(...)). pg has no standalone\n // defs, so `defs` is unused.\n explode: (tables): Definable[] =>\n splitTables(pgLower(tables as unknown as PgTableDef[])),\n\n // One information_schema/pg_catalog read -> ALL kind objects, canonicalized identically to lowering\n // (a clean apply round-trips to a zero diff) and complete (table + index + FK), so no phantom diffs.\n introspectAll: async (conn, exclude) =>\n splitTables(await pgIntrospect(conn, exclude)),\n\n /**\n * Raw READ query for connection RESOLVERS + seed (returns rows opaquely). Postgres binds\n * POSITIONALLY, so the uniform `vars` record is mapped onto `$1..$n`: a string with NAMED `$name`\n * placeholders + `vars` is rewritten to positional `$1..$n` with `vars` bound by name (never\n * string-interpolated); native numeric `$1` is left untouched; no `vars` -> run as-is. To build a\n * query safely from interpolated values, use {@link pgSql} (positional) and run it via the raw\n * connection: `conn.query(q.query, q.params)` — that also avoids rewriting `$` inside string literals.\n */\n async query<T = unknown>(\n conn: PgConn,\n sql: string,\n vars?: Record<string, unknown>,\n ): Promise<T[]> {\n if (!vars || Object.keys(vars).length === 0) {\n return (await conn.query<T>(sql)).rows;\n }\n const params: unknown[] = [];\n const text = sql.replace(\n /\\$([A-Za-z_][A-Za-z0-9_]*)/g,\n (_m, name: string) => {\n if (!(name in vars)) {\n throw new Error(`postgres query: no binding for $${name}`);\n }\n params.push(vars[name]);\n return `$${params.length}`;\n },\n );\n return (await conn.query<T>(text, params)).rows;\n },\n\n connect(\n config: ResolvedConfig,\n _over?: ConnectionOverrides,\n ): Promise<PgConn> {\n // The neutral ResolvedConfig carries the driver-specific connection bag in `params` (our\n // PostgresConnectionConfig minus the neutral schema/migrations/key). PGlite is embedded; treat a\n // `file:`/path url as a data dir, else in-memory.\n const url = typeof config.params.url === \"string\" ? config.params.url : \"\";\n const dir = url.startsWith(\"file:\") ? url.slice(\"file:\".length) : undefined;\n return newPglite(dir);\n },\n\n async apply(\n conn: PgConn,\n statements: string[],\n opts?: ApplyOptions,\n ): Promise<void> {\n if (!statements.length) return;\n const body = statements.join(\"\\n\");\n if (opts?.transactional === false) {\n await conn.exec(body);\n return;\n }\n await conn.exec(`BEGIN;\\n${body}\\nCOMMIT;`);\n },\n\n close(conn: PgConn): Promise<void> {\n return conn.close();\n },\n\n // Apply-time migration bookkeeping (the `_migrations` table SQL behind migrate/rollback/status).\n migrations,\n\n // `schemic init --driver postgres` scaffolds a real connections-only pg project from these files\n // (the CLI adds the neutral migration snapshot).\n initScaffold: () => ({\n \"schemic.config.ts\": INIT_CONFIG_TS,\n \"database/schema/tables.ts\": INIT_SCHEMA_TS,\n \"database/seed.ts\": INIT_SEED_TS,\n \".env.example\": INIT_ENV,\n }),\n\n // `schemic new <kind> <name>` -> the starter authoring module for a new entity. pg's only\n // standalone definable is the `table`; indexes/FKs are authored INSIDE a table, so those kinds\n // throw with guidance. The CLI writes the returned text under registry.display(kind).folder.\n scaffoldEntity: (kind, name) => scaffoldPgEntity(kind, name),\n\n shadow,\n};\n\n// --- `schemic init` scaffold templates ----------------------------------------------------------\n\nconst INIT_CONFIG_TS = `import { defineConfig } from \"@schemic/core/config\";\nimport { postgresConnection } from \"@schemic/postgres\";\n\n// Connections-only config: a map of named connections, each from a driver factory. Values are\n// explicit — read env yourself (no magic env vars).\nexport default defineConfig({\n connections: {\n default: postgresConnection({\n schema: \"./database/schema\",\n // PGlite (embedded): \\`file:<dir>\\` is a persistent data dir; \"\" is in-memory. Point\n // DATABASE_URL at a real server (\\`postgres://…\\`) once the node-postgres client lands.\n url: process.env.DATABASE_URL ?? \"file:./.pgdata\",\n }),\n },\n});\n`;\n\nconst INIT_SCHEMA_TS = `import { defineTable, s, sqlExpr } from \"@schemic/postgres\";\n\nexport const user = defineTable(\"user\", {\n email: s.varchar(255).$unique(),\n name: s.text(),\n age: s.smallint().optional(),\n createdAt: s.timestamptz().$default(sqlExpr(\"now()\")),\n});\n`;\n\nconst INIT_SEED_TS = `// Seed script — run with \\`schemic seed\\`. Receives the live connection(s).\nexport default async function seed() {\n // await conn.query(\"INSERT INTO ...\");\n}\n`;\n\nconst INIT_ENV = `# A real Postgres server (uncomment to use instead of embedded PGlite):\n# DATABASE_URL=postgres://user:pass@localhost:5432/app\n`;\n\n// --- `schemic new <kind> <name>` entity scaffolding ---------------------------------------------\n\n/** A valid JS identifier from an entity name (snake_case kept; other separators -> camelCase; digit-led -> `_`). */\nfunction toIdentifier(name: string): string {\n const camel = name.replace(\n /[^a-zA-Z0-9_$]+([a-zA-Z0-9])?/g,\n (_m, c?: string) => (c ? c.toUpperCase() : \"\"),\n );\n return /^[0-9]/.test(camel) ? `_${camel}` : camel || \"entity\";\n}\n\n/** A starter `defineTable` module for a new table — full templating: commented examples of every clause. */\nfunction scaffoldTable(name: string): string {\n const ident = toIdentifier(name);\n return `import { defineTable, s, sqlExpr } from \"@schemic/postgres\";\n\n// \\`sc new table ${name}\\` scaffolded this. Author your columns, then \\`sc gen\\`.\nexport const ${ident} = defineTable(${JSON.stringify(name)}, {\n // An implicit \\`\"id\" text PRIMARY KEY\\` is added unless you declare a PK below.\n name: s.text(),\n // email: s.varchar(255).$unique(), // -> UNIQUE INDEX\n // age: s.smallint().optional(), // -> nullable column\n // status: s.text().$check(\"status in ('active', 'archived')\"), // -> CHECK constraint\n // owner: s.references(\"other_table\", { onDelete: \"cascade\" }), // -> FOREIGN KEY\n createdAt: s.timestamptz().$default(sqlExpr(\"now()\")),\n});\n// Table-level options (chain onto defineTable(...) above):\n// .primaryKey(\"a\", \"b\") composite PK (drops the implicit id)\n// .check(\"age >= 0\") table-level CHECK\n// .index([\"name\"]) secondary index (add { unique: true } for UNIQUE)\n`;\n}\n\n/**\n * Author a new entity module for `kind`. Postgres' only standalone definable is the `table`; indexes\n * and foreign keys are authored INSIDE a table (`.index([...])` / `s.references(...)`), so those kinds\n * throw with guidance rather than scaffolding a meaningless standalone file. Unknown kinds throw too.\n */\nfunction scaffoldPgEntity(kind: string, name: string): string {\n switch (kind) {\n case \"table\":\n return scaffoldTable(name);\n case \"index\":\n case \"constraint\":\n throw new Error(\n `postgres: \"${kind}\" isn't a standalone entity — indexes and foreign keys are authored inside a table (defineTable(...).index([...]) / s.references(...)). Run \\`sc new table <name>\\`.`,\n );\n default:\n throw new Error(\n `postgres: unknown entity kind \"${kind}\" — pg scaffolds: table.`,\n );\n }\n}\n\nregisterDriver(postgresDriver as Driver<unknown>);\n","// Pure Postgres DDL + type helpers — the shared emit primitives the kind engines (./kinds.ts) +\n// authoring lower (./lower.ts) + introspection (./index.ts) build on, so a table's CREATE/ALTER DDL\n// is produced by ONE set of functions (no drift). No Driver/connection state here: just IR -> pg DDL\n// string transforms. The field/type SUBSTRATE (`PortableField`/`PortableType`) is core's; the table-\n// level container is this driver's own (`PgTable`) — `PortableTable` retired at the kind-registry flip.\n\nimport type {\n PortableField,\n PortableType,\n ScalarName,\n} from \"@schemic/core/driver\";\nimport { nullable } from \"@schemic/core/driver\";\n\n/** A secondary index over one table's columns (this driver emits UNIQUE; others tracked for parity). */\nexport interface PgIndexInfo {\n name: string;\n cols: string[];\n unique: boolean;\n}\n\n/** The driver-private table shape (replaces the retired `PortableTable`): columns + PK + CHECKs + idx. */\nexport interface PgTable {\n name: string;\n fields: PortableField[];\n indexes: PgIndexInfo[];\n primaryKey?: string[];\n checks?: string[];\n}\n\n/** Just what `createTableDdl` needs (a `PgTable` is a structural superset). */\nexport type PgCreateInput = Omit<PgTable, \"indexes\">;\n\nexport const escId = (name: string) => `\"${name.replace(/\"/g, '\"\"')}\"`;\n\n// --- Type mapping (portable <-> Postgres) -------------------------------------------------------\n\nconst SCALAR_TO_PG: Partial<Record<ScalarName, string>> = {\n string: \"text\",\n int: \"integer\",\n float: \"double precision\",\n decimal: \"numeric\",\n number: \"double precision\",\n bool: \"boolean\",\n datetime: \"timestamp with time zone\",\n uuid: \"uuid\",\n bytes: \"bytea\",\n duration: \"interval\",\n};\n\n/** A portable column type and how it lands in Postgres: base SQL type, nullability, and FK target. */\nexport interface PgColumn {\n sql: string;\n nullable: boolean;\n /** A `record<table>` link -> a FK to that table (single-target only; spike scope). */\n references?: string;\n}\n\nexport function pgColumn(type: PortableType): PgColumn {\n // Peel option/nullable: Postgres represents both as a nullable column (the documented collapse).\n if (type.t === \"option\" || type.t === \"nullable\") {\n return { ...pgColumn(type.inner), nullable: true };\n }\n if (type.t === \"scalar\") {\n const sql = SCALAR_TO_PG[type.name];\n if (!sql) throw new Error(`postgres: unsupported scalar \"${type.name}\"`);\n return { sql, nullable: false };\n }\n if (type.t === \"literal\") {\n // A single literal -> its base scalar (PG has no singleton types). Enums (literal unions) below.\n const base =\n typeof type.value === \"number\"\n ? \"double precision\"\n : typeof type.value === \"boolean\"\n ? \"boolean\"\n : \"text\";\n return { sql: base, nullable: false };\n }\n if (type.t === \"union\") {\n // A union of string literals -> text (an enum-ish column; a CHECK could be added later).\n if (\n type.members.every(\n (m) => m.t === \"literal\" && typeof m.value === \"string\",\n )\n ) {\n return { sql: \"text\", nullable: false };\n }\n throw new Error(\"postgres: non-enum unions are unsupported\");\n }\n if (type.t === \"array\" || type.t === \"set\") {\n const elem = pgColumn(type.elem);\n return { sql: `${elem.sql}[]`, nullable: false };\n }\n if (type.t === \"object\") {\n return { sql: \"jsonb\", nullable: false };\n }\n if (type.t === \"record\") {\n if (type.tables.length !== 1) {\n // Multi-target links would need a polymorphic FK; out of spike scope -> plain text id.\n return { sql: \"text\", nullable: false };\n }\n return { sql: \"text\", nullable: false, references: type.tables[0] };\n }\n if (type.t === \"geometry\") {\n // Would map to PostGIS `geometry`; without the extension, store GeoJSON as jsonb.\n return { sql: \"jsonb\", nullable: false };\n }\n if (type.t === \"native\") {\n if (type.db !== \"postgres\") {\n throw new Error(\n `postgres: native type \"${type.name}\" belongs to driver \"${type.db}\"`,\n );\n }\n // params are order-significant: varchar -> (n), numeric -> (p[, s]).\n const params = type.params as (string | number)[] | undefined;\n const sql =\n params && params.length > 0\n ? `${type.name}(${params.join(\", \")})`\n : type.name;\n return { sql, nullable: false };\n }\n throw new Error(`postgres: cannot emit type ${JSON.stringify(type)}`);\n}\n\n// --- normalize: project the portable IR onto what Postgres represents ---------------------------\n\n/** Collapse option -> nullable (Postgres can't distinguish absence from NULL). Idempotent. */\nexport function pgCanonType(type: PortableType): PortableType {\n if (type.t === \"option\") return nullable(pgCanonType(type.inner));\n if (type.t === \"nullable\") return nullable(pgCanonType(type.inner));\n if (type.t === \"array\")\n return {\n t: \"array\",\n elem: pgCanonType(type.elem),\n ...(type.size !== undefined ? { size: type.size } : {}),\n };\n if (type.t === \"set\")\n return {\n t: \"set\",\n elem: pgCanonType(type.elem),\n ...(type.size !== undefined ? { size: type.size } : {}),\n };\n // A nested object becomes an opaque jsonb column -> canonical empty object (sub-keys not tracked).\n if (type.t === \"object\") return { t: \"object\", fields: {} };\n return type;\n}\n\n/** Uppercase a referential action so authored `cascade` matches introspected `CASCADE`; drop NO ACTION (default). */\nexport function normAction(a?: string): string | undefined {\n const u = a?.toUpperCase();\n return u && u !== \"NO ACTION\" ? u : undefined;\n}\n\n/**\n * A field reduced to its EQUALITY-relevant shape: canonical type + the STRUCTURAL clauses Postgres\n * round-trips (identity, FK referential actions). EXPRESSION clauses (`default`/`check`/`computed`/\n * `comment`) are dropped here: Postgres rewrites them on read (`0` -> `0`, `'x'` -> `'x'::text`,\n * `a>0` -> `(a > 0)`), so they emit faithfully but can't round-trip to an exact match — a documented\n * capability gap, not an equality difference (see docs/COVERAGE.md).\n */\nexport function canonField(f: PortableField, table: string): PortableField {\n const out: PortableField = { name: f.name, table, type: pgCanonType(f.type) };\n if (f.identity !== undefined) out.identity = f.identity;\n if (f.reference) {\n const ref: { on_delete?: string; on_update?: string } = {};\n const od = normAction(f.reference.on_delete);\n const ou = normAction(f.reference.on_update);\n if (od) ref.on_delete = od;\n if (ou) ref.on_update = ou;\n if (ref.on_delete !== undefined || ref.on_update !== undefined)\n out.reference = ref;\n }\n return out;\n}\n\n/** Fields ready for emit: drop dotted sub-fields, canonicalize the type, KEEP all DDL clauses, sort. */\nexport function pgEmitFields(t: PgCreateInput): PortableField[] {\n return t.fields\n .filter((f) => !f.name.includes(\".\"))\n .map((f) => ({ ...f, table: t.name, type: pgCanonType(f.type) }))\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\n// --- column + table DDL -------------------------------------------------------------------------\n\n/** `ON DELETE …`/`ON UPDATE …` suffix for a FK constraint (empty when no actions). */\nexport function fkActions(ref?: {\n on_delete?: string;\n on_update?: string;\n}): string {\n let s = \"\";\n if (ref?.on_delete) s += ` ON DELETE ${ref.on_delete}`;\n if (ref?.on_update) s += ` ON UPDATE ${ref.on_update}`;\n return s;\n}\n\n/** A column body for CREATE TABLE: type + NOT NULL + identity/default/generated/check clauses. */\nexport function fieldColumnDdl(f: PortableField): string {\n const col = pgColumn(f.type);\n let s = `${escId(f.name)} ${col.sql}`;\n if (!col.nullable) s += \" NOT NULL\";\n if (f.identity)\n s += ` GENERATED ${f.identity === \"always\" ? \"ALWAYS\" : \"BY DEFAULT\"} AS IDENTITY`;\n if (f.default !== undefined) s += ` DEFAULT ${f.default}`;\n if (f.computed !== undefined)\n s += ` GENERATED ALWAYS AS (${f.computed}) STORED`;\n if (f.check !== undefined) s += ` CHECK (${f.check})`;\n return s;\n}\n\n/**\n * The `CREATE TABLE (...)` statement body for a table — the implicit `id` PK (or a custom/composite\n * PRIMARY KEY), every column with its clauses, and table-level CHECKs. The single source for table\n * creation DDL, used by the `table` kind's `emit`/`canonical`.\n */\nexport function createTableDdl(t: PgCreateInput): string {\n const fields = pgEmitFields(t);\n const custom = !!(t.primaryKey && t.primaryKey.length > 0);\n const cols: string[] = [];\n if (!custom) cols.push(`${escId(\"id\")} text PRIMARY KEY`); // implicit id (mirrors Surreal).\n for (const f of fields) cols.push(fieldColumnDdl(f));\n if (custom) cols.push(`PRIMARY KEY (${t.primaryKey?.map(escId).join(\", \")})`);\n for (const c of t.checks ?? []) cols.push(`CHECK (${c})`);\n return `CREATE TABLE ${escId(t.name)} (\\n ${cols.join(\",\\n \")}\\n);`;\n}\n\n// --- column-level ALTER helpers (used by the field-level diff + the table kind's overwrite) ------\n\n/** A column definition body (`\"name\" type [NOT NULL]`) for ADD COLUMN / CREATE TABLE. */\nexport function colDef(f: PortableField): string {\n const c = pgColumn(f.type);\n return `${escId(f.name)} ${c.sql}${c.nullable ? \"\" : \" NOT NULL\"}`;\n}\nexport const fkName = (table: string, field: string) =>\n `${table}_${field}_fkey`;\nexport const addColSql = (table: string, f: PortableField) =>\n `ALTER TABLE ${escId(table)} ADD COLUMN ${colDef(f)};`;\nexport const dropColSql = (table: string, field: string) =>\n `ALTER TABLE ${escId(table)} DROP COLUMN IF EXISTS ${escId(field)};`;\nexport const dropTableSql = (table: string) =>\n `DROP TABLE IF EXISTS ${escId(table)} CASCADE;`;\n\n/** `ALTER TABLE … ADD CONSTRAINT … FOREIGN KEY …` for a single-column FK to `ref(id)`. */\nexport const addFkSql = (\n table: string,\n field: string,\n ref: string,\n actions = \"\",\n) =>\n `ALTER TABLE ${escId(table)} ADD CONSTRAINT ${escId(fkName(table, field))} FOREIGN KEY (${escId(field)}) REFERENCES ${escId(ref)} (${escId(\"id\")})${actions};`;\n\n/** Drop a FK constraint by its generated name. */\nexport const dropFkSql = (table: string, field: string) =>\n `ALTER TABLE ${escId(table)} DROP CONSTRAINT IF EXISTS ${escId(fkName(table, field))};`;\n","// The POSTGRES kind registry (core-v2). Core no longer hard-codes object kinds; each driver registers\n// its KINDS on a per-driver KindRegistry and core orchestrates generically (lowerSchema / planKinds /\n// buildKindDiff / emitKinds). See packages/core/docs/kind-registry-contract.md.\n//\n// Postgres registers THREE kinds (coarse-to-fine, registration order == ordinal):\n// table — the structured kind: columns (substrate) + PK + table CHECKs; CREATE TABLE; field-\n// level overwrite. A FK COLUMN stays a plain `text` column here; the FK CONSTRAINT is\n// its own kind (below) so the dependency graph can break mutual-FK cycles.\n// index — own kind, deps -> its table (no `owner`); CREATE [UNIQUE] INDEX.\n// constraint — own kind (FK first), deps -> [its table, the referenced table]; ALTER ADD CONSTRAINT.\n//\n// index/constraint DECLINE `owner` (opt-in clustering): without it the spine falls back to ordinal+name,\n// so the emit order is all tables -> all indexes -> all constraints (pg's rank-grouped convention),\n// not clustered per-table. Cross-table FK still emits after both tables (deps); a genuine mutual FK is\n// broken because constraints depend on tables, not each other.\n//\n// `splitTable` turns the driver's table IR (`PgTable`, from ./lower for authoring or ./index's\n// pgIntrospect for a live DB) into these kind objects. The Driver feeds it through both seams:\n// `explode = splitTables(pgLower(...))` (authoring) and `introspectAll = splitTables(pgIntrospect(...))`\n// (live), and core runs the generic spine (lowerSchema/buildKindDiff/emitKinds) over the result. Per\n// the contract, kinds are pg's own — never cross-driver.\n\nimport {\n type KindEngine,\n KindRegistry,\n type PortableObject,\n type Ref,\n} from \"@schemic/core\";\nimport type { DiffItem, PortableField } from \"@schemic/core/driver\";\nimport {\n addFkSql,\n canonField,\n createTableDdl,\n dropFkSql,\n dropTableSql,\n escId,\n fieldColumnDdl,\n fkActions,\n fkName,\n normAction,\n type PgTable,\n pgColumn,\n pgEmitFields,\n} from \"./emit\";\n\n// --- the kinds' portable objects ----------------------------------------------------------------\n\n/** The `table` kind's portable form: emit-ready columns (substrate) + composite PK + table CHECKs. */\nexport interface PgTablePortable extends PortableObject {\n kind: \"table\";\n name: string;\n fields: PortableField[];\n primaryKey?: string[];\n checks?: string[];\n}\n\n/** The `index` kind's portable form (a secondary/unique index over one table's columns). */\nexport interface PgIndexPortable extends PortableObject {\n kind: \"index\";\n name: string;\n table: string;\n cols: string[];\n unique: boolean;\n}\n\n/** The `constraint` kind's portable form (FK only for now; deps -> table + referenced table). */\nexport interface PgConstraintPortable extends PortableObject {\n kind: \"constraint\";\n name: string;\n table: string;\n ctype: \"fk\";\n column: string;\n refTable: string;\n onDelete?: string;\n onUpdate?: string;\n}\n\nconst tableRef = (name: string): Ref => ({ kind: \"table\", name });\n\n// --- table kind ---------------------------------------------------------------------------------\n\n/** Column-level `COMMENT ON COLUMN` lines for a table's commented fields (emit-only; not introspected). */\nfunction commentLines(t: PgTablePortable): string[] {\n return t.fields\n .filter((f) => f.comment !== undefined)\n .map(\n (f) =>\n `COMMENT ON COLUMN ${escId(t.name)}.${escId(f.name)} IS '${(f.comment ?? \"\").replace(/'/g, \"''\")}';`,\n );\n}\n\n/** Clauses pg cannot ALTER in place (need a drop+recreate): identity, generated, field CHECK. */\nconst hasHardClause = (f: PortableField) =>\n f.identity !== undefined || f.computed !== undefined || f.check !== undefined;\n\nconst sameArr = (a?: string[], b?: string[]) =>\n JSON.stringify(a ?? []) === JSON.stringify(b ?? []);\n\n/** Structural equality of two emit-ready fields (the table kind's change unit). */\nconst sameField = (a: PortableField, b: PortableField) =>\n JSON.stringify(a) === JSON.stringify(b);\n\nconst fieldKey = (table: string, name: string) => `field:${table}:${name}`;\nconst createInput = (t: PgTablePortable) => ({\n name: t.name,\n fields: t.fields,\n ...(t.primaryKey ? { primaryKey: t.primaryKey } : {}),\n ...(t.checks ? { checks: t.checks } : {}),\n});\n\n/**\n * Per-FIELD display items for a table change (Manuel's per-field decision): each carries its owner\n * `table` so the CLI groups them under it. `(prev,next)` diffs columns -> add/change/remove; an added\n * table `(undefined,next)` lists every column as an add (the `--full` projection); a dropped table\n * `(prev,undefined)` lists every column as a remove. A change with no column delta (a PK / table-CHECK\n * only change) falls back to a single whole-table item so it's never silently empty. DISPLAY ONLY.\n */\nfunction fieldDisplayItems(\n prev: PgTablePortable | undefined,\n next: PgTablePortable | undefined,\n): DiffItem[] {\n const table = (next ?? prev)?.name ?? \"\";\n const before = new Map((prev?.fields ?? []).map((f) => [f.name, f]));\n const after = new Map((next?.fields ?? []).map((f) => [f.name, f]));\n const items: DiffItem[] = [];\n for (const f of next?.fields ?? [])\n if (!before.has(f.name))\n items.push({\n op: \"add\",\n key: fieldKey(table, f.name),\n kind: \"field\",\n table,\n ddl: fieldColumnDdl(f),\n });\n for (const f of next?.fields ?? []) {\n const b = before.get(f.name);\n if (!b) continue;\n if (fieldColumnDdl(b) !== fieldColumnDdl(f) || b.comment !== f.comment)\n items.push({\n op: \"change\",\n key: fieldKey(table, f.name),\n kind: \"field\",\n table,\n before: fieldColumnDdl(b),\n after: fieldColumnDdl(f),\n });\n }\n for (const f of prev?.fields ?? [])\n if (!after.has(f.name))\n items.push({\n op: \"remove\",\n key: fieldKey(table, f.name),\n kind: \"field\",\n table,\n ddl: `ALTER TABLE ${escId(table)} DROP COLUMN IF EXISTS ${escId(f.name)};`,\n old: fieldColumnDdl(f),\n });\n if (items.length === 0 && prev && next)\n items.push({\n op: \"change\",\n key: `table:${table}:${table}`,\n kind: \"table\",\n table,\n before: createTableDdl(createInput(prev)),\n after: createTableDdl(createInput(next)),\n });\n return items;\n}\n\nconst tableEngine: KindEngine<PgTablePortable, PgTablePortable> = {\n // Objects arrive already in this kind's portable shape (from `explode`/`introspectAll` via splitTable\n // / lowerSchema). `lower` is the identity — the split already produced the normalized portable object.\n lower: (t) => t,\n\n // CREATE TABLE (columns + PK + table CHECKs) followed by any column COMMENTs.\n emit: (t) => [\n createTableDdl({\n name: t.name,\n fields: t.fields,\n ...(t.primaryKey ? { primaryKey: t.primaryKey } : {}),\n ...(t.checks ? { checks: t.checks } : {}),\n }),\n ...commentLines(t),\n ],\n\n // Change-detection key (NOT the emitted DDL): the equality-relevant shape only — canonField keeps\n // type/nullability/identity/FK-actions and DROPS the rewrite-prone/non-introspected clauses\n // (DEFAULT/CHECK/GENERATED/COMMENT), and table-level CHECKs are omitted too. So those clauses stay\n // faithful in `emit` (fresh apply) but never count as a change -> no phantom-diff of a freshly\n // applied schema vs introspect (PG rewrites exprs on read; comments aren't introspected). This is\n // the fixed-slot driver's emit/equal asymmetry, restored at the kind seam.\n canonical: (t) =>\n createTableDdl({\n name: t.name,\n fields: t.fields.map((f) => canonField(f, t.name)),\n ...(t.primaryKey ? { primaryKey: t.primaryKey } : {}),\n }),\n\n // Per-FIELD display items (Manuel's decision: field-level changes grouped under their table). Each\n // carries `table` so the CLI groups them hierarchically. DISPLAY ONLY — never affects up/down DDL.\n // (prev,next): diff the columns; (undefined,next): list all columns as adds (the --full projection).\n displayItems: (prev, next) => fieldDisplayItems(prev, next),\n\n remove: (t) => [dropTableSql(t.name)],\n\n // In-place column ALTERs (add/drop/type/nullability/default/comment). A structural change pg can't\n // ALTER (PK, table CHECK, or a column's identity/generated/field-CHECK) falls back to drop+recreate.\n overwrite: (prev, next) => {\n const before = new Map(prev.fields.map((f) => [f.name, f]));\n const after = new Map(next.fields.map((f) => [f.name, f]));\n\n // Hard structural deltas -> recreate (coarse, destructive — but correct; pg has no in-place form).\n const changedHard = next.fields.some((f) => {\n const b = before.get(f.name);\n return b && (hasHardClause(f) || hasHardClause(b)) && !sameField(b, f);\n });\n const addedHard = next.fields.some(\n (f) => !before.has(f.name) && hasHardClause(f),\n );\n const removedHard = prev.fields.some(\n (f) => !after.has(f.name) && hasHardClause(f),\n );\n if (\n !sameArr(prev.primaryKey, next.primaryKey) ||\n !sameArr(prev.checks, next.checks) ||\n changedHard ||\n addedHard ||\n removedHard\n ) {\n return [...tableEngine.remove(prev), ...tableEngine.emit(next)];\n }\n\n const out: string[] = [];\n const t = next.name;\n // added columns (full column DDL — plain columns match the fixed-slot ADD COLUMN byte-for-byte)\n for (const f of next.fields)\n if (!before.has(f.name))\n out.push(`ALTER TABLE ${escId(t)} ADD COLUMN ${fieldColumnDdl(f)};`);\n // changed columns: type, nullability, default, comment\n for (const f of next.fields) {\n const b = before.get(f.name);\n if (!b) continue;\n const ca = pgColumn(f.type);\n const cb = pgColumn(b.type);\n if (ca.sql !== cb.sql)\n out.push(\n `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} TYPE ${ca.sql};`,\n );\n if (ca.nullable !== cb.nullable)\n out.push(\n `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} ${ca.nullable ? \"DROP NOT NULL\" : \"SET NOT NULL\"};`,\n );\n if (f.default !== b.default)\n out.push(\n f.default === undefined\n ? `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} DROP DEFAULT;`\n : `ALTER TABLE ${escId(t)} ALTER COLUMN ${escId(f.name)} SET DEFAULT ${f.default};`,\n );\n if (f.comment !== b.comment)\n out.push(\n f.comment === undefined\n ? `COMMENT ON COLUMN ${escId(t)}.${escId(f.name)} IS NULL;`\n : `COMMENT ON COLUMN ${escId(t)}.${escId(f.name)} IS '${f.comment.replace(/'/g, \"''\")}';`,\n );\n }\n // dropped columns\n for (const f of prev.fields)\n if (!after.has(f.name))\n out.push(\n `ALTER TABLE ${escId(t)} DROP COLUMN IF EXISTS ${escId(f.name)};`,\n );\n return out;\n },\n};\n\n// --- index kind ---------------------------------------------------------------------------------\n\nconst indexEngine: KindEngine<PgIndexPortable, PgIndexPortable> = {\n lower: (i) => i,\n emit: (i) => [\n `CREATE ${i.unique ? \"UNIQUE \" : \"\"}INDEX ${escId(i.name)} ON ${escId(i.table)} (${i.cols.map(escId).join(\", \")});`,\n ],\n remove: (i) => [`DROP INDEX IF EXISTS ${escId(i.name)};`],\n // An index emits AFTER its table (deps), but NO `owner` -> no clustering: the spine then falls back\n // to ordinal+name, so all indexes emit as a rank group after all tables (pg's emit convention),\n // rather than clustered next to each table. owner is opt-in readability we deliberately decline.\n deps: (i) => [tableRef(i.table)],\n // no overwrite: an index change is a drop+recreate (the spine's default).\n};\n\n// --- constraint kind (FK) -----------------------------------------------------------------------\n\nconst constraintEngine: KindEngine<PgConstraintPortable, PgConstraintPortable> =\n {\n lower: (c) => c,\n emit: (c) => [\n addFkSql(\n c.table,\n c.column,\n c.refTable,\n fkActions({ on_delete: c.onDelete, on_update: c.onUpdate }),\n ),\n ],\n remove: (c) => [dropFkSql(c.table, c.column)],\n // A FK emits AFTER both its own table and the referenced table — this is what breaks mutual-FK\n // cycles (tables have no deps, so they create first, then the constraints between them). NO\n // `owner`: like the index kind, constraints emit as a rank group after all tables (pg convention).\n deps: (c) =>\n c.refTable === c.table\n ? [tableRef(c.table)]\n : [tableRef(c.table), tableRef(c.refTable)],\n // no overwrite: a FK change is drop+recreate (the spine's default).\n };\n\n// --- the registry -------------------------------------------------------------------------------\n\nexport const registry = new KindRegistry();\nregistry.define({\n name: \"table\",\n build: (t: PgTablePortable) => t,\n ...tableEngine,\n});\nregistry.define({\n name: \"index\",\n build: (i: PgIndexPortable) => i,\n ...indexEngine,\n});\nregistry.define({\n name: \"constraint\",\n build: (c: PgConstraintPortable) => c,\n ...constraintEngine,\n});\n\n// --- splitTable: the driver's table IR -> the registry's kind objects ----------------------------\n\n/**\n * Split one `PgTable` (from `lowerTable` for authoring, or `pgIntrospect` for a live DB) into the\n * registry's portable objects: the `table` (columns substrate + PK + table CHECKs, with FK columns kept\n * as plain `text` columns) plus its `index` and `constraint` (FK) objects. The single seam both\n * `explode` (authoring) and `introspectAll` (live) go through, so a clean apply round-trips to a zero\n * diff. Replaces the old PortableDb<->objects facade adapter.\n */\nexport function splitTable(t: PgTable): PortableObject[] {\n const out: PortableObject[] = [];\n const fields = pgEmitFields(t);\n const table: PgTablePortable = {\n kind: \"table\",\n name: t.name,\n fields,\n ...(t.primaryKey && t.primaryKey.length > 0\n ? { primaryKey: t.primaryKey }\n : {}),\n ...(t.checks && t.checks.length > 0 ? { checks: t.checks } : {}),\n };\n out.push(table);\n\n for (const ix of t.indexes) {\n const index: PgIndexPortable = {\n kind: \"index\",\n name: ix.name,\n table: t.name,\n cols: ix.cols,\n unique: ix.unique,\n };\n out.push(index);\n }\n\n for (const f of fields) {\n const ref = pgColumn(f.type).references;\n if (!ref) continue;\n const onDelete = normAction(f.reference?.on_delete);\n const onUpdate = normAction(f.reference?.on_update);\n const fk: PgConstraintPortable = {\n kind: \"constraint\",\n name: fkName(t.name, f.name),\n table: t.name,\n ctype: \"fk\",\n column: f.name,\n refTable: ref,\n ...(onDelete ? { onDelete } : {}),\n ...(onUpdate ? { onUpdate } : {}),\n };\n out.push(fk);\n }\n return out;\n}\n\n/** Split many `PgTable`s into the flat kind-object list (the `explode`/`introspectAll` shape). */\nexport const splitTables = (tables: PgTable[]): PortableObject[] =>\n tables.flatMap(splitTable);\n","// lower: the pg `s.*` authoring objects (./authoring.ts) -> the driver's table IR (`PgTable`). The\n// driver's `explode` then splits each PgTable into kind objects (table/index/constraint); `emit` turns\n// those into pg DDL and `introspectAll` reads DDL back into the same kind objects, so author -> lower\n// -> explode -> emit -> introspect -> diff round-trips. Field TYPE comes from the Zod schema's\n// structural wrappers (optional/nullable/array) combined with the PgMeta pg-type token; DDL clauses\n// (default/check/generated/identity/comment/reference) ride PgMeta into the field's clause slots.\n\nimport type {\n PortableField,\n PortableType,\n ScalarName,\n} from \"@schemic/core/driver\";\nimport type { PgField, PgMeta, PgTableDef } from \"./authoring\";\nimport type { PgIndexInfo, PgTable } from \"./emit\";\n\n/** Minimal view of a Zod schema's internal def (zod v4) — enough to peel structural wrappers. */\ninterface ZodDef {\n type: string;\n innerType?: { _zod: { def: ZodDef } };\n element?: { _zod: { def: ZodDef } };\n}\nconst defOf = (schema: { _zod: { def: ZodDef } }): ZodDef => schema._zod.def;\n\n/** Canonical pg types that map to a PORTABLE scalar (so they port cross-dialect). Others -> native. */\nconst CANON: Record<string, ScalarName> = {\n text: \"string\",\n integer: \"int\",\n \"double precision\": \"float\",\n numeric: \"decimal\",\n boolean: \"bool\",\n timestamptz: \"datetime\",\n uuid: \"uuid\",\n bytea: \"bytes\",\n interval: \"duration\",\n};\n\n/** A pg type token (+ params) -> portable leaf type: canonical -> scalar, parameterized/other -> native. */\nfunction tokenToPortable(\n type: string,\n params?: (string | number)[],\n): PortableType {\n if (type === \"jsonb\") return { t: \"object\", fields: {} };\n if (params && params.length > 0)\n return { t: \"native\", db: \"postgres\", name: type, params };\n const scalar = CANON[type];\n return scalar\n ? { t: \"scalar\", name: scalar }\n : { t: \"native\", db: \"postgres\", name: type };\n}\n\n/** Peel the Zod structural wrappers (optional/nullable/array; default/prefault/catch/readonly are transparent). */\nfunction structure(schema: PgField[\"schema\"]): {\n wrappers: (\"option\" | \"nullable\" | \"array\")[];\n leaf: { _zod: { def: ZodDef } };\n} {\n const wrappers: (\"option\" | \"nullable\" | \"array\")[] = [];\n let cur: { _zod: { def: ZodDef } } = schema;\n for (;;) {\n const def = defOf(cur);\n if (def.type === \"optional\" && def.innerType) {\n wrappers.push(\"option\");\n cur = def.innerType;\n } else if (def.type === \"nullable\" && def.innerType) {\n wrappers.push(\"nullable\");\n cur = def.innerType;\n } else if (def.type === \"array\" && def.element) {\n wrappers.push(\"array\");\n cur = def.element;\n } else if (\n (def.type === \"default\" ||\n def.type === \"prefault\" ||\n def.type === \"catch\" ||\n def.type === \"readonly\") &&\n def.innerType\n ) {\n cur = def.innerType; // App-land wrappers, transparent to the column type\n } else {\n break;\n }\n }\n return { wrappers, leaf: cur };\n}\n\n/** The leaf portable type from the field's pg metadata (FK -> record; else the pg-type token). */\nfunction leafPortable(meta: PgMeta): PortableType {\n if (meta.references) return { t: \"record\", tables: [meta.references.table] };\n if (!meta.pg) return { t: \"scalar\", name: \"string\" };\n return tokenToPortable(meta.pg.type, meta.pg.params);\n}\n\n/** Combine the structural wrappers (outermost-first) around the leaf type. */\nfunction portableType(\n meta: PgMeta,\n wrappers: (\"option\" | \"nullable\" | \"array\")[],\n): PortableType {\n let type = leafPortable(meta);\n for (let i = wrappers.length - 1; i >= 0; i--) {\n const w = wrappers[i];\n type =\n w === \"array\"\n ? { t: \"array\", elem: type }\n : w === \"option\"\n ? { t: \"option\", inner: type }\n : { t: \"nullable\", inner: type };\n }\n return type;\n}\n\n/** One pg field -> a portable field, carrying its DDL clauses into the IR's clause slots. */\nfunction lowerField(\n name: string,\n table: string,\n field: PgField,\n): PortableField {\n const meta = field.native;\n const { wrappers } = structure(field.schema);\n const pf: PortableField = {\n name,\n table,\n type: portableType(meta, wrappers),\n };\n if (meta.default !== undefined) pf.default = meta.default;\n if (meta.check !== undefined) pf.check = meta.check;\n if (meta.generated !== undefined) pf.computed = meta.generated;\n if (meta.identity !== undefined) pf.identity = meta.identity;\n if (meta.comment !== undefined) pf.comment = meta.comment;\n if (meta.references) {\n const ref: { on_delete?: string; on_update?: string } = {};\n if (meta.references.onDelete) ref.on_delete = meta.references.onDelete;\n if (meta.references.onUpdate) ref.on_update = meta.references.onUpdate;\n if (ref.on_delete !== undefined || ref.on_update !== undefined)\n pf.reference = ref;\n }\n return pf;\n}\n\n/** One pg table definition -> the driver's table IR (fields + composite PK + table CHECKs + indexes). */\nexport function lowerTable(def: PgTableDef): PgTable {\n const fields: PortableField[] = [];\n const indexes: PgIndexInfo[] = [];\n const pkCols: string[] = [...(def.config.primaryKey ?? [])];\n\n for (const [name, field] of Object.entries(def.fields)) {\n fields.push(lowerField(name, def.name, field));\n if (field.native.unique)\n indexes.push({\n name: `${def.name}_${name}_key`,\n cols: [name],\n unique: true,\n });\n if (field.native.primaryKey && !pkCols.includes(name)) pkCols.push(name);\n }\n for (const ix of def.config.indexes ?? []) {\n indexes.push({\n name: ix.name ?? `${def.name}_${ix.cols.join(\"_\")}_idx`,\n cols: ix.cols,\n unique: !!ix.unique,\n });\n }\n\n const table: PgTable = { name: def.name, fields, indexes };\n if (pkCols.length > 0) table.primaryKey = pkCols;\n if (def.config.checks && def.config.checks.length > 0)\n table.checks = def.config.checks;\n return table;\n}\n\n/** Lower the authored pg tables (+ standalone defs — none in the pg surface yet) to the table IR. */\nexport function pgLower(tables: PgTableDef[]): PgTable[] {\n return tables.map(lowerTable);\n}\n","// The POSTGRES native authoring surface — `s.*` in pg vocabulary, built on the neutral core base\n// (@schemic/core/authoring). A pg project authors with THESE types (pg lingo: text/varchar/numeric/\n// timestamptz/jsonb/serial/...) and the driver lowers them to the portable IR (see ./lower.ts), then\n// emits pg DDL. Per the multi-DB decision (every driver owns its own `s.*`), this mirrors\n// @schemic/surrealdb's surface but in Postgres terms.\n//\n// Design constraints (Manuel):\n// - LAYER ON ZOD: every field IS a Zod schema (`PgField extends SFieldBase`); pg-native metadata\n// rides the field's opaque `native` slot (PgMeta), never patching Zod internals.\n// - ESCAPE HATCH: `s.$postgres(pgType, codec)` for any type not representable on the wire — a Zod\n// codec (encode/decode) App-side, stored as the given pg type (mirrors surreal's `$surreal`).\n// - DX FIRST: native types + `$`-methods ($default/$check/$generated/$identity/$unique/$primaryKey/\n// $references/$comment) + the full Zod wrapper/passthrough chain, all type-preserving.\n\nimport {\n type AnyField,\n type SchemaOf,\n SFieldBase,\n toZod,\n} from \"@schemic/core/authoring\";\nimport * as z from \"zod\";\n\n// --- PgMeta: the pg-native metadata bag carried on every field ----------------------------------\n\n/** A pg column type token + optional params (`varchar`/[255], `numeric`/[10,2]); the leaf factory sets it. */\nexport interface PgTypeRef {\n type: string;\n params?: (string | number)[];\n}\n\n/** Postgres-native field metadata (the `native` slot of {@link PgField}). All optional; merged by `$`-methods. */\nexport interface PgMeta {\n /** The pg base type (sans option/nullable/array wrappers, which live on the Zod schema). */\n pg?: PgTypeRef;\n /** `DEFAULT <expr>` (verbatim SQL). */\n default?: string;\n /** Field-level `CHECK (<expr>)` (verbatim SQL boolean expr). */\n check?: string;\n /** `GENERATED ALWAYS AS (<expr>) STORED` (verbatim SQL expr). */\n generated?: string;\n /** `GENERATED {ALWAYS|BY DEFAULT} AS IDENTITY` (also how `serial` is modeled). */\n identity?: \"always\" | \"by-default\";\n /** Column-level `UNIQUE`. */\n unique?: boolean;\n /** Column is (part of) the PRIMARY KEY. */\n primaryKey?: boolean;\n /** A foreign key to `table(id)` with optional referential actions. */\n references?: { table: string; onDelete?: string; onUpdate?: string };\n /** `COMMENT ON COLUMN`. */\n comment?: string;\n}\n\nconst blankMeta = (): PgMeta => ({});\n\n/** A raw SQL expression marker for DDL clauses (`$default`/`$check`/`$generated`) — spliced verbatim. */\nexport interface SqlExpr {\n readonly __sql: string;\n}\n/** Mark a string as a raw SQL expression (vs a literal value) for a DDL clause: `s.timestamptz().$default(sqlExpr(\"now()\"))`. */\nexport const sqlExpr = (sql: string): SqlExpr => ({ __sql: sql });\nconst isSqlExpr = (v: unknown): v is SqlExpr =>\n typeof v === \"object\" && v !== null && \"__sql\" in v;\n\n/** Render a JS literal as a Postgres literal (numbers/bools bare, strings single-quoted, null -> NULL). */\nfunction pgLiteral(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"number\") return String(v);\n if (typeof v === \"boolean\") return v ? \"true\" : \"false\";\n return `'${v.replace(/'/g, \"''\")}'`;\n}\nconst toExpr = (v: string | number | boolean | null | SqlExpr): string =>\n isSqlExpr(v) ? v.__sql : pgLiteral(v);\n\n// --- PgField: the dialect subclass -------------------------------------------------------------\n\n/**\n * A Postgres field: a Zod schema (App/Wire typing) + {@link PgMeta} (pg-native DDL metadata). Extends\n * the neutral {@link SFieldBase}, which supplies the codecs, the Zod wrappers, and the `z.*` passthrough;\n * this subclass re-types the wrappers so a chain stays a `PgField`, and adds the pg `$`-methods.\n */\nexport class PgField<\n S extends z.ZodType = z.ZodType,\n Flags extends string = never,\n> extends SFieldBase<S, Flags, PgMeta> {\n protected rebuild<S2 extends z.ZodType, F2 extends string>(\n schema: S2,\n native: PgMeta,\n ): PgField<S2, F2> {\n return new PgField<S2, F2>(schema, native);\n }\n protected blank(): PgMeta {\n return blankMeta();\n }\n\n // Type-only narrowing of the inherited portable wrappers (runtime impl is the base's, which builds a\n // PgField via rebuild) — so a mixed chain like `s.text().$default(\"x\").optional()` stays a PgField.\n declare optional: () => PgField<z.ZodOptional<S>, Flags>;\n declare nullable: () => PgField<z.ZodNullable<S>, Flags>;\n declare nullish: () => PgField<z.ZodOptional<z.ZodNullable<S>>, Flags>;\n declare array: () => PgField<z.ZodArray<S>, Flags>;\n declare default: (value: z.input<S>) => PgField<z.ZodDefault<S>, Flags>;\n declare prefault: (value: z.input<S>) => PgField<z.ZodPrefault<S>, Flags>;\n declare catch: (value: z.output<S>) => PgField<z.ZodCatch<S>, Flags>;\n\n private with(meta: Partial<PgMeta>): PgField<S, Flags> {\n return new PgField<S, Flags>(this.schema, { ...this.native, ...meta });\n }\n\n // --- pg-native `$`-methods (DDL authoring) ---\n /** `DEFAULT <value>` — a JS literal, or `sqlExpr(\"now()\")` for a raw SQL default. */\n $default(value: z.input<S> | SqlExpr): PgField<S, Flags> {\n return this.with({ default: toExpr(value as never) });\n }\n /** Field-level `CHECK (<expr>)`. */\n $check(expr: string | SqlExpr): PgField<S, Flags> {\n return this.with({ check: isSqlExpr(expr) ? expr.__sql : expr });\n }\n /** `GENERATED ALWAYS AS (<expr>) STORED` — a computed column. */\n $generated(expr: string | SqlExpr): PgField<S, Flags> {\n return this.with({ generated: isSqlExpr(expr) ? expr.__sql : expr });\n }\n /** `GENERATED {ALWAYS|BY DEFAULT} AS IDENTITY` (auto-increment). */\n $identity(mode: \"always\" | \"by-default\" = \"by-default\"): PgField<S, Flags> {\n return this.with({ identity: mode });\n }\n /** Column-level `UNIQUE`. */\n $unique(): PgField<S, Flags> {\n return this.with({ unique: true });\n }\n /** Mark this column (part of) the PRIMARY KEY. */\n $primaryKey(): PgField<S, Flags> {\n return this.with({ primaryKey: true });\n }\n /** Foreign key to `table(id)` with optional `ON DELETE`/`ON UPDATE` actions. */\n $references(\n table: string,\n opts?: { onDelete?: string; onUpdate?: string },\n ): PgField<S, Flags> {\n return this.with({ references: { table, ...(opts ?? {}) } });\n }\n /** `COMMENT ON COLUMN`. */\n $comment(text: string): PgField<S, Flags> {\n return this.with({ comment: text });\n }\n\n /**\n * ESCAPE HATCH (chainable form) — teach the driver how to STORE this field's value in Postgres:\n * give the **wire type** as an `s.*`/Zod field (its pg column type is taken from it) plus a codec\n * (`encode`: app -> wire, `decode`: wire -> app). This turns an otherwise-unmappable App value\n * (e.g. `s.instanceof(Money)`) into a real pg column. Omit the codec for an identity mapping (the\n * app value is stored as-is). Mirrors SurrealDB's `.$surreal(wire, codec)`; the standalone\n * {@link s.$postgres} factory is the from-scratch equivalent. `$`-prefixed to avoid clashing with Zod.\n */\n $postgres<WF extends AnyField | z.ZodType, A = z.output<S>>(\n wire: WF,\n codec?: {\n encode: (app: A) => z.output<SchemaOf<WF>>;\n decode: (wire: z.output<SchemaOf<WF>>) => A;\n },\n ): PgField<z.ZodCodec<SchemaOf<WF>, S>, Flags> {\n const wireSchema = toZod(wire) as SchemaOf<WF>;\n const c = z.codec(wireSchema, this.schema, {\n decode: (w) => (codec ? codec.decode(w as never) : w) as never,\n encode: (a) => (codec ? codec.encode(a as A) : a) as never,\n });\n // The stored pg type comes from the WIRE field (its column type); App typing comes from `this`.\n const wirePg = wire instanceof PgField ? wire.native.pg : undefined;\n return new PgField<z.ZodCodec<SchemaOf<WF>, S>, Flags>(c, {\n ...this.native,\n ...(wirePg ? { pg: wirePg } : {}),\n });\n }\n}\n\n// --- the `s` vocabulary (pg lingo) -------------------------------------------------------------\n\nconst mk = (\n type: string,\n schema: z.ZodType,\n params?: (string | number)[],\n): PgField => new PgField(schema, { pg: params ? { type, params } : { type } });\n\n/** The Postgres authoring namespace. Zod drop-ins (string/number/…) + native pg types + `$postgres`. */\nexport const s = {\n // Zod drop-ins (the canonical superset; each maps to a sensible pg default). Native aliases below\n // (text/varchar/int/numeric/…) give precise control.\n string: () => mk(\"text\", z.string()),\n number: () => mk(\"double precision\", z.number()),\n // text\n text: () => mk(\"text\", z.string()),\n varchar: (n?: number) =>\n n === undefined\n ? mk(\"varchar\", z.string())\n : mk(\"varchar\", z.string().max(n), [n]),\n char: (n?: number) =>\n n === undefined ? mk(\"char\", z.string()) : mk(\"char\", z.string(), [n]),\n citext: () => mk(\"citext\", z.string()),\n // numeric\n smallint: () => mk(\"smallint\", z.int().gte(-32768).lte(32767)),\n integer: () => mk(\"integer\", z.int()),\n int: () => mk(\"integer\", z.int()),\n bigint: () => mk(\"bigint\", z.int()),\n serial: () => mk(\"integer\", z.int()).$identity(\"by-default\"),\n bigserial: () => mk(\"bigint\", z.int()).$identity(\"by-default\"),\n numeric: (precision?: number, scale?: number) =>\n precision === undefined\n ? mk(\"numeric\", z.number())\n : // Postgres stores `numeric(p)` as `numeric(p,0)`; keep scale explicit so it round-trips.\n mk(\"numeric\", z.number(), [precision, scale ?? 0]),\n decimal: (precision?: number, scale?: number) => s.numeric(precision, scale),\n real: () => mk(\"real\", z.number()),\n doublePrecision: () => mk(\"double precision\", z.number()),\n float: () => mk(\"double precision\", z.number()),\n money: () => mk(\"money\", z.string()),\n // boolean\n boolean: () => mk(\"boolean\", z.boolean()),\n bool: () => mk(\"boolean\", z.boolean()),\n // temporal\n timestamptz: () => mk(\"timestamptz\", z.date()),\n timestamp: () => mk(\"timestamp\", z.date()),\n date: () => mk(\"date\", z.date()),\n time: () => mk(\"time\", z.string()),\n timetz: () => mk(\"timetz\", z.string()),\n interval: () => mk(\"interval\", z.string()),\n // identity / network / uuid / bytes\n uuid: () => mk(\"uuid\", z.uuid()),\n bytea: () => mk(\"bytea\", z.instanceof(Uint8Array)),\n inet: () => mk(\"inet\", z.string()),\n cidr: () => mk(\"cidr\", z.string()),\n macaddr: () => mk(\"macaddr\", z.string()),\n // json\n jsonb: <T extends z.ZodType = z.ZodUnknown>(shape?: T) =>\n mk(\"jsonb\", shape ?? z.unknown()),\n json: <T extends z.ZodType = z.ZodUnknown>(shape?: T) =>\n mk(\"json\", shape ?? z.unknown()),\n // enum (string-literal union -> text) and single literal\n enum: <const T extends readonly [string, ...string[]]>(values: T) =>\n mk(\"text\", z.enum(values)),\n literal: <const V extends string | number | boolean>(value: V) =>\n mk(\n typeof value === \"number\"\n ? \"double precision\"\n : typeof value === \"boolean\"\n ? \"boolean\"\n : \"text\",\n z.literal(value),\n ),\n // object -> jsonb (opaque on disk). Accepts field OR raw-Zod values (a Zod drop-in superset).\n object: (shape: Record<string, AnyField | z.ZodType>) =>\n mk(\n \"jsonb\",\n z.object(\n Object.fromEntries(\n Object.entries(shape).map(([k, v]) => [k, toZod(v)]),\n ),\n ),\n ),\n // array(elem) -> `<elem>[]`; carries the element's pg metadata so it lowers to an array of that type.\n array: (elem: AnyField | z.ZodType): PgField =>\n new PgField(\n z.array(toZod(elem)),\n elem instanceof PgField ? elem.native : {},\n ),\n // foreign key: `text` column + FK to `table(id)`\n references: (\n table: string,\n opts?: { onDelete?: string; onUpdate?: string },\n ): PgField =>\n new PgField(z.string(), {\n pg: { type: \"text\" },\n references: { table, ...(opts ?? {}) },\n }),\n /**\n * ESCAPE HATCH — a pg type with no portable meaning, stored via a Zod codec (encode/decode). The\n * column is emitted as `pgType`; App-side reads/writes go through `codec`. Mirrors surreal `$surreal`.\n */\n $postgres: <C extends z.ZodType>(pgType: string, codec: C): PgField<C> =>\n new PgField<C>(codec, { pg: { type: pgType } }),\n};\n\n// --- defineTable: a pg table builder producing an `Authored` object -----------------------------\n\n/** Table-level pg config: composite PK, table CHECKs, and secondary indexes. */\nexport interface PgTableConfig {\n primaryKey?: string[];\n checks?: string[];\n indexes?: { name?: string; cols: string[]; unique?: boolean }[];\n}\n\n/**\n * A Postgres table definition — the `Authored` object the driver's `lower` reads. Structurally a\n * `{ name }` (the neutral `Authored` bound); also carries its `fields` (a `{ col: PgField }` map) and\n * table-level config. Chainable: `.primaryKey(...)`, `.check(expr)`, `.index([...])`.\n */\nexport class PgTableDef<\n Name extends string = string,\n F extends Record<string, PgField> = Record<string, PgField>,\n> {\n constructor(\n readonly name: Name,\n readonly fields: F,\n readonly config: PgTableConfig = {},\n ) {}\n\n /** Composite / custom PRIMARY KEY (overrides the implicit `id`). */\n primaryKey(...cols: (keyof F & string)[]): PgTableDef<Name, F> {\n return new PgTableDef(this.name, this.fields, {\n ...this.config,\n primaryKey: cols,\n });\n }\n /** A table-level `CHECK (<expr>)`. */\n check(expr: string): PgTableDef<Name, F> {\n return new PgTableDef(this.name, this.fields, {\n ...this.config,\n checks: [...(this.config.checks ?? []), expr],\n });\n }\n /** A secondary index over `cols` (optionally `UNIQUE`). */\n index(\n cols: (keyof F & string)[],\n opts?: { name?: string; unique?: boolean },\n ): PgTableDef<Name, F> {\n return new PgTableDef(this.name, this.fields, {\n ...this.config,\n indexes: [...(this.config.indexes ?? []), { cols, ...(opts ?? {}) }],\n });\n }\n\n /**\n * A foreign-key field referencing THIS table (for use in another table's shape):\n * `author: user.record({ onDelete: \"cascade\" })`. Also satisfies the CLI's structural table check.\n */\n record(opts?: { onDelete?: string; onUpdate?: string }): PgField {\n return s.references(this.name, opts);\n }\n}\n\n/** Declare a Postgres table: `export const user = defineTable(\"user\", { name: s.text(), age: s.integer().optional() })`. */\nexport function defineTable<\n Name extends string,\n F extends Record<string, PgField>,\n>(name: Name, fields: F, config?: PgTableConfig): PgTableDef<Name, F> {\n return new PgTableDef(name, fields, config ?? {});\n}\n\n// --- App/Wire type inference (DX) --------------------------------------------------------------\n\n/** The decoded (App-land) row type of a table — `z.output` of each field's schema. */\nexport type App<T extends PgTableDef> = {\n [K in keyof T[\"fields\"]]: z.output<T[\"fields\"][K][\"schema\"]>;\n};\n/** The encoded (wire) row type of a table — `z.input` of each field's schema. */\nexport type Wire<T extends PgTableDef> = {\n [K in keyof T[\"fields\"]]: z.input<T[\"fields\"][K][\"schema\"]>;\n};\n"],"mappings":"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","names":["nullable","s","codec","nullable"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schemic/postgres",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.4",
|
|
4
4
|
"description": "PostgreSQL driver for Schemic — emit/introspect/diff the portable IR against Postgres (PGlite).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Vertio Solutions",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"lint": "biome check ."
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@schemic/core": "0.1.0-alpha.
|
|
43
|
+
"@schemic/core": "0.1.0-alpha.4",
|
|
44
44
|
"zod": "^4.3.5"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|