@prisma/orm-mongo 8.0.0-rc.18-dev.19 → 8.0.0-rc.18-dev.21

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.
@@ -0,0 +1 @@
1
+ export * from "@prisma/orm-framework/contract/validate-once";
@@ -0,0 +1,2 @@
1
+ export * from "@prisma/orm-framework/contract/validate-once";
2
+ export {};
@@ -0,0 +1,72 @@
1
+ import { mongoRaw } from "@prisma/orm-family-mongo/orm";
2
+ import { buildMongoEnums, createMongoExecutionContext, createMongoExecutionStack } from "@prisma/orm-family-mongo/runtime";
3
+ import { validateContractOnce } from "@prisma/orm-framework/contract/validate-once";
4
+ import { MongoContractSerializer } from "@prisma/orm-family-mongo/family/ir";
5
+ import mongoRuntimeTarget from "@prisma/orm-target-mongo/target/runtime";
6
+ import mongoRuntimeAdapter from "@prisma/orm-target-mongo/adapter/runtime";
7
+ import { UNBOUND_NAMESPACE_ID } from "@prisma/orm-framework/components/ir";
8
+ import { mongoQuery } from "@prisma/orm-family-mongo/query-builder";
9
+ import { assertDefined } from "@prisma/orm-framework/utils/assertions";
10
+ import { blindCast } from "@prisma/orm-framework/utils/casts";
11
+ //#region ../../../3-extensions/mongo/dist/mongo-static-Bku9f8Ao.mjs
12
+ var version = "8.0.0-rc.18-dev.21";
13
+ const serializer = new MongoContractSerializer();
14
+ const validator = `${mongoRuntimeTarget.targetId}@${version}`;
15
+ /**
16
+ * Validates an emitted Mongo `contract.json` and returns it as the contract type the application
17
+ * names, ready to pass to `mongo({ contract })` and `mongoStatic({ contract })`. Clients built from
18
+ * the result do not validate it again.
19
+ *
20
+ * The returned value's top level is frozen; its nested objects are not. Do not change `json` or the
21
+ * returned value after the call: clients built from the value later do not validate it again.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import type { Contract } from './contract.d';
26
+ * import contractJson from './contract.json' with { type: 'json' };
27
+ *
28
+ * export const contract = contractFromJson<Contract>(contractJson);
29
+ * ```
30
+ */
31
+ function contractFromJson(json) {
32
+ return validateContractOnce(json, validator, (input) => serializer.deserializeContract(input));
33
+ }
34
+ function validateMongoContract(contract) {
35
+ return contractFromJson(contract);
36
+ }
37
+ function buildMongoStaticContext(contract) {
38
+ const context = createMongoExecutionContext({
39
+ contract,
40
+ stack: createMongoExecutionStack({
41
+ target: mongoRuntimeTarget,
42
+ adapter: mongoRuntimeAdapter
43
+ })
44
+ });
45
+ const enumsByNamespace = buildMongoEnums(contract, context.codecs);
46
+ const unbound = enumsByNamespace[UNBOUND_NAMESPACE_ID];
47
+ assertDefined(unbound, "the unbound namespace always exists on a mongo builder output");
48
+ return {
49
+ context,
50
+ contract,
51
+ enums: blindCast(unbound),
52
+ enumsByNamespace,
53
+ query: mongoQuery({ contract }),
54
+ raw: mongoRaw({ contract })
55
+ };
56
+ }
57
+ /**
58
+ * The query surfaces of a Mongo client without a driver: `query`, `raw` and `enums`. Use it where
59
+ * loading `mongodb` is not wanted.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const { enums } = mongoStatic({ contract: contractFromJson<Contract>(contractJson) });
64
+ * ```
65
+ */
66
+ function mongoStatic(options) {
67
+ return buildMongoStaticContext(validateMongoContract(options.contract));
68
+ }
69
+ //#endregion
70
+ export { validateMongoContract as i, contractFromJson as n, mongoStatic as r, buildMongoStaticContext as t };
71
+
72
+ //# sourceMappingURL=mongo-static-Bku9f8Ao-Bf-xeIR_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo-static-Bku9f8Ao-Bf-xeIR_.mjs","names":[],"sources":["../../../../3-extensions/mongo/dist/mongo-static-Bku9f8Ao.mjs"],"sourcesContent":["import { mongoRaw } from \"@internal/mongo-orm\";\nimport { buildMongoEnums, createMongoExecutionContext, createMongoExecutionStack } from \"@internal/mongo-runtime\";\nimport { validateContractOnce } from \"@internal/contract/validate-once\";\nimport { MongoContractSerializer } from \"@internal/family-mongo/ir\";\nimport mongoRuntimeTarget from \"@internal/target-mongo/runtime\";\nimport mongoRuntimeAdapter from \"@internal/adapter-mongo/runtime\";\nimport { UNBOUND_NAMESPACE_ID } from \"@internal/framework-components/ir\";\nimport { mongoQuery } from \"@internal/mongo-query-builder\";\nimport { assertDefined } from \"@internal/utils/assertions\";\nimport { blindCast } from \"@internal/utils/casts\";\n//#region package.json\nvar version = \"8.0.0-rc.18-dev.21\";\n//#endregion\n//#region src/static/contract-from-json.ts\nconst serializer = new MongoContractSerializer();\nconst validator = `${mongoRuntimeTarget.targetId}@${version}`;\n/**\n* Validates an emitted Mongo `contract.json` and returns it as the contract type the application\n* names, ready to pass to `mongo({ contract })` and `mongoStatic({ contract })`. Clients built from\n* the result do not validate it again.\n*\n* The returned value's top level is frozen; its nested objects are not. Do not change `json` or the\n* returned value after the call: clients built from the value later do not validate it again.\n*\n* @example\n* ```ts\n* import type { Contract } from './contract.d';\n* import contractJson from './contract.json' with { type: 'json' };\n*\n* export const contract = contractFromJson<Contract>(contractJson);\n* ```\n*/\nfunction contractFromJson(json) {\n\treturn validateContractOnce(json, validator, (input) => serializer.deserializeContract(input));\n}\nfunction validateMongoContract(contract) {\n\treturn contractFromJson(contract);\n}\n//#endregion\n//#region src/static/mongo-static.ts\nfunction buildMongoStaticContext(contract) {\n\tconst context = createMongoExecutionContext({\n\t\tcontract,\n\t\tstack: createMongoExecutionStack({\n\t\t\ttarget: mongoRuntimeTarget,\n\t\t\tadapter: mongoRuntimeAdapter\n\t\t})\n\t});\n\tconst enumsByNamespace = buildMongoEnums(contract, context.codecs);\n\tconst unbound = enumsByNamespace[UNBOUND_NAMESPACE_ID];\n\tassertDefined(unbound, \"the unbound namespace always exists on a mongo builder output\");\n\treturn {\n\t\tcontext,\n\t\tcontract,\n\t\tenums: blindCast(unbound),\n\t\tenumsByNamespace,\n\t\tquery: mongoQuery({ contract }),\n\t\traw: mongoRaw({ contract })\n\t};\n}\n/**\n* The query surfaces of a Mongo client without a driver: `query`, `raw` and `enums`. Use it where\n* loading `mongodb` is not wanted.\n*\n* @example\n* ```ts\n* const { enums } = mongoStatic({ contract: contractFromJson<Contract>(contractJson) });\n* ```\n*/\nfunction mongoStatic(options) {\n\treturn buildMongoStaticContext(validateMongoContract(options.contract));\n}\n//#endregion\nexport { validateMongoContract as i, mongoStatic as n, contractFromJson as r, buildMongoStaticContext as t };\n\n//# sourceMappingURL=mongo-static-Bku9f8Ao.mjs.map"],"mappings":";;;;;;;;;;;AAWA,IAAI,UAAU;AAGd,MAAM,aAAa,IAAI,wBAAwB;AAC/C,MAAM,YAAY,GAAG,mBAAmB,SAAS,GAAG;;;;;;;;;;;;;;;;;AAiBpD,SAAS,iBAAiB,MAAM;CAC/B,OAAO,qBAAqB,MAAM,YAAY,UAAU,WAAW,oBAAoB,KAAK,CAAC;AAC9F;AACA,SAAS,sBAAsB,UAAU;CACxC,OAAO,iBAAiB,QAAQ;AACjC;AAGA,SAAS,wBAAwB,UAAU;CAC1C,MAAM,UAAU,4BAA4B;EAC3C;EACA,OAAO,0BAA0B;GAChC,QAAQ;GACR,SAAS;EACV,CAAC;CACF,CAAC;CACD,MAAM,mBAAmB,gBAAgB,UAAU,QAAQ,MAAM;CACjE,MAAM,UAAU,iBAAiB;CACjC,cAAc,SAAS,+DAA+D;CACtF,OAAO;EACN;EACA;EACA,OAAO,UAAU,OAAO;EACxB;EACA,OAAO,WAAW,EAAE,SAAS,CAAC;EAC9B,KAAK,SAAS,EAAE,SAAS,CAAC;CAC3B;AACD;;;;;;;;;;AAUA,SAAS,YAAY,SAAS;CAC7B,OAAO,wBAAwB,sBAAsB,QAAQ,QAAQ,CAAC;AACvE"}
@@ -4,7 +4,7 @@ import { UNBOUND_NAMESPACE_ID } from "@prisma/orm-framework/components/ir";
4
4
  import { mongoQuery } from "@prisma/orm-family-mongo/query-builder";
5
5
  import { NamespacedEnums } from "@prisma/orm-framework/contract/enum-accessor";
6
6
  import { AnyMongoTypeMaps, MongoContract, MongoContractWithTypeMaps } from "@prisma/orm-family-mongo/contract";
7
- //#region ../../../3-extensions/mongo/dist/mongo-static-CHHCsRvL.d.mts
7
+ //#region ../../../3-extensions/mongo/dist/mongo-static-D_RcLkSZ.d.mts
8
8
  //#region src/static/mongo-static.d.ts
9
9
  type UnboundEnums<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>> = NamespacedEnums<TContract>[typeof UNBOUND_NAMESPACE_ID];
10
10
  interface MongoStaticContext<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>> {
@@ -14,9 +14,18 @@ interface MongoStaticContext<TContract extends MongoContractWithTypeMaps<MongoCo
14
14
  readonly query: ReturnType<typeof mongoQuery<TContract>>;
15
15
  readonly raw: MongoRawClient<TContract>;
16
16
  }
17
+ /**
18
+ * The query surfaces of a Mongo client without a driver: `query`, `raw` and `enums`. Use it where
19
+ * loading `mongodb` is not wanted.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const { enums } = mongoStatic({ contract: contractFromJson<Contract>(contractJson) });
24
+ * ```
25
+ */
17
26
  declare function mongoStatic<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>>(options: {
18
- readonly contractJson: unknown;
27
+ readonly contract: TContract;
19
28
  }): MongoStaticContext<TContract>;
20
29
  //#endregion
21
30
  export { mongoStatic as n, MongoStaticContext as t };
22
- //# sourceMappingURL=mongo-static-CHHCsRvL-DXMjx76B.d.mts.map
31
+ //# sourceMappingURL=mongo-static-D_RcLkSZ-Cxq_NWiQ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo-static-D_RcLkSZ-Cxq_NWiQ.d.mts","names":[],"sources":["../../../../3-extensions/mongo/dist/mongo-static-D_RcLkSZ.d.mts"],"mappings":";;;;;;;;KAOK,aAAa,kBAAkB,0BAA0B,eAAe,qBAAqB,gBAAgB,kBAAkB;UAC1H,mBAAmB,kBAAkB,0BAA0B,eAAe;WAC7E,SAAS,sBAAsB;WAC/B,UAAU;WACV,OAAO,aAAa;WACpB,OAAO,kBAAkB,WAAW;WACpC,KAAK,eAAe;;;;;;;;;;;iBAWd,YAAY,kBAAkB,0BAA0B,eAAe,mBAAmB;WAChG,UAAU;IACjB,mBAAmB"}
@@ -1,4 +1,4 @@
1
- import { t as MongoStaticContext } from "./mongo-static-CHHCsRvL-DXMjx76B.mjs";
1
+ import { t as MongoStaticContext } from "./mongo-static-D_RcLkSZ-Cxq_NWiQ.mjs";
2
2
  import { MongoClient as MongoClient$1 } from "mongodb";
