@prisma-next/postgres 0.10.0-dev.9 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -85,7 +85,35 @@ When URL binding is used, pool timeouts are configurable via `poolOptions`:
85
85
 
86
86
  ### `@prisma-next/postgres/contract-builder`
87
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.
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. The `defineContract` export is a Postgres-specific wrapper that pre-binds `family` and `target` — callers do not pass those fields:
89
+
90
+ ```typescript
91
+ import { defineContract, field, model } from '@prisma-next/postgres/contract-builder';
92
+
93
+ export const contract = defineContract(
94
+ { extensionPacks: {} },
95
+ ({ field: f, model: m }) => ({
96
+ models: {
97
+ User: m('User', { fields: { id: f.id.uuidv4() } }),
98
+ },
99
+ }),
100
+ );
101
+ ```
102
+
103
+ ### `@prisma-next/postgres/migration`
104
+
105
+ Re-exports everything from `@prisma-next/target-postgres/migration` so a user-authored `migration.ts` file can import its base class, CLI runner, and operation helpers from the single Postgres facade:
106
+
107
+ ```typescript
108
+ import { Migration, MigrationCLI, addColumn, createTable } from '@prisma-next/postgres/migration';
109
+
110
+ export default class M extends Migration {
111
+ up() {
112
+ return [createTable('users', ...)];
113
+ }
114
+ }
115
+ MigrationCLI.run(import.meta.url, M);
116
+ ```
89
117
 
90
118
  ### `@prisma-next/postgres/family`
91
119
 
