import { h as RelationMapEntry, n as CreateDbClientOptions, r as KickDbClient } from "./types-BZGFAXPN.mjs"; import { InjectionToken } from "@forinda/kickjs"; import { Generated, KyselyPlugin } from "kysely"; import { ReadonlyKysely } from "kysely/readonly"; //#region src/snapshot/types.d.ts type Dialect$1 = 'postgres' | 'sqlite' | 'mysql'; type FkAction = 'cascade' | 'restrict' | 'set_null' | 'set_default' | 'no_action'; interface ColumnSnapshot { name: string; type: string; nullable: boolean; default: string | null; primaryKey: boolean; } interface IndexSnapshot { name: string; columns: string[]; unique: boolean; } interface ForeignKeySnapshot { name: string; columns: string[]; refTable: string; refColumns: string[]; onDelete: FkAction; onUpdate: FkAction; } interface CheckSnapshot { name: string; expression: string; } interface TableSnapshot { name: string; columns: Record; indexes: IndexSnapshot[]; foreignKeys: ForeignKeySnapshot[]; checks: CheckSnapshot[]; } /** * PostgreSQL ENUM type declaration. Currently PG-only; the field is * optional on `SchemaSnapshot` so other dialects don't have to carry * a phantom `enums: {}`. */ interface EnumSnapshot { name: string; /** Allowed values, in declaration order. PG preserves the order. */ values: readonly string[]; } /** * Resolved relation graph attached as a sidecar on the snapshot. * Lives on `SchemaSnapshot.relations` (optional). Keyed * sourceTable → relationName → resolved entry. Consumed by the * relational-query compiler in `packages/db/src/query/`. The * migration pipeline does not read this field — relations are * query-time sugar, not DDL. * * Shaped this way (rather than re-using the runtime `RelationsDecl`) * so the snapshot stays JSON-serializable: no function thunks, no * back-references to table objects. */ interface RelationSnapshot { kind: 'one' | 'many'; /** Target table name. */ target: string; /** Columns on the source table that participate in the join. */ sourceColumns: readonly string[]; /** Columns on the target table that participate in the join. */ targetColumns: readonly string[]; /** * Optional pairing tag from `relationName: 'foo'` on both sides of * the relation. Disambiguates multi-FK schemas. See * docs/db/spec-relation-name.md (M4.B). */ relationName?: string; } interface SchemaSnapshot { version: 1; dialect: Dialect$1; tables: Record; /** ENUM types declared via `pgEnum()`. PG-only; absent on other dialects. */ enums?: Record; /** * Optional relation sidecar populated when the schema includes * `relations()` declarations. Absent when no relations are * declared so M0/M1 callers see the same snapshot shape they * always did. */ relations?: Record>; } //#endregion //#region src/snapshot/extract.d.ts declare function extractSnapshot(schema: Record, dialect: Dialect$1): SchemaSnapshot; //#endregion //#region src/snapshot/render.d.ts /** * Render a SchemaSnapshot to TypeScript source matching the kickjs-db DSL. * Inverse of extractSnapshot(). * * Naming: tables become exported `const`s with the same name. Constants * starting with digits get an underscore prefix to stay JS-valid. * * Limits (M1 — refined in M2/M3): * - No relations() emission. Adopter adds them manually post-introspect. * - No checks (M1 doesn't model CHECK constraints in the snapshot). * - Default values pass through as-is. The DSL accepts string defaults, * so 'true' / 'CURRENT_TIMESTAMP' / "'foo'" all round-trip. * - Auto-derived constraint names (`__unique`, `
__fk`) * are detected and rendered as the chained .unique() / .references() form. * Custom-named constraints fall back to the third-arg callback / FK helper. */ declare function renderSchemaSource(snapshot: SchemaSnapshot): string; //#endregion //#region src/diff/types.d.ts interface CreateTable { kind: 'createTable'; table: TableSnapshot; } interface DropTable { kind: 'dropTable'; table: TableSnapshot; } interface RenameTable { kind: 'renameTable'; from: string; to: string; } interface AddColumn { kind: 'addColumn'; table: string; column: ColumnSnapshot; } interface DropColumn { kind: 'dropColumn'; table: string; column: ColumnSnapshot; } interface RenameColumn { kind: 'renameColumn'; table: string; from: string; to: string; } interface AlterColumn { kind: 'alterColumn'; table: string; column: string; before: ColumnSnapshot; after: ColumnSnapshot; } interface AddIndex { kind: 'addIndex'; table: string; index: IndexSnapshot; } interface DropIndex { kind: 'dropIndex'; table: string; index: IndexSnapshot; } interface AddForeignKey { kind: 'addForeignKey'; table: string; fk: ForeignKeySnapshot; } interface DropForeignKey { kind: 'dropForeignKey'; table: string; fk: ForeignKeySnapshot; } interface CreateEnum { kind: 'createEnum'; enum: EnumSnapshot; } interface DropEnum { kind: 'dropEnum'; enum: EnumSnapshot; } /** * PG ALTER TYPE … ADD VALUE — non-destructive value addition. * Removed values can't round-trip without dropping dependent columns; * the diff engine surfaces them via the separate `RemoveEnumValue` * advisory below. Pure reorderings (same value set, different order) * currently produce no diff at all — PG honours the canonical sort * order at storage time, so user-visible behaviour is unchanged. */ interface AddEnumValue { kind: 'addEnumValue'; enum: string; value: string; /** When set, emit `ALTER TYPE … ADD VALUE 'x' BEFORE 'y'`. */ before?: string; } /** * Change raised when an enum keeps the same name but loses one or * more values across the diff. PostgreSQL has no `ALTER TYPE … DROP * VALUE`, so the emitter renders a rename-recreate dance behind a * `-- KICK ENUM REMOVE` header. The runner refuses to apply such a * migration without `confirmEnumDrop: true` on `RunnerOptions` (or * `--confirm-enum-drop` from the CLI). * * Spec: docs/db/spec-enum-value-removal.md. */ interface RemoveEnumValue { kind: 'removeEnumValue'; /** Enum type name. */ enum: string; /** Values present in the previous snapshot but not in the next. */ removed: readonly string[]; /** * Full value list AFTER the removal. Carried on the change so the * emitter can render `CREATE TYPE … AS ENUM (…)` without needing * the next-snapshot reference. */ values: readonly string[]; /** * Columns in the next snapshot whose declared type is this enum. * Each gets one `ALTER TABLE … ALTER COLUMN … TYPE foo USING * column::text::foo` clause inside the rename-recreate block. * * `default` carries the column's literal SQL default expression as * declared on the prior snapshot, or `null` when the column has no * default. The emitter wraps the type swap in * `DROP DEFAULT` / `SET DEFAULT … ::""` brackets only when * this is non-null. Spec: docs/db/spec-default-preservation.md. */ affectedColumns: readonly { table: string; column: string; default: string | null; }[]; } type Change = CreateTable | DropTable | RenameTable | AddColumn | DropColumn | RenameColumn | AlterColumn | AddIndex | DropIndex | AddForeignKey | DropForeignKey | CreateEnum | DropEnum | AddEnumValue | RemoveEnumValue; type ChangeSet = Change[]; //#endregion //#region src/diff/engine.d.ts declare function diff(prev: SchemaSnapshot, next: SchemaSnapshot): ChangeSet; //#endregion //#region src/diff/invert.d.ts /** * Reverse a forward ChangeSet so emitting it produces the SQL that undoes * the forward migration. * * The reverse of an *unambiguous* change is exact (rename → rename swapped, * add → drop, drop → add). The reverse of an *ambiguous* change (drop column, * drop table, type widen, NOT NULL gain without default) is a defensible * best-effort derived from the snapshot the forward change carried — the * runner refuses to apply a non-reviewed migration in non-dev so the operator * always sees the draft before it touches a DB. * * The order is reversed too: drop FK before drop index before drop table is * the safe sequence for tearing down what create-FK / create-index / create- * table built up. */ declare function invertChanges(forward: ChangeSet): ChangeSet; declare function hasAmbiguousReverse(forward: ChangeSet): boolean; //#endregion //#region src/errors.d.ts declare class KickDbError extends Error { readonly code: string; constructor(code: string, message: string); } /** * Thrown by `kick db generate` when the diff would emit a * `removeEnumValue` change against a column whose default is one of * the values being removed. The rename-recreate dance preserves * column DEFAULTs through the type swap (M5.A.1), but it can't * preserve a default that's no longer in the enum's value list — the * `SET DEFAULT 'X'::"foo"` step would fail at apply time. * * The operator's options: change the column's default in the schema * to a value that survives the removal, or drop the default entirely. * * Spec: docs/db/spec-default-preservation.md. */ declare class RemovedValueAsDefaultError extends KickDbError { readonly enum: string; readonly table: string; readonly column: string; readonly value: string; constructor(enumName: string, table: string, column: string, value: string); } //#endregion //#region src/diff/composite-detect.d.ts /** * One composite-type field that holds the target enum. The composite * may itself be referenced by table columns; that second level is not * surfaced — the goal here is to refuse the rename-recreate, not to * map the full dependency graph. */ interface CompositeRef { /** Schema-qualified composite type name, e.g. `"public.address_t"`. */ composite: string; /** Attribute (field) within the composite that holds the enum. */ attribute: string; /** Schema-qualified enum type name. */ enum: string; } /** * Slim contract for a pg-protocol-compatible query function. Both * `pg.Pool` and `@neondatabase/serverless`'s Pool match this shape, as * does the `query` method on a pooled client. */ interface CompositeQueryRunner { query(sql: string, params?: readonly unknown[]): Promise<{ rows: R[]; }>; } /** * Find every PG composite type whose attribute(s) hold the given enum * type. `enumName` may be unqualified (treated as `public.`) or * schema-qualified (`schema.name`). * * Returns an empty array when: * - the enum doesn't exist in the live DB (the diff engine raised it * against a snapshot, but the DB hasn't applied the prior migration * yet — generate-time refusal would be a false alarm), or * - no composite references the enum (the M3.B path is safe). */ declare function detectCompositeReferences(runner: CompositeQueryRunner, enumName: string): Promise; /** * Thrown by `kick db generate` when the diff would emit one or more * `removeEnumValue` changes against an enum that is referenced by a * PG composite type. The rename-recreate dance can't reach into * composite fields, so the generator refuses to write the migration * rather than letting it fail at apply time. * * The operator's options: drop the composite, restructure it not to * use the enum, or keep the value and ship the change later. */ declare class CompositeEnumReferenceError extends KickDbError { readonly refs: readonly CompositeRef[]; constructor(refs: readonly CompositeRef[]); } //#endregion //#region src/migrate/errors.d.ts declare class MigrationError extends KickDbError {} declare class MigrationLockError extends MigrationError { constructor(message: string); } interface SchemaDiffSummary { added: string[]; removed: string[]; changed: string[]; } declare class MigrationDriftError extends MigrationError { readonly diff: SchemaDiffSummary; constructor(message: string, diff: SchemaDiffSummary); } declare class MigrationHashError extends MigrationError { readonly id: string; readonly expected: string; readonly actual: string; constructor(id: string, expected: string, actual: string); } declare class UnreviewedMigrationError extends MigrationError { readonly id: string; constructor(id: string); } /** * Thrown by the runner when a migration carries the `-- KICK ENUM * REMOVE` header and the operator hasn't passed `confirmEnumDrop: * true` (CLI: `--confirm-enum-drop`). Spec: * docs/db/spec-enum-value-removal.md §4. */ declare class MigrationEnumDropError extends MigrationError { readonly id: string; readonly enums: readonly string[]; readonly removed: readonly string[]; readonly columns: readonly string[]; constructor(id: string, enums: readonly string[], removed: readonly string[], columns: readonly string[]); } //#endregion //#region src/migrate/enum-drop-gate.d.ts /** * Runner gate for the `-- KICK ENUM REMOVE` header. * * Pure parser + decision function — no I/O, no adapter, no DB. The * runner reads up.sql, hands it to `parseEnumDropHeader`, and * passes the result to `enforceEnumDropGate` which throws * `MigrationEnumDropError` when the header is present and * `confirmEnumDrop` is falsy. * * Spec: docs/db/spec-enum-value-removal.md §4. */ /** * Parsed payload from the header block. Empty arrays for keys not * present (resilient to operators editing the migration by hand). */ interface EnumDropHeader { enums: string[]; removed: string[]; columns: string[]; } /** * Scan the first 64 lines of an up.sql for one or more enum-drop * header blocks. Returns null when no header is present. */ declare function parseEnumDropHeader(sql: string): EnumDropHeader | null; /** * Throws `MigrationEnumDropError` when the migration has an * enum-drop header and `confirmEnumDrop` is not set. Returns * silently otherwise. */ declare function enforceEnumDropGate(id: string, sql: string, confirmEnumDrop: boolean): EnumDropHeader | null; //#endregion //#region src/migrate/journal.d.ts interface JournalEntry { id: string; tag: string; hash: string; createdAt: string; } interface Journal { version: 1; dialect: Dialect$1; entries: JournalEntry[]; } declare function readJournal(migrationsDir: string, dialect: Dialect$1): Promise; declare function appendJournalEntry(migrationsDir: string, dialect: Dialect$1, entry: JournalEntry): Promise; declare function computeMigrationHash(migrationDir: string): Promise; declare function verifyMigrationHash(migrationDir: string, expected: string): Promise; //#endregion //#region src/migrate/adapter.d.ts interface MigrationRow { id: string; name: string; hash: string; batch: number; appliedAt: string; direction: 'up' | 'down'; } /** * Slim contract that connects the runner to a concrete database driver. * * Concrete impls: MemoryMigrationAdapter (this package, test-only) and * pgAdapter from @forinda/kickjs-db/pg. Future db-sqlite / db-mysql adapter * packages will satisfy this same shape so the runner stays driver-agnostic. */ interface MigrationAdapter { readonly dialect: Dialect$1; /** Idempotent CREATE TABLE IF NOT EXISTS for kick_migrations + kick_migrations_lock. */ ensureMigrationTables(): Promise; /** Read all applied migrations ordered by appliedAt asc, then id asc. */ listApplied(): Promise; /** Insert a new applied migration row; appliedAt is set by the DB. */ recordApplied(row: Omit): Promise; /** Delete an applied migration row (used by `migrate down`). */ removeApplied(id: string): Promise; /** Atomic lock acquire — true if we got it, false if held. Owner string is recorded for diagnostics. */ acquireLock(owner: string): Promise; /** Release the lock (no-op if not held). */ releaseLock(): Promise; /** Run arbitrary SQL inside a transaction. Used to apply up.sql / down.sql. */ applySqlInTx(sql: string): Promise; /** Apply SQL outside any transaction — for migrations with `meta.transaction: false` (CREATE INDEX CONCURRENTLY etc). */ applySqlNoTx(sql: string): Promise; /** Introspect the live schema; returns the canonical SchemaSnapshot. Used by drift detection and `kick db introspect`. */ introspect(): Promise; /** Close any underlying pool / connection. Caller-owned resources may keep the no-op. */ close(): Promise; } //#endregion //#region src/migrate/schema.d.ts declare const KICK_MIGRATIONS_TABLE = "kick_migrations"; declare const KICK_LOCK_TABLE = "kick_migrations_lock"; declare function migrationsTableDdl(dialect: Dialect$1): string; declare function lockTableDdl(dialect: Dialect$1): string; //#endregion //#region src/migrate/memory-adapter.d.ts /** * In-memory MigrationAdapter for unit tests. Lock semantics are exact (single- * holder atomic), but applySqlInTx / applySqlNoTx / introspect are shaped as * test-only stubs — the real DB-bound semantics are validated in db-pg's * integration tests, not here. */ declare class MemoryMigrationAdapter implements MigrationAdapter { readonly dialect: Dialect$1; private rows; private locked; private appliedSql; private currentSchema; ensureMigrationTables(): Promise; listApplied(): Promise; recordApplied(row: Omit): Promise; removeApplied(id: string): Promise; acquireLock(owner: string): Promise; releaseLock(): Promise; applySqlInTx(sql: string): Promise; applySqlNoTx(sql: string): Promise; introspect(): Promise; close(): Promise; /** Test-only setter — let drift tests stage a "live" schema state. */ __setIntrospectedSchema(snap: SchemaSnapshot): void; /** Test-only inspector — what SQL we received. */ __appliedSql(): readonly string[]; } //#endregion //#region src/migrate/introspect-types.d.ts /** * Driver-agnostic SQL runner. Both pg.Client and pg.Pool match this shape via * structural typing. Lets introspectPg() stay portable across pg / pg-pool / * @neondatabase/serverless without importing 'pg' from the core package. */ interface PgQueryRunner { query(sql: string, params?: readonly unknown[]): Promise<{ rows: R[]; }>; } interface IntrospectPgOptions { /** Default 'public'. */ schema?: string; /** Migration tracking tables to skip. Default ['kick_migrations', 'kick_migrations_lock']. */ excludeTables?: readonly string[]; } //#endregion //#region src/migrate/introspect-pg.d.ts declare function introspectPg(client: PgQueryRunner, opts?: IntrospectPgOptions): Promise; //#endregion //#region src/migrate/introspect-sqlite.d.ts /** * Minimal better-sqlite3 surface introspection needs (sync `.all()`). * * `all` is deliberately NOT method-generic: better-sqlite3 v12's own * `Statement.all(...params): Result[]` is non-generic, so a generic * method here would make a real `Database` instance structurally * incompatible (callers had to cast). Row typing happens inside this * module via per-call assertions instead. */ interface SqliteIntrospectDb { prepare(sql: string): { all(...params: unknown[]): unknown[]; }; } interface IntrospectSqliteOptions { excludeTables?: string[]; } /** * Read a live SQLite database into a {@link SchemaSnapshot} via * `sqlite_master` + `PRAGMA` walks. Type strings come back as the * column's *declared* affinity (`TEXT`, `INTEGER`, …) lowercased — SQLite * doesn't preserve the original DSL type (a `uuid()` column reads back as * `text`), so this is primarily for `kick db introspect` (reverse-engineer * a schema), not byte-exact drift against a code-first snapshot. */ declare function introspectSqlite(db: SqliteIntrospectDb, opts?: IntrospectSqliteOptions): SchemaSnapshot; //#endregion //#region src/migrate/introspect-mysql.d.ts /** Minimal mysql2 surface introspection needs. Returns `[rows, fields]`. */ interface MysqlIntrospectDb { query(sql: string, params?: readonly unknown[]): Promise<[R, unknown]>; } interface IntrospectMysqlOptions { excludeTables?: string[]; } /** * Read the current MySQL database into a {@link SchemaSnapshot} via * `information_schema`. Types come back as the column's declared * `COLUMN_TYPE` (`varchar(200)`, `tinyint(1)`, …) lowercased — MySQL * doesn't preserve the original DSL type, so this powers `kick db * introspect` rather than byte-exact drift against a code-first snapshot. */ declare function introspectMysql(db: MysqlIntrospectDb, opts?: IntrospectMysqlOptions): Promise; //#endregion //#region src/migrate/drift.d.ts type DriftBehavior = 'error' | 'warn' | 'ignore'; interface DriftLogger { warn: (message: string) => void; } declare function checkDrift(liveSnapshot: SchemaSnapshot, expectedSnapshot: SchemaSnapshot, behavior: DriftBehavior, log?: DriftLogger): Promise; //#endregion //#region src/adapter.d.ts type MigrationsOnBoot = 'fail-if-pending' | 'apply' | 'ignore'; interface KickDbAdapterConfig { /** The driver-bound MigrationAdapter — pgAdapter() in @forinda/kickjs-db/pg, etc. */ migrationAdapter: MigrationAdapter; /** Directory containing the generated migrations + _journal.json. */ migrationsDir: string; /** Boot policy. Default 'fail-if-pending' — mirror the operator-explicit philosophy. */ migrationsOnBoot?: MigrationsOnBoot; /** Drift detection mode. Default 'error' outside dev. */ driftCheck?: DriftBehavior; /** Default true outside dev. */ requireReviewed?: boolean; /** Optional DI token to register the migrationAdapter under, for adopters who need direct access. */ token?: InjectionToken; /** * Optional KickEventBus the adapter publishes migration events to. * When set, `db:migration-applied` fires after a successful * `migrateLatest()` on boot (apply policy only). Pair with * `DEVTOOLS_BUS` so the events surface in the DevTools panel: * * import { DEVTOOLS_BUS } from '@forinda/kickjs-devtools-kit/bus/token' * // Resolve only when devtools is actually wired — adopters who * // skip @forinda/kickjs-devtools never register the token, and * // resolve() throws on missing tokens. * const adapter = kickDbAdapter({ * ..., * bus: container.has(DEVTOOLS_BUS) ? container.resolve(DEVTOOLS_BUS) : undefined, * }) * * Type imported via `import type` so kickjs-db keeps devtools-kit * as an optional peer. */ bus?: import('@forinda/kickjs-devtools-kit/bus').KickEventBus; } /** * KickJS lifecycle adapter for kickjs-db. Three jobs: * * 1. On boot, decide what to do about pending migrations per `migrationsOnBoot`. * - 'fail-if-pending' (default): throw if any pending exists. Operators * run `kick db migrate latest` explicitly before deploys land. Avoids * the prisma footgun where migrations silently apply on deploy. * - 'apply': run migrateLatest() automatically. Useful for dev / preview * environments where convenience matters more than safety. * - 'ignore': boot regardless. Last-resort escape hatch. * 2. On shutdown, close the migrationAdapter (drains the pool, etc). * 3. Register the migrationAdapter under an optional DI token so adopters * can pull it for ad-hoc tooling. The KickDbClient (Task 19b) registers * separately under DB_PRIMARY. */ declare const kickDbAdapter: import("@forinda/kickjs").AdapterFactory; //#endregion //#region src/tokens.d.ts declare const DB_PRIMARY: InjectionToken; declare const DB_REPLICA: InjectionToken; /** * Alias for the default DB. Adopters who only have one database can inject * `DB_CLIENT` instead of remembering whether it's primary/replica. */ declare const DB_CLIENT: InjectionToken>; //#endregion //#region src/dsl/columns/types.d.ts /** * Runtime + type representation of a column reference (e.g. `users.id`). * Carries the parent table name, the column's own name, plus runtime * accessors used by FK thunks and constraint builders. * * Exported so adopters can annotate self-referencing thunks without * spelling the shape inline: * * parentId: uuid().references((): ColumnRef => categories.id) * * Without the annotation the initializer of a self-referencing const * trips TS7022 — TS needs to infer the const while the initializer * already references it. */ interface ColumnRef { __tableName: string; __name: string; __builder: ColumnBuilder; __state: () => ReturnType; } /** * Resolved FK spec — `table` / `column` are pulled by invoking `thunk()` * lazily. The thunk pattern lets self-referencing tables work: * * const categories = table('categories', { * id: uuid().primaryKey().defaultRandom(), * parentId: uuid().references((): ColumnRef => categories.id), * }) * * If we resolved at `.references()` call time, `categories` would TDZ-fail * inside its own initializer. Storing the thunk and resolving on read * (extract / render / emit) defers until after the const binding lands. */ interface FkSpec { thunk: () => ColumnRef; onDelete: FkAction; onUpdate: FkAction; } interface ColumnState { type: string; nullable: boolean; default: string | null; primaryKey: boolean; unique: boolean; references: FkSpec | null; } /** * Type-only brand attached to a column when it's auto-assigned by the * database (serial / bigserial / smallserial), has a runtime default * (`.default(...)`), or carries an expression default * (`uuid().defaultRandom()`, `timestamp().defaultNow()`). `SchemaToTypes` * reads this marker and wraps the column type in Kysely's `Generated` so * adopters can omit the column on insert. * * Runtime is a no-op — the symbol never reaches a value. */ declare const KICK_GENERATED: unique symbol; type GeneratedBrand = { readonly [KICK_GENERATED]?: true; }; /** * Type-only brand attached to a column when `.notNull()` or `.primaryKey()` * is called. `SchemaToTypes` reads this brand to decide whether the * column type is `T` (NOT NULL) or `T | null` (default nullable). * * Why a brand instead of a class generic: chained methods (notNull, * primaryKey) can return `this & NotNullBrand` to narrow nullability while * preserving the subclass identity — so `uuid().primaryKey().defaultRandom()` * still resolves `defaultRandom()` on `UuidBuilder`. A class generic * `` would collapse the subclass back to the parent. */ declare const KICK_NOT_NULL: unique symbol; type NotNullBrand = { readonly [KICK_NOT_NULL]?: true; }; /** * Re-attach the nullability / generated brands after a transform that * must return a *new* builder type (e.g. `.array()` widening `T` to * `T[]`). Without this, `integer().notNull().array()` silently dropped * `NotNullBrand` and the row type regressed to `number[] | null`. * * Uses the same `extends` checks as `SchemaToTypes` (client/schema-types.ts) * so detection stays consistent in both directions. */ type PreserveBrands = Out & (Self extends NotNullBrand ? NotNullBrand : unknown) & (Self extends GeneratedBrand ? GeneratedBrand : unknown); /** * Phantom-typed column builder. The `T` generic carries the column's TS * value type (number / string / Date / etc.); nullability is tracked via * the `NotNullBrand` intersection rather than a class generic so chain * methods preserve subclass identity. * * Both `T` and the brand are erased at runtime; they exist purely so * `SchemaToTypes` can pull them out per column. */ declare class ColumnBuilder { readonly __t?: T; protected state: ColumnState; constructor(type: string, defaults?: Partial); notNull(): this & NotNullBrand; primaryKey(): this & NotNullBrand; unique(): this; array(): PreserveBrands>; references(target: () => ColumnRef, opts?: { onDelete?: FkAction; onUpdate?: FkAction; }): this; /** * Mark the column as having a runtime / DB-assigned default. The * `GeneratedBrand` flows into `SchemaToTypes` so the column wraps * in `Generated` — adopters can `INSERT` without specifying it. * * Accepts the natural literal for the column type — `boolean().default(false)`, * `integer().default(0)`, `varchar().default('active')`. Non-string * literals are normalised to their SQL-literal text so the snapshot * (`ColumnSnapshot.default: string | null`) and migration emitter stay * string-only. For a quoted string default the text is the value * itself (`'active'`); booleans/numbers emit bare (`false`, `0`). */ default(value: string | number | boolean): this & GeneratedBrand; toJSON(name: string): ColumnSnapshot; __state(): Readonly; } //#endregion //#region src/dsl/constraints.d.ts interface IndexDecl { name: string; columns: string[]; unique: boolean; } interface ColRef { __name: string; } declare function index(name: string): { on(...cols: ColRef[]): IndexDecl; }; declare function unique(name: string): { on(...cols: ColRef[]): IndexDecl; }; //#endregion //#region src/dsl/table.d.ts interface TableDecl = Record> { __isTable: true; __name: TName; __columns: C; __indexes: IndexDecl[]; } type TableRefs> = TableDecl & { [K in keyof C]: ColumnRef }; type ConstraintBuilder> = (refs: { [K in keyof C]: ColumnRef }) => Record; /** * Declare a typed table. The `TName extends string` generic narrows to the * literal table name so `SchemaToTypes` can index by it without losing * the constant — `table('users', …)` widens to `TableDecl<'users', …>`, * not `TableDecl`. */ declare function table>(name: TName, columns: C, constraints?: ConstraintBuilder): TableRefs; //#endregion //#region src/client/schema-types.d.ts /** * Pull each column's TS type and nullability into the row shape Kysely * consumes as its `Database` interface. * * - Columns carrying the `GeneratedBrand` (set by serial / bigSerial / * `default(...)` / `defaultNow()` / `defaultRandom()`) wrap in * Kysely's `Generated` so adopters can omit them on insert. * - `notNull()` / `primaryKey()` stamp `NotNullBrand`, which drops the * `| null` from the row type for that column. * - `jsonb<{...}>()` carries the user-declared shape through without * widening to `unknown`. * * The `Generated | null` form for nullable + default columns models the * SQL semantics: omitted on insert, the DB returns the default; if `null` * is explicitly inserted, the DB stores null. */ type IsNullable = C extends NotNullBrand ? false : true; type ColumnTSType = C extends ColumnBuilder ? IsNullable extends true ? C extends GeneratedBrand ? Generated | null : T | null : C extends GeneratedBrand ? Generated : T : never; type SchemaToTypes = { [K in keyof S as S[K] extends TableDecl> ? S[K]['__name'] : never]: S[K] extends TableDecl ? { [Col in keyof C]: ColumnTSType } : never }; //#endregion //#region src/client/create.d.ts declare function createDbClient>(opts: CreateDbClientOptions): KickDbClient; //#endregion //#region src/client/plugins.d.ts /** * Pass this to `createDbClient({ plugins: [...] })` so * `eb('col', '=', null)` (plus `!=` / `<>`) compiles to `IS NULL` / * `IS NOT NULL` instead of the silently-false `= NULL` default. * * Without the plugin, Kysely passes `null` through as a bound * parameter — the resulting `col = $1` evaluates to UNKNOWN under * three-valued logic, which filters out every row including the * ones the adopter intended to match. The plugin rewrites the AST * before compilation so the operator becomes `IS` / `IS NOT` and * the null literal flows inline (no `$N` parameter binding). * * ```ts * import { createDbClient, safeNullComparison } from '@forinda/kickjs-db' * * const db = createDbClient({ * schema, * dialect: pgDialect({ pool }), * plugins: [safeNullComparison()], * }) * * await db.selectFrom('users').where('deletedAt', '=', null).selectAll().execute() * // → SQL: select * from "users" where "deletedAt" is null * ``` * * Opt-in; default `createDbClient` chains stay byte-identical so * existing repos that work around the gotcha manually don't see a * behaviour change. * * **Why a kickjs-side helper rather than re-exporting Kysely's?** * Kysely 0.29's own `SafeNullComparisonPlugin` ships broken on PG — * it rewrites the operator but keeps the null operand parameterised, * producing `WHERE "col" IS $1` with `$1=null`, which PG rejects * with `syntax error at or near "$1"`. The kickjs version emits the * literal `null` keyword inline so PG accepts it. Tracked upstream * at . */ declare function safeNullComparison(): KyselyPlugin; //#endregion //#region src/migrate/runner.d.ts interface RunnerOptions { adapter: MigrationAdapter; migrationsDir: string; /** When true, refuse to apply migrations whose meta.json.reviewed is false. Defaults to true outside dev. */ requireReviewed?: boolean; /** Owner string written into the lock table for diagnostics. */ owner?: string; /** Drift detection mode. Default 'error'. */ driftCheck?: DriftBehavior; /** Logger surface for drift warnings. Defaults to console. */ log?: DriftLogger; /** * Allow migrations carrying the `-- KICK ENUM REMOVE` header to * apply. Default `false`. CLI exposes via `--confirm-enum-drop`. * Spec: docs/db/spec-enum-value-removal.md. */ confirmEnumDrop?: boolean; } interface AppliedSummary { applied: string[]; batch: number | null; } declare function migrateLatest(opts: RunnerOptions): Promise; declare function migrateUp(opts: RunnerOptions): Promise; interface ReversedSummary { reversed: string | null; } declare function migrateDown(opts: RunnerOptions): Promise; interface RollbackSummary { reversed: string[]; batch: number | null; } interface StatusEntry { id: string; tag: string; hash: string; state: 'applied' | 'pending'; batch: number | null; appliedAt: string | null; reviewed: boolean; } declare function migrateStatus(opts: Pick): Promise; declare function migrateRollback(opts: RunnerOptions): Promise; //#endregion //#region src/migrate/review.d.ts interface ReviewResult { id: string; /** True when the migration was already reviewed (no-op). */ alreadyReviewed: boolean; } /** * Mark a migration as reviewed: flip `meta.json.reviewed` to `true` — * the ONLY review state the runner checks. The SQL files carry an * immutable provenance banner (`-- Generated by @forinda/kickjs-db vX`), * so reviewing never touches them and the journal hash stays valid. * * Legacy migrations (generated before the banner) still carry mutable * `-- REVIEWED: false` markers inside the hashed files; for those we * keep the old behaviour — swap the markers and recompute the journal * hash so all three stay in sync. */ declare function reviewMigration(migrationsDir: string, id: string): Promise; //#endregion //#region src/emit/pg.d.ts declare function emitPg(changes: ChangeSet): string; //#endregion //#region src/emit/sqlite.d.ts /** * Raised when a change set needs a SQLite table rebuild but the emitter * wasn't given the resolved snapshots to build it from (it only has the * per-change diff). `generate()` always passes the snapshots, so this only * surfaces if `emitSqlite` is called bare with a rebuild-requiring change. */ declare class SqliteRebuildRequiredError extends Error { constructor(detail: string); } /** * Resolved before/after schema snapshots, threaded in by `generate()` so * the emitter can build the 12-step table-rebuild for changes SQLite's * `ALTER TABLE` can't express (column type/null/default changes, FK * add/drop on an existing table). `to` is the schema *after* the changes * apply; `from` is before — their column intersection drives the * `INSERT ... SELECT` data copy. */ interface SqliteEmitContext { from?: SchemaSnapshot; to?: SchemaSnapshot; } /** * Emit SQLite DDL for a change set. * * Most operations map to a direct statement (CREATE/DROP/RENAME TABLE, * ADD/DROP/RENAME COLUMN, CREATE/DROP INDEX). The ones SQLite can't `ALTER` * directly — `alterColumn`, and foreign-key add/drop on an existing table — * are handled by a **table rebuild**: create a new table with the desired * shape, copy rows, drop the old, rename, recreate indexes. Foreign keys * are folded into `CREATE TABLE` (SQLite has no `ADD CONSTRAINT`). */ declare function emitSqlite(changes: ChangeSet, ctx?: SqliteEmitContext): string; //#endregion //#region src/emit/mysql.d.ts /** * Emit MySQL DDL for a change set. * * MySQL has full `ALTER TABLE` support (unlike SQLite), so this mirrors * the Postgres emitter's structure — column/FK/index changes map to direct * ALTERs. The MySQL-specific bits: * - backtick identifiers + PG→MySQL type mapping; * - a single integer PK is emitted inline as `... AUTO_INCREMENT PRIMARY * KEY` (MySQL requires an auto-increment column to be a key); * - `alterColumn` uses `MODIFY COLUMN` (MySQL restates the whole column * definition at once, rather than PG's separate SET TYPE / SET DEFAULT * / SET NOT NULL clauses); * - `dropForeignKey` uses `DROP FOREIGN KEY` (not `DROP CONSTRAINT`). * - PG `ENUM` type changes are PG-only and throw (MySQL enums are inline * column types, not standalone objects). */ declare function emitMysql(changes: ChangeSet): string; //#endregion //#region src/cli/config.d.ts type MigrationAdapterFactory = () => MigrationAdapter | Promise; interface DbConfig { schemaPath: string; migrationsDir: string; dialect: Dialect$1; /** * How `kick db migrate` reacts when the live DB has schema not recorded * in the migrations (someone ran DDL out of band): `'error'` (default — * refuse), `'warn'` (log + continue), `'ignore'` (skip the check). The * check is dialect-normalised, so SQLite/MySQL's lossy introspection * doesn't false-positive. */ driftCheck?: DriftBehavior; /** * Postgres connection string for the built-in pgAdapter path. Read from * `db.connectionString` in kick.config.ts, or falls back to the * DATABASE_URL env var. The CLI uses this when no `adapter` factory is * provided. */ connectionString?: string; /** * Escape hatch: a factory returning a fully-constructed MigrationAdapter. * Takes precedence over `connectionString` when both are set. Use this * for non-default adapter wiring (custom pool, neon-serverless, etc). */ adapter?: MigrationAdapterFactory; } declare function resolveDbConfig(opts: { configPath: string; }): Promise; //#endregion //#region src/cli/generate.d.ts interface GenerateOptions { name: string; config: DbConfig; cwd: string; now?: () => Date; /** * When true, skip the schema diff and emit an empty migration shell * (up.sql / down.sql with just the generated-by banner, snapshot.json copying * the prior schema state). Used for data migrations, seed inserts, or any * change the diff engine can't author. Matches knex's `migrate:make`. */ empty?: boolean; /** * M4.C — generate-time gate for `removeEnumValue` changes. When the * diff produces one or more, this callback is invoked once per * affected enum to surface PG composite-type references. A non-empty * result aborts generate with `CompositeEnumReferenceError` (the * rename-recreate USING-cast can't reach into composite fields). * * Optional: when omitted, generate skips the check (no DB connection * required). The CLI wires this for `dialect=postgres` workflows. */ detectCompositeRefs?: (enumName: string) => Promise; } interface GenerateResult { status: 'created' | 'no-changes'; migrationDir?: string; changeCount: number; empty?: boolean; } declare function generate(opts: GenerateOptions): Promise; //#endregion //#region src/dsl/columns/builders.d.ts declare function serial(): ColumnBuilder & GeneratedBrand & NotNullBrand; declare function bigSerial(): ColumnBuilder & GeneratedBrand & NotNullBrand; declare function smallSerial(): ColumnBuilder & GeneratedBrand & NotNullBrand; declare function integer(): ColumnBuilder; declare function bigint(): ColumnBuilder; declare function smallint(): ColumnBuilder; declare function decimal(precision?: number, scale?: number): ColumnBuilder; declare function numeric(precision?: number, scale?: number): ColumnBuilder; declare function real(): ColumnBuilder; declare function doublePrecision(): ColumnBuilder; declare function varchar(length?: number): ColumnBuilder; declare function char(length?: number): ColumnBuilder; declare function text(): ColumnBuilder; declare function boolean(): ColumnBuilder; /** * Subtype builder so `defaultNow()` can mark the resulting column as * generated — when the DB will fill in `CURRENT_TIMESTAMP` if the adopter * omits the column on insert. Returns `this & GeneratedBrand` so the * subclass identity is preserved through the chain. */ declare class TimestampBuilder extends ColumnBuilder { constructor(typeName?: string); defaultNow(): this & GeneratedBrand; } declare function timestamp(): TimestampBuilder; declare function timestamptz(): TimestampBuilder; declare function date(): ColumnBuilder; declare function time(): ColumnBuilder; declare function interval(): ColumnBuilder; /** * Subtype builder so `defaultRandom()` can mark the resulting column as * generated — when the DB fills in `gen_random_uuid()` for omitted columns. * Returns `this & GeneratedBrand` so chaining works in either order: * uuid().defaultRandom().primaryKey() * uuid().primaryKey().defaultRandom() ← also works */ declare class UuidBuilder extends ColumnBuilder { constructor(); defaultRandom(): this & GeneratedBrand; } declare function uuid(): UuidBuilder; /** * The `T` generic exists so adopters can declare their JSON shape: * * meta: jsonb<{ tags: string[] }>() * * `SchemaToTypes` then sees `ColumnBuilder<{ tags: string[] }>` and the * row type narrows to `{ tags: string[] } | null`. */ declare function json(): ColumnBuilder; declare function jsonb(): ColumnBuilder; declare function bytea(): ColumnBuilder; //#endregion //#region src/dsl/relations.d.ts /** * Generic over the target table so the typegen plugin can pull * `target['__name']` without losing the literal string at the type * level. Existing callers that only read `kind` / `fields` / * `references` see the same surface. */ interface RelationOne> = TableDecl>> { kind: 'one'; target: TTarget; fields: ColumnRef[]; references: ColumnRef[]; /** * Disambiguates this relation from sibling `one` relations on the * same source table that point at the same target. Pair with the * matching `relationName` on the inverse `many` side. See * docs/db/spec-relation-name.md. */ relationName?: string; } interface RelationMany> = TableDecl>> { kind: 'many'; target: TTarget; /** * Pairs with the matching `relationName` on the inverse `one` * declaration. Required when the source table has multiple FKs * to the same target; resolver throws * `RelationalQueryMissingInverseError` otherwise. */ relationName?: string; } type Relation = RelationOne | RelationMany; /** * Generic so the typegen plugin can read the source table name and * the per-relation kind/target via `RelationsDecl['__sourceTable']` * and `RelationsDecl['__relations']`. The runtime shape is * unchanged; the generic parameters narrow the type at call sites. */ interface RelationsDecl = Record> { __isRelations: true; __sourceTable: TSource; __relations: TRelations; } interface Helpers { one: >>(target: T, opts: { fields: ColumnRef[]; references: ColumnRef[]; relationName?: string; }) => RelationOne; many: >>(target: T, opts?: { relationName?: string; }) => RelationMany; } /** * Declare a typed relation set for `source`. The return type * preserves `source.__name` and the literal `kind`/`target` of every * helper-built entry so `SchemaToRelationsRegister` (re-exported * from `@forinda/kickjs-db`) can walk the schema barrel and emit a * matching `KickDbRelationsRegister` augmentation at typegen time. */ declare function relations>, R extends Record>(source: T, builder: (h: Helpers) => R): RelationsDecl; //#endregion //#region src/custom-type.d.ts interface CustomTypeOptions { /** * SQL data type as it would appear in `CREATE TABLE` — `'text'`, * `'jsonb'`, `'citext'`, `'geometry(Point, 4326)'`, etc. Returned * via a thunk so adopters can compute the type from runtime config * (e.g. dialect-specific overrides). */ dataType: () => string; /** Optional encode hook applied at insert / update time. */ toDriver?: (value: TJs) => TDriver; /** Optional decode hook applied to selected rows. */ fromDriver?: (driver: TDriver) => TJs; } /** * ColumnBuilder subclass produced by `customType()`. Carries the * driver codecs so the (future) hooks pipeline can wire them through * a Kysely plugin without each consumer re-declaring its mapping. * * The phantom `T` flows through `SchemaToTypes` exactly like any * other ColumnBuilder, so adopters get full row-shape inference * for free. */ declare class CustomColumnBuilder extends ColumnBuilder { /** Encode hook — run on values heading into the database. */ readonly toDriver?: (value: TJs) => unknown; /** Decode hook — run on row values coming out of the database. */ readonly fromDriver?: (driver: unknown) => TJs; constructor(opts: CustomTypeOptions); } /** * Build a reusable column factory for a custom type. The returned * function is what callers use inside `table('foo', { col: factory() })` * — same shape as the built-in `varchar()`, `text()`, etc. * * @example * ```ts * const ulid = customType({ * dataType: () => 'char(26)', * toDriver: (s) => s, * fromDriver: (raw) => String(raw), * }) * * const events = table('events', { * id: ulid().primaryKey(), * ts: timestamp().notNull().defaultNow(), * }) * ``` */ declare function customType(opts: CustomTypeOptions): () => CustomColumnBuilder; //#endregion //#region src/query/relations.d.ts type ResolvedRelation = RelationSnapshot; /** * Sidecar map: source table → relation name → resolved entry. Lives * on `SchemaSnapshot.relations` and is populated by * `extractRelations()` (`query/extract-relations.ts`). */ type ResolvedRelations = Record>; //#endregion //#region src/query/schema-relations-types.d.ts /** * Distribute over `S` (the schema record), keeping only the entries * that are `RelationsDecl<...>`. Each entry contributes one row to * the output object — keyed by the source table's `__name` and * carrying the per-relation `{ kind, target }` map. * * `Record>` is the * structural shape consumed by `KickDbRelationsRegister`; this type * narrows it to the literal table names present in the schema. */ type SchemaToRelationsRegister = MergeBySource<{ [K in keyof S]: S[K] extends RelationsDecl ? Source extends string ? R extends Record ? { source: Source; relations: ResolveRelations; } : never : never : never }[keyof S]>; /** * Pull `{ kind, target }` for each relation entry. `target` shrinks * to the literal table name so the registry stays declarative * (matches the `RelationMapEntry` shape — see `query/types.ts`). */ type ResolveRelations> = { [K in keyof R]: { kind: R[K]['kind']; target: R[K]['target'] extends TableDecl> ? N extends string ? N : string : string; } }; /** * Fold a union of `{ source, relations }` records into a single * object keyed by `source`. TypeScript distributes the conditional * across the union and the mapped type collects every member. */ type MergeBySource; }> = { [Source in U['source']]: Extract['relations'] }; //#endregion //#region src/query/errors.d.ts /** * Thrown at compile time when a `with` key references a relation * that the source table doesn't declare. */ declare class RelationalQueryUnknownRelationError extends KickDbError { readonly sourceTable: string; readonly relationKey: string; constructor(sourceTable: string, relationKey: string); } /** * Thrown at compile time when a `with` clause nests deeper than * `maxDepth` (spec §7 R-3, default 5). Catches infinite specs on * self-referencing tables before any SQL is built. */ declare class RelationalQueryDepthError extends KickDbError { readonly maxDepth: number; readonly trace: readonly string[]; constructor(maxDepth: number, trace: readonly string[]); } /** * Thrown at compile time when a relation name collides with a * literal column on the same table (spec §7 R-5). Forces the schema * author to rename one of them so the LATERAL alias stays * unambiguous. */ declare class RelationalQueryAliasCollisionError extends KickDbError { readonly sourceTable: string; readonly conflictingName: string; constructor(sourceTable: string, conflictingName: string); } /** * Thrown by `db.query.X.find{Many,First,Unique}` when an * `AbortSignal` passed via options fires (or is already aborted at * call time). Wraps the underlying cause — typically a DOMException * with `name === 'AbortError'`, or whatever the caller passed to * `AbortController.abort(reason)` — on the `cause` field for adopter * inspection (e.g. distinguishing HTTP timeout from explicit * cancellation from user-disconnect). * * Spec: docs/db/spec-abortsignal-threading.md. */ declare class RelationalQueryCancelledError extends KickDbError { readonly cause?: unknown; constructor(cause?: unknown); } /** * Thrown by SQLite + MySQL compiler stubs in v1. The interface ships * with PG only; the other dialects fill in during M4 without an API * change at the call site. */ declare class RelationalQueryNotSupportedError extends KickDbError { readonly dialect: string; constructor(dialect: string); } /** * Thrown at extract time when more than one inverse `one` declared * on the **target** table shares the same `relationName` AND points * back at the same source — the actual ambiguity case for resolver * step 1. Scope is per `(sourceTable, targetTable, relationName)`: * the same tag can be reused across unrelated table pairs. Spec: * docs/db/spec-relation-name.md §7 R-2. */ declare class RelationalQueryAmbiguousRelationNameError extends KickDbError { readonly sourceTable: string; readonly targetTable: string; readonly relationName: string; /** Relation keys on the target table whose inverse `one` shares the tag. */ readonly conflicting: readonly string[]; constructor(sourceTable: string, targetTable: string, relationName: string, conflicting: readonly string[]); } /** * Thrown at extract time when a `many` relation has no inverse * `one` declared on the target table. The compiler needs the FK * column pair to build the join predicate; without an inverse we * have no way to discover it. Adopters fix by declaring the inverse * `one` on the target side (drizzle-style symmetric declarations). */ declare class RelationalQueryMissingInverseError extends KickDbError { readonly sourceTable: string; readonly relationName: string; readonly targetTable: string; constructor(sourceTable: string, relationName: string, targetTable: string); } //#endregion //#region src/query/like.d.ts /** * LIKE / ILIKE pattern safety helpers. * * User-supplied search text dropped straight into a `LIKE` pattern lets * the user inject wildcards: searching for `100%` matches everything, * `a_b` matches `axb`. Worse, a literal `%` from the user combined with a * leading wildcard (`%${input}%`) can blow up to a full scan. These * helpers escape the LIKE metacharacters so the input is matched * literally. * * Escapes `%`, `_`, and the escape character itself. The default escape * char is backslash, which Postgres and SQLite honour by default; MySQL * also defaults to backslash. When you build the query, pair the pattern * with the matching `ESCAPE '\'` clause if your dialect/collation needs * it explicit. */ type LikeMatchMode = 'contains' | 'startsWith' | 'endsWith' | 'exact'; /** * Escape LIKE/ILIKE metacharacters in `input` so it matches literally. * * @example * ```ts * escapeLike('100%') // '100\\%' * escapeLike('a_b\\c') // 'a\\_b\\\\c' * ``` */ declare function escapeLike(input: string, escapeChar?: string): string; /** * Build a literal-safe LIKE pattern from user input. * * @example * ```ts * likePattern('john%', 'contains') // '%john\\%%' * likePattern('admin', 'startsWith') // 'admin%' * db.selectFrom('users') * .where('email', 'like', likePattern(ctx.qs().search, 'contains')) * ``` */ declare function likePattern(input: string, mode?: LikeMatchMode, escapeChar?: string): string; //#endregion //#region src/dialect-marker.d.ts /** * Explicit dialect tagging for `createDbClient`'s dialect detection. * * The historical `detectDialect` inspected Kysely ctor names * (`/Postgres/i.test(...)`) with a silent fallback to `'sqlite'` — so a * hand-rolled or future Kysely dialect whose ctor name didn't match * `Postgres`/`Mysql` was silently treated as SQLite, emitting the wrong * JSON aggregation primitives at compile time. * * KickJS's own dialect factories (`pgDialect` / `mysqlDialect` / * `sqliteDialect`) now stamp this marker, so detection is exact for the * supported path. The ctor-name heuristic remains as the fallback for * raw Kysely dialects an adopter constructs directly. * * `Symbol.for` so the marker is shared across module-identity boundaries * (multiple copies of `@forinda/kickjs-db`). */ declare const KICK_DIALECT: unique symbol; type DialectTag = 'postgres' | 'mysql' | 'sqlite'; /** Type guard — `true` when `value` is a supported dialect tag. */ declare function isDialectTag(value: unknown): value is DialectTag; /** Stamp a Kysely dialect object with its KickJS dialect tag (non-enumerable). */ declare function markDialect(dialect: T, tag: DialectTag): T; /** * Read the KickJS dialect tag off a dialect, or `undefined` when * unmarked. A garbage value (the marker is a global `Symbol.for`, so a * rogue stamp is possible) is rejected — `undefined` falls the caller * back to ctor-name detection rather than an impossible dialect state. */ declare function readDialectMark(dialect: object): DialectTag | undefined; //#endregion export { GenerateOptions as $, ColumnSnapshot as $n, IntrospectPgOptions as $t, bigSerial as A, hasAmbiguousReverse as An, ColumnRef as At, json as B, CreateEnum as Bn, KickDbAdapterConfig as Bt, Relation as C, UnreviewedMigrationError as Cn, SchemaToTypes as Ct, relations as D, detectCompositeReferences as Dn, index as Dt, RelationsDecl as E, CompositeRef as En, IndexDecl as Et, date as F, AddForeignKey as Fn, KICK_NOT_NULL as Ft, smallSerial as G, DropIndex as Gn, checkDrift as Gt, numeric as H, DropColumn as Hn, kickDbAdapter as Ht, decimal as I, AddIndex as In, NotNullBrand as It, time as J, RenameColumn as Jn, introspectMysql as Jt, smallint as K, DropTable as Kn, IntrospectMysqlOptions as Kt, doublePrecision as L, AlterColumn as Ln, DB_CLIENT as Lt, boolean as M, diff as Mn, FkSpec as Mt, bytea as N, AddColumn as Nn, GeneratedBrand as Nt, TimestampBuilder as O, KickDbError as On, unique as Ot, char as P, AddEnumValue as Pn, KICK_GENERATED as Pt, varchar as Q, CheckSnapshot as Qn, introspectPg as Qt, integer as R, Change as Rn, DB_PRIMARY as Rt, customType as S, SchemaDiffSummary as Sn, createDbClient as St, RelationOne as T, CompositeQueryRunner as Tn, table as Tt, real as U, DropEnum as Un, DriftBehavior as Ut, jsonb as V, CreateTable as Vn, MigrationsOnBoot as Vt, serial as W, DropForeignKey as Wn, DriftLogger as Wt, timestamptz as X, renderSchemaSource as Xn, SqliteIntrospectDb as Xt, timestamp as Y, RenameTable as Yn, IntrospectSqliteOptions as Yt, uuid as Z, extractSnapshot as Zn, introspectSqlite as Zt, SchemaToRelationsRegister as _, MigrationDriftError as _n, migrateLatest as _t, markDialect as a, migrationsTableDdl as an, RelationSnapshot as ar, emitMysql as at, CustomColumnBuilder as b, MigrationHashError as bn, migrateUp as bt, escapeLike as c, Journal as cn, emitPg as ct, RelationalQueryAmbiguousRelationNameError as d, computeMigrationHash as dn, AppliedSummary as dt, PgQueryRunner as en, Dialect$1 as er, GenerateResult as et, RelationalQueryCancelledError as f, readJournal as fn, ReversedSummary as ft, RelationalQueryUnknownRelationError as g, parseEnumDropHeader as gn, migrateDown as gt, RelationalQueryNotSupportedError as h, enforceEnumDropGate as hn, StatusEntry as ht, isDialectTag as i, lockTableDdl as in, IndexSnapshot as ir, resolveDbConfig as it, bigint as j, invertChanges as jn, ColumnState as jt, UuidBuilder as k, RemovedValueAsDefaultError as kn, ColumnBuilder as kt, likePattern as l, JournalEntry as ln, ReviewResult as lt, RelationalQueryMissingInverseError as m, EnumDropHeader as mn, RunnerOptions as mt, DialectTag as n, KICK_LOCK_TABLE as nn, FkAction as nr, DbConfig as nt, readDialectMark as o, MigrationAdapter as on, SchemaSnapshot as or, SqliteRebuildRequiredError as ot, RelationalQueryDepthError as p, verifyMigrationHash as pn, RollbackSummary as pt, text as q, RemoveEnumValue as qn, MysqlIntrospectDb as qt, KICK_DIALECT as r, KICK_MIGRATIONS_TABLE as rn, ForeignKeySnapshot as rr, MigrationAdapterFactory as rt, LikeMatchMode as s, MigrationRow as sn, TableSnapshot as sr, emitSqlite as st, ReadonlyKysely as t, MemoryMigrationAdapter as tn, EnumSnapshot as tr, generate as tt, RelationalQueryAliasCollisionError as u, appendJournalEntry as un, reviewMigration as ut, ResolvedRelation as v, MigrationEnumDropError as vn, migrateRollback as vt, RelationMany as w, CompositeEnumReferenceError as wn, TableDecl as wt, CustomTypeOptions as x, MigrationLockError as xn, safeNullComparison as xt, ResolvedRelations as y, MigrationError as yn, migrateStatus as yt, interval as z, ChangeSet as zn, DB_REPLICA as zt }; //# sourceMappingURL=index-DcuMZ9kb.d.mts.map