3
3
  import { MongoOrmClient, MongoRawClient } from "@prisma/orm-family-mongo/orm";
4
4
  import { MongoExecutionContext, MongoMiddleware, MongoRuntime } from "@prisma/orm-family-mongo/runtime";
@@ -69,35 +69,27 @@ interface MongoBindingOptions {
69
69
  readonly dbName?: string;
70
70
  readonly mongoClient?: import('mongodb').MongoClient;
71
71
  }
72
- type MongoOptionsWithContract<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>> = MongoBindingOptions & MongoOptionsBase & {
72
+ type MongoOptions<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>> = MongoBindingOptions & MongoOptionsBase & {
73
73
  readonly contract: TContract;
74
- readonly contractJson?: never;
75
74
  };
76
75
  /**
77
- * `TContract` is a phantom parameter that drives explicit-type inference at the
78
- * call site (e.g. `mongo<Contract>({ contractJson })`). It is not referenced in
79
- * the type body — the contract value comes through `contractJson` at runtime.
80
- */
81
- type MongoOptionsWithContractJson<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>> = MongoBindingOptions & MongoOptionsBase & {
82
- readonly contractJson: unknown;
83
- readonly contract?: never;
84
- /**
85
- * @internal phantom field; never set at runtime, only references TContract
86
- * so that strict tsc/biome don't flag the type parameter as unused.
87
- */
88
- readonly __contractPhantom?: TContract;
89
- };
90
- type MongoOptions<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>> = MongoOptionsWithContract<TContract> | MongoOptionsWithContractJson<TContract>;
91
- /**
92
- * Creates a lazy Mongo client from either `contractJson` or a TypeScript-authored `contract`.
93
- * The `orm` and `query` surfaces are available immediately; the underlying driver is connected
94
- * on the first query (or the first explicit `connect()` call), mirroring the Postgres facade.
76
+ * Creates a lazy Mongo client. The client infers its contract type from `contract`: a value from
77
+ * `contractFromJson` for an emitted contract, or a TypeScript-authored contract. A contract is
78
+ * validated once, however many clients are built from it. The `orm` and `query` surfaces are
79
+ * available at once; the driver connects on the first query or `connect()`.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * import { contractFromJson } from '@prisma/orm-mongo/static';
84
+ * import mongo from '@prisma/orm-mongo/runtime';
85
+ * import type { Contract } from './contract.d';
86
+ * import contractJson from './contract.json' with { type: 'json' };
95
87
  *
96
- * - No-emit: pass a TypeScript-authored contract. Example: `mongo({ contract, url })`
97
- * - Emitted: pass `Contract` type explicitly. Example: `mongo<Contract>({ contractJson, url })`
88
+ * export const contract = contractFromJson<Contract>(contractJson);
89
+ * export const db = mongo({ contract, url: process.env['MONGODB_URL']! });
90
+ * ```
98
91
  */
99
- declare function mongo<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>>(options: MongoOptionsWithContract<TContract>): MongoClient<TContract>;
100
- declare function mongo<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>>(options: MongoOptionsWithContractJson<TContract>): MongoClient<TContract>;
92
+ declare function mongo<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>>(options: MongoOptions<TContract>): MongoClient<TContract>;
101
93
  //#endregion
102
- export { type MongoBinding, type MongoBindingInput, type MongoClient, type MongoOptions, type MongoOptionsWithContract, type MongoOptionsWithContractJson, type MongoTargetId, mongo as default };
94
+ export { type MongoBinding, type MongoBindingInput, type MongoClient, type MongoOptions, type MongoTargetId, mongo as default };
103
95
  //# sourceMappingURL=runtime.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.mts","names":[],"sources":["../../../../3-extensions/mongo/dist/runtime.d.mts"],"mappings":";;;;;;;KAMK;WACM;WACA;WACA;;WAEA;WACA,QAAQ;WACR;;KAEN;WACM,SAAS;WACT;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;;WAEA,aAAa;WACb;WACA;WACA;WACA;;;;KAIN;KACA,aAAa,kBAAkB,0BAA0B,eAAe,qBAAqB,mBAAmB;UAC3G,YAAY,kBAAkB,0BAA0B,eAAe;WACtE,KAAK,eAAe;WACpB,OAAO,mBAAmB;WAC1B,KAAK,eAAe;WACpB,UAAU;WACV,OAAO,aAAa;WACpB,SAAS,sBAAsB;EACxC,QAAQ,eAAe,oBAAoB,QAAQ;EACnD,WAAW,QAAQ;EACnB,SAAS;GACR,OAAO,iBAAiB;;UAEjB;WACC;;;;WAIA,sBAAsB;;UAEvB;WACC,UAAU;WACV;WACA;WACA;WACA,gCAAgC;;KAEtC,yBAAyB,kBAAkB,0BAA0B,eAAe,qBAAqB,sBAAsB;WACzH,UAAU;WACV;;;;;;;KAON,6BAA6B,kBAAkB,0BAA0B,eAAe,qBAAqB,sBAAsB;WAC7H;WACA;;;;;WAKA,oBAAoB;;KAE1B,aAAa,kBAAkB,0BAA0B,eAAe,qBAAqB,yBAAyB,aAAa,6BAA6B;;;;;;;;;iBASpJ,MAAM,kBAAkB,0BAA0B,eAAe,mBAAmB,SAAS,yBAAyB,aAAa,YAAY;iBAC/I,MAAM,kBAAkB,0BAA0B,eAAe,mBAAmB,SAAS,6BAA6B,aAAa,YAAY"}
1
+ {"version":3,"file":"runtime.d.mts","names":[],"sources":["../../../../3-extensions/mongo/dist/runtime.d.mts"],"mappings":";;;;;;;KAMK;WACM;WACA;WACA;;WAEA;WACA,QAAQ;WACR;;KAEN;WACM,SAAS;WACT;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;;WAEA,aAAa;WACb;WACA;WACA;WACA;;;;KAIN;KACA,aAAa,kBAAkB,0BAA0B,eAAe,qBAAqB,mBAAmB;UAC3G,YAAY,kBAAkB,0BAA0B,eAAe;WACtE,KAAK,eAAe;WACpB,OAAO,mBAAmB;WAC1B,KAAK,eAAe;WACpB,UAAU;WACV,OAAO,aAAa;WACpB,SAAS,sBAAsB;EACxC,QAAQ,eAAe,oBAAoB,QAAQ;EACnD,WAAW,QAAQ;EACnB,SAAS;GACR,OAAO,iBAAiB;;UAEjB;WACC;;;;WAIA,sBAAsB;;UAEvB;WACC,UAAU;WACV;WACA;WACA;WACA,gCAAgC;;KAEtC,aAAa,kBAAkB,0BAA0B,eAAe,qBAAqB,sBAAsB;WAC7G,UAAU;;;;;;;;;;;;;;;;;;;iBAmBJ,MAAM,kBAAkB,0BAA0B,eAAe,mBAAmB,SAAS,aAAa,aAAa,YAAY"}
package/dist/runtime.mjs CHANGED
@@ -1,9 +1,7 @@
1
- import { t as buildMongoStaticContext } from "./mongo-static-UlmsQasy-DBZWYIip.mjs";
1
+ import { i as validateMongoContract, t as buildMongoStaticContext } from "./mongo-static-Bku9f8Ao-Bf-xeIR_.mjs";
2
2
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
3
- import { MongoContractSerializer } from "@prisma/orm-family-mongo/family/ir";
4
3
  import { mongoOrm } from "@prisma/orm-family-mongo/orm";
5
4
  import { createMongoRuntime } from "@prisma/orm-family-mongo/runtime";
6
- import { blindCast } from "@prisma/orm-framework/utils/casts";
7
5
  import { MongoDriverImpl } from "@prisma/orm-target-mongo/driver";
8
6
  import { AsyncIterableResult } from "@prisma/orm-framework/components/runtime";
9
7
  import { InternalError } from "@prisma/orm-framework/utils/internal-error";
@@ -97,15 +95,25 @@ function resolveOptionalMongoBinding(options) {
97
95
  });
98
96
  throw new InternalError("Invariant violation: expected one mongo binding branch");
99
97
  }
