import { DatabaseAdapter } from '@fossyl/core'; import { Kysely, MigrationProvider, Transaction, Migration } from 'kysely'; import { AsyncLocalStorage } from 'node:async_hooks'; /** * Configuration options for the Kysely adapter. */ type KyselyAdapterOptions = { /** Kysely instance configured with your database dialect */ client: Kysely; /** * Migration provider for running migrations on startup. * Use `createMigrationProvider()` to create one from a record of migrations. * * @example * ```typescript * import { createMigrationProvider } from '@fossyl/kysely'; * * const migrations = createMigrationProvider({ * '001_create_users': { up: ..., down: ... }, * }); * * kyselyAdapter({ client: db, migrations }); * ``` */ migrations?: MigrationProvider; /** * Run pending migrations automatically on startup. * Requires `migrations` to be provided. * @default false */ autoMigrate?: boolean; /** * Use transactions by default for write operations (POST/PUT). * @default true */ defaultTransaction?: boolean; }; declare function kyselyAdapter(options: KyselyAdapterOptions): { adapter: DatabaseAdapter>; db: Kysely; }; /** * Transaction context stored in AsyncLocalStorage. */ type TransactionContext = { trx: Transaction | Kysely; inTransaction: boolean; }; /** * Internal storage type for AsyncLocalStorage. * Uses `any` internally to avoid variance issues with Kysely's complex types. */ type InternalTransactionContext = { trx: any; inTransaction: boolean; }; /** * AsyncLocalStorage instance for managing transaction context. * This allows the transaction/client to be accessed anywhere in the call stack. */ declare const transactionContext: AsyncLocalStorage; /** * Get the current transaction or client from AsyncLocalStorage. * Use this in your service layer to access the database client. * * @throws Error if called outside of a database context * * @example * ```typescript * import { getTransaction } from '@fossyl/prisma-kysely'; * * async function createUser(name: string) { * const db = getTransaction(); * return db.insertInto('users').values({ name }).execute(); * } * ``` */ declare function getTransaction(): Transaction | Kysely; /** @deprecated Use `getDb` instead */ declare const getDb: typeof getTransaction; declare function setBaseClient(client: Kysely): void; declare function createDbProxy(): Kysely; declare const db: Kysely; /** * A migration with up and down functions. * Use Kysely's schema builder to define schema changes. * * @example * ```typescript * import type { KyselyMigration } from '@fossyl/kysely'; * * export const migration: KyselyMigration = { * async up(db) { * await db.schema * .createTable('users') * .addColumn('id', 'uuid', (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)) * .addColumn('name', 'varchar(255)', (col) => col.notNull()) * .addColumn('email', 'varchar(255)', (col) => col.notNull().unique()) * .addColumn('created_at', 'timestamp', (col) => col.notNull().defaultTo(sql`now()`)) * .execute(); * }, * async down(db) { * await db.schema.dropTable('users').execute(); * }, * }; * ``` */ type KyselyMigration = Migration; /** * A record of migrations keyed by their name. * Names should be sortable (e.g., timestamps or numbered prefixes). * * @example * ```typescript * import type { MigrationRecord } from '@fossyl/kysely'; * * export const migrations: MigrationRecord = { * '001_create_users': { * async up(db) { ... }, * async down(db) { ... }, * }, * '002_create_posts': { * async up(db) { ... }, * async down(db) { ... }, * }, * }; * ``` */ type MigrationRecord = Record; /** * Creates a migration provider from a record of migrations. * This is the simplest way to provide migrations to the adapter. * * @example * ```typescript * import { createMigrationProvider } from '@fossyl/kysely'; * * const migrations = createMigrationProvider({ * '001_create_users': { * async up(db) { * await db.schema.createTable('users')... * }, * async down(db) { * await db.schema.dropTable('users').execute(); * }, * }, * }); * * const database = kyselyAdapter({ client: db, migrations }); * ``` */ declare function createMigrationProvider(migrations: MigrationRecord): MigrationProvider; /** * Helper to define a migration with proper typing. * * @example * ```typescript * import { defineMigration } from '@fossyl/kysely'; * import { sql } from 'kysely'; * * export default defineMigration({ * async up(db) { * await db.schema * .createTable('users') * .addColumn('id', 'uuid', (col) => col.primaryKey()) * .execute(); * }, * async down(db) { * await db.schema.dropTable('users').execute(); * }, * }); * ``` */ declare function defineMigration(migration: Migration): Migration; /** * Result of running migrations. */ type MigrationResult = { /** Migrations that were executed */ executed: string[]; /** Any error that occurred */ error?: Error; }; /** * Run all pending migrations. * This is called automatically on startup if migrations are configured. */ declare function runMigrations(db: Kysely, provider: MigrationProvider): Promise; /** * Rollback the last migration. */ declare function rollbackMigration(db: Kysely, provider: MigrationProvider): Promise; /** * Get the status of all migrations. */ declare function getMigrationStatus(db: Kysely, provider: MigrationProvider): Promise<{ pending: string[]; executed: string[]; }>; export { type KyselyAdapterOptions, type KyselyMigration, type MigrationRecord, type MigrationResult, type TransactionContext, createDbProxy, createMigrationProvider, db, defineMigration, getDb, getMigrationStatus, getTransaction, kyselyAdapter, rollbackMigration, runMigrations, setBaseClient, transactionContext };