@@ -1,2 +1,29 @@
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 };
1
+ import { ComposedAuthoringHelpers, ComposedAuthoringHelpers as ComposedAuthoringHelpers$1, ContractDefinition, ContractInput, ContractInput as ContractInput$1, ContractModelBuilder, FieldNode, ForeignKeyNode, IndexNode, ModelLike, ModelNode, PrimaryKeyNode, RelationNode, ScalarFieldBuilder, UniqueConstraintNode, buildSqlContractFromDefinition, defineContract as defineContract$1, field, model, rel } from "@prisma-next/sql-contract-ts/contract-builder";
2
+ import sqlFamilyPack from "@prisma-next/family-sql/pack";
3
+ import postgresPack from "@prisma-next/target-postgres/pack";
4
+ import { ExtensionPackRef } from "@prisma-next/framework-components/components";
5
+ import { PostgresEnumStorageEntry, StorageTypeInstance } from "@prisma-next/sql-contract/types";
6
+
7
+ //#region src/contract/define-contract.d.ts
8
+ type SqlFamily = typeof sqlFamilyPack;
9
+ type PostgresPack = typeof postgresPack;
10
+ type TypesConstraint = Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
11
+ type ModelsConstraint = Record<string, ModelLike>;
12
+ type PostgresResult<Types extends TypesConstraint, Models extends ModelsConstraint, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Capabilities extends Record<string, Record<string, boolean>> | undefined> = Omit<ReturnType<typeof defineContract$1<SqlFamily, PostgresPack, Types, Models, ExtensionPacks, Capabilities>>, 'target' | 'targetFamily'> & {
13
+ readonly target: PostgresPack['targetId'];
14
+ readonly targetFamily: SqlFamily['familyId'];
15
+ };
16
+ type PostgresBaseScaffold<ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Capabilities extends Record<string, Record<string, boolean>> | undefined> = Omit<ContractInput$1<SqlFamily, PostgresPack, Record<never, never>, Record<never, never>, ExtensionPacks, Capabilities>, 'family' | 'target' | 'types' | 'models'>;
17
+ type PostgresDefinition<Types extends TypesConstraint, Models extends ModelsConstraint, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Capabilities extends Record<string, Record<string, boolean>> | undefined> = PostgresBaseScaffold<ExtensionPacks, Capabilities> & {
18
+ readonly types?: Types;
19
+ readonly models?: Models;
20
+ };
21
+ type PostgresScaffold<ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Capabilities extends Record<string, Record<string, boolean>> | undefined> = PostgresBaseScaffold<ExtensionPacks, Capabilities>;
22
+ declare function defineContract<const Types extends TypesConstraint = Record<never, never>, const Models extends ModelsConstraint = Record<never, never>, const ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined, const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined>(definition: PostgresDefinition<Types, Models, ExtensionPacks, Capabilities>): PostgresResult<Types, Models, ExtensionPacks, Capabilities>;
23
+ declare function defineContract<const Types extends TypesConstraint = Record<never, never>, const Models extends ModelsConstraint = Record<never, never>, const ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined, const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined>(scaffold: PostgresScaffold<ExtensionPacks, Capabilities>, factory: (helpers: ComposedAuthoringHelpers$1<SqlFamily, PostgresPack, ExtensionPacks>) => {
24
+ readonly types?: Types;
25
+ readonly models?: Models;
26
+ }): PostgresResult<Types, Models, ExtensionPacks, Capabilities>;
27
+ //#endregion
28
+ 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 };
29
+ //# sourceMappingURL=contract-builder.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-builder.d.mts","names":[],"sources":["../src/contract/define-contract.ts"],"mappings":";;;;;;;KAcK,SAAA,UAAmB,aAAA;AAAA,KACnB,YAAA,UAAsB,YAAA;AAAA,KAEtB,eAAA,GAAkB,MAAA,SAAe,mBAAA,GAAsB,wBAAA;AAAA,KACvD,gBAAA,GAAmB,MAAA,SAAe,SAAA;AAAA,KAMlC,cAAA,eACW,eAAA,iBACC,gBAAA,yBACQ,MAAA,SAAe,gBAAA,mDACjB,MAAA,SAAe,MAAA,kCAClC,IAAA,CACF,UAAA,QACS,gBAAA,CAAmB,SAAA,EAAW,YAAA,EAAc,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,YAAA;EAAA,SAI3E,MAAA,EAAQ,YAAA;EAAA,SACR,YAAA,EAAc,SAAA;AAAA;AAAA,KAMpB,oBAAA,wBACoB,MAAA,SAAe,gBAAA,mDACjB,MAAA,SAAe,MAAA,kCAClC,IAAA,CACF,eAAA,CACE,SAAA,EACA,YAAA,EACA,MAAA,gBACA,MAAA,gBACA,cAAA,EACA,YAAA;AAAA,KAMC,kBAAA,eACW,eAAA,iBACC,gBAAA,yBACQ,MAAA,SAAe,gBAAA,mDACjB,MAAA,SAAe,MAAA,kCAClC,oBAAA,CAAqB,cAAA,EAAgB,YAAA;EAAA,SAC9B,KAAA,GAAQ,KAAA;EAAA,SACR,MAAA,GAAS,MAAA;AAAA;AAAA,KAIf,gBAAA,wBACoB,MAAA,SAAe,gBAAA,mDACjB,MAAA,SAAe,MAAA,kCAClC,oBAAA,CAAqB,cAAA,EAAgB,YAAA;AAAA,iBAGzB,cAAA,qBACM,eAAA,GAAkB,MAAA,qCACjB,gBAAA,GAAmB,MAAA,6CAEpC,MAAA,SAAe,gBAAA,qEAEQ,MAAA,SAAe,MAAA,2CAAA,CAE1C,UAAA,EAAY,kBAAA,CAAmB,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,YAAA,IAC7D,cAAA,CAAe,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,YAAA;AAAA,iBAGjC,cAAA,qBACM,eAAA,GAAkB,MAAA,qCACjB,gBAAA,GAAmB,MAAA,6CAEpC,MAAA,SAAe,gBAAA,qEAEQ,MAAA,SAAe,MAAA,2CAAA,CAE1C,QAAA,EAAU,gBAAA,CAAiB,cAAA,EAAgB,YAAA,GAC3C,OAAA,GAAU,OAAA,EAAS,0BAAA,CAAyB,SAAA,EAAW,YAAA,EAAc,cAAA;EAAA,SAC1D,KAAA,GAAQ,KAAA;EAAA,SACR,MAAA,GAAS,MAAA;AAAA,IAEnB,cAAA,CAAe,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,YAAA"}
@@ -1,2 +1,17 @@
1
- import { buildSqlContractFromDefinition, defineContract, field, model, rel } from "@prisma-next/sql-contract-ts/contract-builder";
1
+ import { buildSqlContractFromDefinition, defineContract as defineContract$1, field, model, rel } from "@prisma-next/sql-contract-ts/contract-builder";
2
+ import sqlFamilyPack from "@prisma-next/family-sql/pack";
3
+ import postgresPack from "@prisma-next/target-postgres/pack";
4
+ //#region src/contract/define-contract.ts
5
+ function defineContract(scaffold, factory) {
6
+ const full = {
7
+ ...scaffold,
8
+ family: sqlFamilyPack,
9
+ target: postgresPack
10
+ };
11
+ if (factory !== void 0) return defineContract$1(full, factory);
12
+ return defineContract$1(full);
13
+ }
14
+ //#endregion
2
15
  export { buildSqlContractFromDefinition, defineContract, field, model, rel };