100
- function hasContractJson(options) {
101
- return "contractJson" in options;
102
- }
103
- function resolveContract(options) {
104
- const contractInput = hasContractJson(options) ? options.contractJson : options.contract;
105
- return blindCast(new MongoContractSerializer().deserializeContract(contractInput));
106
- }
98
+ /**
99
+ * Creates a lazy Mongo client. The client infers its contract type from `contract`: a value from
100
+ * `contractFromJson` for an emitted contract, or a TypeScript-authored contract. A contract is
101
+ * validated once, however many clients are built from it. The `orm` and `query` surfaces are
102
+ * available at once; the driver connects on the first query or `connect()`.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * import { contractFromJson } from '@prisma/orm-mongo/static';
107
+ * import mongo from '@prisma/orm-mongo/runtime';
108
+ * import type { Contract } from './contract.d';
109
+ * import contractJson from './contract.json' with { type: 'json' };
110
+ *
111
+ * export const contract = contractFromJson<Contract>(contractJson);
112
+ * export const db = mongo({ contract, url: process.env['MONGODB_URL']! });
113
+ * ```
114
+ */
107
115
  function mongo(options) {
108
- const contract = resolveContract(options);
116
+ const contract = validateMongoContract(options.contract);
109
117
  let binding = resolveOptionalMongoBinding(options);
110
118
  const { context, query, enums, enumsByNamespace, raw } = buildMongoStaticContext(contract);
111
119
  let runtimePromise;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":[],"sources":["../../../../3-extensions/mongo/dist/runtime.mjs"],"sourcesContent":["import { t as buildMongoStaticContext } from \"./mongo-static-UlmsQasy.mjs\";\nimport { ifDefined } from \"@internal/utils/defined\";\nimport { MongoDriverImpl } from \"@internal/driver-mongo\";\nimport { MongoContractSerializer } from \"@internal/family-mongo/ir\";\nimport { AsyncIterableResult } from \"@internal/framework-components/runtime\";\nimport { mongoOrm } from \"@internal/mongo-orm\";\nimport { createMongoRuntime } from \"@internal/mongo-runtime\";\nimport { blindCast } from \"@internal/utils/casts\";\nimport { InternalError } from \"@internal/utils/internal-error\";\nimport { ConnectionString } from \"mongodb-connection-string-url\";\nimport { structuredError } from \"@internal/utils/structured-error\";\n//#region src/runtime/mongo-errors.ts\nfunction mongoError(code, message, options) {\n\treturn structuredError(code, message, {\n\t\t...options,\n\t\tmeta: {\n\t\t\t...options?.meta,\n\t\t\textension: \"mongo\"\n\t\t}\n\t});\n}\n//#endregion\n//#region src/runtime/binding.ts\nconst URL_SCHEME_PATTERN = /^([a-z][a-z\\d+.-]*):\\/\\//i;\nconst MONGO_SCHEMES = /* @__PURE__ */ new Set([\"mongodb\", \"mongodb+srv\"]);\nfunction validateMongoUrl(url) {\n\tconst trimmed = url.trim();\n\tif (trimmed.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a non-empty string\");\n\tconst scheme = URL_SCHEME_PATTERN.exec(trimmed)?.[1];\n\tif (scheme === void 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a valid URL\");\n\tif (!MONGO_SCHEMES.has(scheme)) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must use mongodb:// or mongodb+srv://\");\n\ttry {\n\t\treturn new ConnectionString(trimmed);\n\t} catch {\n\t\tthrow mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a valid URL\");\n\t}\n}\nfunction extractDbNameFromUrl(parsed) {\n\tconst [encodedDbName = \"\"] = parsed.pathname.slice(1).split(\"/\");\n\tif (encodedDbName.length === 0) return;\n\ttry {\n\t\treturn decodeURIComponent(encodedDbName);\n\t} catch {\n\t\tthrow mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a valid URL\");\n\t}\n}\nfunction resolveMongoBinding(options) {\n\tconst providedCount = Number(options.binding !== void 0) + Number(options.url !== void 0) + Number(options.uri !== void 0) + Number(options.mongoClient !== void 0);\n\tif (providedCount !== 1) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Provide one binding input: binding, url, uri+dbName, or mongoClient+dbName\", { meta: { received: providedCount } });\n\tif (options.binding !== void 0) return options.binding;\n\tif (options.url !== void 0) {\n\t\tconst parsed = validateMongoUrl(options.url);\n\t\tif (options.dbName !== void 0 && options.dbName.trim().length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo binding via { url, dbName } requires a non-empty dbName\");\n\t\tconst explicitDbName = options.dbName?.trim();\n\t\tconst dbName = explicitDbName !== void 0 && explicitDbName.length > 0 ? explicitDbName : extractDbNameFromUrl(parsed);\n\t\tif (dbName === void 0 || dbName.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must include a database name in its path (e.g. mongodb://host:27017/mydb), or pass dbName explicitly\");\n\t\treturn {\n\t\t\tkind: \"url\",\n\t\t\turl: options.url.trim(),\n\t\t\tdbName\n\t\t};\n\t}\n\tif (options.uri !== void 0) {\n\t\tvalidateMongoUrl(options.uri);\n\t\tconst dbName = options.dbName?.trim();\n\t\tif (dbName === void 0 || dbName.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo binding via { uri, dbName } requires a non-empty dbName\");\n\t\treturn {\n\t\t\tkind: \"url\",\n\t\t\turl: options.uri.trim(),\n\t\t\tdbName\n\t\t};\n\t}\n\tconst mongoClient = options.mongoClient;\n\tif (mongoClient === void 0) throw new InternalError(\"Invariant violation: expected mongo binding after validation\");\n\tconst dbName = options.dbName?.trim();\n\tif (dbName === void 0 || dbName.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo binding via { mongoClient, dbName } requires a non-empty dbName\");\n\treturn {\n\t\tkind: \"mongoClient\",\n\t\tclient: mongoClient,\n\t\tdbName\n\t};\n}\nfunction resolveOptionalMongoBinding(options) {\n\tconst providedCount = Number(options.binding !== void 0) + Number(options.url !== void 0) + Number(options.uri !== void 0) + Number(options.mongoClient !== void 0);\n\tif (providedCount === 0) return;\n\tif (providedCount !== 1) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Provide one binding input: binding, url, uri+dbName, or mongoClient+dbName\", { meta: { received: providedCount } });\n\tif (options.binding !== void 0) return resolveMongoBinding({ binding: options.binding });\n\tif (options.url !== void 0) return resolveMongoBinding(options.dbName !== void 0 ? {\n\t\turl: options.url,\n\t\tdbName: options.dbName\n\t} : { url: options.url });\n\tif (options.uri !== void 0) return resolveMongoBinding({\n\t\turi: options.uri,\n\t\tdbName: options.dbName ?? \"\"\n\t});\n\tif (options.mongoClient !== void 0) return resolveMongoBinding({\n\t\tmongoClient: options.mongoClient,\n\t\tdbName: options.dbName ?? \"\"\n\t});\n\tthrow new InternalError(\"Invariant violation: expected one mongo binding branch\");\n}\n//#endregion\n//#region src/runtime/mongo.ts\nfunction hasContractJson(options) {\n\treturn \"contractJson\" in options;\n}\nfunction resolveContract(options) {\n\tconst contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n\treturn blindCast(new MongoContractSerializer().deserializeContract(contractInput));\n}\nfunction mongo(options) {\n\tconst contract = resolveContract(options);\n\tlet binding = resolveOptionalMongoBinding(options);\n\tconst { context, query, enums, enumsByNamespace, raw } = buildMongoStaticContext(contract);\n\tlet runtimePromise;\n\tlet closed = false;\n\tlet ownedDispose;\n\tconst buildRuntime = async (resolvedBinding) => {\n\t\tconst driver = resolvedBinding.kind === \"url\" ? await MongoDriverImpl.fromConnection(resolvedBinding.url, resolvedBinding.dbName) : MongoDriverImpl.fromDb(resolvedBinding.client.db(resolvedBinding.dbName));\n\t\tif (resolvedBinding.kind === \"url\") ownedDispose = () => driver.close();\n\t\treturn createMongoRuntime({\n\t\t\tcontext,\n\t\t\tdriver,\n\t\t\t...ifDefined(\"mode\", options.mode),\n\t\t\t...ifDefined(\"middleware\", options.middleware)\n\t\t});\n\t};\n\tconst getRuntime = () => {\n\t\tif (closed) return Promise.reject(mongoError(\"DRIVER.NOT_CONNECTED\", \"Mongo client is closed\"));\n\t\tif (runtimePromise !== void 0) return runtimePromise;\n\t\tif (binding === void 0) return Promise.reject(mongoError(\"RUNTIME.BINDING_MISSING\", \"Mongo binding not configured. Pass url/uri+dbName/mongoClient+dbName/binding to mongo(...) or call db.connect({ ... }).\"));\n\t\truntimePromise = buildRuntime(binding).catch((err) => {\n\t\t\truntimePromise = void 0;\n\t\t\tthrow err;\n\t\t});\n\t\treturn runtimePromise;\n\t};\n\tfunction queryRows(plan) {\n\t\tasync function* iterate() {\n\t\t\tyield* (await getRuntime()).query(plan);\n\t\t}\n\t\treturn new AsyncIterableResult(iterate());\n\t}\n\tasync function executeStats(plan) {\n\t\treturn (await getRuntime()).execute(plan);\n\t}\n\treturn {\n\t\torm: mongoOrm({\n\t\t\tcontract,\n\t\t\texecutor: {\n\t\t\t\tquery: queryRows,\n\t\t\t\texecute: executeStats\n\t\t\t},\n\t\t\tmutationDefaults: context,\n\t\t\tenums: enumsByNamespace\n\t\t}),\n\t\tquery,\n\t\traw,\n\t\tcontract,\n\t\tenums,\n\t\tcontext,\n\t\tasync connect(bindingInput) {\n\t\t\tif (closed) throw mongoError(\"DRIVER.NOT_CONNECTED\", \"Mongo client is closed\");\n\t\t\tif (runtimePromise !== void 0) throw mongoError(\"DRIVER.ALREADY_CONNECTED\", \"Mongo client already connected\");\n\t\t\tif (bindingInput !== void 0) binding = resolveMongoBinding(bindingInput);\n\t\t\tif (binding === void 0) throw mongoError(\"RUNTIME.BINDING_MISSING\", \"Mongo binding not configured. Pass url/uri+dbName/mongoClient+dbName/binding to mongo(...) or call db.connect({ ... }).\");\n\t\t\treturn getRuntime();\n\t\t},\n\t\truntime() {\n\t\t\treturn getRuntime();\n\t\t},\n\t\tasync close() {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tif (runtimePromise === void 0) return;\n\t\t\ttry {\n\t\t\t\tawait runtimePromise;\n\t\t\t} catch {}\n\t\t\tconst dispose = ownedDispose;\n\t\t\townedDispose = void 0;\n\t\t\tawait dispose?.();\n\t\t},\n\t\t[Symbol.asyncDispose]() {\n\t\t\treturn this.close();\n\t\t}\n\t};\n}\n//#endregion\nexport { mongo as default };\n\n//# sourceMappingURL=runtime.mjs.map"],"mappings":"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"}
