import { Kysely, PostgresDialect } from "kysely"; import pg from "pg"; import type { DB } from "./types.ts"; // int8 → number(大小/序号都在 2^53 内;超出即报错而不是静默丢精度) pg.types.setTypeParser(pg.types.builtins.INT8, (v: string) => { const n = Number(v); if (!Number.isSafeInteger(n)) throw new RangeError(`int8 超出安全整数范围: ${v}`); return n; }); // date → 原样 'YYYY-MM-DD' 字符串,避免按本地时区转成 Date 造成日期漂移 pg.types.setTypeParser(pg.types.builtins.DATE, (v: string) => v); export interface CreateDbOptions { /** 默认读 process.env.DATABASE_URL */ connectionString?: string; max?: number; } /** 创建带连接池的 Kysely 实例;调用方负责在退出时 db.destroy() */ export function createDb(opts: CreateDbOptions = {}): Kysely { const connectionString = opts.connectionString ?? process.env.DATABASE_URL; if (!connectionString) throw new Error("DATABASE_URL 未设置"); const pool = new pg.Pool({ connectionString, max: opts.max ?? 10 }); return new Kysely({ dialect: new PostgresDialect({ pool }) }); }