@prisma-next/postgres 0.5.0-dev.46 → 0.5.0-dev.47
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 +49 -12
- package/dist/postgres-Cr7DL_TS.d.mts +84 -0
- package/dist/postgres-Cr7DL_TS.d.mts.map +1 -0
- package/dist/runtime.d.mts +2 -84
- package/dist/serverless.d.mts +62 -0
- package/dist/serverless.d.mts.map +1 -0
- package/dist/serverless.mjs +81 -0
- package/dist/serverless.mjs.map +1 -0
- package/package.json +17 -16
- package/src/exports/serverless.ts +9 -0
- package/src/runtime/postgres-serverless.ts +185 -0
- package/dist/runtime.d.mts.map +0 -1
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,23 @@ 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/serverless`
|
|
87
|
+
|
|
88
|
+
`@prisma-next/postgres/serverless` exposes `postgresServerless(...)` for per-request runtimes. The returned client exposes only:
|
|
89
|
+
|
|
90
|
+
- `db.sql`
|
|
91
|
+
- `db.context`
|
|
92
|
+
- `db.stack`
|
|
93
|
+
- `db.contract`
|
|
94
|
+
- `db.connect({ url })` — returns `Promise<Runtime & AsyncDisposable>`
|
|
95
|
+
|
|
96
|
+
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 }`.
|
|
97
|
+
|
|
59
98
|
## Responsibilities
|
|
60
99
|
|
|
61
100
|
- Build a static Postgres execution stack from target, adapter, and driver descriptors
|
|
62
|
-
- Build typed SQL
|
|
63
|
-
- Build static
|
|
101
|
+
- Build a typed SQL authoring surface from the execution context
|
|
102
|
+
- Build a static ORM root from the execution context
|
|
64
103
|
- Normalize runtime binding input (`binding`, `url`, `pg`)
|
|
65
104
|
- Lazily instantiate runtime resources on first `db.runtime()` or `db.connect(...)` call
|
|
66
105
|
- Connect the internal Postgres driver through `db.connect(...)` or from initial binding options
|
|
@@ -73,19 +112,17 @@ When URL binding is used, pool timeouts are configurable via `poolOptions`:
|
|
|
73
112
|
- `@prisma-next/target-postgres` for target descriptor
|
|
74
113
|
- `@prisma-next/adapter-postgres` for adapter descriptor
|
|
75
114
|
- `@prisma-next/driver-postgres` for driver descriptor
|
|
76
|
-
- `@prisma-next/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(...)`
|
|
115
|
+
- `@prisma-next/sql-builder` for `sql(...)`
|
|
79
116
|
- `@prisma-next/sql-orm-client` for `orm(...)`
|
|
80
117
|
- `@prisma-next/sql-contract` for `validateContract(...)` and contract types
|
|
81
|
-
- `pg` for
|
|
118
|
+
- `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
119
|
|
|
83
120
|
## Architecture
|
|
84
121
|
|
|
85
122
|
```mermaid
|
|
86
123
|
flowchart TD
|
|
87
124
|
App[App Code] --> Client[postgres(...)]
|
|
88
|
-
Client --> Static[Roots: sql
|
|
125
|
+
Client --> Static[Roots: sql orm context stack]
|
|
89
126
|
Client --> Lazy[runtime()]
|
|
90
127
|
|
|
91
128
|
Lazy --> Instantiate[instantiateExecutionStack]
|
|
@@ -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-Cr7DL_TS.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-Cr7DL_TS.d.mts","names":[],"sources":["../src/runtime/binding.ts","../src/runtime/postgres.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,84 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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-Cr7DL_TS.mjs";
|
|
2
|
+
export { type PostgresBinding, type PostgresClient, type PostgresOptions, type PostgresOptionsBase, type PostgresOptionsWithContract, type PostgresOptionsWithContractJson, postgres as default };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { o as PostgresTargetId } from "./postgres-Cr7DL_TS.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"],"sourcesContent":[],"mappings":";;;;;;;;KA8BY,+BAAA,GAAkC,YAAY;UAEzC,2CAA2C,SAAS;EAFzD,SAAA,GAAA,EAGI,EAHJ,CAGO,SAHP,CAAA;EAEK,SAAA,OAAA,EAEG,gBAFqB,CAEJ,SAFI,CAAA;EAA4B,SAAA,KAAA,EAGnD,2BAHmD,CAGvB,gBAHuB,CAAA;EAAT,SAAA,QAAA,EAIvC,SAJuC;EACzC,OAAA,CAAA,OAAA,EAAA;IAAH,SAAA,GAAA,EAAA,MAAA;EACqB,CAAA,CAAA,EAGS,OAHT,CAGiB,OAHjB,GAG2B,eAH3B,CAAA;;AACS,UAK7B,6BAAA,CAL6B;EAA5B,SAAA,UAAA,CAAA,EAAA,SAMe,6BANf,CAM6C,gBAN7C,CAAA,EAAA;EACG,SAAA,UAAA,CAAA,EAAA,SAMY,aANZ,EAAA;EACiC,SAAA,MAAA,CAAA,EAMlC,oBANkC;EAAU,SAAA,MAAA,CAAA,EAO5C,+BAP4C;;AAAX,KAUzC,qCAVyC,CAAA,kBAUe,QAVf,CAUwB,UAVxB,CAAA,CAAA,GAWnD,6BAXmD,GAAA;EAGpC,SAAA,QAAA,EASM,SATN;EAC8C,SAAA,YAAA,CAAA,EAAA,KAAA;CAA9B;AACA,KAWrB,yCAXqB,CAAA,kBAWuC,QAXvC,CAWgD,UAXhD,CAAA,CAAA,GAY/B,6BAZ+B,GAAA;EACb,SAAA,YAAA,EAAA,OAAA;EACA,SAAA,QAAA,CAAA,EAAA,KAAA;EAA+B,SAAA,SAAA,CAAA,EAa1B,SAb0B;AAGnD,CAAA;AAA6E,KAajE,yBAbiE,CAAA,kBAarB,QAbqB,CAaZ,UAbY,CAAA,CAAA,GAczE,qCAdyE,CAcnC,SAdmC,CAAA,GAezE,yCAfyE,CAe/B,SAf+B,CAAA;;;;;AAM7E;;;;;;AAOA;;;;;;;;AAEyD;;;;;AAgD7B,iBAFJ,kBAEI,CAAA,kBAFiC,QAEjC,CAF0C,UAE1C,CAAA,CAAA,CAAA,OAAA,EADjB,qCACiB,CADqB,SACrB,CAAA,CAAA,EAAzB,wBAAyB,CAAA,SAAA,CAAA;AAAzB,iBACqB,kBADrB,CAAA,kBAC0D,QAD1D,CACmE,UADnE,CAAA,CAAA,CAAA,OAAA,EAEQ,yCAFR,CAEkD,SAFlD,CAAA,CAAA,EAGA,wBAHA,CAGyB,SAHzB,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
|
|
12
|
+
//#region src/runtime/postgres-serverless.ts
|
|
13
|
+
function hasContractJson(options) {
|
|
14
|
+
return "contractJson" in options;
|
|
15
|
+
}
|
|
16
|
+
function resolveContract(options) {
|
|
17
|
+
return validateContract(hasContractJson(options) ? options.contractJson : options.contract, emptyCodecLookup);
|
|
18
|
+
}
|
|
19
|
+
function validateConnectionString(url) {
|
|
20
|
+
const trimmed = url.trim();
|
|
21
|
+
if (trimmed.length === 0) throw new Error("Postgres URL must be a non-empty string");
|
|
22
|
+
return trimmed;
|
|
23
|
+
}
|
|
24
|
+
function postgresServerless(options) {
|
|
25
|
+
const contract = resolveContract(options);
|
|
26
|
+
const stack = createSqlExecutionStack({
|
|
27
|
+
target: postgresTarget,
|
|
28
|
+
adapter: postgresAdapter,
|
|
29
|
+
driver: postgresDriver,
|
|
30
|
+
extensionPacks: options.extensions ?? []
|
|
31
|
+
});
|
|
32
|
+
const context = createExecutionContext({
|
|
33
|
+
contract,
|
|
34
|
+
stack
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
sql: sql({ context }),
|
|
38
|
+
context,
|
|
39
|
+
stack,
|
|
40
|
+
contract,
|
|
41
|
+
async connect(binding) {
|
|
42
|
+
const url = validateConnectionString(binding.url);
|
|
43
|
+
const driverDescriptor = stack.driver;
|
|
44
|
+
if (!driverDescriptor) throw new Error("Driver descriptor missing from execution stack");
|
|
45
|
+
const stackInstance = instantiateExecutionStack(stack);
|
|
46
|
+
const driver = driverDescriptor.create({ ...ifDefined("cursor", options.cursor) });
|
|
47
|
+
const client = new Client({ connectionString: url });
|
|
48
|
+
await driver.connect({
|
|
49
|
+
kind: "pgClient",
|
|
50
|
+
client
|
|
51
|
+
});
|
|
52
|
+
let runtime;
|
|
53
|
+
try {
|
|
54
|
+
runtime = createRuntime({
|
|
55
|
+
stackInstance,
|
|
56
|
+
context,
|
|
57
|
+
driver,
|
|
58
|
+
verify: options.verify ?? {
|
|
59
|
+
mode: "onFirstUse",
|
|
60
|
+
requireMarker: false
|
|
61
|
+
},
|
|
62
|
+
...ifDefined("middleware", options.middleware)
|
|
63
|
+
});
|
|
64
|
+
} catch (err) {
|
|
65
|
+
await driver.close().catch(() => void 0);
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
Object.defineProperty(runtime, Symbol.asyncDispose, {
|
|
69
|
+
value: () => runtime.close(),
|
|
70
|
+
configurable: true,
|
|
71
|
+
writable: false,
|
|
72
|
+
enumerable: false
|
|
73
|
+
});
|
|
74
|
+
return runtime;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
export { postgresServerless as default };
|
|
81
|
+
//# sourceMappingURL=serverless.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverless.mjs","names":["sqlBuilder","runtime: Runtime"],"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;AACjE,QAAO,kBAAkB;;AAG3B,SAAS,gBACP,SACW;AAEX,QAAO,iBADe,gBAAgB,QAAQ,GAAG,QAAQ,eAAe,QAAQ,UAC9B,iBAAiB;;AAGrE,SAAS,yBAAyB,KAAqB;CACrD,MAAM,UAAU,IAAI,MAAM;AAC1B,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MAAM,0CAA0C;AAE5D,QAAO;;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;AAIF,QAAO;EACL,KAHyBA,IAAsB,EAAE,SAAS,CAAC;EAI3D;EACA;EACA;EAEA,MAAM,QAAQ,SAAS;GACrB,MAAM,MAAM,yBAAyB,QAAQ,IAAI;GAEjD,MAAM,mBAAmB,MAAM;AAC/B,OAAI,CAAC,iBACH,OAAM,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;AACpD,SAAM,OAAO,QAAQ;IAAE,MAAM;IAAY;IAAQ,CAAC;GAElD,IAAIC;AACJ,OAAI;AACF,cAAU,cAAc;KACtB;KACA;KACA;KACA,QAAQ,QAAQ,UAAU;MAAE,MAAM;MAAc,eAAe;MAAO;KACtE,GAAG,UAAU,cAAc,QAAQ,WAAW;KAC/C,CAAC;YACK,KAAK;AAOZ,UAAM,OAAO,OAAO,CAAC,YAAY,OAAU;AAC3C,UAAM;;AAGR,UAAO,eAAe,SAAS,OAAO,cAAc;IAClD,aAAa,QAAQ,OAAO;IAC5B,cAAc;IACd,UAAU;IACV,YAAY;IACb,CAAC;AAEF,UAAO;;EAEV"}
|
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/postgres",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.47",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "One-liner lazy Postgres client composition for Prisma Next",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"pathe": "^2.0.3",
|
|
9
9
|
"pg": "8.16.3",
|
|
10
|
-
"@prisma-next/adapter-postgres": "0.5.0-dev.
|
|
11
|
-
"@prisma-next/config": "0.5.0-dev.
|
|
12
|
-
"@prisma-next/contract": "0.5.0-dev.
|
|
13
|
-
"@prisma-next/family-sql": "0.5.0-dev.
|
|
14
|
-
"@prisma-next/
|
|
15
|
-
"@prisma-next/
|
|
16
|
-
"@prisma-next/
|
|
17
|
-
"@prisma-next/sql-contract-psl": "0.5.0-dev.
|
|
18
|
-
"@prisma-next/sql-
|
|
19
|
-
"@prisma-next/sql-
|
|
20
|
-
"@prisma-next/sql-
|
|
21
|
-
"@prisma-next/target-postgres": "0.5.0-dev.
|
|
22
|
-
"@prisma-next/sql-runtime": "0.5.0-dev.
|
|
23
|
-
"@prisma-next/
|
|
24
|
-
"@prisma-next/
|
|
10
|
+
"@prisma-next/adapter-postgres": "0.5.0-dev.47",
|
|
11
|
+
"@prisma-next/config": "0.5.0-dev.47",
|
|
12
|
+
"@prisma-next/contract": "0.5.0-dev.47",
|
|
13
|
+
"@prisma-next/family-sql": "0.5.0-dev.47",
|
|
14
|
+
"@prisma-next/sql-contract": "0.5.0-dev.47",
|
|
15
|
+
"@prisma-next/driver-postgres": "0.5.0-dev.47",
|
|
16
|
+
"@prisma-next/framework-components": "0.5.0-dev.47",
|
|
17
|
+
"@prisma-next/sql-contract-psl": "0.5.0-dev.47",
|
|
18
|
+
"@prisma-next/sql-builder": "0.5.0-dev.47",
|
|
19
|
+
"@prisma-next/sql-contract-ts": "0.5.0-dev.47",
|
|
20
|
+
"@prisma-next/sql-relational-core": "0.5.0-dev.47",
|
|
21
|
+
"@prisma-next/target-postgres": "0.5.0-dev.47",
|
|
22
|
+
"@prisma-next/sql-runtime": "0.5.0-dev.47",
|
|
23
|
+
"@prisma-next/utils": "0.5.0-dev.47",
|
|
24
|
+
"@prisma-next/sql-orm-client": "0.5.0-dev.47"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/pg": "8.16.0",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"exports": {
|
|
48
48
|
"./config": "./dist/config.mjs",
|
|
49
49
|
"./runtime": "./dist/runtime.mjs",
|
|
50
|
+
"./serverless": "./dist/serverless.mjs",
|
|
50
51
|
"./package.json": "./package.json"
|
|
51
52
|
},
|
|
52
53
|
"main": "./dist/runtime.mjs",
|
|
@@ -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,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
|
+
}
|
package/dist/runtime.d.mts.map
DELETED
|
@@ -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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"}
|