1
+ {"version":3,"file":"runtime.mjs","names":[],"sources":["../../../../3-extensions/mongo/dist/runtime.mjs"],"sourcesContent":["import { i as validateMongoContract, t as buildMongoStaticContext } from \"./mongo-static-Bku9f8Ao.mjs\";\nimport { ifDefined } from \"@internal/utils/defined\";\nimport { MongoDriverImpl } from \"@internal/driver-mongo\";\nimport { AsyncIterableResult } from \"@internal/framework-components/runtime\";\nimport { mongoOrm } from \"@internal/mongo-orm\";\nimport { createMongoRuntime } from \"@internal/mongo-runtime\";\nimport { InternalError } from \"@internal/utils/internal-error\";\nimport { ConnectionString } from \"mongodb-connection-string-url\";\nimport { structuredError } from \"@internal/utils/structured-error\";\n//#region src/runtime/mongo-errors.ts\nfunction mongoError(code, message, options) {\n\treturn structuredError(code, message, {\n\t\t...options,\n\t\tmeta: {\n\t\t\t...options?.meta,\n\t\t\textension: \"mongo\"\n\t\t}\n\t});\n}\n//#endregion\n//#region src/runtime/binding.ts\nconst URL_SCHEME_PATTERN = /^([a-z][a-z\\d+.-]*):\\/\\//i;\nconst MONGO_SCHEMES = /* @__PURE__ */ new Set([\"mongodb\", \"mongodb+srv\"]);\nfunction validateMongoUrl(url) {\n\tconst trimmed = url.trim();\n\tif (trimmed.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a non-empty string\");\n\tconst scheme = URL_SCHEME_PATTERN.exec(trimmed)?.[1];\n\tif (scheme === void 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a valid URL\");\n\tif (!MONGO_SCHEMES.has(scheme)) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must use mongodb:// or mongodb+srv://\");\n\ttry {\n\t\treturn new ConnectionString(trimmed);\n\t} catch {\n\t\tthrow mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a valid URL\");\n\t}\n}\nfunction extractDbNameFromUrl(parsed) {\n\tconst [encodedDbName = \"\"] = parsed.pathname.slice(1).split(\"/\");\n\tif (encodedDbName.length === 0) return;\n\ttry {\n\t\treturn decodeURIComponent(encodedDbName);\n\t} catch {\n\t\tthrow mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must be a valid URL\");\n\t}\n}\nfunction resolveMongoBinding(options) {\n\tconst providedCount = Number(options.binding !== void 0) + Number(options.url !== void 0) + Number(options.uri !== void 0) + Number(options.mongoClient !== void 0);\n\tif (providedCount !== 1) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Provide one binding input: binding, url, uri+dbName, or mongoClient+dbName\", { meta: { received: providedCount } });\n\tif (options.binding !== void 0) return options.binding;\n\tif (options.url !== void 0) {\n\t\tconst parsed = validateMongoUrl(options.url);\n\t\tif (options.dbName !== void 0 && options.dbName.trim().length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo binding via { url, dbName } requires a non-empty dbName\");\n\t\tconst explicitDbName = options.dbName?.trim();\n\t\tconst dbName = explicitDbName !== void 0 && explicitDbName.length > 0 ? explicitDbName : extractDbNameFromUrl(parsed);\n\t\tif (dbName === void 0 || dbName.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo URL must include a database name in its path (e.g. mongodb://host:27017/mydb), or pass dbName explicitly\");\n\t\treturn {\n\t\t\tkind: \"url\",\n\t\t\turl: options.url.trim(),\n\t\t\tdbName\n\t\t};\n\t}\n\tif (options.uri !== void 0) {\n\t\tvalidateMongoUrl(options.uri);\n\t\tconst dbName = options.dbName?.trim();\n\t\tif (dbName === void 0 || dbName.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo binding via { uri, dbName } requires a non-empty dbName\");\n\t\treturn {\n\t\t\tkind: \"url\",\n\t\t\turl: options.uri.trim(),\n\t\t\tdbName\n\t\t};\n\t}\n\tconst mongoClient = options.mongoClient;\n\tif (mongoClient === void 0) throw new InternalError(\"Invariant violation: expected mongo binding after validation\");\n\tconst dbName = options.dbName?.trim();\n\tif (dbName === void 0 || dbName.length === 0) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Mongo binding via { mongoClient, dbName } requires a non-empty dbName\");\n\treturn {\n\t\tkind: \"mongoClient\",\n\t\tclient: mongoClient,\n\t\tdbName\n\t};\n}\nfunction resolveOptionalMongoBinding(options) {\n\tconst providedCount = Number(options.binding !== void 0) + Number(options.url !== void 0) + Number(options.uri !== void 0) + Number(options.mongoClient !== void 0);\n\tif (providedCount === 0) return;\n\tif (providedCount !== 1) throw mongoError(\"RUNTIME.BINDING_INVALID\", \"Provide one binding input: binding, url, uri+dbName, or mongoClient+dbName\", { meta: { received: providedCount } });\n\tif (options.binding !== void 0) return resolveMongoBinding({ binding: options.binding });\n\tif (options.url !== void 0) return resolveMongoBinding(options.dbName !== void 0 ? {\n\t\turl: options.url,\n\t\tdbName: options.dbName\n\t} : { url: options.url });\n\tif (options.uri !== void 0) return resolveMongoBinding({\n\t\turi: options.uri,\n\t\tdbName: options.dbName ?? \"\"\n\t});\n\tif (options.mongoClient !== void 0) return resolveMongoBinding({\n\t\tmongoClient: options.mongoClient,\n\t\tdbName: options.dbName ?? \"\"\n\t});\n\tthrow new InternalError(\"Invariant violation: expected one mongo binding branch\");\n}\n//#endregion\n//#region src/runtime/mongo.ts\n/**\n* Creates a lazy Mongo client. The client infers its contract type from `contract`: a value from\n* `contractFromJson` for an emitted contract, or a TypeScript-authored contract. A contract is\n* validated once, however many clients are built from it. The `orm` and `query` surfaces are\n* available at once; the driver connects on the first query or `connect()`.\n*\n* @example\n* ```ts\n* import { contractFromJson } from '@prisma/orm-mongo/static';\n* import mongo from '@prisma/orm-mongo/runtime';\n* import type { Contract } from './contract.d';\n* import contractJson from './contract.json' with { type: 'json' };\n*\n* export const contract = contractFromJson<Contract>(contractJson);\n* export const db = mongo({ contract, url: process.env['MONGODB_URL']! });\n* ```\n*/\nfunction mongo(options) {\n\tconst contract = validateMongoContract(options.contract);\n\tlet binding = resolveOptionalMongoBinding(options);\n\tconst { context, query, enums, enumsByNamespace, raw } = buildMongoStaticContext(contract);\n\tlet runtimePromise;\n\tlet closed = false;\n\tlet ownedDispose;\n\tconst buildRuntime = async (resolvedBinding) => {\n\t\tconst driver = resolvedBinding.kind === \"url\" ? await MongoDriverImpl.fromConnection(resolvedBinding.url, resolvedBinding.dbName) : MongoDriverImpl.fromDb(resolvedBinding.client.db(resolvedBinding.dbName));\n\t\tif (resolvedBinding.kind === \"url\") ownedDispose = () => driver.close();\n\t\treturn createMongoRuntime({\n\t\t\tcontext,\n\t\t\tdriver,\n\t\t\t...ifDefined(\"mode\", options.mode),\n\t\t\t...ifDefined(\"middleware\", options.middleware)\n\t\t});\n\t};\n\tconst getRuntime = () => {\n\t\tif (closed) return Promise.reject(mongoError(\"DRIVER.NOT_CONNECTED\", \"Mongo client is closed\"));\n\t\tif (runtimePromise !== void 0) return runtimePromise;\n\t\tif (binding === void 0) return Promise.reject(mongoError(\"RUNTIME.BINDING_MISSING\", \"Mongo binding not configured. Pass url/uri+dbName/mongoClient+dbName/binding to mongo(...) or call db.connect({ ... }).\"));\n\t\truntimePromise = buildRuntime(binding).catch((err) => {\n\t\t\truntimePromise = void 0;\n\t\t\tthrow err;\n\t\t});\n\t\treturn runtimePromise;\n\t};\n\tfunction queryRows(plan) {\n\t\tasync function* iterate() {\n\t\t\tyield* (await getRuntime()).query(plan);\n\t\t}\n\t\treturn new AsyncIterableResult(iterate());\n\t}\n\tasync function executeStats(plan) {\n\t\treturn (await getRuntime()).execute(plan);\n\t}\n\treturn {\n\t\torm: mongoOrm({\n\t\t\tcontract,\n\t\t\texecutor: {\n\t\t\t\tquery: queryRows,\n\t\t\t\texecute: executeStats\n\t\t\t},\n\t\t\tmutationDefaults: context,\n\t\t\tenums: enumsByNamespace\n\t\t}),\n\t\tquery,\n\t\traw,\n\t\tcontract,\n\t\tenums,\n\t\tcontext,\n\t\tasync connect(bindingInput) {\n\t\t\tif (closed) throw mongoError(\"DRIVER.NOT_CONNECTED\", \"Mongo client is closed\");\n\t\t\tif (runtimePromise !== void 0) throw mongoError(\"DRIVER.ALREADY_CONNECTED\", \"Mongo client already connected\");\n\t\t\tif (bindingInput !== void 0) binding = resolveMongoBinding(bindingInput);\n\t\t\tif (binding === void 0) throw mongoError(\"RUNTIME.BINDING_MISSING\", \"Mongo binding not configured. Pass url/uri+dbName/mongoClient+dbName/binding to mongo(...) or call db.connect({ ... }).\");\n\t\t\treturn getRuntime();\n\t\t},\n\t\truntime() {\n\t\t\treturn getRuntime();\n\t\t},\n\t\tasync close() {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tif (runtimePromise === void 0) return;\n\t\t\ttry {\n\t\t\t\tawait runtimePromise;\n\t\t\t} catch {}\n\t\t\tconst dispose = ownedDispose;\n\t\t\townedDispose = void 0;\n\t\t\tawait dispose?.();\n\t\t},\n\t\t[Symbol.asyncDispose]() {\n\t\t\treturn this.close();\n\t\t}\n\t};\n}\n//#endregion\nexport { mongo as default };\n\n//# sourceMappingURL=runtime.mjs.map"],"mappings":"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"}
package/dist/static.d.mts CHANGED
@@ -1,2 +1,24 @@
1
- import { n as mongoStatic, t as MongoStaticContext } from "./mongo-static-CHHCsRvL-DXMjx76B.mjs";
2
- export { type MongoStaticContext, mongoStatic as default };
1
+ import { n as mongoStatic, t as MongoStaticContext } from "./mongo-static-D_RcLkSZ-Cxq_NWiQ.mjs";
2
+ import { AnyMongoTypeMaps, MongoContract, MongoContractWithTypeMaps } from "@prisma/orm-family-mongo/contract";
3
+ //#region ../../../3-extensions/mongo/dist/static.d.mts
4
+ //#region src/static/contract-from-json.d.ts
5
+ /**
6
+ * Validates an emitted Mongo `contract.json` and returns it as the contract type the application
7
+ * names, ready to pass to `mongo({ contract })` and `mongoStatic({ contract })`. Clients built from
8
+ * the result do not validate it again.
9
+ *
10
+ * The returned value's top level is frozen; its nested objects are not. Do not change `json` or the
11
+ * returned value after the call: clients built from the value later do not validate it again.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import type { Contract } from './contract.d';
16
+ * import contractJson from './contract.json' with { type: 'json' };
17
+ *
18
+ * export const contract = contractFromJson<Contract>(contractJson);
19
+ * ```
20
+ */
21
+ declare function contractFromJson<TContract extends MongoContractWithTypeMaps<MongoContract, AnyMongoTypeMaps>>(json: unknown): TContract;
22
+ //#endregion
23
+ export { type MongoStaticContext, contractFromJson, mongoStatic as default };
24
+ //# sourceMappingURL=static.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.d.mts","names":[],"sources":["../../../../3-extensions/mongo/dist/static.d.mts"],"mappings":";;;;;;;;;;;;;;;;;;;;iBAmBiB,iBAAiB,kBAAkB,0BAA0B,eAAe,mBAAmB,gBAAgB"}
package/dist/static.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as mongoStatic } from "./mongo-static-UlmsQasy-DBZWYIip.mjs";
2
- export { mongoStatic as default };
1
+ import { n as contractFromJson, r as mongoStatic } from "./mongo-static-Bku9f8Ao-Bf-xeIR_.mjs";
2
+ export { contractFromJson, mongoStatic as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/orm-mongo",
3
- "version": "8.0.0-rc.18-dev.19",
3
+ "version": "8.0.0-rc.18-dev.21",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -10,18 +10,18 @@
10
10
  "skills"
11
11
  ],
12
12
  "dependencies": {
13
- "@prisma/orm-family-mongo": "8.0.0-rc.18-dev.19",
14
- "@prisma/orm-framework": "8.0.0-rc.18-dev.19",
15
- "@prisma/orm-target-mongo": "8.0.0-rc.18-dev.19",
16
- "@prisma/orm-toolchain": "8.0.0-rc.18-dev.19",
13
+ "@prisma/orm-family-mongo": "8.0.0-rc.18-dev.21",
14
+ "@prisma/orm-framework": "8.0.0-rc.18-dev.21",
15
+ "@prisma/orm-target-mongo": "8.0.0-rc.18-dev.21",
16
+ "@prisma/orm-toolchain": "8.0.0-rc.18-dev.21",
17
17
  "mongodb-connection-string-url": "^7.0.1",
18
18
  "pathe": "^2.0.3",
19
19
  "tinyglobby": "^0.2.17"
20
20
  },
21
21
  "devDependencies": {
22
- "@internal/mongo": "8.0.0-rc.18-dev.19",
23
- "@repo/tsconfig": "8.0.0-rc.18-dev.19",
24
- "@repo/tsdown": "8.0.0-rc.18-dev.19",
22
+ "@internal/mongo": "8.0.0-rc.18-dev.21",
23
+ "@repo/tsconfig": "8.0.0-rc.18-dev.21",
24
+ "@repo/tsdown": "8.0.0-rc.18-dev.21",
25
25
  "tsdown": "0.22.14",
26
26
  "typescript": "5.9.3"
27
27
  },
@@ -62,6 +62,7 @@
62
62
  "./contract/resolve-domain-model": "./dist/contract__resolve-domain-model.mjs",
63
63
  "./contract/types": "./dist/contract__types.mjs",
64
64
  "./contract/validate-domain": "./dist/contract__validate-domain.mjs",
65
+ "./contract/validate-once": "./dist/contract__validate-once.mjs",
65
66
  "./contract-builder": "./dist/contract-builder.mjs",
66
67
  "./control": "./dist/control.mjs",
67
68
  "./driver": "./dist/driver.mjs",
@@ -15,7 +15,7 @@ description: >-
15
15
  ORM 7 or earlier (schema.prisma + @prisma/client).
16
16
  metadata:
17
17
  library: '@prisma/orm-mongo'
18
- library_version: '8.0.0-rc.18-dev.19'
18
+ library_version: '8.0.0-rc.18-dev.21'
19
19
  version: '2026-09-12'
20
20
  ---
21
21
 
