@prisma-next/postgres 0.5.0-dev.9 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,11 +2,18 @@
2
2
 
3
3
  One-package Postgres setup for Prisma Next. Install this single package to get config, runtime, and all transitive type dependencies.
4
4
 
5
+ Two runtime facades ship under different entrypoints:
6
+
7
+ - `@prisma-next/postgres/runtime` — long-lived Node process facade with closure-cached `runtime()`, `orm`, and `transaction()`.
8
+ - `@prisma-next/postgres/serverless` — per-request facade for serverless / edge runtimes (Cloudflare Workers + Hyperdrive, AWS Lambda, Vercel, Deno Deploy, Bun edge). Each `connect()` returns a fresh `Runtime & AsyncDisposable`.
9
+
10
+ Pick the facade that matches your deployment lifecycle. The asymmetry is intentional: closure caching is unsafe across `fetch` invocations (stale connections after isolate idle, concurrent-query races, no clean shutdown), so the serverless facade deliberately omits `orm`, `runtime()`, and `transaction()`. See `docs/architecture docs/subsystems/4. Runtime & Middleware Framework.md` and the deployment guide for the rationale.
11
+
5
12
  ## Package Classification
6
13
 
7
14
  - **Domain**: extensions
8
15
  - **Layer**: adapters
9
- - **Planes**: shared (config), runtime (runtime)
16
+ - **Planes**: shared (config), runtime (runtime, serverless)
10
17
 
11
18
  ## Quick Start
12
19
 
@@ -20,6 +27,8 @@ export default defineConfig({
20
27
  });
21
28
  ```
22
29
 
30
+ ### Node (long-lived process)
31
+
23
32
  ```typescript
24
33
  // db.ts
25
34
  import postgres from '@prisma-next/postgres/runtime';
@@ -29,6 +38,28 @@ import contractJson from './contract.json' with { type: 'json' };
29
38
  export const db = postgres<Contract>({ contractJson });
30
39
  ```
31
40
 
41
+ ### Serverless / per-request runtimes
42
+
43
+ ```typescript
44
+ // db.ts — module scope: only the static authoring surface is built here.
45
+ import postgresServerless from '@prisma-next/postgres/serverless';
46
+ import type { Contract } from './contract.d';
47
+ import contractJson from './contract.json' with { type: 'json' };
48
+
49
+ export const db = postgresServerless<Contract>({ contractJson });
50
+
51
+ // worker.ts — per-request: acquire a fresh Runtime, dispose with `await using`.
52
+ export default {
53
+ async fetch(_req: Request, env: Env): Promise<Response> {
54
+ await using runtime = await db.connect({ url: env.HYPERDRIVE.connectionString });
55
+ const rows = await runtime.execute(db.sql.from(/* ... */).build());
56
+ return Response.json(rows);
57
+ },
58
+ };
59
+ ```
60
+
61
+ The returned client exposes `sql`, `context`, `stack`, `contract`, and `connect()` — and intentionally nothing else. Construct ORM clients (or invoke `withTransaction` from `@prisma-next/sql-runtime`) against the runtime returned by `connect()` instead of caching one on the closure.
62
+
32
63
  ## Exports
33
64
 
34
65
  ### `@prisma-next/postgres/config`
@@ -40,14 +71,10 @@ Simplified `defineConfig` that pre-wires all Postgres internals (family, target,
40
71
  `@prisma-next/postgres/runtime` exposes a single `postgres(...)` helper that composes the Postgres execution stack and returns query/runtime roots:
41
72
 
42
73
  - `db.sql`
43
- - `db.kysely` (lane-owned build-only authoring surface: `build(query)` + `whereExpr(query)`)
44
- - `db.schema`
45
74
  - `db.orm`
46
75
  - `db.context`
47
76
  - `db.stack`
48
77
 
49
- `db.kysely` is produced by `@prisma-next/sql-kysely-lane` and intentionally exposes lane behavior, not raw Kysely execution APIs. `build(query)` infers plan row type from `query.compile()`, and `whereExpr(query)` produces `ToWhereExpr` payloads for ORM `.where(...)` interop.
50
-
51
78
  Runtime resources are deferred until `db.runtime()` or `db.connect(...)` is called.
52
79
  Connection binding can be provided up front (`url`, `pg`, `binding`) or deferred via `db.connect(...)`.
53
80
 
@@ -56,11 +83,35 @@ When URL binding is used, pool timeouts are configurable via `poolOptions`:
56
83
  - `poolOptions.connectionTimeoutMillis` (default `20_000`)
57
84
  - `poolOptions.idleTimeoutMillis` (default `30_000`)
58
85
 
86
+ ### `@prisma-next/postgres/contract-builder`
87
+
88
+ Re-exports the TypeScript contract authoring DSL (`defineContract`, `field`, `model`, `rel`, ...) so a generated `prisma/contract.ts` can author its contract using only this facade package.
89
+
90
+ ### `@prisma-next/postgres/family`
91
+
92
+ Re-exports the SQL family pack (the value passed as `family:` to `defineContract`).
93
+
94
+ ### `@prisma-next/postgres/target`
95
+
96
+ Re-exports the Postgres target pack (the value passed as `target:` to `defineContract`).
97
+
98
+ ### `@prisma-next/postgres/serverless`
99
+
100
+ `@prisma-next/postgres/serverless` exposes `postgresServerless(...)` for per-request runtimes. The returned client exposes only:
101
+
102
+ - `db.sql`
103
+ - `db.context`
104
+ - `db.stack`
105
+ - `db.contract`
106
+ - `db.connect({ url })` — returns `Promise<Runtime & AsyncDisposable>`
107
+
108
+ Each `connect()` call constructs a fresh `pg.Client` and a fresh `Runtime`. No `pg.Pool` is allocated. `[Symbol.asyncDispose]` calls `runtime.close()`, which closes the underlying client. `pg-cursor` is enabled by default; opt out via `cursor: { disabled: true }`.
109
+
59
110
  ## Responsibilities
60
111
 
61
112
  - Build a static Postgres execution stack from target, adapter, and driver descriptors
62
- - Build typed SQL and a build-only Kysely authoring surface from the same execution context
63
- - Build static schema and ORM roots from the execution context
113
+ - Build a typed SQL authoring surface from the execution context
114
+ - Build a static ORM root from the execution context
64
115
  - Normalize runtime binding input (`binding`, `url`, `pg`)
65
116
  - Lazily instantiate runtime resources on first `db.runtime()` or `db.connect(...)` call
66
117
  - Connect the internal Postgres driver through `db.connect(...)` or from initial binding options
@@ -73,19 +124,17 @@ When URL binding is used, pool timeouts are configurable via `poolOptions`:
73
124
  - `@prisma-next/target-postgres` for target descriptor
74
125
  - `@prisma-next/adapter-postgres` for adapter descriptor
75
126
  - `@prisma-next/driver-postgres` for driver descriptor
76
- - `@prisma-next/sql-lane` for `sql(...)`
77
- - `@prisma-next/sql-kysely-lane` for contract-to-Kysely typing and build-only Kysely plan assembly
78
- - `@prisma-next/sql-relational-core` for `schema(...)`
127
+ - `@prisma-next/sql-builder` for `sql(...)`
79
128
  - `@prisma-next/sql-orm-client` for `orm(...)`
80
129
  - `@prisma-next/sql-contract` for `validateContract(...)` and contract types
81
- - `pg` for lazy `Pool` construction when using URL binding
130
+ - `pg` for `Pool` construction (URL / `pgPool` binding on the Node factory) and `Client` construction (`pgClient` binding on the Node factory; per-`connect()` on the serverless facade)
82
131
 
83
132
  ## Architecture
84
133
 
85
134
  ```mermaid
86
135
  flowchart TD
87
136
  App[App Code] --> Client[postgres(...)]
88
- Client --> Static[Roots: sql kysely(build-only) schema orm context stack]
137
+ Client --> Static[Roots: sql orm context stack]
89
138
  Client --> Lazy[runtime()]
90
139
 
91
140
  Lazy --> Instantiate[instantiateExecutionStack]
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.mts","names":[],"sources":["../src/config/define-config.ts"],"sourcesContent":[],"mappings":";;;;UAYiB,qBAAA;;EAAA,SAAA,EAAA,CAAA,EAAA;IAmBD,SAAA,UAAY,CAAA,EAAU,MAAA;;iCAdL;;;;;iBAcjB,YAAA,UAAsB,wBAAwB"}
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../src/config/define-config.ts"],"mappings":";;;;UAYiB,qBAAA;EAAA,SACN,QAAA;EAAA,SACA,EAAA;IAAA,SACE,UAAA;EAAA;EAAA,SAEF,UAAA,YAAsB,0BAAA;EAAA,SACtB,UAAA;IAAA,SACE,GAAA;EAAA;AAAA;AAAA,iBAYG,YAAA,CAAa,OAAA,EAAS,qBAAA,GAAwB,gBAAA"}
package/dist/config.mjs CHANGED
@@ -7,7 +7,6 @@ import { typescriptContractFromPath } from "@prisma-next/sql-contract-ts/config-
7
7
  import postgres from "@prisma-next/target-postgres/control";
8
8
  import { ifDefined } from "@prisma-next/utils/defined";
9
9
  import { extname } from "pathe";
10
-
11
10
  //#region src/config/define-config.ts
12
11
  function deriveOutputPath(contractPath) {
13
12
  const ext = extname(contractPath);
@@ -31,7 +30,7 @@ function defineConfig(options) {
31
30
  ...ifDefined("migrations", options.migrations)
32
31
  });
33
32
  }
34
-
35
33
  //#endregion
36
34
  export { defineConfig };
35
+
37
36
  //# sourceMappingURL=config.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":["coreDefineConfig"],"sources":["../src/config/define-config.ts"],"sourcesContent":["import postgresAdapter from '@prisma-next/adapter-postgres/control';\nimport type { PrismaNextConfig } from '@prisma-next/config/config-types';\nimport { defineConfig as coreDefineConfig } from '@prisma-next/config/config-types';\nimport postgresDriver from '@prisma-next/driver-postgres/control';\nimport sql from '@prisma-next/family-sql/control';\nimport type { ControlExtensionDescriptor } from '@prisma-next/framework-components/control';\nimport { prismaContract } from '@prisma-next/sql-contract-psl/provider';\nimport { typescriptContractFromPath } from '@prisma-next/sql-contract-ts/config-types';\nimport postgres from '@prisma-next/target-postgres/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { extname } from 'pathe';\n\nexport interface PostgresConfigOptions {\n readonly contract: string;\n readonly db?: {\n readonly connection?: string;\n };\n readonly extensions?: readonly ControlExtensionDescriptor<'sql', 'postgres'>[];\n readonly migrations?: {\n readonly dir?: string;\n };\n}\n\nfunction deriveOutputPath(contractPath: string): string {\n const ext = extname(contractPath);\n if (ext.length === 0) {\n return `${contractPath}.json`;\n }\n return `${contractPath.slice(0, -ext.length)}.json`;\n}\n\nexport function defineConfig(options: PostgresConfigOptions): PrismaNextConfig<'sql', 'postgres'> {\n const extensions = options.extensions ?? [];\n const output = deriveOutputPath(options.contract);\n const ext = extname(options.contract);\n\n const contractConfig =\n ext === '.ts'\n ? typescriptContractFromPath(options.contract, output)\n : prismaContract(options.contract, {\n output,\n target: postgres,\n });\n\n return coreDefineConfig({\n family: sql,\n target: postgres,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: extensions,\n contract: contractConfig,\n ...ifDefined('db', options.db),\n ...ifDefined('migrations', options.migrations),\n });\n}\n"],"mappings":";;;;;;;;;;;AAuBA,SAAS,iBAAiB,cAA8B;CACtD,MAAM,MAAM,QAAQ,aAAa;AACjC,KAAI,IAAI,WAAW,EACjB,QAAO,GAAG,aAAa;AAEzB,QAAO,GAAG,aAAa,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC;;AAG/C,SAAgB,aAAa,SAAqE;CAChG,MAAM,aAAa,QAAQ,cAAc,EAAE;CAC3C,MAAM,SAAS,iBAAiB,QAAQ,SAAS;AAWjD,QAAOA,eAAiB;EACtB,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,gBAAgB;EAChB,UAhBU,QAAQ,QAAQ,SAAS,KAG3B,QACJ,2BAA2B,QAAQ,UAAU,OAAO,GACpD,eAAe,QAAQ,UAAU;GAC/B;GACA,QAAQ;GACT,CAAC;EASN,GAAG,UAAU,MAAM,QAAQ,GAAG;EAC9B,GAAG,UAAU,cAAc,QAAQ,WAAW;EAC/C,CAAC"}
