import { DatabaseSync } from 'node:sqlite'; import { KyselyPlugin, Kysely } from 'kysely'; import { ConnectionMigrator, MaybePromise, SchemaDiffResult, PlanStep, PlanResult, IConnectionConfig, Connection, Dialect, IntrospectResult as IntrospectResult$1, TransactionOptions as TransactionOptions$1 } from 'lite-supa'; import { ParseResult } from 'libpg-query'; import { DeparserOptions } from 'pgsql-deparser'; /** * Nested object for runtime variable substitution. * Paths are resolved via lodash-style dot-path access (e.g. "auth.jwt.role" → vars.auth.jwt.role). * e.g. { auth: { uid: "uuid-here", role: "authenticated", jwt: { role: "admin" } } } */ type VarsContext = Record; type ColumnDef = { column?: string; cast?: string; preCast?: string; aggregate?: AggregateFunction; bareCount?: boolean; path?: string; /** True when the trailing JSON-path operator was `->>` (text extract). */ pathText?: boolean; /** First key reached after an earlier `->>` text extraction. */ invalidJsonTextTraversalKey?: string; }; type EmbedDef = { select?: SelectEntry[]; where?: Where; order?: OrderEntry[]; limit?: number; offset?: number; spread?: boolean; join?: JoinMap; }; type SelectEntry = string | Record; type JoinDef = { from?: string; type?: "inner" | "left"; hint?: string; on?: Where; }; type JoinMap = Record; type Where = Record; type OrderEntry = { column: string; direction?: "asc" | "desc"; nullsFirst?: boolean; /** For ordering by embedded resource column: embed alias */ embed?: string; }; type ExplainOptions = { analyze?: boolean; verbose?: boolean; settings?: boolean; buffers?: boolean; wal?: boolean; }; type Meta = { cardinality?: "one" | "maybe" | "many"; count?: "exact" | "planned" | "estimated"; head?: boolean; maxAffected?: number; rollback?: boolean; missing?: "null" | "default"; handling?: "strict" | "lenient"; timezone?: string; columns?: string[]; stripNulls?: boolean; explain?: ExplainOptions; headers?: Record; return?: "minimal" | "headers-only" | "representation"; tx?: "commit" | "rollback"; }; type AnyAST = { type?: string; from?: string; function?: string; schema?: string; join?: JoinMap; select?: SelectEntry[]; where?: Where; values?: object | object[]; args?: object | unknown[]; order?: OrderEntry[]; limit?: number; offset?: number; group?: string[]; onConflict?: string[]; ignoreDuplicates?: boolean; httpMethod?: "GET" | "POST"; paramsType?: "named" | "positional"; inputType?: "json" | "text" | "binary" | "xml"; $meta?: Meta; }; type AggregateFunction = "count" | "sum" | "avg" | "min" | "max"; type TUnwrappedConst = string | number | boolean | null | undefined; type PolicyCommand = "SELECT" | "INSERT" | "UPDATE" | "DELETE" | "ALL"; type PolicyRole = "anon" | "authenticated" | string; interface PolicyData { name: string; table: string; schema?: string; command: PolicyCommand; permissive: boolean; roles: PolicyRole[]; using?: Where; withCheck?: Where; } declare class Policy { readonly data: PolicyData; constructor(data: PolicyData); appliesTo(cmd: "SELECT" | "INSERT" | "UPDATE" | "DELETE"): boolean; appliesToRole(role: string): boolean; toJSON(): PolicyData; static fromJSON(data: PolicyData): Policy; } declare class CheckConstraintError extends Error { readonly table: string; readonly column: string; readonly constraint: string; readonly value: unknown; constructor(table: string, column: string, constraint: string, value: unknown); } type SqliteType = "INTEGER" | "REAL" | "TEXT" | "BLOB" | "ANY"; type DefaultFn = () => unknown; interface ValidationResult { status: "pass" | "warn" | "fail"; message: string | null; action?: string; } interface FieldContext { schema: string; table: string; column: string; pgTypeName: string; nullable: boolean; defaultValue: string | null; defaultFn?: DefaultFn | null; isPrimaryKey: boolean; isUnique: boolean; isSerial: boolean; isGenerated?: boolean; fkRef?: { refSchema?: string; refTable: string; refColumn: string; constraintName?: string; }; hasCheck?: boolean; checkConstraintName?: string; uniqueConstraintName?: string; } interface ColumnDDLOptions { includeNullable?: boolean; } declare abstract class Field { readonly context: FieldContext; constructor(context: FieldContext); abstract get sqliteType(): SqliteType; get isShimBacked(): boolean; checkConstraint(): string | null; serialize(value: unknown): unknown; deserialize(value: unknown): unknown; validateStorage(_rawSqliteValue: unknown): ValidationResult; protected validationFail(message: string, action?: string): ValidationResult; protected validationPass(): ValidationResult; protected isNullish(value: unknown): value is null | undefined; toColumnDDL(options?: ColumnDDLOptions): string; protected checkError(constraint: string, value: unknown): CheckConstraintError; protected quoteIfNeeded(name: string): string; } type FunctionResolutionMode = "synthetic" | "translate" | "auto"; declare class TableSchema { readonly table: string; readonly schema: string; private fields; constructor(table: string, schema?: string, fields?: Map); get(col: string): Field | undefined; has(col: string): boolean; set(col: string, field: Field): void; columns(): string[]; all(): Field[]; serializeRow(row: Record): Record; deserializeRow(row: Record): Record; applyDefaults(row: Record): Record; } type CollectedEnums = Map; type CollectedVariable = { local?: boolean; value: TUnwrappedConst; }; type CollectedVariables = Map; type CollectedRlsTables = Set; type CollectedSchema = Map; type CollectedTableConstraint = { schema: string; table: string; kind: "unique" | "check" | "foreign_key"; name?: string; columns: string[]; refSchema?: string; refTable?: string; refColumns?: string[]; }; type CollectedComment = { schema: string; table: string; column?: string; text: string; }; interface TableInfo { name: string; sql: string; schema: string; type: "table" | "view"; rows: number; engine: string; collation: string; } interface ColumnInfo { table: string; name: string; type: string; nullable: boolean; default_value: string | null; is_primary_key: boolean; schema: string; ordinal_position: number; collation: string; character_maximum_length: string | null; precision: { precision: number | null; scale: number | null; } | null; is_identity: boolean; pg_type?: string; is_generated?: boolean; } interface IndexInfo { table: string; name: string; unique: boolean; columns: string[]; schema: string; } interface ForeignKeyInfo { table: string; column: string; ref_table: string; ref_column: string; on_update: string; on_delete: string; schema: string; ref_schema?: string; foreign_key_name: string; fk_def: string; is_visible?: boolean; } interface PrimaryKeyInfo { table: string; columns: string[]; schema: string; field_count: number; } interface ViewInfo { name: string; sql: string; schema: string; } interface CheckConstraintInfo { schema: string; table: string; expression: string; name?: string; column?: string; } interface UniqueConstraintInfo { schema: string; table: string; name: string; columns: string[]; } interface CommentInfo { schema: string; table: string; column?: string; text: string; } interface TriggerInfo { table: string; name: string; sql: string; schema: string; } interface CustomTypesInfo { schema: string; type: string; kind: "enum" | "composite"; values?: string[]; fields?: { name: string; type: string; }[]; } interface IntrospectResult { tables: TableInfo[]; columns: ColumnInfo[]; indexes: IndexInfo[]; foreign_keys: ForeignKeyInfo[]; primary_keys: PrimaryKeyInfo[]; views: ViewInfo[]; check_constraints: CheckConstraintInfo[]; unique_constraints: UniqueConstraintInfo[]; comments: CommentInfo[]; custom_types: CustomTypesInfo[]; triggers: TriggerInfo[]; database_name: string; version: string; ddl_dialect?: "postgres" | "sqlite"; schema_separator?: string; } type SchemaHandling = "default" | "prefix"; interface DeparseOptions extends DeparserOptions { schemaHandling?: SchemaHandling; forceDefaultSchema?: string | false; enums?: CollectedEnums; /** Current DB introspection. Required for ALTER TABLE ops that need 12-step rebuild. */ introspection?: IntrospectResult; functionResolution?: FunctionResolutionMode; } declare function deparsePostgresDdl(pgSql: string, options?: DeparseOptions & { strict?: boolean; }): Promise<{ ddl: string; enums: CollectedEnums; rls: { tables: CollectedRlsTables; policies: Policy[]; }; schema: CollectedSchema; vars: CollectedVariables; tableConstraints: CollectedTableConstraint[]; comments: CollectedComment[]; ast: ParseResult; }>; type SqliteMigratorOptions = { onTranslation?: (result: SqlitePostgresTranslationResult) => MaybePromise; }; declare class SqliteMigrator implements ConnectionMigrator { private readonly conn; private readonly desiredSchema; private readonly options; private readonly differ; private readonly planner; translationResult?: SqlitePostgresTranslationResult; constructor(conn: SqliteConnection, desiredSchema: string, options?: SqliteMigratorOptions); getDesiredSchema(): Promise; diff(): Promise; safeSortPlanSteps(steps: PlanStep[]): PlanStep[]; migratePlan(planResult: PlanResult, opts?: { force?: boolean; }): Promise; migrate(opts?: { force?: boolean; }): Promise; } interface ISqliteConnectionConfig extends IConnectionConfig { /** * The origin dialect for schema declarations. If "postgres", * the schema declarations will be translated to SQLite syntax. * If "sqlite", the schema declarations will be left as is. * @default "postgres" */ ddlDialect?: "postgres" | "sqlite"; /** * The origin dialect for query execution. If "sqlite", the queries will be executed as is. * Currently only "sqlite" is supported. * @default "sqlite" */ queryDialect?: "sqlite"; /** * Max bound parameters per statement. Enforced across all SQLite drivers * for portability: drivers and hosts vary in how many parameters they * accept (e.g. Cloudflare D1, sqlite-wasm), so we cap conservatively. * Statements exceeding this throw before execution. * @default 100 */ maxBoundParameters?: number; /** * Translation options for SQLite databases */ translation?: { /** * The approach to take when translating PostgreSQL schema declarations to SQLite syntax. * Only applies if `ddl` is "postgres". */ schemas?: { /** * The approach to take when translating PostgreSQL schema declarations to SQLite syntax. * If "quote" -> `public`.`table` -> `"public.table"` * If "snake_case" -> `public`.`table` -> `public__table` * @default "quote" */ approach?: "quote" | "snake_case"; /** * Whether to append the default schema to the table name when a table does not have a schema * @default false */ appendDefaultSchema?: boolean; /** * The default schema to use when a table does not have a schema * @default "public" */ defaultSchema?: string | false; }; /** * Deparse details the connection must be aware of */ deparse?: SqlitePostgresDeparseInfo; }; } type DeparsePostgresDdlResult = Awaited>; type SqlitePostgresDeparseInfo = Pick & Partial>; type SqlitePostgresTranslationResult = Pick & Partial; declare abstract class SqliteConnection extends Connection { dialect: Dialect; deserializeRow(row: Record): Record; constructor(config?: Config); static parseDeparseInfo(details: any): { rls?: undefined; vars?: undefined; } | { rls: { tables: any; policies: any; }; vars: any; }; updateDeparseInfo(details: NonNullable["deparse"]): void; protected withSqlitePlugins(add_plugins?: KyselyPlugin[]): KyselyPlugin[]; translateDdl(ddl: string): Promise; introspect(options?: { useCache?: boolean; postprocess?: boolean; }): Promise; transaction(statements: string[], opts?: TransactionOptions$1): Promise; close(): Promise; /** * When ddlDialect === "postgres", enrich the PRAGMA-derived IntrospectResult * with metadata recovered from the parsed Postgres DDL: real FK constraint * names, table-level UNIQUE/CHECK constraints, column pg_type / is_generated, * and comments. */ private mergeDeparseMetadata; private markForeignKeyVisibility; /** * Create a migrator for the given schema. * @param desiredSchema The desired schema to migrate to. Input DDL is expected to be `config.ddlDialect`. * @returns A migrator instance. */ createMigrator(desiredSchema: string): SqliteMigrator; get maxBoundParameters(): number; /** * Throws if the compiled statement has more bound parameters than * `maxBoundParameters`. Drivers call this from their query executor so * the same limit is enforced regardless of host capability. */ assertParamLimit(parameters: readonly unknown[] | undefined): void; /** * Asserts the parameter limit and normalizes bind values. Drivers call * this once per statement; same limit and same value coercion everywhere. */ prepareBindParams(parameters: readonly unknown[] | undefined): unknown[]; /** * Coerces JS values to types every SQLite driver accepts. Drivers vary: * `bun:sqlite` silently coerces booleans, `node:sqlite` throws. Normalize * centrally so the executor boundary behaves identically everywhere. * * - `undefined` is dropped (matches prior DO behaviour and Kysely slots * that never bound a value). * - `boolean` → `0` / `1`. * - pass-through: `null`, `number`, `bigint`, `string`, `Uint8Array`, * `ArrayBuffer`, `Date` (drivers handle these, or upstream field * serializers have already converted). * - unknown types throw with the offending index so divergence surfaces * loudly instead of as a driver-specific bind error. */ normalizeBindParams(parameters: readonly unknown[] | undefined): unknown[]; normalizeDbError(e: unknown): unknown; onPostgrestAST(ast: AnyAST, vars?: VarsContext): Promise; private applyRls; } interface INodeSqliteConnectionConfig extends ISqliteConnectionConfig { } declare class NodeSqliteConnection extends SqliteConnection { kysely: Kysely; driver: DatabaseSync; constructor(config?: INodeSqliteConnectionConfig); exec(query: string, ...parameters: readonly unknown[]): Promise; close(): Promise; } declare function createConnection(config?: INodeSqliteConnectionConfig): NodeSqliteConnection; type TransactionOptions = { intent?: "migration"; }; interface ICloudConnectionConfig extends ISqliteConnectionConfig { projectRef: string; token: string; host: string; } declare class CloudConnection extends SqliteConnection { readonly config: ICloudConnectionConfig; dialect: "sqlite"; driver: never; kysely: never; constructor(config: ICloudConnectionConfig); private fetch; introspect(options?: { useCache?: boolean; postprocess?: boolean; }): Promise; transaction(statements: string[], opts?: TransactionOptions): Promise; exec(statement: string, ...parameters: readonly unknown[]): Promise; close(): Promise; } declare function cloud(config: ICloudConnectionConfig): CloudConnection; export { CloudConnection, type ICloudConnectionConfig, type INodeSqliteConnectionConfig, type ISqliteConnectionConfig, SqliteConnection, type SqlitePostgresTranslationResult, cloud, createConnection };