16
+
17
+ //# sourceMappingURL=contract-builder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-builder.mjs","names":["baseDefineContract"],"sources":["../src/contract/define-contract.ts"],"sourcesContent":["import sqlFamilyPack from '@prisma-next/family-sql/pack';\nimport type { ExtensionPackRef } from '@prisma-next/framework-components/components';\nimport type {\n PostgresEnumStorageEntry,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport type {\n ComposedAuthoringHelpers,\n ContractInput,\n ModelLike,\n} from '@prisma-next/sql-contract-ts/contract-builder';\nimport { defineContract as baseDefineContract } from '@prisma-next/sql-contract-ts/contract-builder';\nimport postgresPack from '@prisma-next/target-postgres/pack';\n\ntype SqlFamily = typeof sqlFamilyPack;\ntype PostgresPack = typeof postgresPack;\n\ntype TypesConstraint = Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;\ntype ModelsConstraint = Record<string, ModelLike>;\n\n// Return type threaded with all inferred type params.\n// We override target/targetFamily via intersection to preserve the literal values\n// ('postgres', 'sql') even when TypeScript defers conditional-type evaluation on\n// unresolved generic params.\ntype PostgresResult<\n Types extends TypesConstraint,\n Models extends ModelsConstraint,\n ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined,\n> = Omit<\n ReturnType<\n typeof baseDefineContract<SqlFamily, PostgresPack, Types, Models, ExtensionPacks, Capabilities>\n >,\n 'target' | 'targetFamily'\n> & {\n readonly target: PostgresPack['targetId'];\n readonly targetFamily: SqlFamily['familyId'];\n};\n\n// Scaffold that carries all ContractInput fields EXCEPT family, target, types, models.\n// Built from ContractInput with concrete Record<never, never> defaults to avoid\n// the ContractInput Models constraint (which requires ContractModelBuilder, not ModelLike).\ntype PostgresBaseScaffold<\n ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined,\n> = Omit<\n ContractInput<\n SqlFamily,\n PostgresPack,\n Record<never, never>,\n Record<never, never>,\n ExtensionPacks,\n Capabilities\n >,\n 'family' | 'target' | 'types' | 'models'\n>;\n\n// Definition form: inline types + models (uses ModelLike for models, not ContractModelBuilder)\ntype PostgresDefinition<\n Types extends TypesConstraint,\n Models extends ModelsConstraint,\n ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined,\n> = PostgresBaseScaffold<ExtensionPacks, Capabilities> & {\n readonly types?: Types;\n readonly models?: Models;\n};\n\n// Factory form: scaffold without types/models (factory provides them)\ntype PostgresScaffold<\n ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined,\n> = PostgresBaseScaffold<ExtensionPacks, Capabilities>;\n\n// Overload 1: definition form (models/types inline in scaffold)\nexport function defineContract<\n const Types extends TypesConstraint = Record<never, never>,\n const Models extends ModelsConstraint = Record<never, never>,\n const ExtensionPacks extends\n | Record<string, ExtensionPackRef<'sql', string>>\n | undefined = undefined,\n const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,\n>(\n definition: PostgresDefinition<Types, Models, ExtensionPacks, Capabilities>,\n): PostgresResult<Types, Models, ExtensionPacks, Capabilities>;\n\n// Overload 2: factory form (scaffold without models/types; factory provides them)\nexport function defineContract<\n const Types extends TypesConstraint = Record<never, never>,\n const Models extends ModelsConstraint = Record<never, never>,\n const ExtensionPacks extends\n | Record<string, ExtensionPackRef<'sql', string>>\n | undefined = undefined,\n const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,\n>(\n scaffold: PostgresScaffold<ExtensionPacks, Capabilities>,\n factory: (helpers: ComposedAuthoringHelpers<SqlFamily, PostgresPack, ExtensionPacks>) => {\n readonly types?: Types;\n readonly models?: Models;\n },\n): PostgresResult<Types, Models, ExtensionPacks, Capabilities>;\n\n// Implementation — the runtime type is richer than the wide impl signature;\n// as unknown is safe because every declared overload produces a PostgresResult.\nexport function defineContract(\n scaffold: Omit<ContractInput, 'family' | 'target'>,\n factory?: (helpers: ComposedAuthoringHelpers<SqlFamily, PostgresPack, undefined>) => {\n readonly types?: TypesConstraint;\n readonly models?: ModelsConstraint;\n },\n): PostgresResult<TypesConstraint, ModelsConstraint, undefined, undefined> {\n const full = {\n ...scaffold,\n family: sqlFamilyPack,\n target: postgresPack,\n } as ContractInput;\n if (factory !== undefined) {\n return baseDefineContract(\n full,\n factory as Parameters<typeof baseDefineContract>[1],\n ) as unknown as PostgresResult<TypesConstraint, ModelsConstraint, undefined, undefined>;\n }\n return baseDefineContract(full) as unknown as PostgresResult<\n TypesConstraint,\n ModelsConstraint,\n undefined,\n undefined\n >;\n}\n"],"mappings":";;;;AAwGA,SAAgB,eACd,UACA,SAIyE;CACzE,MAAM,OAAO;EACX,GAAG;EACH,QAAQ;EACR,QAAQ;EACT;CACD,IAAI,YAAY,KAAA,GACd,OAAOA,iBACL,MACA,QACD;CAEH,OAAOA,iBAAmB,KAAK"}
@@ -0,0 +1 @@
1
+ export * from "@prisma-next/target-postgres/migration";
@@ -0,0 +1,2 @@
1
+ export * from "@prisma-next/target-postgres/migration";
2
+ export {};
@@ -1,9 +1,9 @@
1
1
  import { orm } from "@prisma-next/sql-orm-client";
2
2
  import { BindSiteParams, Declaration, ExecutionContext, ParamsFromDeclaration, PreparedStatement, Runtime, RuntimeVerifyOptions, SqlExecutionStackWithDriver, SqlMiddleware, SqlRuntimeExtensionDescriptor, TransactionContext } from "@prisma-next/sql-runtime";
3
3
  import { Client, Pool } from "pg";
4
+ import { ExtractCodecTypes, SqlStorage } from "@prisma-next/sql-contract/types";
4
5
  import { Contract } from "@prisma-next/contract/types";
5
6
  import { Db } from "@prisma-next/sql-builder/types";
6
- import { ExtractCodecTypes, SqlStorage } from "@prisma-next/sql-contract/types";
7
7
  import { CodecTypesBase } from "@prisma-next/sql-relational-core/expression";
8
8
  import { SqlQueryPlan } from "@prisma-next/sql-relational-core/plan";
9
9
 
