@prisma-next/postgres 0.5.0-dev.8 → 0.5.0-dev.87
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 +61 -12
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +1 -2
- package/dist/config.mjs.map +1 -1
- package/dist/contract-builder.d.mts +2 -0
- package/dist/contract-builder.mjs +2 -0
- package/dist/family.d.mts +2 -0
- package/dist/family.mjs +2 -0
- package/dist/postgres-Bkdcp2EZ.d.mts +84 -0
- package/dist/postgres-Bkdcp2EZ.d.mts.map +1 -0
- package/dist/runtime.d.mts +2 -84
- package/dist/runtime.mjs +3 -4
- package/dist/runtime.mjs.map +1 -1
- package/dist/serverless.d.mts +62 -0
- package/dist/serverless.d.mts.map +1 -0
- package/dist/serverless.mjs +80 -0
- package/dist/serverless.mjs.map +1 -0
- package/dist/target.d.mts +2 -0
- package/dist/target.mjs +2 -0
- package/package.json +27 -24
- package/src/exports/contract-builder.ts +21 -0
- package/src/exports/family.ts +1 -0
- package/src/exports/serverless.ts +9 -0
- package/src/exports/target.ts +1 -0
- package/src/runtime/postgres-serverless.ts +185 -0
- package/src/runtime/postgres.ts +2 -1
- 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,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
|
|
63
|
-
- Build static
|
|
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-
|
|
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
|
|
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
|
|
137
|
+
Client --> Static[Roots: sql orm context stack]
|
|
89
138
|
Client --> Lazy[runtime()]
|
|
90
139
|
|
|
91
140
|
Lazy --> Instantiate[instantiateExecutionStack]
|
package/dist/config.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config/define-config.ts"],"
|
|
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
|
package/dist/config.mjs.map
CHANGED
|
@@ -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":"
|
|
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 };
|
package/dist/family.mjs
ADDED
|
@@ -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"}
|
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-Bkdcp2EZ.mjs";
|
|
2
|
+
export { type PostgresBinding, type PostgresClient, type PostgresOptions, type PostgresOptionsBase, type PostgresOptionsWithContract, type PostgresOptionsWithContractJson, postgres as default };
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ifDefined } from "@prisma-next/utils/defined";
|
|
1
2
|
import postgresAdapter from "@prisma-next/adapter-postgres/runtime";
|
|
2
3
|
import postgresDriver from "@prisma-next/driver-postgres/runtime";
|
|
3
4
|
import { emptyCodecLookup } from "@prisma-next/framework-components/codec";
|
|
@@ -8,7 +9,6 @@ import { orm } from "@prisma-next/sql-orm-client";
|
|
|
8
9
|
import { createExecutionContext, createRuntime, createSqlExecutionStack, withTransaction } from "@prisma-next/sql-runtime";
|
|
9
10
|
import postgresTarget from "@prisma-next/target-postgres/runtime";
|
|
10
11
|
import { Client, Pool } from "pg";
|
|
11
|
-
|
|
12
12
|
//#region src/runtime/binding.ts
|
|
13
13
|
function validatePostgresUrl(url) {
|
|
14
14
|
const trimmed = url.trim();
|
|
@@ -45,7 +45,6 @@ function resolveOptionalPostgresBinding(options) {
|
|
|
45
45
|
if (Number(options.binding !== void 0) + Number(options.url !== void 0) + Number(options.pg !== void 0) === 0) return;
|
|
46
46
|
return resolvePostgresBinding(options);
|
|
47
47
|
}
|
|
48
|
-
|
|
49
48
|
//#endregion
|
|
50
49
|
//#region src/runtime/postgres.ts
|
|
51
50
|
function hasContractJson(options) {
|
|
@@ -115,7 +114,7 @@ function postgres(options) {
|
|
|
115
114
|
mode: "onFirstUse",
|
|
116
115
|
requireMarker: false
|
|
117
116
|
},
|
|
118
|
-
...
|
|
117
|
+
...ifDefined("middleware", options.middleware)
|
|
119
118
|
});
|
|
120
119
|
return runtimeInstance;
|
|
121
120
|
};
|
|
@@ -164,7 +163,7 @@ function postgres(options) {
|
|
|
164
163
|
}
|
|
165
164
|
};
|
|
166
165
|
}
|
|
167
|
-
|
|
168
166
|
//#endregion
|
|
169
167
|
export { postgres as default };
|
|
168
|
+
|
|
170
169
|
//# sourceMappingURL=runtime.mjs.map
|
package/dist/runtime.mjs.map
CHANGED
|
@@ -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 { 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 ...(options.middleware ? { 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":"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"}
|
|
@@ -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"}
|
package/dist/target.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/postgres",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.87",
|
|
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.
|
|
10
|
-
"@prisma-next/config": "0.5.0-dev.
|
|
11
|
-
"@prisma-next/
|
|
12
|
-
"@prisma-next/
|
|
13
|
-
"@prisma-next/
|
|
14
|
-
"@prisma-next/
|
|
15
|
-
"@prisma-next/
|
|
16
|
-
"@prisma-next/sql-contract": "0.5.0-dev.
|
|
17
|
-
"@prisma-next/
|
|
18
|
-
"@prisma-next/sql-
|
|
19
|
-
"@prisma-next/sql-
|
|
20
|
-
"@prisma-next/sql-relational-core": "0.5.0-dev.
|
|
21
|
-
"@prisma-next/sql-builder": "0.5.0-dev.
|
|
22
|
-
"@prisma-next/
|
|
23
|
-
"@prisma-next/
|
|
24
|
-
"@prisma-next/utils": "0.5.0-dev.
|
|
10
|
+
"pg": "8.20.0",
|
|
11
|
+
"@prisma-next/config": "0.5.0-dev.87",
|
|
12
|
+
"@prisma-next/driver-postgres": "0.5.0-dev.87",
|
|
13
|
+
"@prisma-next/family-sql": "0.5.0-dev.87",
|
|
14
|
+
"@prisma-next/framework-components": "0.5.0-dev.87",
|
|
15
|
+
"@prisma-next/sql-contract": "0.5.0-dev.87",
|
|
16
|
+
"@prisma-next/contract": "0.5.0-dev.87",
|
|
17
|
+
"@prisma-next/sql-contract-psl": "0.5.0-dev.87",
|
|
18
|
+
"@prisma-next/adapter-postgres": "0.5.0-dev.87",
|
|
19
|
+
"@prisma-next/sql-orm-client": "0.5.0-dev.87",
|
|
20
|
+
"@prisma-next/sql-contract-ts": "0.5.0-dev.87",
|
|
21
|
+
"@prisma-next/sql-relational-core": "0.5.0-dev.87",
|
|
22
|
+
"@prisma-next/sql-builder": "0.5.0-dev.87",
|
|
23
|
+
"@prisma-next/sql-runtime": "0.5.0-dev.87",
|
|
24
|
+
"@prisma-next/target-postgres": "0.5.0-dev.87",
|
|
25
|
+
"@prisma-next/utils": "0.5.0-dev.87"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
|
-
"@types/pg": "8.
|
|
28
|
-
"tsdown": "0.
|
|
28
|
+
"@types/pg": "8.20.0",
|
|
29
|
+
"tsdown": "0.22.0",
|
|
29
30
|
"typescript": "5.9.3",
|
|
30
|
-
"vitest": "4.
|
|
31
|
+
"vitest": "4.1.5",
|
|
31
32
|
"@prisma-next/test-utils": "0.0.1",
|
|
32
|
-
"@prisma-next/
|
|
33
|
-
"@prisma-next/
|
|
33
|
+
"@prisma-next/tsconfig": "0.0.0",
|
|
34
|
+
"@prisma-next/tsdown": "0.0.0"
|
|
34
35
|
},
|
|
35
36
|
"files": [
|
|
36
37
|
"dist",
|
|
@@ -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
|
+
}
|
package/src/runtime/postgres.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
withTransaction,
|
|
25
25
|
} from '@prisma-next/sql-runtime';
|
|
26
26
|
import postgresTarget from '@prisma-next/target-postgres/runtime';
|
|
27
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
27
28
|
import { type Client, Pool } from 'pg';
|
|
28
29
|
import {
|
|
29
30
|
type PostgresBinding,
|
|
@@ -200,7 +201,7 @@ export default function postgres<TContract extends Contract<SqlStorage>>(
|
|
|
200
201
|
context,
|
|
201
202
|
driver,
|
|
202
203
|
verify: options.verify ?? { mode: 'onFirstUse', requireMarker: false },
|
|
203
|
-
...(
|
|
204
|
+
...ifDefined('middleware', options.middleware),
|
|
204
205
|
});
|
|
205
206
|
|
|
206
207
|
return runtimeInstance;
|
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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"}
|