import type * as rdsdata from "@distilled.cloud/aws/rds-data"; import * as AWS from "alchemy/AWS"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import { Database } from "./Database.ts"; /** * Minimal shape of the RDS Data API surface the Kysely dialect drives — * promise-based so the same dialect serves the runtime (backed by the * `AWS.RDSData.*` bindings) and deploy-time migrations (backed by * distilled with ambient credentials). * * @internal */ export interface DataApiExecutor { readonly execute: (request: { sql: string; parameters?: rdsdata.SqlParameter[]; includeResultMetadata?: boolean; transactionId?: string; }) => Promise; readonly begin: () => Promise<{ transactionId?: string; }>; readonly commit: (transactionId: string) => Promise; readonly rollback: (transactionId: string) => Promise; } interface DataApiResponse { records?: rdsdata.Field[][]; columnMetadata?: rdsdata.ColumnMetadata[]; numberOfRecordsUpdated?: number; } /** * Build a Kysely dialect over the RDS Data API. * * Postgres-flavoured, with `$n` placeholders rewritten to the Data API's * named `:n` parameters. Streaming is unsupported (the Data API is * request/response). * * @internal */ export declare const makeDataApiDialect: (executor: DataApiExecutor) => Effect.Effect; export interface AuroraDataApiOptions { /** * Secrets Manager secret holding the database credentials. Required when * passing a bare `DBCluster`; defaults to the composite's `secret` when * passing an `AWS.RDS.Aurora` result. */ readonly secret?: AWS.SecretsManager.Secret; /** Database name inside the cluster. */ readonly database?: string; /** * Deploy-time automatic migration (over the Data API with ambient * credentials). `false` disables. * @default enabled */ readonly migrate?: false; } /** The `AWS.RDS.Aurora` composite pieces this layer consumes. */ interface AuroraLike { readonly cluster: AWS.RDS.DBCluster; readonly secret: AWS.SecretsManager.Secret; readonly writer: AWS.RDS.DBInstance; } /** * Aurora (RDS Data API) database layer for Better Auth — the optimal * Lambda → Aurora pairing: SQL over HTTPS with IAM auth, no VPC * attachment, no `pg`, no connection pooling concerns. * * Runtime access flows through the `AWS.RDSData.*` bindings, which grant * the host `rds-data:*` + `secretsmanager:GetSecretValue` IAM and inject * the cluster/secret ARNs. Requires the cluster to have the Data API * enabled (`AWS.RDS.Aurora` enables it by default). * * * ### Lambda with an Aurora-backed BetterAuth * Pass the `AWS.RDS.Aurora` composite directly — the layer wires the * cluster, credentials secret, and the writer-instance dependency (so * deploy-time migrations wait for the cluster to be queryable) from one * value. * **Example:** Function URL serving auth over the Data API * ```typescript * import { BetterAuth } from "@alchemy.run/better-auth"; * import { AuroraDataApi } from "@alchemy.run/better-auth/AuroraDataApi"; * import * as AWS from "alchemy/AWS"; * * export const Db = AWS.RDS.Aurora("AuthDb", { subnetIds, securityGroupIds }); * * export default AuthFunction.make( * { main, url: true, memorySize: 512 }, * Effect.gen(function* () { * const auth = yield* BetterAuth({ emailAndPassword: { enabled: true } }); * return { fetch: ... }; * }).pipe(Effect.provide(AuroraDataApi(Db, { database: "postgres" }))), * ); * ``` * * ### Serverless v2 scale-from-zero * A paused cluster answers `DatabaseResumingException` while waking; the * layer retries the transient window with bounded backoff at both deploy * and runtime. * **Example:** Bare cluster + explicit secret * ```typescript * AuroraDataApi(cluster, { secret, database: "auth" }) * ``` * * @layer * @provides BetterAuth.Database * @peer kysely * @peer @distilled.cloud/aws * @product Aurora */ export declare const AuroraDataApi: (cluster: AWS.RDS.DBCluster | AuroraLike | Effect.Effect, options?: AuroraDataApiOptions) => Layer.Layer; export {}; //# sourceMappingURL=AuroraDataApi.d.ts.map