@@ -48,6 +48,8 @@ interface PostgresClient<TContract extends Contract<SqlStorage>> {
48
48
  runtime(): Runtime;
49
49
  transaction<R>(fn: (tx: PostgresTransactionContext<TContract>) => PromiseLike<R>): Promise<R>;
50
50
  prepare<D extends Declaration<CT>, Row, CT extends CodecTypesBase = ExtractCodecTypes<TContract> & CodecTypesBase>(declaration: D, callback: (sql: Db<TContract>, params: BindSiteParams<D>) => SqlQueryPlan<Row>): Promise<PreparedStatement<ParamsFromDeclaration<D, CT>, Row>>;
51
+ close(): Promise<void>;
52
+ [Symbol.asyncDispose](): Promise<void>;
51
53
  }
52
54
  interface PostgresOptionsBase {
53
55
  readonly extensions?: readonly SqlRuntimeExtensionDescriptor<PostgresTargetId>[];
@@ -84,4 +86,4 @@ declare function postgres<TContract extends Contract<SqlStorage>>(options: Postg
84
86
  declare function postgres<TContract extends Contract<SqlStorage>>(options: PostgresOptionsWithContractJson<TContract>): PostgresClient<TContract>;
85
87
  //#endregion
86
88
  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 };
87
- //# sourceMappingURL=postgres-V6YAIWZd.d.mts.map
89
+ //# sourceMappingURL=postgres-DTqYNIbs.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-V6YAIWZd.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;;;KCiBH,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;EAC3F,OAAA,WACY,WAAA,CAAY,EAAA,mBAEX,cAAA,GAAiB,iBAAA,CAAkB,SAAA,IAAa,cAAA,EAE3D,WAAA,EAAa,CAAA,EACb,QAAA,GAAW,GAAA,EAAK,EAAA,CAAG,SAAA,GAAY,MAAA,EAAQ,cAAA,CAAe,CAAA,MAAO,YAAA,CAAa,GAAA,IACzE,OAAA,CAAQ,iBAAA,CAAkB,qBAAA,CAAsB,CAAA,EAAG,EAAA,GAAK,GAAA;AAAA;AAAA,UAG5C,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;AA5DpC;;;;;AAA0C;;AAA1C,iBAsGwB,QAAA,mBAA2B,QAAA,CAAS,UAAA,EAAA,CAC1D,OAAA,EAAS,2BAAA,CAA4B,SAAA,IACpC,cAAA,CAAe,SAAA;AAAA,iBACM,QAAA,mBAA2B,QAAA,CAAS,UAAA,EAAA,CAC1D,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,cAAA,CAAe,SAAA"}
1
+ {"version":3,"file":"postgres-DTqYNIbs.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;;;KCiBH,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;EAC3F,OAAA,WACY,WAAA,CAAY,EAAA,mBAEX,cAAA,GAAiB,iBAAA,CAAkB,SAAA,IAAa,cAAA,EAE3D,WAAA,EAAa,CAAA,EACb,QAAA,GAAW,GAAA,EAAK,EAAA,CAAG,SAAA,GAAY,MAAA,EAAQ,cAAA,CAAe,CAAA,MAAO,YAAA,CAAa,GAAA,IACzE,OAAA,CAAQ,iBAAA,CAAkB,qBAAA,CAAsB,CAAA,EAAG,EAAA,GAAK,GAAA;EAC3D,KAAA,IAAS,OAAA;EAAA,CACR,MAAA,CAAO,YAAP,KAAwB,OAAA;AAAA;AAAA,UAGV,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;;;;AA9DM;;;;iBAwGlB,QAAA,mBAA2B,QAAA,CAAS,UAAA,EAAA,CAC1D,OAAA,EAAS,2BAAA,CAA4B,SAAA,IACpC,cAAA,CAAe,SAAA;AAAA,iBACM,QAAA,mBAA2B,QAAA,CAAS,UAAA,EAAA,CAC1D,OAAA,EAAS,+BAAA,CAAgC,SAAA,IACxC,cAAA,CAAe,SAAA"}
@@ -1,2 +1,2 @@
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-V6YAIWZd.mjs";
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-DTqYNIbs.mjs";
2
2
  export { type PostgresBinding, type PostgresClient, type PostgresOptions, type PostgresOptionsBase, type PostgresOptionsWithContract, type PostgresOptionsWithContractJson, postgres as default };
package/dist/runtime.mjs CHANGED
@@ -82,22 +82,34 @@ function postgres(options) {
82
82
  let driverConnected = false;
83
83
  let connectPromise;
84
84
  let backgroundConnectError;
85
+ let closed = false;
86
+ let ownedDispose;
85
87
  const connectDriver = async (resolvedBinding) => {
86
88
  if (driverConnected) return;
87
89
  if (!runtimeDriver) throw new Error("Postgres runtime driver missing");
88
90
  if (connectPromise) return connectPromise;
89
91
  const runtimeBinding = toRuntimeBinding(resolvedBinding, options);
92
+ if (resolvedBinding.kind === "url" && runtimeBinding.kind === "pgPool") {
93
+ const pool = runtimeBinding.pool;
94
+ let disposed = false;
95
+ ownedDispose = async () => {
96
+ if (disposed) return;
97
+ disposed = true;
98
+ await pool.end().then(() => void 0);
99
+ };
100
+ }
90
101
  connectPromise = runtimeDriver.connect(runtimeBinding).then(() => {
91
102
  driverConnected = true;
92
103
  }).catch(async (err) => {
93
104
  backgroundConnectError = err;
94
105
  connectPromise = void 0;
95
- if (resolvedBinding.kind === "url" && runtimeBinding.kind === "pgPool") await runtimeBinding.pool.end().catch(() => void 0);
106
+ await ownedDispose?.().catch(() => void 0);
96
107
  throw err;
97
108
  });
98
109
  return connectPromise;
99
110
  };
100
111
  const getRuntime = () => {
112
+ if (closed) throw new Error("Postgres client is closed");
101
113
  if (backgroundConnectError !== void 0) throw backgroundConnectError;
102
114
  if (runtimeInstance) return runtimeInstance;
103
115
  const stackInstance = instantiateExecutionStack(stack);
@@ -136,6 +148,7 @@ function postgres(options) {
136
148
  context,
137
149
  stack,
138
150
  async connect(bindingInput) {
151
+ if (closed) throw new Error("Postgres client is closed");
139
152
  if (driverConnected || connectPromise) throw new Error("Postgres client already connected");
140
153
  if (bindingInput !== void 0) binding = resolvePostgresBinding(bindingInput);
141
154
  if (binding === void 0) throw new Error("Postgres binding not configured. Pass url/pg/binding to postgres(...) or call db.connect({ ... }).");
@@ -164,6 +177,15 @@ function postgres(options) {
164
177
  orm: txOrm
165
178
  }));
166
179
  });
180
+ },
181
+ async close() {
182
+ if (closed) return;
183
+ closed = true;
184
+ await connectPromise?.catch(() => void 0);
185
+ await ownedDispose?.();
186
+ },
187
+ [Symbol.asyncDispose]() {
188
+ return this.close();
167
189
  }
