import { PgClient } from "@effect/sql-pg" import { PostgreSqlContainer } from "@testcontainers/postgresql" import { Context, Data, Effect, Layer, Redacted, String } from "effect" export class ContainerError extends Data.TaggedError("ContainerError")<{ cause: unknown }> {} export class PgContainer extends Context.Service()("test/PgContainer", { make: Effect.acquireRelease( Effect.tryPromise({ try: () => new PostgreSqlContainer("postgres:alpine").start(), catch: (cause) => new ContainerError({ cause }) }), (container) => Effect.promise(() => container.stop()) ) }) { static readonly layer = Layer.effect(this)(this.make) static layerClient = Layer.unwrap( Effect.gen(function*() { const container = yield* PgContainer return PgClient.layer({ url: Redacted.make(container.getConnectionUri()) }) }) ).pipe(Layer.provide(this.layer)) static layerMakeClient = Layer.unwrap( Effect.gen(function*() { const container = yield* PgContainer return PgClient.layerFrom(PgClient.makeClient({ url: Redacted.make(container.getConnectionUri()) })) }) ).pipe(Layer.provide(this.layer)) static layerClientWithTransforms = Layer.unwrap( Effect.gen(function*() { const container = yield* PgContainer return PgClient.layer({ url: Redacted.make(container.getConnectionUri()), transformResultNames: String.snakeToCamel, transformQueryNames: String.camelToSnake }) }) ).pipe(Layer.provide(this.layer)) static layerClientSingleConnection = Layer.unwrap( Effect.gen(function*() { const container = yield* PgContainer return PgClient.layer({ url: Redacted.make(container.getConnectionUri()), maxConnections: 1 }) }) ).pipe(Layer.provide(this.layer)) }