1
+ {"version":3,"file":"config.mjs","names":["coreDefineConfig"],"sources":["../src/config/define-config.ts"],"sourcesContent":["import postgresAdapter from '@prisma-next/adapter-postgres/control';\nimport type { PrismaNextConfig } from '@prisma-next/config/config-types';\nimport { defineConfig as coreDefineConfig } from '@prisma-next/config/config-types';\nimport postgresDriver from '@prisma-next/driver-postgres/control';\nimport sql from '@prisma-next/family-sql/control';\nimport type { ControlExtensionDescriptor } from '@prisma-next/framework-components/control';\nimport { prismaContract } from '@prisma-next/sql-contract-psl/provider';\nimport { typescriptContractFromPath } from '@prisma-next/sql-contract-ts/config-types';\nimport postgres from '@prisma-next/target-postgres/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { extname } from 'pathe';\n\nexport interface PostgresConfigOptions {\n readonly contract: string;\n readonly db?: {\n readonly connection?: string;\n };\n readonly extensions?: readonly ControlExtensionDescriptor<'sql', 'postgres'>[];\n readonly migrations?: {\n readonly dir?: string;\n };\n}\n\nfunction deriveOutputPath(contractPath: string): string {\n const ext = extname(contractPath);\n if (ext.length === 0) {\n return `${contractPath}.json`;\n }\n return `${contractPath.slice(0, -ext.length)}.json`;\n}\n\nexport function defineConfig(options: PostgresConfigOptions): PrismaNextConfig<'sql', 'postgres'> {\n const extensions = options.extensions ?? [];\n const output = deriveOutputPath(options.contract);\n const ext = extname(options.contract);\n\n const contractConfig =\n ext === '.ts'\n ? typescriptContractFromPath(options.contract, output)\n : prismaContract(options.contract, {\n output,\n target: postgres,\n });\n\n return coreDefineConfig({\n family: sql,\n target: postgres,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: extensions,\n contract: contractConfig,\n ...ifDefined('db', options.db),\n ...ifDefined('migrations', options.migrations),\n });\n}\n"],"mappings":";;;;;;;;;;AAuBA,SAAS,iBAAiB,cAA8B;CACtD,MAAM,MAAM,QAAQ,aAAa;CACjC,IAAI,IAAI,WAAW,GACjB,OAAO,GAAG,aAAa;CAEzB,OAAO,GAAG,aAAa,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC;;AAG/C,SAAgB,aAAa,SAAqE;CAChG,MAAM,aAAa,QAAQ,cAAc,EAAE;CAC3C,MAAM,SAAS,iBAAiB,QAAQ,SAAS;CAWjD,OAAOA,eAAiB;EACtB,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,gBAAgB;EAChB,UAhBU,QAAQ,QAAQ,SAGvB,KAAK,QACJ,2BAA2B,QAAQ,UAAU,OAAO,GACpD,eAAe,QAAQ,UAAU;GAC/B;GACA,QAAQ;GACT,CAAC;EASN,GAAG,UAAU,MAAM,QAAQ,GAAG;EAC9B,GAAG,UAAU,cAAc,QAAQ,WAAW;EAC/C,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { ComposedAuthoringHelpers, ContractDefinition, ContractInput, ContractModelBuilder, FieldNode, ForeignKeyNode, IndexNode, ModelNode, PrimaryKeyNode, RelationNode, ScalarFieldBuilder, UniqueConstraintNode, buildSqlContractFromDefinition, defineContract, field, model, rel } from "@prisma-next/sql-contract-ts/contract-builder";
2
+ export { type ComposedAuthoringHelpers, type ContractDefinition, type ContractInput, type ContractModelBuilder, type FieldNode, type ForeignKeyNode, type IndexNode, type ModelNode, type PrimaryKeyNode, type RelationNode, type ScalarFieldBuilder, type UniqueConstraintNode, buildSqlContractFromDefinition, defineContract, field, model, rel };
@@ -0,0 +1,2 @@
1
+ import { buildSqlContractFromDefinition, defineContract, field, model, rel } from "@prisma-next/sql-contract-ts/contract-builder";
2
+ export { buildSqlContractFromDefinition, defineContract, field, model, rel };
@@ -0,0 +1,2 @@
1
+ import pack_default from "@prisma-next/family-sql/pack";
2
+ export { pack_default as default };
@@ -0,0 +1,2 @@
1
+ import pack_default from "@prisma-next/family-sql/pack";
2
+ export { pack_default as default };
@@ -0,0 +1,84 @@
1
+ import { orm } from "@prisma-next/sql-orm-client";
2
+ import { ExecutionContext, Runtime, RuntimeVerifyOptions, SqlExecutionStackWithDriver, SqlMiddleware, SqlRuntimeExtensionDescriptor, TransactionContext } from "@prisma-next/sql-runtime";
3
+ import { Client, Pool } from "pg";
4
+ import { Contract } from "@prisma-next/contract/types";
5
+ import { Db } from "@prisma-next/sql-builder/types";
6
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
7
+
8
+ //#region src/runtime/binding.d.ts
9
+ type PostgresBinding = {
10
+ readonly kind: 'url';
11
+ readonly url: string;
12
+ } | {
13
+ readonly kind: 'pgPool';
14
+ readonly pool: Pool;
15
+ } | {
16
+ readonly kind: 'pgClient';
17
+ readonly client: Client;
18
+ };
19
+ type PostgresBindingInput = {
20
+ readonly binding: PostgresBinding;
21
+ readonly url?: never;
22
+ readonly pg?: never;
23
+ } | {
24
+ readonly url: string;
25
+ readonly binding?: never;
26
+ readonly pg?: never;
27
+ } | {
28
+ readonly pg: Pool | Client;
29
+ readonly binding?: never;
30
+ readonly url?: never;
31
+ };
32
+ //#endregion
33
+ //#region src/runtime/postgres.d.ts
34
+ type PostgresTargetId = 'postgres';
35
+ type OrmClient<TContract extends Contract<SqlStorage>> = ReturnType<typeof orm<TContract>>;
36
+ interface PostgresTransactionContext<TContract extends Contract<SqlStorage>> extends TransactionContext {
37
+ readonly sql: Db<TContract>;
38
+ readonly orm: OrmClient<TContract>;
39
+ }
40
+ interface PostgresClient<TContract extends Contract<SqlStorage>> {
41
+ readonly sql: Db<TContract>;
42
+ readonly orm: OrmClient<TContract>;
43
+ readonly context: ExecutionContext<TContract>;
44
+ readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;
45
+ connect(bindingInput?: PostgresBindingInput): Promise<Runtime>;
46
+ runtime(): Runtime;
47
+ transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R>;
48
+ }
49
+ interface PostgresOptionsBase {
50
+ readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];
51
+ readonly middleware?: readonly SqlMiddleware[];
52
+ readonly verify?: RuntimeVerifyOptions;
53
+ readonly poolOptions?: {
54
+ readonly connectionTimeoutMillis?: number;
55
+ readonly idleTimeoutMillis?: number;
56
+ };
57
+ }
58
+ interface PostgresBindingOptions {
59
+ readonly binding?: PostgresBinding;
60
+ readonly url?: string;
61
+ readonly pg?: Pool | Client;
62
+ }
63
+ type PostgresOptionsWithContract<TContract extends Contract<SqlStorage>> = PostgresBindingOptions & PostgresOptionsBase & {
64
+ readonly contract: TContract;
65
+ readonly contractJson?: never;
66
+ };
67
+ type PostgresOptionsWithContractJson<TContract extends Contract<SqlStorage>> = PostgresBindingOptions & PostgresOptionsBase & {
68
+ readonly contractJson: unknown;
69
+ readonly contract?: never;
70
+ readonly _contract?: TContract;
71
+ };
72
+ type PostgresOptions<TContract extends Contract<SqlStorage>> = PostgresOptionsWithContract<TContract> | PostgresOptionsWithContractJson<TContract>;
73
+ /**
74
+ * Creates a lazy Postgres client from either `contractJson` or a TypeScript-authored `contract`.
75
+ * Static query surfaces are available immediately, while `runtime()` instantiates the driver/pool on first call.
76
+ *
77
+ * - No-emit: pass a TypeScript-authored contract. Example: postgres({ contract })
78
+ * - Emitted: pass Contract type explicitly. Example: postgres<Contract>({ contractJson, url })
79
+ */
80
+ declare function postgres<TContract extends Contract<SqlStorage>>(options: PostgresOptionsWithContract<TContract>): PostgresClient<TContract>;
81
+ declare function postgres<TContract extends Contract<SqlStorage>>(options: PostgresOptionsWithContractJson<TContract>): PostgresClient<TContract>;
82
+ //#endregion
83
+ export { PostgresOptionsWithContractJson as a, PostgresBinding as c, PostgresOptionsWithContract as i, PostgresOptions as n, PostgresTargetId as o, PostgresOptionsBase as r, postgres as s, PostgresClient as t };
84
+ //# sourceMappingURL=postgres-Bkdcp2EZ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-Bkdcp2EZ.d.mts","names":[],"sources":["../src/runtime/binding.ts","../src/runtime/postgres.ts"],"mappings":";;;;;;;;KAGY,eAAA;EAAA,SACG,IAAA;EAAA,SAAsB,GAAA;AAAA;EAAA,SACtB,IAAA;EAAA,SAAyB,IAAA,EAAM,IAAA;AAAA;EAAA,SAC/B,IAAA;EAAA,SAA2B,MAAA,EAAQ,MAAA;AAAA;AAAA,KAEtC,oBAAA;EAAA,SAEG,OAAA,EAAS,eAAA;EAAA,SACT,GAAA;EAAA,SACA,EAAA;AAAA;EAAA,SAGA,GAAA;EAAA,SACA,OAAA;EAAA,SACA,EAAA;AAAA;EAAA,SAGA,EAAA,EAAI,IAAA,GAAO,MAAA;EAAA,SACX,OAAA;EAAA,SACA,GAAA;AAAA;;;KCaH,gBAAA;AAAA,KACP,SAAA,mBAA4B,QAAA,CAAS,UAAA,KAAe,UAAA,QAAkB,GAAA,CAAW,SAAA;AAAA,UAErE,0BAAA,mBAA6C,QAAA,CAAS,UAAA,WAC7D,kBAAA;EAAA,SACC,GAAA,EAAK,EAAA,CAAG,SAAA;EAAA,SACR,GAAA,EAAK,SAAA,CAAU,SAAA;AAAA;AAAA,UAGT,cAAA,mBAAiC,QAAA,CAAS,UAAA;EAAA,SAChD,GAAA,EAAK,EAAA,CAAG,SAAA;EAAA,SACR,GAAA,EAAK,SAAA,CAAU,SAAA;EAAA,SACf,OAAA,EAAS,gBAAA,CAAiB,SAAA;EAAA,SAC1B,KAAA,EAAO,2BAAA,CAA4B,gBAAA;EAC5C,OAAA,CAAQ,YAAA,GAAe,oBAAA,GAAuB,OAAA,CAAQ,OAAA;EACtD,OAAA,IAAW,OAAA;EACX,WAAA,IAAe,EAAA,GAAK,EAAA,EAAI,0BAAA,CAA2B,SAAA,MAAe,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,CAAA;AAAA;AAAA,UAG5E,mBAAA;EAAA,SACN,UAAA,YAAsB,6BAAA,CAA8B,gBAAA;EAAA,SACpD,UAAA,YAAsB,aAAA;EAAA,SACtB,MAAA,GAAS,oBAAA;EAAA,SACT,WAAA;IAAA,SACE,uBAAA;IAAA,SACA,iBAAA;EAAA;AAAA;AAAA,UAII,sBAAA;EAAA,SACN,OAAA,GAAU,eAAA;EAAA,SACV,GAAA;EAAA,SACA,EAAA,GAAK,IAAA,GAAO,MAAA;AAAA;AAAA,KAGX,2BAAA,mBAA8C,QAAA,CAAS,UAAA,KACjE,sBAAA,GACE,mBAAA;EAAA,SACW,QAAA,EAAU,SAAA;EAAA,SACV,YAAA;AAAA;AAAA,KAGH,+BAAA,mBAAkD,QAAA,CAAS,UAAA,KACrE,sBAAA,GACE,mBAAA;EAAA,SACW,YAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA,GAAY,SAAA;AAAA;AAAA,KAGf,eAAA,mBAAkC,QAAA,CAAS,UAAA,KACnD,2BAAA,CAA4B,SAAA,IAC5B,+BAAA,CAAgC,SAAA;;AApDpC;;;;;AAA0C;iBA4FlB,QAAA,mBAA2B,QAAA,CAAS,UAAA,EAAA,CAC1D,OAAA,EAAS,2BAAA,CAA4B,SAAA,IACpC,cAAA,CAAe,SAAA;AAAA,iBACM,QAAA,mBAA2B,QAAA,CAAS,UAAA,EAAA,CAC1D,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,cAAA,CAAe,SAAA"}
@@ -1,84 +1,2 @@
1
- import { orm } from "@prisma-next/sql-orm-client";
2
- import { ExecutionContext, Runtime, RuntimeVerifyOptions, SqlExecutionStackWithDriver, SqlMiddleware, SqlRuntimeExtensionDescriptor, TransactionContext } from "@prisma-next/sql-runtime";
3
- import { Client, Pool } from "pg";
4
- import { Contract } from "@prisma-next/contract/types";
5
- import { Db } from "@prisma-next/sql-builder/types";
6
- import { SqlStorage } from "@prisma-next/sql-contract/types";
7
-
8
- //#region src/runtime/binding.d.ts
9
- type PostgresBinding = {
10
- readonly kind: 'url';
11
- readonly url: string;
12
- } | {
13
- readonly kind: 'pgPool';
14
- readonly pool: Pool;
15
- } | {
16
- readonly kind: 'pgClient';
17
- readonly client: Client;
18
- };
19
- type PostgresBindingInput = {
20
- readonly binding: PostgresBinding;
21
- readonly url?: never;
22
- readonly pg?: never;
23
- } | {
24
- readonly url: string;
25
- readonly binding?: never;
26
- readonly pg?: never;
27
- } | {
28
- readonly pg: Pool | Client;
29
- readonly binding?: never;
30
- readonly url?: never;
31
- };
32
- //#endregion
33
- //#region src/runtime/postgres.d.ts
34
- type PostgresTargetId = 'postgres';
35
- type OrmClient<TContract extends Contract<SqlStorage>> = ReturnType<typeof orm<TContract>>;
36
- interface PostgresTransactionContext<TContract extends Contract<SqlStorage>> extends TransactionContext {
37
- readonly sql: Db<TContract>;
38
- readonly orm: OrmClient<TContract>;
39
- }
40
- interface PostgresClient<TContract extends Contract<SqlStorage>> {
41
- readonly sql: Db<TContract>;
42
- readonly orm: OrmClient<TContract>;
43
- readonly context: ExecutionContext<TContract>;
44
- readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;
45
- connect(bindingInput?: PostgresBindingInput): Promise<Runtime>;
46
- runtime(): Runtime;
47
- transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R>;
48
- }
49
- interface PostgresOptionsBase {
50
- readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];
51
- readonly middleware?: readonly SqlMiddleware[];
52
- readonly verify?: RuntimeVerifyOptions;
53
- readonly poolOptions?: {
54
- readonly connectionTimeoutMillis?: number;
55
- readonly idleTimeoutMillis?: number;
56
- };
57
- }
58
- interface PostgresBindingOptions {
59
- readonly binding?: PostgresBinding;
60
- readonly url?: string;
61
- readonly pg?: Pool | Client;
62
- }
63
- type PostgresOptionsWithContract<TContract extends Contract<SqlStorage>> = PostgresBindingOptions & PostgresOptionsBase & {
64
- readonly contract: TContract;
65
- readonly contractJson?: never;
66
- };
67
- type PostgresOptionsWithContractJson<TContract extends Contract<SqlStorage>> = PostgresBindingOptions & PostgresOptionsBase & {
68
- readonly contractJson: unknown;
69
- readonly contract?: never;
70
- readonly _contract?: TContract;
71
- };
72
- type PostgresOptions<TContract extends Contract<SqlStorage>> = PostgresOptionsWithContract<TContract> | PostgresOptionsWithContractJson<TContract>;
73
- /**
74
- * Creates a lazy Postgres client from either `contractJson` or a TypeScript-authored `contract`.
75
- * Static query surfaces are available immediately, while `runtime()` instantiates the driver/pool on first call.
76
- *
77
- * - No-emit: pass a TypeScript-authored contract. Example: postgres({ contract })
78
- * - Emitted: pass Contract type explicitly. Example: postgres<Contract>({ contractJson, url })
79
- */
80
- declare function postgres<TContract extends Contract<SqlStorage>>(options: PostgresOptionsWithContract<TContract>): PostgresClient<TContract>;
81
- declare function postgres<TContract extends Contract<SqlStorage>>(options: PostgresOptionsWithContractJson<TContract>): PostgresClient<TContract>;
82
- //#endregion
83
- export { type PostgresBinding, type PostgresClient, type PostgresOptions, type PostgresOptionsBase, type PostgresOptionsWithContract, type PostgresOptionsWithContractJson, postgres as default };
84
- //# sourceMappingURL=runtime.d.mts.map
1
+ import { a as PostgresOptionsWithContractJson, c as PostgresBinding, i as PostgresOptionsWithContract, n as PostgresOptions, r as PostgresOptionsBase, s as postgres, t as PostgresClient } from "./postgres-Bkdcp2EZ.mjs";
2
+ export { type PostgresBinding, type PostgresClient, type PostgresOptions, type PostgresOptionsBase, type PostgresOptionsWithContract, type PostgresOptionsWithContractJson, postgres as default };
package/dist/runtime.mjs CHANGED
@@ -9,7 +9,6 @@ import { orm } from "@prisma-next/sql-orm-client";
9
9
  import { createExecutionContext, createRuntime, createSqlExecutionStack, withTransaction } from "@prisma-next/sql-runtime";