168
190
  };
169
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":["PgPool","PgClient","orm","ormBuilder","sql","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 { 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 { ExtractCodecTypes, SqlStorage } from '@prisma-next/sql-contract/types';\nimport { orm as ormBuilder } from '@prisma-next/sql-orm-client';\nimport type { CodecTypesBase } from '@prisma-next/sql-relational-core/expression';\nimport type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport type {\n BindSiteParams,\n Declaration,\n ExecutionContext,\n ParamsFromDeclaration,\n PreparedStatement,\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, { PostgresContractSerializer } 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 prepare<\n D extends Declaration<CT>,\n Row,\n CT extends CodecTypesBase = ExtractCodecTypes<TContract> & CodecTypesBase,\n >(\n declaration: D,\n callback: (sql: Db<TContract>, params: BindSiteParams<D>) => SqlQueryPlan<Row>,\n ): Promise<PreparedStatement<ParamsFromDeclaration<D, CT>, Row>>;\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\nconst contractSerializer = new PostgresContractSerializer();\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): TContract {\n const contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n return contractSerializer.deserializeContract(contractInput) as TContract;\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 prepare<\n D extends Declaration<CT>,\n Row,\n CT extends CodecTypesBase = ExtractCodecTypes<TContract> & CodecTypesBase,\n >(\n declaration: D,\n callback: (sql: Db<TContract>, params: BindSiteParams<D>) => SqlQueryPlan<Row>,\n ): Promise<PreparedStatement<ParamsFromDeclaration<D, CT>, Row>> {\n return getRuntime().prepare<D, Row, CT>(declaration, (params) => callback(sql, params));\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","sql","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 { 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 { ExtractCodecTypes, SqlStorage } from '@prisma-next/sql-contract/types';\nimport { orm as ormBuilder } from '@prisma-next/sql-orm-client';\nimport type { CodecTypesBase } from '@prisma-next/sql-relational-core/expression';\nimport type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport type {\n BindSiteParams,\n Declaration,\n ExecutionContext,\n ParamsFromDeclaration,\n PreparedStatement,\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, { PostgresContractSerializer } 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 prepare<\n D extends Declaration<CT>,\n Row,\n CT extends CodecTypesBase = ExtractCodecTypes<TContract> & CodecTypesBase,\n >(\n declaration: D,\n callback: (sql: Db<TContract>, params: BindSiteParams<D>) => SqlQueryPlan<Row>,\n ): Promise<PreparedStatement<ParamsFromDeclaration<D, CT>, Row>>;\n close(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\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\nconst contractSerializer = new PostgresContractSerializer();\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: PostgresOptions<TContract>,\n): TContract {\n const contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n return contractSerializer.deserializeContract(contractInput) as TContract;\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 let closed = false;\n let ownedDispose: (() => Promise<void>) | undefined;\n\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 if (resolvedBinding.kind === 'url' && runtimeBinding.kind === 'pgPool') {\n const pool = runtimeBinding.pool;\n let disposed = false;\n ownedDispose = async () => {\n if (disposed) return;\n disposed = true;\n await pool.end().then(() => undefined);\n };\n }\n connectPromise = runtimeDriver\n .connect(runtimeBinding)\n .then(() => {\n driverConnected = true;\n })\n .catch(async (err) => {\n backgroundConnectError = err;\n connectPromise = undefined;\n await ownedDispose?.().catch(() => undefined);\n throw err;\n });\n return connectPromise;\n };\n const getRuntime = (): Runtime => {\n if (closed) {\n throw new Error('Postgres client is closed');\n }\n\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 (closed) {\n throw new Error('Postgres client is closed');\n }\n\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 prepare<\n D extends Declaration<CT>,\n Row,\n CT extends CodecTypesBase = ExtractCodecTypes<TContract> & CodecTypesBase,\n >(\n declaration: D,\n callback: (sql: Db<TContract>, params: BindSiteParams<D>) => SqlQueryPlan<Row>,\n ): Promise<PreparedStatement<ParamsFromDeclaration<D, CT>, Row>> {\n return getRuntime().prepare<D, Row, CT>(declaration, (params) => callback(sql, params));\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 async close(): Promise<void> {\n if (closed) return;\n closed = true;\n await connectPromise?.catch(() => undefined);\n await ownedDispose?.();\n },\n\n [Symbol.asyncDispose](): Promise<void> {\n return this.close();\n },\n };\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { o as PostgresTargetId } from "./postgres-V6YAIWZd.mjs";
1
+ import { o as PostgresTargetId } from "./postgres-DTqYNIbs.mjs";
2
2
  import { PostgresDriverCreateOptions } from "@prisma-next/driver-postgres/runtime";
3
3
  import { ExecutionContext, Runtime, RuntimeVerifyOptions, SqlExecutionStackWithDriver, SqlMiddleware, SqlRuntimeExtensionDescriptor } from "@prisma-next/sql-runtime";
4
+ import { SqlStorage } from "@prisma-next/sql-contract/types";
4
5
  import { Contract } from "@prisma-next/contract/types";
5
6
  import { Db } from "@prisma-next/sql-builder/types";
6
- import { SqlStorage } from "@prisma-next/sql-contract/types";
7
7
 
8
8
  //#region src/runtime/postgres-serverless.d.ts
9
9
  type PostgresServerlessCursorOptions = NonNullable<PostgresDriverCreateOptions['cursor']>;
package/package.json CHANGED
@@ -1,35 +1,35 @@
1
1
  {
2
2
  "name": "@prisma-next/postgres",
3
- "version": "0.10.0-dev.9",
3
+ "version": "0.11.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "One-liner lazy Postgres client composition for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/adapter-postgres": "0.10.0-dev.9",
10
- "@prisma-next/cli": "0.10.0-dev.9",
11
- "@prisma-next/config": "0.10.0-dev.9",
12
- "@prisma-next/contract": "0.10.0-dev.9",
13
- "@prisma-next/driver-postgres": "0.10.0-dev.9",
14
- "@prisma-next/family-sql": "0.10.0-dev.9",
15
- "@prisma-next/framework-components": "0.10.0-dev.9",
16
- "@prisma-next/sql-contract": "0.10.0-dev.9",
17
- "@prisma-next/sql-contract-psl": "0.10.0-dev.9",
18
- "@prisma-next/sql-contract-ts": "0.10.0-dev.9",
19
- "@prisma-next/sql-builder": "0.10.0-dev.9",
20
- "@prisma-next/sql-orm-client": "0.10.0-dev.9",
21
- "@prisma-next/sql-relational-core": "0.10.0-dev.9",
22
- "@prisma-next/sql-runtime": "0.10.0-dev.9",
23
- "@prisma-next/target-postgres": "0.10.0-dev.9",
24
- "@prisma-next/utils": "0.10.0-dev.9",
9
+ "@prisma-next/adapter-postgres": "0.11.0",
10
+ "@prisma-next/cli": "0.11.0",
11
+ "@prisma-next/config": "0.11.0",
12
+ "@prisma-next/contract": "0.11.0",
13
+ "@prisma-next/driver-postgres": "0.11.0",
14
+ "@prisma-next/family-sql": "0.11.0",
15
+ "@prisma-next/framework-components": "0.11.0",
16
+ "@prisma-next/sql-contract": "0.11.0",
17
+ "@prisma-next/sql-contract-psl": "0.11.0",
18
+ "@prisma-next/sql-contract-ts": "0.11.0",
19
+ "@prisma-next/sql-builder": "0.11.0",
20
+ "@prisma-next/sql-orm-client": "0.11.0",
21
+ "@prisma-next/sql-relational-core": "0.11.0",
22
+ "@prisma-next/sql-runtime": "0.11.0",
23
+ "@prisma-next/target-postgres": "0.11.0",
24
+ "@prisma-next/utils": "0.11.0",
25
25
  "pathe": "^2.0.3",
26
26
  "pg": "8.20.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@prisma-next/psl-parser": "0.10.0-dev.9",
30
- "@prisma-next/test-utils": "0.10.0-dev.9",
31
- "@prisma-next/tsconfig": "0.10.0-dev.9",
32
- "@prisma-next/tsdown": "0.10.0-dev.9",
29
+ "@prisma-next/psl-parser": "0.11.0",
30
+ "@prisma-next/test-utils": "0.11.0",
31
+ "@prisma-next/tsconfig": "0.11.0",
32
+ "@prisma-next/tsdown": "0.11.0",
33
33
  "@types/pg": "8.20.0",
34
34
  "tsdown": "0.22.0",
35
35
  "typescript": "5.9.3",
@@ -52,6 +52,7 @@
52
52
  "./contract-builder": "./dist/contract-builder.mjs",
53
53
  "./control": "./dist/control.mjs",
54
54
  "./family": "./dist/family.mjs",
55
+ "./migration": "./dist/migration.mjs",
55
56
  "./runtime": "./dist/runtime.mjs",
56
57
  "./serverless": "./dist/serverless.mjs",
57
58
  "./target": "./dist/target.mjs",
@@ -0,0 +1,129 @@
1
+ import sqlFamilyPack from '@prisma-next/family-sql/pack';
2
+ import type { ExtensionPackRef } from '@prisma-next/framework-components/components';
3
+ import type {
4
+ PostgresEnumStorageEntry,
5
+ StorageTypeInstance,
6
+ } from '@prisma-next/sql-contract/types';
7
+ import type {
8
+ ComposedAuthoringHelpers,
9
+ ContractInput,
10
+ ModelLike,
11
+ } from '@prisma-next/sql-contract-ts/contract-builder';
12
+ import { defineContract as baseDefineContract } from '@prisma-next/sql-contract-ts/contract-builder';
13
+ import postgresPack from '@prisma-next/target-postgres/pack';
14
+
15
+ type SqlFamily = typeof sqlFamilyPack;
16
+ type PostgresPack = typeof postgresPack;
17
+
18
+ type TypesConstraint = Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
19
+ type ModelsConstraint = Record<string, ModelLike>;
20
+
21
+ // Return type threaded with all inferred type params.
22
+ // We override target/targetFamily via intersection to preserve the literal values
23
+ // ('postgres', 'sql') even when TypeScript defers conditional-type evaluation on
24
+ // unresolved generic params.
25
+ type PostgresResult<
26
+ Types extends TypesConstraint,
27
+ Models extends ModelsConstraint,
28
+ ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
29
+ Capabilities extends Record<string, Record<string, boolean>> | undefined,
30
+ > = Omit<
31
+ ReturnType<
32
+ typeof baseDefineContract<SqlFamily, PostgresPack, Types, Models, ExtensionPacks, Capabilities>
33
+ >,
34
+ 'target' | 'targetFamily'
35
+ > & {
36
+ readonly target: PostgresPack['targetId'];
37
+ readonly targetFamily: SqlFamily['familyId'];
38
+ };
39
+
40
+ // Scaffold that carries all ContractInput fields EXCEPT family, target, types, models.
41
+ // Built from ContractInput with concrete Record<never, never> defaults to avoid
42
+ // the ContractInput Models constraint (which requires ContractModelBuilder, not ModelLike).
43
+ type PostgresBaseScaffold<
44
+ ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
45
+ Capabilities extends Record<string, Record<string, boolean>> | undefined,
46
+ > = Omit<
47
+ ContractInput<
48
+ SqlFamily,
49
+ PostgresPack,
50
+ Record<never, never>,
51
+ Record<never, never>,
52
+ ExtensionPacks,
53
+ Capabilities
54
+ >,
55
+ 'family' | 'target' | 'types' | 'models'
56
+ >;
57
+
58
+ // Definition form: inline types + models (uses ModelLike for models, not ContractModelBuilder)
59
+ type PostgresDefinition<
60
+ Types extends TypesConstraint,
61
+ Models extends ModelsConstraint,
62
+ ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
63
+ Capabilities extends Record<string, Record<string, boolean>> | undefined,
64
+ > = PostgresBaseScaffold<ExtensionPacks, Capabilities> & {
65
+ readonly types?: Types;
66
+ readonly models?: Models;
67
+ };
68
+
69
+ // Factory form: scaffold without types/models (factory provides them)
70
+ type PostgresScaffold<
71
+ ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined,
72
+ Capabilities extends Record<string, Record<string, boolean>> | undefined,
73
+ > = PostgresBaseScaffold<ExtensionPacks, Capabilities>;
74
+
75
+ // Overload 1: definition form (models/types inline in scaffold)
76
+ export function defineContract<
77
+ const Types extends TypesConstraint = Record<never, never>,
78
+ const Models extends ModelsConstraint = Record<never, never>,
79
+ const ExtensionPacks extends
80
+ | Record<string, ExtensionPackRef<'sql', string>>
81
+ | undefined = undefined,
82
+ const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
83
+ >(
84
+ definition: PostgresDefinition<Types, Models, ExtensionPacks, Capabilities>,
85
+ ): PostgresResult<Types, Models, ExtensionPacks, Capabilities>;
86
+
87
+ // Overload 2: factory form (scaffold without models/types; factory provides them)
88
+ export function defineContract<
89
+ const Types extends TypesConstraint = Record<never, never>,
90
+ const Models extends ModelsConstraint = Record<never, never>,
91
+ const ExtensionPacks extends
92
+ | Record<string, ExtensionPackRef<'sql', string>>
93
+ | undefined = undefined,
94
+ const Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
95
+ >(
96
+ scaffold: PostgresScaffold<ExtensionPacks, Capabilities>,
97
+ factory: (helpers: ComposedAuthoringHelpers<SqlFamily, PostgresPack, ExtensionPacks>) => {
98
+ readonly types?: Types;
99
+ readonly models?: Models;
100
+ },
101
+ ): PostgresResult<Types, Models, ExtensionPacks, Capabilities>;
102
+
103
+ // Implementation — the runtime type is richer than the wide impl signature;
104
+ // as unknown is safe because every declared overload produces a PostgresResult.
105
+ export function defineContract(
106
+ scaffold: Omit<ContractInput, 'family' | 'target'>,
107
+ factory?: (helpers: ComposedAuthoringHelpers<SqlFamily, PostgresPack, undefined>) => {
108
+ readonly types?: TypesConstraint;
109
+ readonly models?: ModelsConstraint;
110
+ },
111
+ ): PostgresResult<TypesConstraint, ModelsConstraint, undefined, undefined> {
112
+ const full = {
113
+ ...scaffold,
114
+ family: sqlFamilyPack,
115
+ target: postgresPack,
116
+ } as ContractInput;
117
+ if (factory !== undefined) {
118
+ return baseDefineContract(
119
+ full,
120
+ factory as Parameters<typeof baseDefineContract>[1],
121
+ ) as unknown as PostgresResult<TypesConstraint, ModelsConstraint, undefined, undefined>;
122
+ }
123
+ return baseDefineContract(full) as unknown as PostgresResult<
124
+ TypesConstraint,
125
+ ModelsConstraint,
126
+ undefined,
127
+ undefined
128
+ >;
129
+ }
@@ -14,8 +14,8 @@ export type {
14
14
  } from '@prisma-next/sql-contract-ts/contract-builder';
15
15
  export {
16
16
  buildSqlContractFromDefinition,
17
- defineContract,
18
17
  field,
19
18
  model,
20
19
  rel,
21
20
  } from '@prisma-next/sql-contract-ts/contract-builder';
21
+ export { defineContract } from '../contract/define-contract';
@@ -0,0 +1 @@
1
+ export * from '@prisma-next/target-postgres/migration';
@@ -62,6 +62,8 @@ export interface PostgresClient<TContract extends Contract<SqlStorage>> {
62
62
  declaration: D,
63
63
  callback: (sql: Db<TContract>, params: BindSiteParams<D>) => SqlQueryPlan<Row>,
64
64
  ): Promise<PreparedStatement<ParamsFromDeclaration<D, CT>, Row>>;
65
+ close(): Promise<void>;
66
+ [Symbol.asyncDispose](): Promise<void>;
65
67
  }
66
68
 
67
69
  export interface PostgresOptionsBase {
@@ -167,11 +169,23 @@ export default function postgres<TContract extends Contract<SqlStorage>>(
167
169
  let driverConnected = false;
168
170
  let connectPromise: Promise<void> | undefined;
169
171
  let backgroundConnectError: unknown;
172
+ let closed = false;
173
+ let ownedDispose: (() => Promise<void>) | undefined;
174
+
170
175
  const connectDriver = async (resolvedBinding: PostgresBinding): Promise<void> => {
171
176
  if (driverConnected) return;
172
177
  if (!runtimeDriver) throw new Error('Postgres runtime driver missing');
173
178
  if (connectPromise) return connectPromise;
174
179
  const runtimeBinding = toRuntimeBinding(resolvedBinding, options);
180
+ if (resolvedBinding.kind === 'url' && runtimeBinding.kind === 'pgPool') {
181
+ const pool = runtimeBinding.pool;
182
+ let disposed = false;
183
+ ownedDispose = async () => {
184
+ if (disposed) return;
185
+ disposed = true;
186
+ await pool.end().then(() => undefined);
187
+ };
188
+ }
175
189
  connectPromise = runtimeDriver
176
190
  .connect(runtimeBinding)
177
191
  .then(() => {
@@ -180,14 +194,16 @@ export default function postgres<TContract extends Contract<SqlStorage>>(
180
194
  .catch(async (err) => {
181
195
  backgroundConnectError = err;
182
196
  connectPromise = undefined;
183
- if (resolvedBinding.kind === 'url' && runtimeBinding.kind === 'pgPool') {
184
- await runtimeBinding.pool.end().catch(() => undefined);
185
- }
197
+ await ownedDispose?.().catch(() => undefined);
186
198
  throw err;
187
199
  });
188
200
  return connectPromise;
189
201
  };
190
202
  const getRuntime = (): Runtime => {
203
+ if (closed) {
204
+ throw new Error('Postgres client is closed');
205
+ }
206
+
191
207
  if (backgroundConnectError !== undefined) {
192
208
  throw backgroundConnectError;
193
209
  }
@@ -241,6 +257,10 @@ export default function postgres<TContract extends Contract<SqlStorage>>(
241
257
  stack,
242
258
 
243
259
  async connect(bindingInput) {
260
+ if (closed) {
261
+ throw new Error('Postgres client is closed');
262
+ }
263
+
244
264
  if (driverConnected || connectPromise) {
245
265
  throw new Error('Postgres client already connected');
246
266
  }
@@ -304,5 +324,16 @@ export default function postgres<TContract extends Contract<SqlStorage>>(
304
324
  return fn(tx);
305
325
  });
306
326
  },
327
+
328
+ async close(): Promise<void> {
329
+ if (closed) return;
330
+ closed = true;
331
+ await connectPromise?.catch(() => undefined);
332
+ await ownedDispose?.();
333
+ },
334
+
335
+ [Symbol.asyncDispose](): Promise<void> {
336
+ return this.close();
337
+ },
307
338
  };
308
339
  }