// Isolated SQLite backend for e2e tests. // // The shipped runtime (Pikku Fabric) serves the API with an injected SQLite // kysely built via `createSQLiteKysely`. The standalone `start.ts` uses the // libsql *web* dialect, which only talks to a remote libsql server — it can't // open a local file. This entry mirrors the Fabric runtime instead: it opens the // local better-sqlite3 database (provisioned by `pikku db reset` in the e2e // hooks) and injects the resulting kysely into `createSingletonServices` so // better-auth (account/session tables) works fully offline and per-run isolated. // // Env: // E2E_DB_FILE path to the provisioned sqlite file to open // PORT http port (default 6099) // BETTER_AUTH_SECRET better-auth signing secret (default e2e-test-secret) import { resolve, dirname } from 'node:path' import { fileURLToPath } from 'node:url' import Database from 'better-sqlite3' import { Kysely, SqliteDialect, CamelCasePlugin } from 'kysely' import { SerializePlugin } from '@pikku/kysely' import { PikkuFastifyServer } from '@pikku/fastify' import type { DB } from '@perauset/functions/.pikku/db/schema.js' import { createConfig } from '@perauset/functions/src/config.js' import { createSingletonServices } from '@perauset/functions/src/services.js' import '@perauset/functions/.pikku/pikku-bootstrap.gen.js' import '@perauset/functions/src/middleware.js' import '@perauset/functions/src/wirings/auth.wiring.js' import '@perauset/functions/src/wirings/http.wiring.js' import '@perauset/functions/src/wirings/http-phase1b.wiring.js' import '@perauset/functions/src/wirings/http-phase2.wiring.js' import '@perauset/functions/src/lib/permissions.js' const __dirname = dirname(fileURLToPath(import.meta.url)) const projectDir = resolve(__dirname, '../..') function openDatabase(dbFile: string): Database.Database { // The db file is provisioned by `pikku db reset` (migrations + sqlite-seed.sql) // before this process starts — see the e2e BeforeAll hooks. Here we only open it. const db = new Database(dbFile) db.pragma('journal_mode = WAL') db.pragma('foreign_keys = ON') return db } async function main(): Promise { try { process.env.BETTER_AUTH_SECRET ??= 'e2e-test-secret' const dbFile = process.env.E2E_DB_FILE ?? resolve(projectDir, '.pikku-runtime/e2e.db') const db = openDatabase(dbFile) // Mirror the Fabric runtime's kysely: SerializePlugin for JSON columns + // CamelCasePlugin so camelCase model fields (and better-auth's userId etc.) // map to the snake_case columns in db/sqlite/*.sql. const kysely = new Kysely({ dialect: new SqliteDialect({ database: db }), plugins: [new SerializePlugin(), new CamelCasePlugin()], }) const config = await createConfig() const singletonServices = await createSingletonServices(config, { kysely }) const appServer = new PikkuFastifyServer(config, singletonServices.logger) appServer.enableExitOnSigInt() await appServer.init({ exposeErrors: true }) await appServer.start() } catch (e: any) { console.error(e.stack ?? e.toString()) process.exit(1) } } main()