@@ -63,7 +63,7 @@ Open the reference whose triggers match the task. If more than one matches, open
63
63
  | Migration graph, refs, plan origin | [`references/migration-model.md`](references/migration-model.md) | migration graph, refs, `migration ref set` / `list` / `delete`, the `db` ref, `--advance-ref`, `--no-advance-ref`, `migration plan --from`, `from: (baseline)` in plan output, greenfield / from-scratch plan, baseline, first migration before deploy (Composer / CD-managed databases), chaining migrations, retrofitting migrations onto an existing database, `MIGRATION.HASH_NOT_IN_GRAPH`, `MIGRATION.PATH_UNREACHABLE` at plan/chain time |
64
64
  | Review migrations on deploy | [`references/migration-review.md`](references/migration-review.md) | "what migrations are going to run", "what runs on deploy / merge", merge conflict, diamond convergence, concurrent migrations, migration status, ref management for CI, staging / production environment refs, `MIGRATION.MARKER_NOT_IN_HISTORY`, `MIGRATION.MISSING_INVARIANTS`, `db migrate --show` |
65
65
  | Write queries | [`references/queries.md`](references/queries.md) | query, where, select, project, orderBy, limit, offset, take, skip, include, lookup, first, all, count, aggregate, groupBy, create, update, delete, upsert, returning, transaction, `db.orm`, `db.sql`, `runtime.query(plan)` vs `runtime.execute(plan)`, `db.prepare` / prepared statements, streaming / `for await`, many-to-many `include` and nested `connect`, `and` / `or` / `not` from `@prisma/orm-postgres/orm-client`, `db.query.from(...)` (Mongo pipeline), namespace-aware accessors, `.all()` Thenable, single-use iterators (`RUNTIME.ITERATOR_CONSUMED`), target-declared aggregate types (`count`, integer `sum`, and integer `avg` are `number`; `count` and integer `sum` throw outside ±(2^53 − 1) rather than round, while `avg` is a fraction already and carries no guard; `countBigInt` / `sumBigInt` / `avgDecimal` are the lossless forms, `avgDecimal` on PostgreSQL only), custom collection class (`extends Collection`), `with` and query fragments (`QueryFragment`, `Filtered`, `Ordered`), shared query fragments and scopes (`db.orm.fragment(fields, body)` for a filter on every model with given fields, `CodecField`, `db.orm.public.Post.fragment(...)` for a shared `select` / `include`, `orderByField` for an order or sort parameter from a request), drizzle-style, kysely-style. Naming types (§ *Naming model and result types*): "type of my model", "return type of a query", `ResultType`, `Scalars`, `Shape`, `models` / `Models` namespace in `contract.d.ts`, `Models.public_User`, Prisma 7 `Prisma.User` / `GetPayload` / `UserGetPayload` equivalents. Postgres/SQLite specifics: [`references/queries-postgres.md`](references/queries-postgres.md); Mongo specifics: [`references/queries-mongo.md`](references/queries-mongo.md) |
66
- | Wire the runtime | [`references/runtime.md`](references/runtime.md) | `db.ts`, `postgres<Contract>(...)` / `sqlite<Contract>(...)` / `mongo<Contract>(...)` façades, middleware composition (lints, budgets, cache via `@prisma/orm-extension-middleware-cache`, custom `activityEnded` middleware, `@prisma/orm-postgres/family-runtime`), `DATABASE_URL`, `.env`, connection pool / `poolOptions`, dev vs prod config, transactions, read replicas, multi-database, script won't exit / hangs, `db.close` / `pool.end`, `await using` / `[Symbol.asyncDispose]` |
66
+ | Wire the runtime | [`references/runtime.md`](references/runtime.md) | `db.ts`, `contractFromJson<Contract>(...)`, `postgres({ contract })` / `sqlite({ contract })` / `mongo({ contract })` façades, middleware composition (lints, budgets, cache via `@prisma/orm-extension-middleware-cache`, custom `activityEnded` middleware, `@prisma/orm-postgres/family-runtime`), `DATABASE_URL`, `.env`, connection pool / `poolOptions`, dev vs prod config, transactions, read replicas, multi-database, script won't exit / hangs, `db.close` / `pool.end`, `await using` / `[Symbol.asyncDispose]` |
67
67
  | Build-tool integration | [`references/build.md`](references/build.md) | Vite plugin (`@internal/vite-plugin-contract-emit`, Vite 7/8), `vite.config.ts`, contract emit on save, HMR / dev server, Next.js / Webpack / esbuild / Rollup / Turbopack (named gaps, not fabricated) |
68
68
  | Supabase | [`references/supabase.md`](references/supabase.md) | `@internal/extension-supabase`, RLS, row level security, policies (`policy_select` / `policy_update` / `@@rls`, `auth.uid()`), role binding (`asUser(jwt)` / `asAnon()` / `asServiceRole()`), `auth.users`, cross-space FKs to `supabase:auth.AuthUser`, JWT / JWKS (`SUPABASE_JWKS_URL`, `SUPABASE_JWT_SECRET`), `SUPABASE.JWT_INVALID`, `SUPABASE.CONFIG_INVALID`, `RoleBoundDb`, session pooler |
69
69
  | Debug an error | [`references/debug.md`](references/debug.md) | any structured error envelope (code, severity, why, fix, nextActions, meta), emit failed, query won't typecheck, query crashed, migration won't apply, `MIGRATION.HASH_MISMATCH`, `MIGRATION.RUNNER_FAILED`, `BUDGET.ROWS_EXCEEDED`, `BUDGET.TIME_EXCEEDED`, `RUNTIME.ABORTED`, `RUNTIME.TEMPORAL_UNAVAILABLE`, `PLAN.HASH_MISMATCH`, `CONTRACT.MARKER_MISSING`, `CONFIG.*` / `CLI.*` / `CONTRACT.*` / `MIGRATION.*` / `ORM.*` / `RUNTIME.*` codes, legacy `PN-*` codes, exit code 4 findings, drift, capability missing, planner conflict, EXPLAIN, query log, script won't exit / close connection |
@@ -40,7 +40,7 @@ Both files are **emitted artefacts**. Edit the source; never the JSON or `.d.ts`
40
40
 
41
41
  ## Key Concepts
42
42
 
43
- - **The `@internal/<target>` façade is the only surface user-authored code imports from.** For a Postgres app: `@internal/postgres/config`, `@internal/postgres/contract-builder`, `@internal/postgres/control`, `@internal/postgres/runtime`. Mongo has the same layout (`@internal/mongo/config`, `@internal/mongo/contract-builder`, `@internal/mongo/runtime`). Each extension publishes its own façade — `@internal/extension-pgvector/control`, `@internal/extension-postgis/control`, `@internal/extension-paradedb/control`. **Never reach into `@internal/cli/*`, `@internal/family-*`, `@internal/target-*`, `@internal/adapter-*`, `@internal/driver-*`, or `@internal/sql-contract-*` from user code.** The façade bakes the family / target / adapter / driver wiring in. See *Common Pitfalls* #4.
43
+ - **The `@internal/<target>` façade is the only surface user-authored code imports from.** For a Postgres app: `@internal/postgres/config`, `@internal/postgres/contract-builder`, `@internal/postgres/control`, `@internal/postgres/runtime`, `@internal/postgres/static`. Mongo has the same layout (`@internal/mongo/config`, `@internal/mongo/contract-builder`, `@internal/mongo/runtime`, `@internal/mongo/static`). Each extension publishes its own façade — `@internal/extension-pgvector/control`, `@internal/extension-postgis/control`, `@internal/extension-paradedb/control`. **Never reach into `@internal/cli/*`, `@internal/family-*`, `@internal/target-*`, `@internal/adapter-*`, `@internal/driver-*`, or `@internal/sql-contract-*` from user code.** The façade bakes the family / target / adapter / driver wiring in. See *Common Pitfalls* #4.
44
44
  - **Contract source.** A file the framework reads and lowers to the canonical Contract IR. Two flavours, both first-class:
45
45
  - **`contract.prisma` (PSL)** — schema-flavoured DSL. Canonical for typical apps and brownfield Prisma users. Wired by `contract: './<path>/contract.prisma'` — the target config (`ormConfig`, below) detects the `.prisma` extension and routes through the PSL provider. The first line of every `.prisma` file is `// use prisma-8`; `orm init` and `contract infer` write it, and the language server only serves diagnostics, completion, and formatting on files that carry it (it still recognises the header earlier releases wrote and rewrites it on Format).
46
46
  - **`contract.ts` (TypeScript builder)** — programmatic authoring with `defineContract({...}, ({ field, model, rel, type }) => ({...}))` from `@internal/postgres/contract-builder` (or `@internal/mongo/contract-builder`). Wired by `contract: './<path>/contract.ts'` — the façade detects the `.ts` extension and routes through the TS provider. Use when you need programmatic composition (per-tenant variants, generated fields) or constructs PSL doesn't yet express (e.g. registering a parameterised extension type — see pgvector's contract).
@@ -68,7 +68,7 @@ These symptoms are not structured envelopes — route on the message text and ch
68
68
  | Symptom | Next move |
69
69
  |---|---|
70
70
  | `TypeError: db.end is not a function` | The runtime client does not expose `db.end()` — that's the `node-postgres` pool API (`pool.end()`). The right call is `await db.close()`. See `references/runtime.md` § *Running as a script (teardown)*. |
71
- | Script hangs after queries print / process won't exit | On Postgres the façade-owned `pg.Pool` keeps the event loop alive. Call `await db.close()` before the script returns, or `await using db = postgres<Contract>(...)` at the top of a script module (do NOT put `await using` inside a request handler — block-scoped, would close per-request). See `references/runtime.md` § *Running as a script (teardown)*. |
71
+ | Script hangs after queries print / process won't exit | On Postgres the façade-owned `pg.Pool` keeps the event loop alive. Call `await db.close()` before the script returns, or `await using db = postgres({ contract, ... })` at the top of a script module (do NOT put `await using` inside a request handler — block-scoped, would close per-request). See `references/runtime.md` § *Running as a script (teardown)*. |
72
72
  | `Error('Postgres client is closed')` / `Error('SQLite client is closed')` / `Error('Mongo client is closed')` | The client was closed via `db.close()` (terminal state). Remove the early `close()`, reorder so `close()` runs last after all queries, or construct a new `db` if reconnection is intended. See `references/runtime.md` § *Running as a script (teardown)*. |
73
73
 
74
74
  ## Routing — symptom and code → next move
@@ -114,7 +114,7 @@ The single source of truth: read the envelope, find the row by `code`, follow th
114
114
  | `RUNTIME.ABORTED` (`details.phase` = `encode\|decode\|stream\|beforeEncode\|onRow`) | Runtime, when an `AbortSignal` fires mid-execute | Cancellation, not a bug; surface to the caller. |
115
115
  | `SqlQueryError` (no dotted code) | Raw-SQL paths surfacing a driver error | Inspect `sqlState` + `constraint` + `table` + `column`. Postgres `23505` = unique violation, `23503` = foreign-key violation, etc. Fix the data or the schema. |
116
116
  | TypeScript error mentioning a capability (e.g. `returning()` not on the type, `include` of a many-relation off a many-load) | Authoring-time, before any envelope fires | Capability gates are declared in the **contract** (`capabilities` block, namespaced by target/family), not in `prisma.config.ts`. Route to `references/contract.md` for capability declaration and to `references/queries.md` for which method gates on which capability. Re-emit (`pnpm prisma contract emit`) after enabling. |
117
- | TypeScript error mentioning a missing field/method on `db.orm.<ns>.<Model>` or a stale `Contract` shape | Authoring-time | Re-emit (`pnpm prisma contract emit`); confirm `db.ts` instantiates with `postgres<Contract>(...)` (the single type parameter propagates the contract types). See `references/runtime.md` and `references/contract.md`. |
117
+ | TypeScript error mentioning a missing field/method on `db.orm.<ns>.<Model>` or a stale `Contract` shape | Authoring-time | Re-emit (`pnpm prisma contract emit`); confirm `db.ts` builds its contract with `contractFromJson<Contract>(contractJson)` and passes it to `postgres({ contract })` (the client infers the contract types from it). See `references/runtime.md` and `references/contract.md`. |
118
118
 
