import type { Database } from './types.js' export type MaybePromise = T | Promise /** * Resolves the database available to one request. * * Bindings are deliberately opaque to the API. A Node adapter can ignore them, * while an edge adapter can read a runtime binding (for example, a Hyperdrive * connection) without coupling Hookfish to that runtime. */ export interface DatabaseBinding { getDatabase(bindings: Bindings): MaybePromise migrate?(bindings: Bindings): MaybePromise } /** A ready Hookfish database is also accepted for simple and embedded hosts. */ export type DatabaseInput = | Database | Promise | DatabaseBinding export function defineDatabase( getDatabase: (bindings: Bindings) => MaybePromise, migrate?: (bindings: Bindings) => MaybePromise, ): DatabaseBinding { return migrate ? { getDatabase, migrate } : { getDatabase } } function isDatabaseBinding( value: DatabaseInput, ): value is DatabaseBinding { return ( typeof value === 'object' && value !== null && 'getDatabase' in value && typeof value.getDatabase === 'function' ) } export async function resolveDatabase( input: DatabaseInput, bindings: Bindings, ): Promise { if (isDatabaseBinding(input)) return input.getDatabase(bindings) return input } export async function migrateDatabase( input: DatabaseInput, bindings: Bindings, ): Promise { if (!isDatabaseBinding(input) || !input.migrate) { throw new Error('The configured database does not support migrations.') } await input.migrate(bindings) }