10
10
  import postgresTarget from "@prisma-next/target-postgres/runtime";
11
11
  import { Client, Pool } from "pg";
12
-
13
12
  //#region src/runtime/binding.ts
14
13
  function validatePostgresUrl(url) {
15
14
  const trimmed = url.trim();
@@ -46,7 +45,6 @@ function resolveOptionalPostgresBinding(options) {
46
45
  if (Number(options.binding !== void 0) + Number(options.url !== void 0) + Number(options.pg !== void 0) === 0) return;
47
46
  return resolvePostgresBinding(options);
48
47
  }
49
-
50
48
  //#endregion
51
49
  //#region src/runtime/postgres.ts
52
50
  function hasContractJson(options) {
@@ -165,7 +163,7 @@ function postgres(options) {
165
163
  }
166
164
  };
167
165
  }
168
-
169
166
  //#endregion
170
167
  export { postgres as default };
168
+
171
169
  //# sourceMappingURL=runtime.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":["parsed: URL","PgPool","PgClient","runtimeInstance: Runtime | undefined","runtimeDriver: { connect(binding: unknown): Promise<void> } | undefined","connectPromise: Promise<void> | undefined","backgroundConnectError: unknown","orm: OrmClient<TContract>","ormBuilder","sqlBuilder","txSql: Db<TContract>","txOrm: OrmClient<TContract>"],"sources":["../src/runtime/binding.ts","../src/runtime/postgres.ts"],"sourcesContent":["import type { Client, Pool } from 'pg';\nimport { Client as PgClient, Pool as PgPool } from 'pg';\n\nexport type PostgresBinding =\n | { readonly kind: 'url'; readonly url: string }\n | { readonly kind: 'pgPool'; readonly pool: Pool }\n | { readonly kind: 'pgClient'; readonly client: Client };\n\nexport type PostgresBindingInput =\n | {\n readonly binding: PostgresBinding;\n readonly url?: never;\n readonly pg?: never;\n }\n | {\n readonly url: string;\n readonly binding?: never;\n readonly pg?: never;\n }\n | {\n readonly pg: Pool | Client;\n readonly binding?: never;\n readonly url?: never;\n };\n\ntype PostgresBindingFields = {\n readonly binding?: PostgresBinding;\n readonly url?: string;\n readonly pg?: Pool | Client;\n};\n\nfunction validatePostgresUrl(url: string): string {\n const trimmed = url.trim();\n if (trimmed.length === 0) {\n throw new Error('Postgres URL must be a non-empty string');\n }\n\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n throw new Error('Postgres URL must be a valid URL');\n }\n\n if (parsed.protocol !== 'postgres:' && parsed.protocol !== 'postgresql:') {\n throw new Error('Postgres URL must use postgres:// or postgresql://');\n }\n\n return trimmed;\n}\n\nexport function resolvePostgresBinding(options: PostgresBindingInput): PostgresBinding {\n const providedCount =\n Number(options.binding !== undefined) +\n Number(options.url !== undefined) +\n Number(options.pg !== undefined);\n\n if (providedCount !== 1) {\n throw new Error('Provide one binding input: binding, url, or pg');\n }\n\n if (options.binding !== undefined) {\n return options.binding;\n }\n\n if (options.url !== undefined) {\n return { kind: 'url', url: validatePostgresUrl(options.url) };\n }\n\n const pgBinding = options.pg;\n if (pgBinding === undefined) {\n throw new Error('Invariant violation: expected pg binding after validation');\n }\n\n if (pgBinding instanceof PgPool) {\n return { kind: 'pgPool', pool: pgBinding };\n }\n\n if (pgBinding instanceof PgClient) {\n return { kind: 'pgClient', client: pgBinding };\n }\n\n throw new Error(\n 'Unable to determine pg binding type from pg input; use binding with explicit kind',\n );\n}\n\nexport function resolveOptionalPostgresBinding(\n options: PostgresBindingFields,\n): PostgresBinding | undefined {\n const providedCount =\n Number(options.binding !== undefined) +\n Number(options.url !== undefined) +\n Number(options.pg !== undefined);\n\n if (providedCount === 0) {\n return undefined;\n }\n\n return resolvePostgresBinding(options as PostgresBindingInput);\n}\n","import postgresAdapter from '@prisma-next/adapter-postgres/runtime';\nimport type { Contract } from '@prisma-next/contract/types';\nimport postgresDriver from '@prisma-next/driver-postgres/runtime';\nimport { emptyCodecLookup } from '@prisma-next/framework-components/codec';\nimport { instantiateExecutionStack } from '@prisma-next/framework-components/execution';\nimport { sql as sqlBuilder } from '@prisma-next/sql-builder/runtime';\nimport type { Db } from '@prisma-next/sql-builder/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { validateContract } from '@prisma-next/sql-contract/validate';\nimport { orm as ormBuilder } from '@prisma-next/sql-orm-client';\nimport type {\n ExecutionContext,\n Runtime,\n RuntimeVerifyOptions,\n SqlExecutionStackWithDriver,\n SqlMiddleware,\n SqlRuntimeExtensionDescriptor,\n TransactionContext,\n} from '@prisma-next/sql-runtime';\nimport {\n createExecutionContext,\n createRuntime,\n createSqlExecutionStack,\n withTransaction,\n} from '@prisma-next/sql-runtime';\nimport postgresTarget from '@prisma-next/target-postgres/runtime';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { type Client, Pool } from 'pg';\nimport {\n type PostgresBinding,\n type PostgresBindingInput,\n resolveOptionalPostgresBinding,\n resolvePostgresBinding,\n} from './binding';\n\nexport type PostgresTargetId = 'postgres';\ntype OrmClient<TContract extends Contract<SqlStorage>> = ReturnType<typeof ormBuilder<TContract>>;\n\nexport interface PostgresTransactionContext<TContract extends Contract<SqlStorage>>\n extends TransactionContext {\n readonly sql: Db<TContract>;\n readonly orm: OrmClient<TContract>;\n}\n\nexport interface PostgresClient<TContract extends Contract<SqlStorage>> {\n readonly sql: Db<TContract>;\n readonly orm: OrmClient<TContract>;\n readonly context: ExecutionContext<TContract>;\n readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;\n connect(bindingInput?: PostgresBindingInput): Promise<Runtime>;\n runtime(): Runtime;\n transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R>;\n}\n\nexport interface PostgresOptionsBase {\n readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];\n readonly middleware?: readonly SqlMiddleware[];\n readonly verify?: RuntimeVerifyOptions;\n readonly poolOptions?: {\n readonly connectionTimeoutMillis?: number;\n readonly idleTimeoutMillis?: number;\n };\n}\n\nexport interface PostgresBindingOptions {\n readonly binding?: PostgresBinding;\n readonly url?: string;\n readonly pg?: Pool | Client;\n}\n\nexport type PostgresOptionsWithContract<TContract extends Contract<SqlStorage>> =\n PostgresBindingOptions &\n PostgresOptionsBase & {\n readonly contract: TContract;\n readonly contractJson?: never;\n };\n\nexport type PostgresOptionsWithContractJson<TContract extends Contract<SqlStorage>> =\n PostgresBindingOptions &\n PostgresOptionsBase & {\n readonly contractJson: unknown;\n readonly contract?: never;\n readonly _contract?: TContract;\n };\n\nexport type PostgresOptions<TContract extends Contract<SqlStorage>> =\n | PostgresOptionsWithContract<TContract>\n | PostgresOptionsWithContractJson<TContract>;\n\nfunction hasContractJson<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): options is PostgresOptionsWithContractJson<TContract> {\n return 'contractJson' in options;\n}\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): TContract {\n const contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n return validateContract<TContract>(contractInput, emptyCodecLookup);\n}\n\nfunction toRuntimeBinding<TContract extends Contract<SqlStorage>>(\n binding: PostgresBinding,\n options: PostgresOptions<TContract>,\n) {\n if (binding.kind !== 'url') {\n return binding;\n }\n\n return {\n kind: 'pgPool',\n pool: new Pool({\n connectionString: binding.url,\n connectionTimeoutMillis: options.poolOptions?.connectionTimeoutMillis ?? 20_000,\n idleTimeoutMillis: options.poolOptions?.idleTimeoutMillis ?? 30_000,\n }),\n } as const;\n}\n\n/**\n * Creates a lazy Postgres client from either `contractJson` or a TypeScript-authored `contract`.\n * Static query surfaces are available immediately, while `runtime()` instantiates the driver/pool on first call.\n *\n * - No-emit: pass a TypeScript-authored contract. Example: postgres({ contract })\n * - Emitted: pass Contract type explicitly. Example: postgres<Contract>({ contractJson, url })\n */\nexport default function postgres<TContract extends Contract<SqlStorage>>(\n options: PostgresOptionsWithContract<TContract>,\n): PostgresClient<TContract>;\nexport default function postgres<TContract extends Contract<SqlStorage>>(\n options: PostgresOptionsWithContractJson<TContract>,\n): PostgresClient<TContract>;\nexport default function postgres<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): PostgresClient<TContract> {\n const contract = resolveContract(options);\n let binding = resolveOptionalPostgresBinding(options);\n const stack = createSqlExecutionStack({\n target: postgresTarget,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: options.extensions ?? [],\n });\n\n const context = createExecutionContext({\n contract,\n stack,\n });\n\n let runtimeInstance: Runtime | undefined;\n let runtimeDriver: { connect(binding: unknown): Promise<void> } | undefined;\n let driverConnected = false;\n let connectPromise: Promise<void> | undefined;\n let backgroundConnectError: unknown;\n const connectDriver = async (resolvedBinding: PostgresBinding): Promise<void> => {\n if (driverConnected) return;\n if (!runtimeDriver) throw new Error('Postgres runtime driver missing');\n if (connectPromise) return connectPromise;\n const runtimeBinding = toRuntimeBinding(resolvedBinding, options);\n connectPromise = runtimeDriver\n .connect(runtimeBinding)\n .then(() => {\n driverConnected = true;\n })\n .catch(async (err) => {\n backgroundConnectError = err;\n connectPromise = undefined;\n if (resolvedBinding.kind === 'url' && runtimeBinding.kind === 'pgPool') {\n await runtimeBinding.pool.end().catch(() => undefined);\n }\n throw err;\n });\n return connectPromise;\n };\n const getRuntime = (): Runtime => {\n if (backgroundConnectError !== undefined) {\n throw backgroundConnectError;\n }\n\n if (runtimeInstance) {\n return runtimeInstance;\n }\n\n const stackInstance = instantiateExecutionStack(stack);\n const driverDescriptor = stack.driver;\n if (!driverDescriptor) {\n throw new Error('Driver descriptor missing from execution stack');\n }\n\n const driver = driverDescriptor.create({\n cursor: { disabled: true },\n });\n runtimeDriver = driver;\n if (binding !== undefined) {\n void connectDriver(binding).catch(() => undefined);\n }\n\n runtimeInstance = createRuntime({\n stackInstance,\n context,\n driver,\n verify: options.verify ?? { mode: 'onFirstUse', requireMarker: false },\n ...ifDefined('middleware', options.middleware),\n });\n\n return runtimeInstance;\n };\n const orm: OrmClient<TContract> = ormBuilder({\n runtime: {\n execute(plan) {\n return getRuntime().execute(plan);\n },\n connection() {\n return getRuntime().connection();\n },\n },\n context,\n });\n\n const sql: Db<TContract> = sqlBuilder<TContract>({ context });\n\n return {\n sql,\n orm,\n context,\n stack,\n\n async connect(bindingInput) {\n if (driverConnected || connectPromise) {\n throw new Error('Postgres client already connected');\n }\n\n if (bindingInput !== undefined) {\n binding = resolvePostgresBinding(bindingInput);\n }\n\n if (binding === undefined) {\n throw new Error(\n 'Postgres binding not configured. Pass url/pg/binding to postgres(...) or call db.connect({ ... }).',\n );\n }\n\n const runtime = getRuntime();\n if (driverConnected) {\n return runtime;\n }\n\n await connectDriver(binding);\n return runtime;\n },\n\n runtime() {\n return getRuntime();\n },\n\n transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R> {\n return withTransaction(getRuntime(), (txCtx) => {\n const txSql: Db<TContract> = sqlBuilder<TContract>({ context });\n\n const txOrm: OrmClient<TContract> = ormBuilder({\n runtime: {\n execute(plan) {\n return txCtx.execute(plan);\n },\n },\n context,\n });\n\n // Use `txCtx` as the prototype instead of spreading it so that live\n // accessors (notably the `invalidated` getter, which reads a closure\n // variable in `withTransaction`) remain wired to the original object.\n // Spreading would evaluate the getter once and freeze its value.\n const tx: PostgresTransactionContext<TContract> = Object.assign(\n Object.create(txCtx) as TransactionContext,\n { sql: txSql, orm: txOrm },\n );\n\n return fn(tx);\n });\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runtime.mjs","names":["PgPool","PgClient","orm","ormBuilder","sqlBuilder"],"sources":["../src/runtime/binding.ts","../src/runtime/postgres.ts"],"sourcesContent":["import type { Client, Pool } from 'pg';\nimport { Client as PgClient, Pool as PgPool } from 'pg';\n\nexport type PostgresBinding =\n | { readonly kind: 'url'; readonly url: string }\n | { readonly kind: 'pgPool'; readonly pool: Pool }\n | { readonly kind: 'pgClient'; readonly client: Client };\n\nexport type PostgresBindingInput =\n | {\n readonly binding: PostgresBinding;\n readonly url?: never;\n readonly pg?: never;\n }\n | {\n readonly url: string;\n readonly binding?: never;\n readonly pg?: never;\n }\n | {\n readonly pg: Pool | Client;\n readonly binding?: never;\n readonly url?: never;\n };\n\ntype PostgresBindingFields = {\n readonly binding?: PostgresBinding;\n readonly url?: string;\n readonly pg?: Pool | Client;\n};\n\nfunction validatePostgresUrl(url: string): string {\n const trimmed = url.trim();\n if (trimmed.length === 0) {\n throw new Error('Postgres URL must be a non-empty string');\n }\n\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n throw new Error('Postgres URL must be a valid URL');\n }\n\n if (parsed.protocol !== 'postgres:' && parsed.protocol !== 'postgresql:') {\n throw new Error('Postgres URL must use postgres:// or postgresql://');\n }\n\n return trimmed;\n}\n\nexport function resolvePostgresBinding(options: PostgresBindingInput): PostgresBinding {\n const providedCount =\n Number(options.binding !== undefined) +\n Number(options.url !== undefined) +\n Number(options.pg !== undefined);\n\n if (providedCount !== 1) {\n throw new Error('Provide one binding input: binding, url, or pg');\n }\n\n if (options.binding !== undefined) {\n return options.binding;\n }\n\n if (options.url !== undefined) {\n return { kind: 'url', url: validatePostgresUrl(options.url) };\n }\n\n const pgBinding = options.pg;\n if (pgBinding === undefined) {\n throw new Error('Invariant violation: expected pg binding after validation');\n }\n\n if (pgBinding instanceof PgPool) {\n return { kind: 'pgPool', pool: pgBinding };\n }\n\n if (pgBinding instanceof PgClient) {\n return { kind: 'pgClient', client: pgBinding };\n }\n\n throw new Error(\n 'Unable to determine pg binding type from pg input; use binding with explicit kind',\n );\n}\n\nexport function resolveOptionalPostgresBinding(\n options: PostgresBindingFields,\n): PostgresBinding | undefined {\n const providedCount =\n Number(options.binding !== undefined) +\n Number(options.url !== undefined) +\n Number(options.pg !== undefined);\n\n if (providedCount === 0) {\n return undefined;\n }\n\n return resolvePostgresBinding(options as PostgresBindingInput);\n}\n","import postgresAdapter from '@prisma-next/adapter-postgres/runtime';\nimport type { Contract } from '@prisma-next/contract/types';\nimport postgresDriver from '@prisma-next/driver-postgres/runtime';\nimport { emptyCodecLookup } from '@prisma-next/framework-components/codec';\nimport { instantiateExecutionStack } from '@prisma-next/framework-components/execution';\nimport { sql as sqlBuilder } from '@prisma-next/sql-builder/runtime';\nimport type { Db } from '@prisma-next/sql-builder/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { validateContract } from '@prisma-next/sql-contract/validate';\nimport { orm as ormBuilder } from '@prisma-next/sql-orm-client';\nimport type {\n ExecutionContext,\n Runtime,\n RuntimeVerifyOptions,\n SqlExecutionStackWithDriver,\n SqlMiddleware,\n SqlRuntimeExtensionDescriptor,\n TransactionContext,\n} from '@prisma-next/sql-runtime';\nimport {\n createExecutionContext,\n createRuntime,\n createSqlExecutionStack,\n withTransaction,\n} from '@prisma-next/sql-runtime';\nimport postgresTarget from '@prisma-next/target-postgres/runtime';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { type Client, Pool } from 'pg';\nimport {\n type PostgresBinding,\n type PostgresBindingInput,\n resolveOptionalPostgresBinding,\n resolvePostgresBinding,\n} from './binding';\n\nexport type PostgresTargetId = 'postgres';\ntype OrmClient<TContract extends Contract<SqlStorage>> = ReturnType<typeof ormBuilder<TContract>>;\n\nexport interface PostgresTransactionContext<TContract extends Contract<SqlStorage>>\n extends TransactionContext {\n readonly sql: Db<TContract>;\n readonly orm: OrmClient<TContract>;\n}\n\nexport interface PostgresClient<TContract extends Contract<SqlStorage>> {\n readonly sql: Db<TContract>;\n readonly orm: OrmClient<TContract>;\n readonly context: ExecutionContext<TContract>;\n readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;\n connect(bindingInput?: PostgresBindingInput): Promise<Runtime>;\n runtime(): Runtime;\n transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R>;\n}\n\nexport interface PostgresOptionsBase {\n readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];\n readonly middleware?: readonly SqlMiddleware[];\n readonly verify?: RuntimeVerifyOptions;\n readonly poolOptions?: {\n readonly connectionTimeoutMillis?: number;\n readonly idleTimeoutMillis?: number;\n };\n}\n\nexport interface PostgresBindingOptions {\n readonly binding?: PostgresBinding;\n readonly url?: string;\n readonly pg?: Pool | Client;\n}\n\nexport type PostgresOptionsWithContract<TContract extends Contract<SqlStorage>> =\n PostgresBindingOptions &\n PostgresOptionsBase & {\n readonly contract: TContract;\n readonly contractJson?: never;\n };\n\nexport type PostgresOptionsWithContractJson<TContract extends Contract<SqlStorage>> =\n PostgresBindingOptions &\n PostgresOptionsBase & {\n readonly contractJson: unknown;\n readonly contract?: never;\n readonly _contract?: TContract;\n };\n\nexport type PostgresOptions<TContract extends Contract<SqlStorage>> =\n | PostgresOptionsWithContract<TContract>\n | PostgresOptionsWithContractJson<TContract>;\n\nfunction hasContractJson<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): options is PostgresOptionsWithContractJson<TContract> {\n return 'contractJson' in options;\n}\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): TContract {\n const contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n return validateContract<TContract>(contractInput, emptyCodecLookup);\n}\n\nfunction toRuntimeBinding<TContract extends Contract<SqlStorage>>(\n binding: PostgresBinding,\n options: PostgresOptions<TContract>,\n) {\n if (binding.kind !== 'url') {\n return binding;\n }\n\n return {\n kind: 'pgPool',\n pool: new Pool({\n connectionString: binding.url,\n connectionTimeoutMillis: options.poolOptions?.connectionTimeoutMillis ?? 20_000,\n idleTimeoutMillis: options.poolOptions?.idleTimeoutMillis ?? 30_000,\n }),\n } as const;\n}\n\n/**\n * Creates a lazy Postgres client from either `contractJson` or a TypeScript-authored `contract`.\n * Static query surfaces are available immediately, while `runtime()` instantiates the driver/pool on first call.\n *\n * - No-emit: pass a TypeScript-authored contract. Example: postgres({ contract })\n * - Emitted: pass Contract type explicitly. Example: postgres<Contract>({ contractJson, url })\n */\nexport default function postgres<TContract extends Contract<SqlStorage>>(\n options: PostgresOptionsWithContract<TContract>,\n): PostgresClient<TContract>;\nexport default function postgres<TContract extends Contract<SqlStorage>>(\n options: PostgresOptionsWithContractJson<TContract>,\n): PostgresClient<TContract>;\nexport default function postgres<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): PostgresClient<TContract> {\n const contract = resolveContract(options);\n let binding = resolveOptionalPostgresBinding(options);\n const stack = createSqlExecutionStack({\n target: postgresTarget,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: options.extensions ?? [],\n });\n\n const context = createExecutionContext({\n contract,\n stack,\n });\n\n let runtimeInstance: Runtime | undefined;\n let runtimeDriver: { connect(binding: unknown): Promise<void> } | undefined;\n let driverConnected = false;\n let connectPromise: Promise<void> | undefined;\n let backgroundConnectError: unknown;\n const connectDriver = async (resolvedBinding: PostgresBinding): Promise<void> => {\n if (driverConnected) return;\n if (!runtimeDriver) throw new Error('Postgres runtime driver missing');\n if (connectPromise) return connectPromise;\n const runtimeBinding = toRuntimeBinding(resolvedBinding, options);\n connectPromise = runtimeDriver\n .connect(runtimeBinding)\n .then(() => {\n driverConnected = true;\n })\n .catch(async (err) => {\n backgroundConnectError = err;\n connectPromise = undefined;\n if (resolvedBinding.kind === 'url' && runtimeBinding.kind === 'pgPool') {\n await runtimeBinding.pool.end().catch(() => undefined);\n }\n throw err;\n });\n return connectPromise;\n };\n const getRuntime = (): Runtime => {\n if (backgroundConnectError !== undefined) {\n throw backgroundConnectError;\n }\n\n if (runtimeInstance) {\n return runtimeInstance;\n }\n\n const stackInstance = instantiateExecutionStack(stack);\n const driverDescriptor = stack.driver;\n if (!driverDescriptor) {\n throw new Error('Driver descriptor missing from execution stack');\n }\n\n const driver = driverDescriptor.create({\n cursor: { disabled: true },\n });\n runtimeDriver = driver;\n if (binding !== undefined) {\n void connectDriver(binding).catch(() => undefined);\n }\n\n runtimeInstance = createRuntime({\n stackInstance,\n context,\n driver,\n verify: options.verify ?? { mode: 'onFirstUse', requireMarker: false },\n ...ifDefined('middleware', options.middleware),\n });\n\n return runtimeInstance;\n };\n const orm: OrmClient<TContract> = ormBuilder({\n runtime: {\n execute(plan) {\n return getRuntime().execute(plan);\n },\n connection() {\n return getRuntime().connection();\n },\n },\n context,\n });\n\n const sql: Db<TContract> = sqlBuilder<TContract>({ context });\n\n return {\n sql,\n orm,\n context,\n stack,\n\n async connect(bindingInput) {\n if (driverConnected || connectPromise) {\n throw new Error('Postgres client already connected');\n }\n\n if (bindingInput !== undefined) {\n binding = resolvePostgresBinding(bindingInput);\n }\n\n if (binding === undefined) {\n throw new Error(\n 'Postgres binding not configured. Pass url/pg/binding to postgres(...) or call db.connect({ ... }).',\n );\n }\n\n const runtime = getRuntime();\n if (driverConnected) {\n return runtime;\n }\n\n await connectDriver(binding);\n return runtime;\n },\n\n runtime() {\n return getRuntime();\n },\n\n transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R> {\n return withTransaction(getRuntime(), (txCtx) => {\n const txSql: Db<TContract> = sqlBuilder<TContract>({ context });\n\n const txOrm: OrmClient<TContract> = ormBuilder({\n runtime: {\n execute(plan) {\n return txCtx.execute(plan);\n },\n },\n context,\n });\n\n // Use `txCtx` as the prototype instead of spreading it so that live\n // accessors (notably the `invalidated` getter, which reads a closure\n // variable in `withTransaction`) remain wired to the original object.\n // Spreading would evaluate the getter once and freeze its value.\n const tx: PostgresTransactionContext<TContract> = Object.assign(\n Object.create(txCtx) as TransactionContext,\n { sql: txSql, orm: txOrm },\n );\n\n return fn(tx);\n });\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;AA+BA,SAAS,oBAAoB,KAAqB;CAChD,MAAM,UAAU,IAAI,MAAM;CAC1B,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,IAAI;CACJ,IAAI;EACF,SAAS,IAAI,IAAI,QAAQ;SACnB;EACN,MAAM,IAAI,MAAM,mCAAmC;;CAGrD,IAAI,OAAO,aAAa,eAAe,OAAO,aAAa,eACzD,MAAM,IAAI,MAAM,qDAAqD;CAGvE,OAAO;;AAGT,SAAgB,uBAAuB,SAAgD;CAMrF,IAJE,OAAO,QAAQ,YAAY,KAAA,EAAU,GACrC,OAAO,QAAQ,QAAQ,KAAA,EAAU,GACjC,OAAO,QAAQ,OAAO,KAAA,EAAU,KAEZ,GACpB,MAAM,IAAI,MAAM,iDAAiD;CAGnE,IAAI,QAAQ,YAAY,KAAA,GACtB,OAAO,QAAQ;CAGjB,IAAI,QAAQ,QAAQ,KAAA,GAClB,OAAO;EAAE,MAAM;EAAO,KAAK,oBAAoB,QAAQ,IAAI;EAAE;CAG/D,MAAM,YAAY,QAAQ;CAC1B,IAAI,cAAc,KAAA,GAChB,MAAM,IAAI,MAAM,4DAA4D;CAG9E,IAAI,qBAAqBA,MACvB,OAAO;EAAE,MAAM;EAAU,MAAM;EAAW;CAG5C,IAAI,qBAAqBC,QACvB,OAAO;EAAE,MAAM;EAAY,QAAQ;EAAW;CAGhD,MAAM,IAAI,MACR,oFACD;;AAGH,SAAgB,+BACd,SAC6B;CAM7B,IAJE,OAAO,QAAQ,YAAY,KAAA,EAAU,GACrC,OAAO,QAAQ,QAAQ,KAAA,EAAU,GACjC,OAAO,QAAQ,OAAO,KAAA,EAAU,KAEZ,GACpB;CAGF,OAAO,uBAAuB,QAAgC;;;;ACVhE,SAAS,gBACP,SACuD;CACvD,OAAO,kBAAkB;;AAG3B,SAAS,gBACP,SACW;CAEX,OAAO,iBADe,gBAAgB,QAAQ,GAAG,QAAQ,eAAe,QAAQ,UAC9B,iBAAiB;;AAGrE,SAAS,iBACP,SACA,SACA;CACA,IAAI,QAAQ,SAAS,OACnB,OAAO;CAGT,OAAO;EACL,MAAM;EACN,MAAM,IAAI,KAAK;GACb,kBAAkB,QAAQ;GAC1B,yBAAyB,QAAQ,aAAa,2BAA2B;GACzE,mBAAmB,QAAQ,aAAa,qBAAqB;GAC9D,CAAC;EACH;;AAgBH,SAAwB,SACtB,SAC2B;CAC3B,MAAM,WAAW,gBAAgB,QAAQ;CACzC,IAAI,UAAU,+BAA+B,QAAQ;CACrD,MAAM,QAAQ,wBAAwB;EACpC,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,gBAAgB,QAAQ,cAAc,EAAE;EACzC,CAAC;CAEF,MAAM,UAAU,uBAAuB;EACrC;EACA;EACD,CAAC;CAEF,IAAI;CACJ,IAAI;CACJ,IAAI,kBAAkB;CACtB,IAAI;CACJ,IAAI;CACJ,MAAM,gBAAgB,OAAO,oBAAoD;EAC/E,IAAI,iBAAiB;EACrB,IAAI,CAAC,eAAe,MAAM,IAAI,MAAM,kCAAkC;EACtE,IAAI,gBAAgB,OAAO;EAC3B,MAAM,iBAAiB,iBAAiB,iBAAiB,QAAQ;EACjE,iBAAiB,cACd,QAAQ,eAAe,CACvB,WAAW;GACV,kBAAkB;IAClB,CACD,MAAM,OAAO,QAAQ;GACpB,yBAAyB;GACzB,iBAAiB,KAAA;GACjB,IAAI,gBAAgB,SAAS,SAAS,eAAe,SAAS,UAC5D,MAAM,eAAe,KAAK,KAAK,CAAC,YAAY,KAAA,EAAU;GAExD,MAAM;IACN;EACJ,OAAO;;CAET,MAAM,mBAA4B;EAChC,IAAI,2BAA2B,KAAA,GAC7B,MAAM;EAGR,IAAI,iBACF,OAAO;EAGT,MAAM,gBAAgB,0BAA0B,MAAM;EACtD,MAAM,mBAAmB,MAAM;EAC/B,IAAI,CAAC,kBACH,MAAM,IAAI,MAAM,iDAAiD;EAGnE,MAAM,SAAS,iBAAiB,OAAO,EACrC,QAAQ,EAAE,UAAU,MAAM,EAC3B,CAAC;EACF,gBAAgB;EAChB,IAAI,YAAY,KAAA,GACd,cAAmB,QAAQ,CAAC,YAAY,KAAA,EAAU;EAGpD,kBAAkB,cAAc;GAC9B;GACA;GACA;GACA,QAAQ,QAAQ,UAAU;IAAE,MAAM;IAAc,eAAe;IAAO;GACtE,GAAG,UAAU,cAAc,QAAQ,WAAW;GAC/C,CAAC;EAEF,OAAO;;CAET,MAAMC,QAA4BC,IAAW;EAC3C,SAAS;GACP,QAAQ,MAAM;IACZ,OAAO,YAAY,CAAC,QAAQ,KAAK;;GAEnC,aAAa;IACX,OAAO,YAAY,CAAC,YAAY;;GAEnC;EACD;EACD,CAAC;CAIF,OAAO;EACL,KAHyBC,IAAsB,EAAE,SAAS,CAGvD;EACH,KAAA;EACA;EACA;EAEA,MAAM,QAAQ,cAAc;GAC1B,IAAI,mBAAmB,gBACrB,MAAM,IAAI,MAAM,oCAAoC;GAGtD,IAAI,iBAAiB,KAAA,GACnB,UAAU,uBAAuB,aAAa;GAGhD,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MACR,qGACD;GAGH,MAAM,UAAU,YAAY;GAC5B,IAAI,iBACF,OAAO;GAGT,MAAM,cAAc,QAAQ;GAC5B,OAAO;;EAGT,UAAU;GACR,OAAO,YAAY;;EAGrB,YAAe,IAA+E;GAC5F,OAAO,gBAAgB,YAAY,GAAG,UAAU;IAC9C,MAAM,QAAuBA,IAAsB,EAAE,SAAS,CAAC;IAE/D,MAAM,QAA8BD,IAAW;KAC7C,SAAS,EACP,QAAQ,MAAM;MACZ,OAAO,MAAM,QAAQ,KAAK;QAE7B;KACD;KACD,CAAC;IAWF,OAAO,GAL2C,OAAO,OACvD,OAAO,OAAO,MAAM,EACpB;KAAE,KAAK;KAAO,KAAK;KAAO,CAGhB,CAAC;KACb;;EAEL"}