119
119
  If the envelope's `code` is not in this table, follow the envelope's `fix` field literally — it's the framework's first-party next move. If `fix` is empty or unhelpful, escalate via `references/feedback.md`.
120
120
 
@@ -263,17 +263,18 @@ MigrationCLI.run(import.meta.url, M);
263
263
 
264
264
  Replace both `placeholder(...)` calls with query-plan closures built from `endContract`. The `check` closure must return a **rowset query whose presence of any row signals "work remains"** — conventionally `<table>.select('id').where(<violation predicate>).limit(1)`. Scalar/aggregate shapes (`count(*)`, `bool_and(...)`) silently break the contract: the runner wraps `check` twice (`EXISTS(...)` for precheck, `NOT EXISTS(...)` for postcheck), and a query that always returns one row makes `EXISTS` always true and `NOT EXISTS` always false.
265
265
 
266
- Build the query builder against `endContract` so the storage hashes line up — using a different contract reference raises `MIGRATION.DATA_TRANSFORM_CONTRACT_MISMATCH`. The cheapest way to get a typed SQL builder over the end contract is the façade itself: `postgres<End>({ contractJson: endContract })` connects lazily, so constructing it inside `migration.ts` opens no connection; its `sql` is the builder and its `contract` is the validated contract to hand to `this.dataTransform`. The filled-in shape is the rendered scaffold above with only the two `placeholder(...)` arrows replaced (the operation list, including the `this.setNotNull({...})` the planner rendered after the transform, stays as rendered):
266
+ Build the query builder against `endContract` so the storage hashes line up — using a different contract reference raises `MIGRATION.DATA_TRANSFORM_CONTRACT_MISMATCH`. The cheapest way to get a typed SQL builder over the end contract is the façade itself: `postgres({ contract: contractFromJson<End>(endContract) })` connects lazily, so constructing it inside `migration.ts` opens no connection; its `sql` is the builder and its `contract` is the validated contract to hand to `this.dataTransform`. The filled-in shape is the rendered scaffold above with only the two `placeholder(...)` arrows replaced (the operation list, including the `this.setNotNull({...})` the planner rendered after the transform, stays as rendered):
267
267
 
268
268
  ```typescript
269
269
  import { col, Migration, MigrationCLI } from '@internal/postgres/migration';
270
270
  import postgres from '@internal/postgres/runtime';
271
+ import { contractFromJson } from '@internal/postgres/static';
271
272
  import type { Contract as End } from '../../snapshots/93f07d1b…c9e1e5a2/contract';
272
273
  import endContract from '../../snapshots/93f07d1b…c9e1e5a2/contract.json' with { type: 'json' };
273
274
  import type { Contract as Start } from '../../snapshots/f62a4154…d07dddc/contract';
274
275
  import startContract from '../../snapshots/f62a4154…d07dddc/contract.json' with { type: 'json' };
275
276
 
276
- const { sql: db, contract } = postgres<End>({ contractJson: endContract });
277
+ const { sql: db, contract } = postgres({ contract: contractFromJson<End>(endContract) });
277
278
 
278
279
  export default class M extends Migration<Start, End> {
279
280
  override readonly startContractJson = startContract;
@@ -6,7 +6,7 @@ Shared concepts (result consumption, script teardown, cross-target pitfalls, cap
6
6
 
7
7
  ## Key Concepts
8
8
 
9
- **Mongo** (`mongo<Contract>(...)` from `@internal/mongo/runtime`):
9
+ **Mongo** (`mongo({ contract, ... })` from `@internal/mongo/runtime`):
10
10
 
11
11
  - **`db.orm.<root>`** — ORM, lowercased plural contract root (`db.orm.users`, `db.orm.posts`). Same fluent chaining; `.where({ field: value })` object equality is the idiomatic filter form.
12
12
  - **`db.query`** — typed aggregation-pipeline builder. Start with `db.query.from('<root>')`, chain `.match(...)` / `.project(...)` / `.group(...)` / `.lookup(...)`, terminal with `.build()`. Run via `(await db.runtime()).query(plan)` for anything that returns documents; `execute(plan)` is only for a write you want an affected count from, and it throws `RUNTIME.MONGO_STATISTICS_UNSUPPORTED` on a find or aggregate.
@@ -6,7 +6,7 @@ Shared concepts (result consumption, script teardown, cross-target pitfalls, cap
6
6
 
7
7
  ## Key Concepts
8
8
 
9
- **Postgres** (`postgres<Contract>(...)` from `@internal/postgres/runtime`):
9
+ **Postgres** (`postgres({ contract, ... })` from `@internal/postgres/runtime`):
10
10
 
11
11
  - **`db.orm.<ns>.<Model>`** — ORM, PascalCase model name (`db.orm.public.User`). Fluent `.where(...).select(...).orderBy(...).all()`, fully typed against `Contract`. Default lane for CRUD with relations.
12
12
  - **`db.sql.<ns>.<table>`** — SQL builder, lowercase storage name (`db.sql.public.user`). Produces a *plan*. A plan that returns rows (`select`, or a write with `.returning(...)`) runs through `db.runtime().query(plan)`; a write with no `RETURNING` runs through `db.runtime().execute(plan)`, which resolves `{ affectedRows }`. Use when the ORM is too high-level — explicit `JOIN`, computed projections, set operations, window functions.
@@ -32,7 +32,7 @@ This skill does **not** cover migrating from another ORM (Drizzle, Prisma 6/7, S
32
32
  - **Contract**: the data model. Authored as `contract.prisma` (PSL, the canonical surface) or `contract.ts` (TypeScript builder). The framework reads it and emits two artefacts: `contract.json` (runtime IR) and `contract.d.ts` (types).
33
33
  - **Target**: the backing store. Today: `postgres` or `mongodb`. Picked at `init` time; baked into the `@internal/<target>` façade the scaffold imports from.
34
34
  - **Authoring mode**: how you write the contract. `psl` (Prisma Schema Language, default) or `typescript` (programmatic builder, optionally paired with the Vite plugin for auto-emit during `vite dev` — see `references/build.md`).
35
- - **Façade packages.** The scaffold installs exactly one façade per target — `@internal/postgres` (or `@internal/mongo`). User code imports from façade subpaths (`@internal/postgres/config`, `@internal/postgres/runtime`, `@internal/postgres/contract-builder`). The façade bakes in the family / target / adapter / driver wiring; never reach past it. See `references/contract.md` for the full list.
35
+ - **Façade packages.** The scaffold installs exactly one façade per target — `@internal/postgres` (or `@internal/mongo`). User code imports from façade subpaths (`@internal/postgres/config`, `@internal/postgres/runtime`, `@internal/postgres/static`, `@internal/postgres/contract-builder`). The façade bakes in the family / target / adapter / driver wiring; never reach past it. See `references/contract.md` for the full list.
36
36
  - **`db.ts`**: the runtime entry point. Lives next to the contract source at `src/prisma/db.ts`. Imports the contract artefacts and exports a `db` value the rest of the app uses.
37
37
  - **Marker**: a row in the `prisma_contract.marker` table (Postgres) or a document in the `_prisma_migrations` collection (Mongo) that records the contract hash per contract space. Lets PN detect drift between contract and live DB. Created by `db init` (greenfield / first-touch orientation) or `db sign` (brownfield).
38
38
 
@@ -27,8 +27,8 @@ This skill covers the **runtime entry point** — `db.ts` — and how to compose
27
27
 
28
28
  ## Key Concepts
29
29
 
30
- - **`db.ts` is the runtime entry point.** Imports the runtime factory from the `@internal/<target>` façade (`@internal/postgres/runtime`, `@internal/sqlite/runtime`, or `@internal/mongo/runtime`), the contract artefacts (`contract.json` + the `Contract` type from `contract.d.ts`), and any middleware. Exports a `db` value the rest of your app imports. On a per-request runtime, `db.ts` imports `postgresServerless` from `@internal/postgres/serverless` instead and exports the serverless client `postgres`; see *Workflow — Serverless and per-request runtimes*.
31
- - **The façade's runtime factory is the only surface user-authored `db.ts` imports from.** Each factory is a *default* export. For Postgres: `import postgres from '@internal/postgres/runtime'`; SQLite: `import sqlite from '@internal/sqlite/runtime'`; Mongo: `import mongo from '@internal/mongo/runtime'`. The factory signature is `<Target><Contract>(options)` — a single type parameter (the `Contract` type from `contract.d.ts`), and one options object.
30
+ - **`db.ts` is the runtime entry point.** Imports the runtime factory from the `@internal/<target>` façade (`@internal/postgres/runtime`, `@internal/sqlite/runtime`, or `@internal/mongo/runtime`), `contractFromJson` from the same façade's `/static` entry point, the contract artefacts (`contract.json` + the `Contract` type from `contract.d.ts`), and any middleware. Exports the typed `contract` and a `db` value the rest of your app imports. On a per-request runtime, `db.ts` imports `postgresServerless` from `@internal/postgres/serverless` instead and exports the serverless client `postgres`; see *Workflow — Serverless and per-request runtimes*.
31
+ - **`db.ts` imports only from the façade's `/runtime` and `/static` entry points.** Each factory is a *default* export. For Postgres: `import postgres from '@internal/postgres/runtime'`; SQLite: `import sqlite from '@internal/sqlite/runtime'`; Mongo: `import mongo from '@internal/mongo/runtime'`. The factory takes one options object and no type argument: it infers the contract type from `contract`. Turn the emitted JSON into a typed value once with `contractFromJson<Contract>(contractJson)` from the façade's `/static` entry point (`@internal/postgres/static`, `@internal/sqlite/static`, `@internal/mongo/static`; Supabase uses the Postgres one). That call is the only place you write the `Contract` type argument. A contract written in TypeScript with `defineContract` is already a typed value and goes to `{ contract }` directly. A contract value is validated once, however many clients use it.
32
32
  - **Lazy connect.** The factory does not connect to the database synchronously. `db.sql` and `db.orm` are available immediately; the driver / pool is instantiated on the first call that needs a runtime (or when you explicitly call `await db.connect({ url })`, which binds the client to that URL), and the pool opens its first database connection on the first query. This is why `db.ts` can be imported in modules that load before the env is ready.
33
33
  - **Middleware composes in order.** Every hook runs in the order of the `middleware: [...]` array — the first middleware's `beforeEncode` sees the statement first, and `intercept.onQuery` handlers are consulted in registration order with the first non-`undefined` result winning. Register a cache first so it gets first claim on a hit. Every middleware's `activityEnded` still fires on a cache hit, with `result.source: 'middleware'`.
34
34
  - **`prisma.config.ts` vs `.env`.** The config (`definePrismaConfig({ orm: ormConfig({ contract, db, extensions, migrations }) })` — see `references/contract.md`) is for static project shape: contract path, installed extensions, migrations directory, default connection string. `.env` is for per-environment values (`DATABASE_URL`, secrets). Nothing reads `.env` on its own: the scaffolded `prisma.config.ts` starts with `import 'dotenv/config'`, and that import is what loads `.env` into `process.env` before the config (and the CLI running it) reads `process.env['DATABASE_URL']`. Keep the import; a config without it sees no `.env` values. Hardcoding `DATABASE_URL` in the config file leaks credentials and bypasses per-env overrides.
@@ -36,18 +36,21 @@ This skill covers the **runtime entry point** — `db.ts` — and how to compose
36
36
 
37
37
  ## Workflow — Basic `db.ts`
38
38
 
39
- The concept: `db.ts` is the seam between the emitted contract artefacts (target-shaped) and the runtime that executes queries against them. Three imports are required — the runtime factory, the `Contract` type (so the static query surfaces are typed), and the JSON artefact (so the runtime validates the structure at construct time).
39
+ The concept: `db.ts` is the seam between the emitted contract artefacts (target-shaped) and the runtime that executes queries against them. Four imports are required — the runtime factory, `contractFromJson` from the façade's `/static` entry point, the `Contract` type (so the static query surfaces are typed), and the JSON artefact (which `contractFromJson` validates once).
40
40
 
41
41
  `init` scaffolds something like this (for `--target postgres`):
42
42
 
43
43
  ```typescript
44
44
  // src/prisma/db.ts
45
45
  import postgres from '@internal/postgres/runtime';
46
+ import { contractFromJson } from '@internal/postgres/static';
46
47
  import type { Contract } from './contract.d';
47
48
  import contractJson from './contract.json' with { type: 'json' };
48
49
 
49
- export const db = postgres<Contract>({
50
- contractJson,
50
+ export const contract = contractFromJson<Contract>(contractJson);
51
+
52
+ export const db = postgres({
53
+ contract,
51
54
  url: process.env['DATABASE_URL']!,
52
55
  });
53
56
  ```
@@ -56,7 +59,7 @@ export const db = postgres<Contract>({
56
59
 
57
60
  Three things to know:
58
61
 
59
- - **`<Contract>` type parameter is required.** Without it, the static surfaces collapse to a generic shape and you lose autocomplete on model names. Always import `Contract` from the emitted `./contract.d.ts`.
62
+ - **Name `Contract` on `contractFromJson`, not on the client.** `contractFromJson<Contract>(contractJson)` is where the JSON gets its type; without the type argument, the static surfaces collapse to a generic shape and you lose autocomplete on model names. Always import `Contract` from the emitted `./contract.d.ts`. The clients take no type argument and no `contractJson` option.
60
63
  - **`with { type: 'json' }` is required.** Node's ESM JSON-import-attribute spec. Without it, the import errors.
61
64
  - **`url` is optional at construct time.** If `DATABASE_URL` is not set when `db.ts` loads, the factory still returns a client; you can call `await db.connect({ url })` later. The factory throws lazily — only when a runtime is actually needed.
62
65
 
@@ -84,10 +87,9 @@ await db.close();
84
87
  ```typescript
85
88
  // src/scripts/hello.ts — top-level await in a script module
86
89
  import postgres from '@internal/postgres/runtime';
87
- import type { Contract } from '../prisma/contract.d';
88
- import contractJson from '../prisma/contract.json' with { type: 'json' };
90
+ import { contract } from '../prisma/db';
89
91
 
90
- await using db = postgres<Contract>({ contractJson, url: process.env.DATABASE_URL! });
92
+ await using db = postgres({ contract, url: process.env.DATABASE_URL! });
91
93
 
92
94
  const user = await db.orm.public.User.first();
93
95
  console.log(user);
@@ -103,7 +105,7 @@ This is the most important rule in this section. `await using db = postgres(...)
103
105
  ```typescript
104
106
  // DO NOT do this — closes the pool after every request.
105
107
  app.get('/users', async (req, res) => {
106
- await using db = postgres<Contract>({ contractJson, url: process.env.DATABASE_URL! });
108
+ await using db = postgres({ contract, url: process.env.DATABASE_URL! });
107
109
  const users = await db.orm.public.User.all();
108
110
  res.json(users);
109
111
  });
@@ -113,7 +115,7 @@ The right server pattern is a **module-level singleton** in `db.ts`, imported by
113
115
 
114
116
  ```typescript
115
117
  // src/prisma/db.ts — constructed once, lives for the process
116
- export const db = postgres<Contract>({ contractJson, url: process.env.DATABASE_URL });
118
+ export const db = postgres({ contract, url: process.env.DATABASE_URL });
117
119
 
118
120
  // src/routes/users.ts
119
121
  import { db } from '../prisma/db';
@@ -142,10 +144,12 @@ The concept: a per-request runtime (Cloudflare Workers + Hyperdrive, AWS Lambda,
142
144
  ```typescript
143
145
  // src/prisma/db.ts — the serverless client: module scope, built once per isolate, holds no database connection
144
146
  import postgresServerless from '@internal/postgres/serverless';
147
+ import { contractFromJson } from '@internal/postgres/static';
145
148
  import type { Contract } from './contract.d';
146
149
  import contractJson from './contract.json' with { type: 'json' };
147
150
 
148
- export const postgres = postgresServerless<Contract>({ contractJson });
151
+ export const contract = contractFromJson<Contract>(contractJson);
152
+ export const postgres = postgresServerless({ contract });
149
153
 
150
154
  // src/worker.ts
151
155
  import { postgres } from './prisma/db';
@@ -215,12 +219,15 @@ Both are exported from the façade's `family-runtime` subpath — `@prisma/orm-p
215
219
 
216
220
  ```typescript
217
221
  import postgres from '@internal/postgres/runtime';
222
+ import { contractFromJson } from '@internal/postgres/static';
218
223
  import { budgets, lints } from '@prisma/orm-postgres/family-runtime';
219
224
  import type { Contract } from './contract.d';
220
225
  import contractJson from './contract.json' with { type: 'json' };
221
226
 
222
- export const db = postgres<Contract>({
223
- contractJson,
227
+ export const contract = contractFromJson<Contract>(contractJson);
228
+
229
+ export const db = postgres({
230
+ contract,
224
231
  url: process.env['DATABASE_URL'],
225
232
  middleware: [
226
233
  lints({
@@ -259,8 +266,8 @@ import {
259
266
  export const cache = createCacheMiddleware({
260
267
  store: createInMemoryCacheStore({ maxEntries: 1_000, ttlMs: 60_000 }),
261
268
  });
262
- export const db = postgres<Contract>({
263
- contractJson,
269
+ export const db = postgres({
270
+ contract,
264
271
  url: process.env['DATABASE_URL']!,
265
272
  middleware: [cache, lints(), budgets({ maxRows: 10_000 })],
266
273
  });
@@ -298,8 +305,8 @@ The concept: the runtime takes one of three binding shapes — `url`, `pg` (a pr
298
305
 
299
306
  ```typescript
300
307
  // Default — URL string, factory constructs the pool.
301
- postgres<Contract>({
302
- contractJson,
308
+ postgres({
309
+ contract,
303
310
  url: process.env['DATABASE_URL'],
304
311
  poolOptions: {
305
312
  connectionTimeoutMillis: 20_000,
@@ -312,7 +319,7 @@ postgres<Contract>({
312
319
  // BYO pool — pass a pg.Pool you already created.
313
320
  import { Pool } from 'pg';
314
321
  const pool = new Pool({ connectionString: process.env['DATABASE_URL'] });
315
- postgres<Contract>({ contractJson, pg: pool });
322
+ postgres({ contract, pg: pool });
316
323
  ```
317
324
 
318
325
  The `url` and `pg` keys are mutually exclusive at the type level; passing both errors.
@@ -326,8 +333,8 @@ The concept: one `DATABASE_URL` per environment; the rest of the `db.ts` shape i
326
333
  ```typescript
327
334
  const isProd = process.env['NODE_ENV'] === 'production';
328
335
 
329
- export const db = postgres<Contract>({
330
- contractJson,
336
+ export const db = postgres({
337
+ contract,
331
338
  url: process.env['DATABASE_URL']!,
332
339
  middleware: isProd
333
340
  ? [slowQueryWarning({ thresholdMs: 250 })]
@@ -363,10 +370,12 @@ After the switch (Mongo):
363
370
  ```typescript
364
371
  // src/prisma/db.ts (Mongo)
365
372
  import mongo from '@internal/mongo/runtime';
373
+ import { contractFromJson } from '@internal/mongo/static';
366
374
  import type { Contract } from './contract.d';
367
375
  import contractJson from './contract.json' with { type: 'json' };
368
376
 
369
- export const db = mongo<Contract>({ contractJson, url: process.env['DATABASE_URL'] });
377
+ export const contract = contractFromJson<Contract>(contractJson);
378
+ export const db = mongo({ contract, url: process.env['DATABASE_URL'] });
370
379
  ```
371
380
 
372
381
  SQLite:
@@ -374,10 +383,12 @@ SQLite:
374
383
  ```typescript
375
384
  // src/prisma/db.ts (SQLite)
376
385
  import sqlite from '@internal/sqlite/runtime';
386
+ import { contractFromJson } from '@internal/sqlite/static';
377
387
  import type { Contract } from './contract.d';
378
388
  import contractJson from './contract.json' with { type: 'json' };
379
389
 
380
- export const db = sqlite<Contract>({ contractJson, path: 'app.db' });
390
+ export const contract = contractFromJson<Contract>(contractJson);
391
+ export const db = sqlite({ contract, path: 'app.db' });
381
392
  ```
382
393
 
383
394
  `path` is optional at construct time (you can call `db.connect({ path })` later); omit it and the façade still returns a client. The SQLite façade exposes the same `db.sql`, `db.orm`, `db.transaction(...)`, `db.close()`, and `[Symbol.asyncDispose]` surfaces as Postgres, with one addressing difference: SQLite has no schemas, so `db.sql` and `db.orm` are the unbound namespace itself (`db.orm.User`, `db.sql.user`) instead of Postgres's `db.orm.public.User` / `db.sql.public.user`. The Mongo façade shares `db.orm`, `db.close()`, and `[Symbol.asyncDispose]` but has no `db.sql` and no `db.transaction(...)`.
@@ -396,13 +407,13 @@ The runtime side (this skill) is the same regardless: `db.ts` reads `contract.js
396
407
  ## Common Pitfalls
397
408
 
398
409
  1. **Hardcoding `DATABASE_URL` in `prisma.config.ts`.** Leaks credentials; bypasses per-environment overrides. Use `.env`.
399
- 2. **Omitting the `<Contract>` type parameter** in `postgres<Contract>(...)`. Without it, static surfaces collapse to a generic shape and you lose autocomplete for models. There is no second type parameter — the older two-param signature (`postgres<Contract, TypeMaps>`) is gone.
410
+ 2. **Writing the type argument on the client, or passing `contractJson`.** `postgres<Contract>({ contractJson })` no longer compiles: the clients take `{ contract }` and infer its type. Write `contractFromJson<Contract>(contractJson)` and pass the result. Omitting `<Contract>` there collapses the static surfaces to a generic shape and you lose autocomplete for models.
400
411
  3. **Forgetting `with { type: 'json' }` on the contract import.** Required by Node's ESM JSON-import-attribute spec.
401
412
  4. **Middleware order matters.** Registration order is hook order; put the cache first so its `intercept.onActivity` and `intercept.onQuery` are consulted first.
402
413
  5. **Importing middleware from a non-existent package or subpath.** There is no `@internal/postgres/middleware` subpath and no `@internal/middleware-telemetry` package. `lints` / `budgets` / `SqlMiddleware` come from `@prisma/orm-postgres/family-runtime`; the cache comes from `@prisma/orm-extension-middleware-cache`; a query log or telemetry hook is a custom `activityEnded` middleware (above).
403
414
  6. **Confabulating lint / budget option names.** Lints take `severities` (with the five keys above), not `requireWhere` / `maxRowsWithoutLimit`. Budgets use `maxLatencyMs` (not `maxDurationMs`) plus `maxRows` / `defaultTableRows` / `tableRows`. When in doubt, read the source.
404
415
  7. **Switching targets without re-emitting.** The contract artefacts are target-shaped; emit after the target change.
405
- 8. **Script hangs after queries finish on Postgres.** The `pg.Pool` keeps Node's event loop alive. Solution: `await db.close()` before the script returns, or `await using db = postgres<Contract>(...)` at the top of a script module. Do not put `await using db = postgres(...)` inside a request handler — it's block-scoped and would close the pool after every request. The right server pattern is a module-level singleton in `db.ts` that lives for the process lifetime. On a per-request runtime, use `postgresServerless()` and `await using db = await postgres.connect({ url })` in the handler instead (see *Workflow — Serverless and per-request runtimes*).
416
+ 8. **Script hangs after queries finish on Postgres.** The `pg.Pool` keeps Node's event loop alive. Solution: `await db.close()` before the script returns, or `await using db = postgres({ contract, ... })` at the top of a script module. Do not put `await using db = postgres(...)` inside a request handler — it's block-scoped and would close the pool after every request. The right server pattern is a module-level singleton in `db.ts` that lives for the process lifetime. On a per-request runtime, use `postgresServerless()` and `await using db = await postgres.connect({ url })` in the handler instead (see *Workflow — Serverless and per-request runtimes*).
406
417
 
407
418
  ## What Prisma 8 doesn't do yet
408
419
 
@@ -417,15 +428,15 @@ This skill is intentionally body-only; `prisma orm init --help`, the target `def
417
428
 
418
429
  ## Checklist
419
430
 
420
- - [ ] `db.ts` imports the runtime factory from `@internal/<target>/runtime` (`postgres`, `sqlite`, or `mongo`) and the `Contract` type from `./contract.d`.
431
+ - [ ] `db.ts` imports the runtime factory from `@internal/<target>/runtime` (`postgres`, `sqlite`, or `mongo`), `contractFromJson` from `@internal/<target>/static`, and the `Contract` type from `./contract.d`.
421
432
  - [ ] `with { type: 'json' }` on the contract JSON import.
422
- - [ ] `<Contract>` is the single type parameter on `postgres<Contract>(...)` (no second parameter).
433
+ - [ ] `Contract` is named once, on `contractFromJson<Contract>(contractJson)`, and the client gets `{ contract }` with no type argument.
423
434
  - [ ] `DATABASE_URL` lives in `.env`, not in `prisma.config.ts`.
424
435
  - [ ] Middleware ordered intentionally (cache first when used).
425
436
  - [ ] `lints` / `budgets` imported from `@prisma/orm-postgres/family-runtime` and using the verified option keys (`severities`, `maxLatencyMs`, `maxRows`, `tableRows`).
426
437
  - [ ] Per-env divergence (if any) gated by `NODE_ENV` or similar.
427
438
  - [ ] Did NOT hardcode credentials in any committed file.
428
- - [ ] Did NOT confabulate a `@internal/postgres/middleware` subpath, a `@internal/middleware-telemetry` package, a `@internal/postgres-extension-audit` package, or a second type parameter on `postgres<...>`.
439
+ - [ ] Did NOT confabulate a `@internal/postgres/middleware` subpath, a `@internal/middleware-telemetry` package, a `@internal/postgres-extension-audit` package, or a type argument or `contractJson` option on `postgres(...)`.
429
440
  - [ ] Did NOT claim `db.transaction(...)` exists on the Mongo façade — only Postgres and SQLite expose it.
430
441
  - [ ] Did NOT confabulate read-replica / multi-DB / extra pool config — pointed at *What Prisma 8 doesn't do yet* and routed to `references/feedback.md`.
431
442
  - [ ] For build-system / dev-server prompts (Vite plugin, Next.js plugin, …) routed to `references/build.md`.
@@ -108,11 +108,14 @@ The concept: instead of the stock `postgres()` factory, a Supabase app builds it
108
108
  ```typescript
109
109
  // src/prisma/db.ts
110
110
  import { supabase } from '@internal/extension-supabase/runtime';
111
+ import { contractFromJson } from '@internal/postgres/static';
111
112
  import type { Contract } from './contract.d';
112
113
  import contractJson from './contract.json' with { type: 'json' };
113
114
 
114
- export const db = await supabase<Contract>({
115
- contractJson,
115
+ export const contract = contractFromJson<Contract>(contractJson);
116
+
117
+ export const db = await supabase({
118
+ contract,
116
119
  url: process.env['DATABASE_URL'], // direct Postgres connection — see pitfalls
117
120
  jwksUrl: process.env['SUPABASE_JWKS_URL'], // https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json
118
121
  // Legacy HS256 projects use jwtSecret: process.env['SUPABASE_JWT_SECRET'] instead — exactly one of the two.
@@ -223,7 +226,7 @@ The concept: the runtime needs a **direct, session-capable** Postgres connection
223
226
  - [ ] `extensions: [supabasePack]` (the `pack` export) in `ormConfig({...})` inside `definePrismaConfig({ orm: ... })`.
224
227
  - [ ] Cross-space FK typed `supabase:auth.AuthUser` with explicit `fields` / `references` (+ `onDelete` if wanted).
225
228
  - [ ] Every policy target model carries `@@rls`; predicates quote camelCase columns and cast for `auth.uid()`.
226
- - [ ] `db.ts` uses `await supabase<Contract>({ contractJson, url, jwksUrl | jwtSecret })` — exactly one JWT key source; `jwksUrl` for current projects, `jwtSecret` only for legacy HS256.
229
+ - [ ] `db.ts` uses `await supabase({ contract, url, jwksUrl | jwtSecret })`, with `contract` from `contractFromJson<Contract>(contractJson)` of `@internal/postgres/static` — exactly one JWT key source; `jwksUrl` for current projects, `jwtSecret` only for legacy HS256.
227
230
  - [ ] Queries go through a `RoleBoundDb` from `asUser` / `asAnon` / `asServiceRole`; `asUser` is awaited.
228
231
  - [ ] `auth.*` / `storage.*` reads go through `asServiceRole().supabase` only, after the one-time narrow grant (`GRANT USAGE ON SCHEMA auth` + `GRANT SELECT` on the tables you read).
229
232
  - [ ] No per-table grants added for your own `public` tables — Supabase default privileges cover them; RLS does the protecting.
@@ -1 +0,0 @@
1
- {"version":3,"file":"mongo-static-CHHCsRvL-DXMjx76B.d.mts","names":[],"sources":["../../../../3-extensions/mongo/dist/mongo-static-CHHCsRvL.d.mts"],"mappings":";;;;;;;;KAOK,aAAa,kBAAkB,0BAA0B,eAAe,qBAAqB,gBAAgB,kBAAkB;UAC1H,mBAAmB,kBAAkB,0BAA0B,eAAe;WAC7E,SAAS,sBAAsB;WAC/B,UAAU;WACV,OAAO,aAAa;WACpB,OAAO,kBAAkB,WAAW;WACpC,KAAK,eAAe;;iBAEd,YAAY,kBAAkB,0BAA0B,eAAe,mBAAmB;WAChG;IACP,mBAAmB"}
@@ -1,37 +0,0 @@
1
- import { MongoContractSerializer } from "@prisma/orm-family-mongo/family/ir";
2
- import { mongoRaw } from "@prisma/orm-family-mongo/orm";
3
- import { buildMongoEnums, createMongoExecutionContext, createMongoExecutionStack } from "@prisma/orm-family-mongo/runtime";
4
- import { blindCast } from "@prisma/orm-framework/utils/casts";
5
- import mongoRuntimeAdapter from "@prisma/orm-target-mongo/adapter/runtime";
6
- import { UNBOUND_NAMESPACE_ID } from "@prisma/orm-framework/components/ir";
7
- import { mongoQuery } from "@prisma/orm-family-mongo/query-builder";
8
- import mongoRuntimeTarget from "@prisma/orm-target-mongo/target/runtime";
9
- import { assertDefined } from "@prisma/orm-framework/utils/assertions";
10
- //#region ../../../3-extensions/mongo/dist/mongo-static-UlmsQasy.mjs
11
- function buildMongoStaticContext(contract) {
12
- const context = createMongoExecutionContext({
13
- contract,
14
- stack: createMongoExecutionStack({
15
- target: mongoRuntimeTarget,
16
- adapter: mongoRuntimeAdapter
17
- })
18
- });
19
- const enumsByNamespace = buildMongoEnums(contract, context.codecs);
20
- const unbound = enumsByNamespace[UNBOUND_NAMESPACE_ID];
21
- assertDefined(unbound, "the unbound namespace always exists on a mongo builder output");
22
- return {
23
- context,
24
- contract,
25
- enums: blindCast(unbound),
26
- enumsByNamespace,
27
- query: mongoQuery({ contractJson: contract }),
28
- raw: mongoRaw({ contract })
29
- };
30
- }
31
- function mongoStatic(options) {
32
- return buildMongoStaticContext(blindCast(new MongoContractSerializer().deserializeContract(options.contractJson)));
33
- }
34
- //#endregion
35
- export { mongoStatic as n, buildMongoStaticContext as t };
36
-
37
- //# sourceMappingURL=mongo-static-UlmsQasy-DBZWYIip.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mongo-static-UlmsQasy-DBZWYIip.mjs","names":[],"sources":["../../../../3-extensions/mongo/dist/mongo-static-UlmsQasy.mjs"],"sourcesContent":["import { MongoContractSerializer } from \"@internal/family-mongo/ir\";\nimport { mongoRaw } from \"@internal/mongo-orm\";\nimport { buildMongoEnums, createMongoExecutionContext, createMongoExecutionStack } from \"@internal/mongo-runtime\";\nimport { blindCast } from \"@internal/utils/casts\";\nimport mongoRuntimeAdapter from \"@internal/adapter-mongo/runtime\";\nimport { UNBOUND_NAMESPACE_ID } from \"@internal/framework-components/ir\";\nimport { mongoQuery } from \"@internal/mongo-query-builder\";\nimport mongoRuntimeTarget from \"@internal/target-mongo/runtime\";\nimport { assertDefined } from \"@internal/utils/assertions\";\n//#region src/static/mongo-static.ts\nfunction buildMongoStaticContext(contract) {\n\tconst context = createMongoExecutionContext({\n\t\tcontract,\n\t\tstack: createMongoExecutionStack({\n\t\t\ttarget: mongoRuntimeTarget,\n\t\t\tadapter: mongoRuntimeAdapter\n\t\t})\n\t});\n\tconst enumsByNamespace = buildMongoEnums(contract, context.codecs);\n\tconst unbound = enumsByNamespace[UNBOUND_NAMESPACE_ID];\n\tassertDefined(unbound, \"the unbound namespace always exists on a mongo builder output\");\n\treturn {\n\t\tcontext,\n\t\tcontract,\n\t\tenums: blindCast(unbound),\n\t\tenumsByNamespace,\n\t\tquery: mongoQuery({ contractJson: contract }),\n\t\traw: mongoRaw({ contract })\n\t};\n}\nfunction mongoStatic(options) {\n\treturn buildMongoStaticContext(blindCast(new MongoContractSerializer().deserializeContract(options.contractJson)));\n}\n//#endregion\nexport { mongoStatic as n, buildMongoStaticContext as t };\n\n//# sourceMappingURL=mongo-static-UlmsQasy.mjs.map"],"mappings":";;;;;;;;;;AAUA,SAAS,wBAAwB,UAAU;CAC1C,MAAM,UAAU,4BAA4B;EAC3C;EACA,OAAO,0BAA0B;GAChC,QAAQ;GACR,SAAS;EACV,CAAC;CACF,CAAC;CACD,MAAM,mBAAmB,gBAAgB,UAAU,QAAQ,MAAM;CACjE,MAAM,UAAU,iBAAiB;CACjC,cAAc,SAAS,+DAA+D;CACtF,OAAO;EACN;EACA;EACA,OAAO,UAAU,OAAO;EACxB;EACA,OAAO,WAAW,EAAE,cAAc,SAAS,CAAC;EAC5C,KAAK,SAAS,EAAE,SAAS,CAAC;CAC3B;AACD;AACA,SAAS,YAAY,SAAS;CAC7B,OAAO,wBAAwB,UAAU,IAAI,wBAAwB,CAAC,CAAC,oBAAoB,QAAQ,YAAY,CAAC,CAAC;AAClH"}