@@ -0,0 +1,62 @@
1
+ import { o as PostgresTargetId } from "./postgres-Bkdcp2EZ.mjs";
2
+ import { PostgresDriverCreateOptions } from "@prisma-next/driver-postgres/runtime";
3
+ import { ExecutionContext, Runtime, RuntimeVerifyOptions, SqlExecutionStackWithDriver, SqlMiddleware, SqlRuntimeExtensionDescriptor } from "@prisma-next/sql-runtime";
4
+ import { Contract } from "@prisma-next/contract/types";
5
+ import { Db } from "@prisma-next/sql-builder/types";
6
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
7
+
8
+ //#region src/runtime/postgres-serverless.d.ts
9
+ type PostgresServerlessCursorOptions = NonNullable<PostgresDriverCreateOptions['cursor']>;
10
+ interface PostgresServerlessClient<TContract extends Contract<SqlStorage>> {
11
+ readonly sql: Db<TContract>;
12
+ readonly context: ExecutionContext<TContract>;
13
+ readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;
14
+ readonly contract: TContract;
15
+ connect(binding: {
16
+ readonly url: string;
17
+ }): Promise<Runtime & AsyncDisposable>;
18
+ }
19
+ interface PostgresServerlessOptionsBase {
20
+ readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];
21
+ readonly middleware?: readonly SqlMiddleware[];
22
+ readonly verify?: RuntimeVerifyOptions;
23
+ readonly cursor?: PostgresServerlessCursorOptions;
24
+ }
25
+ type PostgresServerlessOptionsWithContract<TContract extends Contract<SqlStorage>> = PostgresServerlessOptionsBase & {
26
+ readonly contract: TContract;
27
+ readonly contractJson?: never;
28
+ };
29
+ type PostgresServerlessOptionsWithContractJson<TContract extends Contract<SqlStorage>> = PostgresServerlessOptionsBase & {
30
+ readonly contractJson: unknown;
31
+ readonly contract?: never;
32
+ readonly _contract?: TContract;
33
+ };
34
+ type PostgresServerlessOptions<TContract extends Contract<SqlStorage>> = PostgresServerlessOptionsWithContract<TContract> | PostgresServerlessOptionsWithContractJson<TContract>;
35
+ /**
36
+ * Per-request Postgres facade for serverless / edge runtimes (Cloudflare Workers + Hyperdrive,
37
+ * AWS Lambda, Vercel, Deno Deploy, Bun edge, etc.).
38
+ *
39
+ * Construction shape mirrors the Node `postgres()` factory but the returned client deliberately
40
+ * omits `orm`, `runtime()`, and `transaction()`. Closure-cached convenience surfaces are unsafe
41
+ * across `fetch` invocations: stale connections after isolate idle, concurrent-query races on a
42
+ * shared `pg.Client`, no clean shutdown. Per-request callers acquire a fresh `Runtime` via
43
+ * `db.connect({ url })` and dispose it via `await using` on scope exit.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * const db = postgresServerless<Contract>({ contractJson });
48
+ *
49
+ * export default {
50
+ * async fetch(_req: Request, env: Env): Promise<Response> {
51
+ * await using runtime = await db.connect({ url: env.HYPERDRIVE.connectionString });
52
+ * const rows = await runtime.execute(db.sql.from(t).select(...).build());
53
+ * return Response.json(rows);
54
+ * },
55
+ * };
56
+ * ```
57
+ */
58
+ declare function postgresServerless<TContract extends Contract<SqlStorage>>(options: PostgresServerlessOptionsWithContract<TContract>): PostgresServerlessClient<TContract>;
59
+ declare function postgresServerless<TContract extends Contract<SqlStorage>>(options: PostgresServerlessOptionsWithContractJson<TContract>): PostgresServerlessClient<TContract>;
60
+ //#endregion
61
+ export { type PostgresServerlessClient, type PostgresServerlessCursorOptions, type PostgresServerlessOptions, type PostgresServerlessOptionsBase, type PostgresServerlessOptionsWithContract, type PostgresServerlessOptionsWithContractJson, postgresServerless as default };
62
+ //# sourceMappingURL=serverless.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serverless.d.mts","names":[],"sources":["../src/runtime/postgres-serverless.ts"],"mappings":";;;;;;;;KA8BY,+BAAA,GAAkC,WAAA,CAAY,2BAAA;AAAA,UAEzC,wBAAA,mBAA2C,QAAA,CAAS,UAAA;EAAA,SAC1D,GAAA,EAAK,EAAA,CAAG,SAAA;EAAA,SACR,OAAA,EAAS,gBAAA,CAAiB,SAAA;EAAA,SAC1B,KAAA,EAAO,2BAAA,CAA4B,gBAAA;EAAA,SACnC,QAAA,EAAU,SAAA;EACnB,OAAA,CAAQ,OAAA;IAAA,SAAoB,GAAA;EAAA,IAAgB,OAAA,CAAQ,OAAA,GAAU,eAAA;AAAA;AAAA,UAG/C,6BAAA;EAAA,SACN,UAAA,YAAsB,6BAAA,CAA8B,gBAAA;EAAA,SACpD,UAAA,YAAsB,aAAA;EAAA,SACtB,MAAA,GAAS,oBAAA;EAAA,SACT,MAAA,GAAS,+BAAA;AAAA;AAAA,KAGR,qCAAA,mBAAwD,QAAA,CAAS,UAAA,KAC3E,6BAAA;EAAA,SACW,QAAA,EAAU,SAAA;EAAA,SACV,YAAA;AAAA;AAAA,KAGD,yCAAA,mBAA4D,QAAA,CAAS,UAAA,KAC/E,6BAAA;EAAA,SACW,YAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA,GAAY,SAAA;AAAA;AAAA,KAGb,yBAAA,mBAA4C,QAAA,CAAS,UAAA,KAC7D,qCAAA,CAAsC,SAAA,IACtC,yCAAA,CAA0C,SAAA;;;;;;;;;;;;;;;;;;;;;AAtB9C;;;iBAoEwB,kBAAA,mBAAqC,QAAA,CAAS,UAAA,EAAA,CACpE,OAAA,EAAS,qCAAA,CAAsC,SAAA,IAC9C,wBAAA,CAAyB,SAAA;AAAA,iBACJ,kBAAA,mBAAqC,QAAA,CAAS,UAAA,EAAA,CACpE,OAAA,EAAS,yCAAA,CAA0C,SAAA,IAClD,wBAAA,CAAyB,SAAA"}
@@ -0,0 +1,80 @@
1
+ import { ifDefined } from "@prisma-next/utils/defined";
2
+ import postgresAdapter from "@prisma-next/adapter-postgres/runtime";
3
+ import postgresDriver from "@prisma-next/driver-postgres/runtime";
4
+ import { emptyCodecLookup } from "@prisma-next/framework-components/codec";
5
+ import { instantiateExecutionStack } from "@prisma-next/framework-components/execution";
6
+ import { sql } from "@prisma-next/sql-builder/runtime";
7
+ import { validateContract } from "@prisma-next/sql-contract/validate";
8
+ import { createExecutionContext, createRuntime, createSqlExecutionStack } from "@prisma-next/sql-runtime";
9
+ import postgresTarget from "@prisma-next/target-postgres/runtime";
10
+ import { Client } from "pg";
11
+ //#region src/runtime/postgres-serverless.ts
12
+ function hasContractJson(options) {
13
+ return "contractJson" in options;
14
+ }
15
+ function resolveContract(options) {
16
+ return validateContract(hasContractJson(options) ? options.contractJson : options.contract, emptyCodecLookup);
17
+ }
18
+ function validateConnectionString(url) {
19
+ const trimmed = url.trim();
20
+ if (trimmed.length === 0) throw new Error("Postgres URL must be a non-empty string");
21
+ return trimmed;
22
+ }
23
+ function postgresServerless(options) {
24
+ const contract = resolveContract(options);
25
+ const stack = createSqlExecutionStack({
26
+ target: postgresTarget,
27
+ adapter: postgresAdapter,
28
+ driver: postgresDriver,
29
+ extensionPacks: options.extensions ?? []
30
+ });
31
+ const context = createExecutionContext({
32
+ contract,
33
+ stack
34
+ });
35
+ return {
36
+ sql: sql({ context }),
37
+ context,
38
+ stack,
39
+ contract,
40
+ async connect(binding) {
41
+ const url = validateConnectionString(binding.url);
42
+ const driverDescriptor = stack.driver;
43
+ if (!driverDescriptor) throw new Error("Driver descriptor missing from execution stack");
44
+ const stackInstance = instantiateExecutionStack(stack);
45
+ const driver = driverDescriptor.create({ ...ifDefined("cursor", options.cursor) });
46
+ const client = new Client({ connectionString: url });
47
+ await driver.connect({
48
+ kind: "pgClient",
49
+ client
50
+ });
51
+ let runtime;
52
+ try {
53
+ runtime = createRuntime({
54
+ stackInstance,
55
+ context,
56
+ driver,
57
+ verify: options.verify ?? {
58
+ mode: "onFirstUse",
59
+ requireMarker: false
60
+ },
61
+ ...ifDefined("middleware", options.middleware)
62
+ });
63
+ } catch (err) {
64
+ await driver.close().catch(() => void 0);
65
+ throw err;
66
+ }
67
+ Object.defineProperty(runtime, Symbol.asyncDispose, {
68
+ value: () => runtime.close(),
69
+ configurable: true,
70
+ writable: false,
71
+ enumerable: false
72
+ });
73
+ return runtime;
74
+ }
75
+ };
76
+ }
77
+ //#endregion
78
+ export { postgresServerless as default };
79
+
80
+ //# sourceMappingURL=serverless.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serverless.mjs","names":["sqlBuilder"],"sources":["../src/runtime/postgres-serverless.ts"],"sourcesContent":["import postgresAdapter from '@prisma-next/adapter-postgres/runtime';\nimport type { Contract } from '@prisma-next/contract/types';\nimport postgresDriver, {\n type PostgresDriverCreateOptions,\n} from '@prisma-next/driver-postgres/runtime';\nimport { emptyCodecLookup } from '@prisma-next/framework-components/codec';\nimport { instantiateExecutionStack } from '@prisma-next/framework-components/execution';\nimport { sql as sqlBuilder } from '@prisma-next/sql-builder/runtime';\nimport type { Db } from '@prisma-next/sql-builder/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { validateContract } from '@prisma-next/sql-contract/validate';\nimport type {\n ExecutionContext,\n Runtime,\n RuntimeVerifyOptions,\n SqlExecutionStackWithDriver,\n SqlMiddleware,\n SqlRuntimeExtensionDescriptor,\n} from '@prisma-next/sql-runtime';\nimport {\n createExecutionContext,\n createRuntime,\n createSqlExecutionStack,\n} from '@prisma-next/sql-runtime';\nimport postgresTarget from '@prisma-next/target-postgres/runtime';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { Client } from 'pg';\n\nimport type { PostgresTargetId } from './postgres';\n\nexport type PostgresServerlessCursorOptions = NonNullable<PostgresDriverCreateOptions['cursor']>;\n\nexport interface PostgresServerlessClient<TContract extends Contract<SqlStorage>> {\n readonly sql: Db<TContract>;\n readonly context: ExecutionContext<TContract>;\n readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;\n readonly contract: TContract;\n connect(binding: { readonly url: string }): Promise<Runtime & AsyncDisposable>;\n}\n\nexport interface PostgresServerlessOptionsBase {\n readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];\n readonly middleware?: readonly SqlMiddleware[];\n readonly verify?: RuntimeVerifyOptions;\n readonly cursor?: PostgresServerlessCursorOptions;\n}\n\nexport type PostgresServerlessOptionsWithContract<TContract extends Contract<SqlStorage>> =\n PostgresServerlessOptionsBase & {\n readonly contract: TContract;\n readonly contractJson?: never;\n };\n\nexport type PostgresServerlessOptionsWithContractJson<TContract extends Contract<SqlStorage>> =\n PostgresServerlessOptionsBase & {\n readonly contractJson: unknown;\n readonly contract?: never;\n readonly _contract?: TContract;\n };\n\nexport type PostgresServerlessOptions<TContract extends Contract<SqlStorage>> =\n | PostgresServerlessOptionsWithContract<TContract>\n | PostgresServerlessOptionsWithContractJson<TContract>;\n\nfunction hasContractJson<TContract extends Contract<SqlStorage>>(\n options: PostgresServerlessOptions<TContract>,\n): options is PostgresServerlessOptionsWithContractJson<TContract> {\n return 'contractJson' in options;\n}\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: PostgresServerlessOptions<TContract>,\n): TContract {\n const contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n return validateContract<TContract>(contractInput, emptyCodecLookup);\n}\n\nfunction validateConnectionString(url: string): string {\n const trimmed = url.trim();\n if (trimmed.length === 0) {\n throw new Error('Postgres URL must be a non-empty string');\n }\n return trimmed;\n}\n\n/**\n * Per-request Postgres facade for serverless / edge runtimes (Cloudflare Workers + Hyperdrive,\n * AWS Lambda, Vercel, Deno Deploy, Bun edge, etc.).\n *\n * Construction shape mirrors the Node `postgres()` factory but the returned client deliberately\n * omits `orm`, `runtime()`, and `transaction()`. Closure-cached convenience surfaces are unsafe\n * across `fetch` invocations: stale connections after isolate idle, concurrent-query races on a\n * shared `pg.Client`, no clean shutdown. Per-request callers acquire a fresh `Runtime` via\n * `db.connect({ url })` and dispose it via `await using` on scope exit.\n *\n * @example\n * ```ts\n * const db = postgresServerless<Contract>({ contractJson });\n *\n * export default {\n * async fetch(_req: Request, env: Env): Promise<Response> {\n * await using runtime = await db.connect({ url: env.HYPERDRIVE.connectionString });\n * const rows = await runtime.execute(db.sql.from(t).select(...).build());\n * return Response.json(rows);\n * },\n * };\n * ```\n */\nexport default function postgresServerless<TContract extends Contract<SqlStorage>>(\n options: PostgresServerlessOptionsWithContract<TContract>,\n): PostgresServerlessClient<TContract>;\nexport default function postgresServerless<TContract extends Contract<SqlStorage>>(\n options: PostgresServerlessOptionsWithContractJson<TContract>,\n): PostgresServerlessClient<TContract>;\nexport default function postgresServerless<TContract extends Contract<SqlStorage>>(\n options: PostgresServerlessOptions<TContract>,\n): PostgresServerlessClient<TContract> {\n const contract = resolveContract(options);\n const stack = createSqlExecutionStack({\n target: postgresTarget,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: options.extensions ?? [],\n });\n\n const context = createExecutionContext({\n contract,\n stack,\n });\n\n const sql: Db<TContract> = sqlBuilder<TContract>({ context });\n\n return {\n sql,\n context,\n stack,\n contract,\n\n async connect(binding) {\n const url = validateConnectionString(binding.url);\n\n const driverDescriptor = stack.driver;\n if (!driverDescriptor) {\n throw new Error('Driver descriptor missing from execution stack');\n }\n\n const stackInstance = instantiateExecutionStack(stack);\n const driver = driverDescriptor.create({\n ...ifDefined('cursor', options.cursor),\n });\n\n const client = new Client({ connectionString: url });\n await driver.connect({ kind: 'pgClient', client });\n\n let runtime: Runtime;\n try {\n runtime = createRuntime({\n stackInstance,\n context,\n driver,\n verify: options.verify ?? { mode: 'onFirstUse', requireMarker: false },\n ...ifDefined('middleware', options.middleware),\n });\n } catch (err) {\n // The driver is bound to the pg.Client at this point; without a runtime\n // to wrap it, the caller has no handle to dispose. Close the driver so\n // the underlying pg.Client is released even if its TCP socket has not\n // yet opened (lazy connect): keeps cleanup symmetric with successful\n // construction and prevents real socket leaks if pg ever changes its\n // connect semantics.\n await driver.close().catch(() => undefined);\n throw err;\n }\n\n Object.defineProperty(runtime, Symbol.asyncDispose, {\n value: () => runtime.close(),\n configurable: true,\n writable: false,\n enumerable: false,\n });\n\n return runtime as Runtime & AsyncDisposable;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;AAgEA,SAAS,gBACP,SACiE;CACjE,OAAO,kBAAkB;;AAG3B,SAAS,gBACP,SACW;CAEX,OAAO,iBADe,gBAAgB,QAAQ,GAAG,QAAQ,eAAe,QAAQ,UAC9B,iBAAiB;;AAGrE,SAAS,yBAAyB,KAAqB;CACrD,MAAM,UAAU,IAAI,MAAM;CAC1B,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,0CAA0C;CAE5D,OAAO;;AAgCT,SAAwB,mBACtB,SACqC;CACrC,MAAM,WAAW,gBAAgB,QAAQ;CACzC,MAAM,QAAQ,wBAAwB;EACpC,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,gBAAgB,QAAQ,cAAc,EAAE;EACzC,CAAC;CAEF,MAAM,UAAU,uBAAuB;EACrC;EACA;EACD,CAAC;CAIF,OAAO;EACL,KAHyBA,IAAsB,EAAE,SAAS,CAGvD;EACH;EACA;EACA;EAEA,MAAM,QAAQ,SAAS;GACrB,MAAM,MAAM,yBAAyB,QAAQ,IAAI;GAEjD,MAAM,mBAAmB,MAAM;GAC/B,IAAI,CAAC,kBACH,MAAM,IAAI,MAAM,iDAAiD;GAGnE,MAAM,gBAAgB,0BAA0B,MAAM;GACtD,MAAM,SAAS,iBAAiB,OAAO,EACrC,GAAG,UAAU,UAAU,QAAQ,OAAO,EACvC,CAAC;GAEF,MAAM,SAAS,IAAI,OAAO,EAAE,kBAAkB,KAAK,CAAC;GACpD,MAAM,OAAO,QAAQ;IAAE,MAAM;IAAY;IAAQ,CAAC;GAElD,IAAI;GACJ,IAAI;IACF,UAAU,cAAc;KACtB;KACA;KACA;KACA,QAAQ,QAAQ,UAAU;MAAE,MAAM;MAAc,eAAe;MAAO;KACtE,GAAG,UAAU,cAAc,QAAQ,WAAW;KAC/C,CAAC;YACK,KAAK;IAOZ,MAAM,OAAO,OAAO,CAAC,YAAY,KAAA,EAAU;IAC3C,MAAM;;GAGR,OAAO,eAAe,SAAS,OAAO,cAAc;IAClD,aAAa,QAAQ,OAAO;IAC5B,cAAc;IACd,UAAU;IACV,YAAY;IACb,CAAC;GAEF,OAAO;;EAEV"}
@@ -0,0 +1,2 @@
1
+ import pack_default from "@prisma-next/target-postgres/pack";
2
+ export { pack_default as default };
@@ -0,0 +1,2 @@
1
+ import pack_default from "@prisma-next/target-postgres/pack";
2
+ export { pack_default as default };
package/package.json CHANGED
@@ -1,33 +1,34 @@
1
1
  {
2
2
  "name": "@prisma-next/postgres",
3
- "version": "0.5.0-dev.9",
3
+ "version": "0.5.0",
4
+ "license": "Apache-2.0",
4
5
  "type": "module",
5
6
  "sideEffects": false,
6
7
  "description": "One-liner lazy Postgres client composition for Prisma Next",
7
8
  "dependencies": {
8
9
  "pathe": "^2.0.3",
9
- "pg": "8.16.3",
10
- "@prisma-next/config": "0.5.0-dev.9",
11
- "@prisma-next/contract": "0.5.0-dev.9",
12
- "@prisma-next/adapter-postgres": "0.5.0-dev.9",
13
- "@prisma-next/driver-postgres": "0.5.0-dev.9",
14
- "@prisma-next/framework-components": "0.5.0-dev.9",
15
- "@prisma-next/family-sql": "0.5.0-dev.9",
16
- "@prisma-next/sql-contract-psl": "0.5.0-dev.9",
17
- "@prisma-next/sql-contract-ts": "0.5.0-dev.9",
18
- "@prisma-next/sql-contract": "0.5.0-dev.9",
19
- "@prisma-next/sql-orm-client": "0.5.0-dev.9",
20
- "@prisma-next/sql-runtime": "0.5.0-dev.9",
21
- "@prisma-next/sql-builder": "0.5.0-dev.9",
22
- "@prisma-next/sql-relational-core": "0.5.0-dev.9",
23
- "@prisma-next/target-postgres": "0.5.0-dev.9",
24
- "@prisma-next/utils": "0.5.0-dev.9"
10
+ "pg": "8.20.0",
11
+ "@prisma-next/adapter-postgres": "0.5.0",
12
+ "@prisma-next/config": "0.5.0",
13
+ "@prisma-next/contract": "0.5.0",
14
+ "@prisma-next/driver-postgres": "0.5.0",
15
+ "@prisma-next/sql-contract": "0.5.0",
16
+ "@prisma-next/family-sql": "0.5.0",
17
+ "@prisma-next/framework-components": "0.5.0",
18
+ "@prisma-next/sql-contract-psl": "0.5.0",
19
+ "@prisma-next/sql-contract-ts": "0.5.0",
20
+ "@prisma-next/sql-builder": "0.5.0",
21
+ "@prisma-next/sql-orm-client": "0.5.0",
22
+ "@prisma-next/sql-relational-core": "0.5.0",
23
+ "@prisma-next/sql-runtime": "0.5.0",
24
+ "@prisma-next/target-postgres": "0.5.0",
25
+ "@prisma-next/utils": "0.5.0"
25
26
  },
26
27
  "devDependencies": {
27
- "@types/pg": "8.16.0",
28
- "tsdown": "0.18.4",
28
+ "@types/pg": "8.20.0",
29
+ "tsdown": "0.22.0",
29
30
  "typescript": "5.9.3",
30
- "vitest": "4.0.17",
31
+ "vitest": "4.1.5",
31
32
  "@prisma-next/test-utils": "0.0.1",
32
33
  "@prisma-next/tsconfig": "0.0.0",
33
34
  "@prisma-next/tsdown": "0.0.0"
@@ -46,11 +47,13 @@
46
47
  },
47
48
  "exports": {
48
49
  "./config": "./dist/config.mjs",
50
+ "./contract-builder": "./dist/contract-builder.mjs",
51
+ "./family": "./dist/family.mjs",
49
52
  "./runtime": "./dist/runtime.mjs",
53
+ "./serverless": "./dist/serverless.mjs",
54
+ "./target": "./dist/target.mjs",
50
55
  "./package.json": "./package.json"
51
56
  },
52
- "main": "./dist/runtime.mjs",
53
- "module": "./dist/runtime.mjs",
54
57
  "types": "./dist/runtime.d.mts",
55
58
  "scripts": {
56
59
  "build": "tsdown",
@@ -0,0 +1,21 @@
1
+ export type {
2
+ ComposedAuthoringHelpers,
3
+ ContractDefinition,
4
+ ContractInput,
5
+ ContractModelBuilder,
6
+ FieldNode,
7
+ ForeignKeyNode,
8
+ IndexNode,
9
+ ModelNode,
10
+ PrimaryKeyNode,
11
+ RelationNode,
12
+ ScalarFieldBuilder,
13
+ UniqueConstraintNode,
14
+ } from '@prisma-next/sql-contract-ts/contract-builder';
15
+ export {
16
+ buildSqlContractFromDefinition,
17
+ defineContract,
18
+ field,
19
+ model,
20
+ rel,
21
+ } from '@prisma-next/sql-contract-ts/contract-builder';
@@ -0,0 +1 @@
1
+ export { default } from '@prisma-next/family-sql/pack';
@@ -0,0 +1,9 @@
1
+ export type {
2
+ PostgresServerlessClient,
3
+ PostgresServerlessCursorOptions,
4
+ PostgresServerlessOptions,
5
+ PostgresServerlessOptionsBase,
6
+ PostgresServerlessOptionsWithContract,
7
+ PostgresServerlessOptionsWithContractJson,
8
+ } from '../runtime/postgres-serverless';
9
+ export { default } from '../runtime/postgres-serverless';
@@ -0,0 +1 @@
1
+ export { default } from '@prisma-next/target-postgres/pack';
@@ -0,0 +1,185 @@
1
+ import postgresAdapter from '@prisma-next/adapter-postgres/runtime';
2
+ import type { Contract } from '@prisma-next/contract/types';
3
+ import postgresDriver, {
4
+ type PostgresDriverCreateOptions,
5
+ } from '@prisma-next/driver-postgres/runtime';
6
+ import { emptyCodecLookup } from '@prisma-next/framework-components/codec';
7
+ import { instantiateExecutionStack } from '@prisma-next/framework-components/execution';
8
+ import { sql as sqlBuilder } from '@prisma-next/sql-builder/runtime';
9
+ import type { Db } from '@prisma-next/sql-builder/types';
10
+ import type { SqlStorage } from '@prisma-next/sql-contract/types';
11
+ import { validateContract } from '@prisma-next/sql-contract/validate';
12
+ import type {
13
+ ExecutionContext,
14
+ Runtime,
15
+ RuntimeVerifyOptions,
16
+ SqlExecutionStackWithDriver,
17
+ SqlMiddleware,
18
+ SqlRuntimeExtensionDescriptor,
19
+ } from '@prisma-next/sql-runtime';
20
+ import {
21
+ createExecutionContext,
22
+ createRuntime,
23
+ createSqlExecutionStack,
24
+ } from '@prisma-next/sql-runtime';
25
+ import postgresTarget from '@prisma-next/target-postgres/runtime';
26
+ import { ifDefined } from '@prisma-next/utils/defined';
27
+ import { Client } from 'pg';
28
+
29
+ import type { PostgresTargetId } from './postgres';
30
+
31
+ export type PostgresServerlessCursorOptions = NonNullable<PostgresDriverCreateOptions['cursor']>;
32
+
33
+ export interface PostgresServerlessClient<TContract extends Contract<SqlStorage>> {
34
+ readonly sql: Db<TContract>;
35
+ readonly context: ExecutionContext<TContract>;
36
+ readonly stack: SqlExecutionStackWithDriver<PostgresTargetId>;
37
+ readonly contract: TContract;
38
+ connect(binding: { readonly url: string }): Promise<Runtime & AsyncDisposable>;
39
+ }
40
+
41
+ export interface PostgresServerlessOptionsBase {
42
+ readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];
43
+ readonly middleware?: readonly SqlMiddleware[];
44
+ readonly verify?: RuntimeVerifyOptions;
45
+ readonly cursor?: PostgresServerlessCursorOptions;
46
+ }
47
+
48
+ export type PostgresServerlessOptionsWithContract<TContract extends Contract<SqlStorage>> =
49
+ PostgresServerlessOptionsBase & {
50
+ readonly contract: TContract;
51
+ readonly contractJson?: never;
52
+ };
53
+
54
+ export type PostgresServerlessOptionsWithContractJson<TContract extends Contract<SqlStorage>> =
55
+ PostgresServerlessOptionsBase & {
56
+ readonly contractJson: unknown;
57
+ readonly contract?: never;
58
+ readonly _contract?: TContract;
59
+ };
60
+
61
+ export type PostgresServerlessOptions<TContract extends Contract<SqlStorage>> =
62
+ | PostgresServerlessOptionsWithContract<TContract>
63
+ | PostgresServerlessOptionsWithContractJson<TContract>;
64
+
65
+ function hasContractJson<TContract extends Contract<SqlStorage>>(
66
+ options: PostgresServerlessOptions<TContract>,
67
+ ): options is PostgresServerlessOptionsWithContractJson<TContract> {
68
+ return 'contractJson' in options;
69
+ }
70
+
71
+ function resolveContract<TContract extends Contract<SqlStorage>>(
72
+ options: PostgresServerlessOptions<TContract>,
73
+ ): TContract {
74
+ const contractInput = hasContractJson(options) ? options.contractJson : options.contract;
75
+ return validateContract<TContract>(contractInput, emptyCodecLookup);
76
+ }
77
+
78
+ function validateConnectionString(url: string): string {
79
+ const trimmed = url.trim();
80
+ if (trimmed.length === 0) {
81
+ throw new Error('Postgres URL must be a non-empty string');
82
+ }
83
+ return trimmed;
84
+ }
85
+
86
+ /**
87
+ * Per-request Postgres facade for serverless / edge runtimes (Cloudflare Workers + Hyperdrive,
88
+ * AWS Lambda, Vercel, Deno Deploy, Bun edge, etc.).
89
+ *
90
+ * Construction shape mirrors the Node `postgres()` factory but the returned client deliberately
91
+ * omits `orm`, `runtime()`, and `transaction()`. Closure-cached convenience surfaces are unsafe
92
+ * across `fetch` invocations: stale connections after isolate idle, concurrent-query races on a
93
+ * shared `pg.Client`, no clean shutdown. Per-request callers acquire a fresh `Runtime` via
94
+ * `db.connect({ url })` and dispose it via `await using` on scope exit.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const db = postgresServerless<Contract>({ contractJson });
99
+ *
100
+ * export default {
101
+ * async fetch(_req: Request, env: Env): Promise<Response> {
102
+ * await using runtime = await db.connect({ url: env.HYPERDRIVE.connectionString });
103
+ * const rows = await runtime.execute(db.sql.from(t).select(...).build());
104
+ * return Response.json(rows);
105
+ * },
106
+ * };
107
+ * ```
108
+ */
109
+ export default function postgresServerless<TContract extends Contract<SqlStorage>>(
110
+ options: PostgresServerlessOptionsWithContract<TContract>,
111
+ ): PostgresServerlessClient<TContract>;
112
+ export default function postgresServerless<TContract extends Contract<SqlStorage>>(
113
+ options: PostgresServerlessOptionsWithContractJson<TContract>,
114
+ ): PostgresServerlessClient<TContract>;
115
+ export default function postgresServerless<TContract extends Contract<SqlStorage>>(
116
+ options: PostgresServerlessOptions<TContract>,
117
+ ): PostgresServerlessClient<TContract> {
118
+ const contract = resolveContract(options);
119
+ const stack = createSqlExecutionStack({
120
+ target: postgresTarget,
121
+ adapter: postgresAdapter,
122
+ driver: postgresDriver,
123
+ extensionPacks: options.extensions ?? [],
124
+ });
125
+
126
+ const context = createExecutionContext({
127
+ contract,
128
+ stack,
129
+ });
130
+
131
+ const sql: Db<TContract> = sqlBuilder<TContract>({ context });
132
+
133
+ return {
134
+ sql,
135
+ context,
136
+ stack,
137
+ contract,
138
+
139
+ async connect(binding) {
140
+ const url = validateConnectionString(binding.url);
141
+
142
+ const driverDescriptor = stack.driver;
143
+ if (!driverDescriptor) {
144
+ throw new Error('Driver descriptor missing from execution stack');
145
+ }
146
+
147
+ const stackInstance = instantiateExecutionStack(stack);
148
+ const driver = driverDescriptor.create({
149
+ ...ifDefined('cursor', options.cursor),
150
+ });
151
+
152
+ const client = new Client({ connectionString: url });
153
+ await driver.connect({ kind: 'pgClient', client });
154
+
155
+ let runtime: Runtime;
156
+ try {
157
+ runtime = createRuntime({
158
+ stackInstance,
159
+ context,
160
+ driver,
161
+ verify: options.verify ?? { mode: 'onFirstUse', requireMarker: false },
162
+ ...ifDefined('middleware', options.middleware),
163
+ });
164
+ } catch (err) {
165
+ // The driver is bound to the pg.Client at this point; without a runtime
166
+ // to wrap it, the caller has no handle to dispose. Close the driver so
167
+ // the underlying pg.Client is released even if its TCP socket has not
168
+ // yet opened (lazy connect): keeps cleanup symmetric with successful
169
+ // construction and prevents real socket leaks if pg ever changes its
170
+ // connect semantics.
171
+ await driver.close().catch(() => undefined);
172
+ throw err;
173
+ }
174
+
175
+ Object.defineProperty(runtime, Symbol.asyncDispose, {
176
+ value: () => runtime.close(),
177
+ configurable: true,
178
+ writable: false,
179
+ enumerable: false,
180
+ });
181
+
182
+ return runtime as Runtime & AsyncDisposable;
183
+ },
184
+ };
185
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/runtime/binding.ts","../src/runtime/postgres.ts"],"sourcesContent":[],"mappings":"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"}