@prisma/orm-mongo 8.0.0-rc.18-dev.38 → 8.0.0-rc.18-dev.40

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.
@@ -8,8 +8,8 @@ import { UNBOUND_NAMESPACE_ID } from "@prisma/orm-framework/components/ir";
8
8
  import { mongoQuery } from "@prisma/orm-family-mongo/query-builder";
9
9
  import { assertDefined } from "@prisma/orm-framework/utils/assertions";
10
10
  import { blindCast } from "@prisma/orm-framework/utils/casts";
11
- //#region ../../../3-extensions/mongo/dist/mongo-static-C5NGF9kL.mjs
12
- var version = "8.0.0-rc.18-dev.38";
11
+ //#region ../../../3-extensions/mongo/dist/mongo-static-BLSBJfkE.mjs
12
+ var version = "8.0.0-rc.18-dev.40";
13
13
  const serializer = new MongoContractSerializer();
14
14
  const validator = `${mongoRuntimeTarget.targetId}@${version}`;
15
15
  /**
@@ -69,4 +69,4 @@ function mongoStatic(options) {
69
69
  //#endregion
70
70
  export { validateMongoContract as i, contractFromJson as n, mongoStatic as r, buildMongoStaticContext as t };
71
71
 
72
- //# sourceMappingURL=mongo-static-C5NGF9kL-BPajKe-F.mjs.map
72
+ //# sourceMappingURL=mongo-static-BLSBJfkE-YKXGJBB1.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mongo-static-C5NGF9kL-BPajKe-F.mjs","names":[],"sources":["../../../../3-extensions/mongo/dist/mongo-static-C5NGF9kL.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.38\";\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-C5NGF9kL.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"}
1
+ {"version":3,"file":"mongo-static-BLSBJfkE-YKXGJBB1.mjs","names":[],"sources":["../../../../3-extensions/mongo/dist/mongo-static-BLSBJfkE.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.40\";\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-BLSBJfkE.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"}
package/dist/runtime.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as validateMongoContract, t as buildMongoStaticContext } from "./mongo-static-C5NGF9kL-BPajKe-F.mjs";
1
+ import { i as validateMongoContract, t as buildMongoStaticContext } from "./mongo-static-BLSBJfkE-YKXGJBB1.mjs";
2
2
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
3
3
  import { mongoOrm } from "@prisma/orm-family-mongo/orm";
4
4
  import { createMongoRuntime } from "@prisma/orm-family-mongo/runtime";
@@ -1 +1 @@
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-C5NGF9kL.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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"}
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-BLSBJfkE.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.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as contractFromJson, r as mongoStatic } from "./mongo-static-C5NGF9kL-BPajKe-F.mjs";
1
+ import { n as contractFromJson, r as mongoStatic } from "./mongo-static-BLSBJfkE-YKXGJBB1.mjs";
2
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.38",
3
+ "version": "8.0.0-rc.18-dev.40",
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.38",
14
- "@prisma/orm-framework": "8.0.0-rc.18-dev.38",
15
- "@prisma/orm-target-mongo": "8.0.0-rc.18-dev.38",
16
- "@prisma/orm-toolchain": "8.0.0-rc.18-dev.38",
13
+ "@prisma/orm-family-mongo": "8.0.0-rc.18-dev.40",
14
+ "@prisma/orm-framework": "8.0.0-rc.18-dev.40",
15
+ "@prisma/orm-target-mongo": "8.0.0-rc.18-dev.40",
16
+ "@prisma/orm-toolchain": "8.0.0-rc.18-dev.40",
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.38",
23
- "@repo/tsconfig": "8.0.0-rc.18-dev.38",
24
- "@repo/tsdown": "8.0.0-rc.18-dev.38",
22
+ "@internal/mongo": "8.0.0-rc.18-dev.40",
23
+ "@repo/tsconfig": "8.0.0-rc.18-dev.40",
24
+ "@repo/tsdown": "8.0.0-rc.18-dev.40",
25
25
  "tsdown": "0.22.14",
26
26
  "typescript": "5.9.3"
27
27
  },
@@ -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.38'
18
+ library_version: '8.0.0-rc.18-dev.40'
19
19
  version: '2026-09-12'
20
20
  ---
21
21
 
@@ -101,7 +101,7 @@ The single source of truth: read the envelope, find the row by `code`, follow th
101
101
  | `CLI.CONSENT_UNUSED` | `migration plan` / `db update` | Every question was answered, and a `--delete` or `--allow` was left over: a typo, a subject the plan does not touch, or a `--confirm` (which consents to nothing). Fix or drop the flag. A typo next to a question nobody answered is reported as `CLI.CONSENT_REQUIRED` instead, which names the flag that matched nothing. On `db update --dry-run` the same mistake is `MIGRATION.STATEMENT_ANSWERS_NO_QUESTION`. |
102
102
  | `MIGRATION.STATEMENT_DID_NOT_RESOLVE_LOSS` | A rename typed at the data-loss prompt | The rename still loses the subject's data. Answer with `delete`, or give a rename whose old name is the subject. |
103
103
  | `MIGRATION.NO_INVARIANT_PATH` / `MIGRATION.UNKNOWN_INVARIANT` | `db migrate` | Concurrent-migration and invariant flows — `references/migration-review.md`. |
104
- | `DRIVER.NOT_CONNECTED` with message `Runtime is closed` | A query, prepared statement or `db.runtime().connection()` that starts after `db.close()` and after the runtime was idle for one turn of the event loop, or after the `await using` scope that held a serverless connection ended | The work started after the runtime closed. Almost always it is a lazy read (`db.orm...all()`, `db.runtime().query(...)`) returned without `await`, which starts only when the caller awaits it, or work that waited on something other than the database first. Write `return await ...`, or move the call before `close()`. See `references/runtime.md` § *Workflow — Serverless and per-request runtimes*. |
104
+ | `DRIVER.NOT_CONNECTED` with message `Runtime is closed` | A query, prepared statement or `db.runtime().connection()` that starts after `db.close()` and after the runtime was idle for one turn of the event loop, or after the `await using` scope that held a serverless connection ended | The work started after the runtime closed. Almost always it is a lazy read (`db.orm...all()`, `db.query(...)`) returned without `await`, which starts only when the caller awaits it, or work that waited on something other than the database first. Write `return await ...`, or move the call before `close()`. See `references/runtime.md` § *Workflow — Serverless and per-request runtimes*. |
105
105
  | `await db.close()` or the end of an `await using` scope never settles in a test | A test that installed fake timers (`vi.useFakeTimers()`, Jest's modern fake timers) before the Prisma runtime module was imported | `close()` waits one turn of the event loop through a `setTimeout(0)` that the runtime module takes when it loads. Install fake timers after the imports, or advance the fake clock (`await vi.runAllTimersAsync()`) before awaiting the close. |
106
106
  | `MIGRATION.PATH_UNREACHABLE` / `MIGRATION.MARKER_MISMATCH` | `db migrate`; `db migrate --show` raises `MARKER_MISMATCH` too | For `PATH_UNREACHABLE`, run `db migrate --show --db $URL` to inspect the path. Then run `migration plan --from <from> --to <target>`, or `migration list` to audit the graph — see `references/migration-review.md`. |
107
107
  | `MIGRATION.PLAN_ORIGIN_UNKNOWN` / `MIGRATION.HASH_NOT_IN_GRAPH` / `MIGRATION.SNAPSHOT_MISSING` | `migration plan`, `migration new` | Origin resolution — `references/migration-model.md` § *The trap* and `references/migrations.md` § *Dev → ship transition*. |
@@ -9,7 +9,7 @@ Shared concepts (result consumption, script teardown, cross-target pitfalls, cap
9
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
- - **`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.
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.query(plan)`; a write with no `RETURNING` runs through `db.execute(plan)`, which resolves `{ affectedRows }`. Use when the ORM is too high-level — explicit `JOIN`, computed projections, set operations, window functions.
13
13
 
14
14
  Reach for the ORM first; drop to `db.sql` when the ORM can't express the shape. Lane choice is local — one query function picks one lane, not the whole app.
15
15
 
@@ -539,7 +539,7 @@ If `?? 0` is showing up on every aggregate, that's a signal you're calling `sum`
539
539
 
540
540
  ## Workflow — SQL builder (`db.sql.<ns>.<table>`)
541
541
 
542
- The concept: `db.sql.<ns>.<table>` is a table-shaped builder that produces a *plan*. The plan is a serialisable description of the query (AST + parameters); you run it through the runtime. Pick the runtime method by the result the plan declares: `db.runtime().query(plan)` for rows (it returns the same `AsyncIterableResult` as `.all()`, so `await` it for an array), `db.runtime().execute(plan)` for a write with no `RETURNING` (it resolves `{ affectedRows }` and returns no rows). The builder gives you the lanes the ORM doesn't express — explicit `JOIN`, arbitrary expression projection, target-specific operations through extension helpers — without dropping to raw SQL.
542
+ The concept: `db.sql.<ns>.<table>` is a table-shaped builder that produces a *plan*. The plan is a serialisable description of the query (AST + parameters); you run it through the client. Pick the method by the result the plan declares: `db.query(plan)` for rows (it returns the same `AsyncIterableResult` as `.all()`, so `await` it for an array), `db.execute(plan)` for a write with no `RETURNING` (it resolves `{ affectedRows }` and returns no rows). The builder gives you the lanes the ORM doesn't express — explicit `JOIN`, arbitrary expression projection, target-specific operations through extension helpers — without dropping to raw SQL.
543
543
 
544
544
  ```typescript
545
545
  // src/queries/posts.ts — adjust the relative import to match file depth.
@@ -552,7 +552,7 @@ const plan = db.sql.public.post
552
552
  .limit(limit)
553
553
  .build();
554
554
 
555
- const rows = await db.runtime().query(plan);
555
+ const rows = await db.query(plan);
556
556
  ```
557
557
 
558
558
  The `.where(...)` callback receives `(fields, fns)` — `fields` is the field proxy (column references), `fns` is the operator namespace (`fns.eq`, `fns.ne`, `fns.gt`, …). Extensions inject extension-shaped helpers into the same `fns` namespace (`fns.distanceSphere`, `fns.cosineDistance`, etc.).
@@ -565,7 +565,7 @@ const plan = db.sql.public.user
565
565
  .insert([{ email }])
566
566
  .returning('id', 'email')
567
567
  .build();
568
- const [row] = await db.runtime().query(plan);
568
+ const [row] = await db.query(plan);
569
569
 
570
570
  // Update with predicate and returning.
571
571
  const updatePlan = db.sql.public.user
@@ -573,14 +573,14 @@ const updatePlan = db.sql.public.user
573
573
  .where((f, fns) => fns.eq(f.id, userId))
574
574
  .returning('id', 'email')
575
575
  .build();
576
- const rows = await db.runtime().query(updatePlan);
576
+ const rows = await db.query(updatePlan);
577
577
 
578
578
  // Delete with predicate, no RETURNING — `execute` resolves the affected count.
579
579
  const deletePlan = db.sql.public.user
580
580
  .delete()
581
581
  .where((f, fns) => fns.eq(f.id, userId))
582
582
  .build();
583
- const { affectedRows } = await db.runtime().execute(deletePlan);
583
+ const { affectedRows } = await db.execute(deletePlan);
584
584
  ```
585
585
 
586
586
  `.returning(...)` requires the target adapter to advertise the `returning` capability. The Postgres adapter advertises it by default.
@@ -596,7 +596,7 @@ const plan = db.sql.public.cafe
596
596
  .orderBy((f) => f.id, { direction: 'asc' })
597
597
  .limit(limit)
598
598
  .build();
599
- const rows = await db.runtime().query(plan);
599
+ const rows = await db.query(plan);
600
600
 
601
601
  // Self-join with an alias.
602
602
  db.sql.public.post
@@ -609,7 +609,7 @@ The SQL builder's `.orderBy(column, { direction, nulls })` takes the same null p
609
609
 
610
610
  ## Workflow — Transactions
611
611
 
612
- The concept: `db.transaction(fn)` opens a transaction and passes a `tx` context to the callback. `tx` offers the client's query members with the same types, and each runs inside the transaction: `sql`, `orm` (with the client's custom collection classes), `raw`, `prepare`, `query(plan)` (rows) and `execute(plan)` (affected count), plus `enums` and `nativeEnums`. A prepared statement runs on what it is given, so `ps.query(tx, params)` runs inside the transaction. See *Workflow — Transactions* in `references/runtime.md` for raw SQL and `tx.prepare`. The transaction commits on the callback's successful return and rolls back on any thrown error.
612
+ The concept: `db.transaction(fn)` opens a transaction and passes a `tx` context to the callback. `tx` offers the client's query members with the same types, and each runs inside the transaction: `sql`, `orm` (with the client's custom collection classes), `raw`, `prepare`, `query(plan)` (rows) and `execute(plan)` (affected count), plus `toSql`, `enums` and `nativeEnums`. A prepared statement runs on what it is given, so `ps.query(tx, params)` runs inside the transaction. See *Workflow — Transactions* in `references/runtime.md` for raw SQL and `tx.prepare`. The transaction commits on the callback's successful return and rolls back on any thrown error.
613
613
 
614
614
  ```typescript
615
615
  await db.transaction(async (tx) => {
@@ -658,7 +658,7 @@ On Postgres both `db.sql` and `db.orm` are keyed by storage namespace (the Postg
658
658
  // db.sql.<namespace>.<table>
659
659
  const plan = db.sql.public.user.select('id', 'email').build();
660
660
  const authPlan = db.sql.auth.users.select('id', 'token').build();
661
- const rows = await db.runtime().query(plan);
661
+ const rows = await db.query(plan);
662
662
 
663
663
  // db.orm.<namespace>.<Model>
664
664
  const user = await db.orm.public.User.create({ id: 1, email: 'a@x.io' });
@@ -677,10 +677,10 @@ Cross-namespace relations (e.g. `public.Profile` → `auth.User`) follow the sam
677
677
  4. **Reaching for `.between(a, b)` on a field proxy.** It doesn't exist. Either chain `.where((m) => m.field.gte(a)).where((m) => m.field.lte(b))` or use `and(m.field.gte(a), m.field.lte(b))` inside one `.where()` clause.
678
678
  5. **Importing `and` / `or` / `not` from an internal package.** They are exported from `@prisma/orm-postgres/orm-client`; do not reach into `@internal/sql-orm-client`.
679
679
  6. **Trying to `db.sql.from(tables.user)`.** That surface does not exist. The builder is table-shaped: `db.sql.<ns>.<tableName>.select(...)`. There is no `db.schema.tables` either.
680
- 7. **Trying to `db.execute(plan)` directly, or reading rows with `execute`.** Plans run through the runtime: `db.runtime().query(plan)` for rows, `db.runtime().execute(plan)` for a non-returning write (`{ affectedRows }`). Inside a transaction, `tx.query(plan)` / `tx.execute(plan)`. `execute` never yields rows — a `select` or `.returning(...)` plan passed to it gives you statistics, not data.
680
+ 7. **Reading rows with `execute`.** Plans run through the client: `db.query(plan)` for rows, `db.execute(plan)` for a non-returning write (`{ affectedRows }`). Inside a transaction, `tx.query(plan)` / `tx.execute(plan)`. `execute` never yields rows — a `select` or `.returning(...)` plan passed to it gives you statistics, not data.
681
681
  8. **Setting `capabilities: { lateral: true }` in `prisma.config.ts`.** The ORM config (`ormConfig({...})`) does not take `capabilities`. Capabilities are declared by the active adapter and become part of the emitted contract; the Postgres adapter advertises `lateral`, `jsonAgg`, and `returning` out of the box. Enable extension capabilities through `extensions: [...]` in the config (see `references/contract.md`).
682
682
  9. **Confabulating a TypedSQL or `.stream()` surface.** Neither exists. Raw SQL does: the client's raw lane, ``db.raw.sql`…` ``. Reusable statements do: `db.prepare(...)` (see *Prepared statements* in [`queries.md`](./queries.md)). Streaming: `for await` over a read terminal or `runtime.query(plan)` — with the caveats in *Streaming* in [`queries.md`](./queries.md).
683
- 10. **Mixing the ORM mutation return with `runtime.query(plan)` / `runtime.execute(plan)`.** ORM terminals issue the query themselves and return rows. The runtime methods are for SQL-builder plans.
683
+ 10. **Mixing the ORM mutation return with `db.query(plan)` / `db.execute(plan)`.** ORM terminals issue the query themselves and return rows. `query` and `execute` are for plans.
684
684
  11. **Adding a `cursor()` to a relation, count, operation or `nulls` order.** It throws `ORM.ARGUMENT_INVALID`. Use `.limit(n).offset(n)`, or order by plain columns.
685
685
  12. **Ordering grouped rows by an aggregate metric.** The grouped collection supports `.orderBy(...)` on group keys plus `.limit(...)` / `.offset(...)`, but it cannot order by an aggregate alias such as `SUM(amount)`. Sorting the materialized aggregate result in JS is fine at small cardinalities; for large grouped result sets, drop to `db.sql.<ns>.<table>`.
686
686
  13. **Locking a parent row with `forUpdate()` while other transactions write rows that reference it.** Every insert or update of a row with a foreign key to the locked row takes `FOR KEY SHARE` on it to check the key, and `FOR KEY SHARE` conflicts with `FOR UPDATE`, so those writes wait and can deadlock. Use `forNoKeyUpdate()`: it still blocks writes to the row, but not the foreign-key check.
@@ -702,7 +702,7 @@ Cross-namespace relations (e.g. `public.Profile` → `auth.User`) follow the sam
702
702
  - [ ] For cursor pagination, used `.orderBy(...).cursor({ field: lastValue }).limit(n).all()` — did NOT hand-write a `.where(p => p.field.lt(cursor))` workaround when the `.cursor()` API serves the same purpose.
703
703
  - [ ] For ORM combinators, imported `and` / `or` / `not` from `@prisma/orm-postgres/orm-client`.
704
704
  - [ ] Wrote a query piece shared between places as a function: a query fragment from `db.orm.fragment(fields, body)` or `collection.fragment(body)` run with `.with(...)`, a `where` callback typed with `CodecField`, or `orderByField` for an order parameter from a request.
705
- - [ ] Ran SQL-builder plans via `db.runtime().query(plan)` when they return rows and `db.runtime().execute(plan)` only for non-returning writes (`tx.query` / `tx.execute` inside a transaction). Passed `insert()` an array of rows.
705
+ - [ ] Ran SQL-builder plans via `db.query(plan)` when they return rows and `db.execute(plan)` only for non-returning writes (`tx.query` / `tx.execute` inside a transaction). Passed `insert()` an array of rows.
706
706
  - [ ] Wrapped multi-statement work in `db.transaction(async (tx) => { ... })` where atomicity matters.
707
707
  - [ ] For top-N grouped aggregates at meaningful scale, dropped to `db.sql.<ns>.<table>` rather than JS-side sort + slice over `groupBy(...).aggregate(...)`.
708
708
  - [ ] Did NOT confabulate TypedSQL, `.stream()`, `db.batch`, `.between(...)`, a collection-level `.count()`, a `capabilities` field on the config, or a `db.sql.from(tables.user)` API — routed to *What Prisma 8 doesn't do yet* / `references/feedback.md` instead. Raw SQL is spelled `db.raw.sql`, not `db.sql.raw`.
@@ -125,12 +125,25 @@ console.log('Seeded.');
125
125
  await db.close();
126
126
  ```
127
127
 
128
+ ## Running a plan and printing its SQL (SQL targets)
129
+
130
+ A plan from `db.sql`, `db.raw` or the ORM (`.prepared.all().plan`) runs on the client: `db.query(plan)` returns its rows as an `AsyncIterableResult`, and `db.execute(plan)` resolves `{ affectedRows }` with no rows. Inside a transaction use `tx.query` / `tx.execute`; they have the same types. On Supabase, call them on a role-bound client (`db.asAnon()`, `await db.asUser(jwt)`). `db.query` on an ORM plan yields the database rows, not the result the ORM builds from them. To run a plan, use `db.query` and `db.execute`, not `db.runtime()`. `db.runtime()` remains for runtime-level work: `connection()`, `close()`, `telemetry()`, and as the target of a prepared statement (`ps.query(db.runtime(), params)`).
131
+
132
+ `db.toSql(plan)` returns `{ sql, params }` and needs no database, so a script can import `db.ts` with no `DATABASE_URL` set and print what a query would send. `params` are the plan's values before codecs encode them for the driver. Middleware rewrites (`beforeCompile`) are not applied. A plan with `prepare` bind sites throws `RUNTIME.PREPARE_BIND_ON_ADHOC`. `postgresStatic()` and `sqliteStatic()` have `toSql` too.
133
+
134
+ ```typescript
135
+ import { db } from '../src/prisma/db';
136
+
137
+ const plan = db.orm.public.Post.where({ published: true }).prepared.all().plan;
138
+ console.log(db.toSql(plan));
139
+ ```
140
+
128
141
  ## Streaming
129
142
 
130
- Every read terminal (`.all()`, and `runtime.query(plan)` for a SQL-builder plan) returns an `AsyncIterableResult`, so `for await` is always available. What it buys you depends on the `cursor` option, which `postgres()` and `postgresServerless()` (`@prisma/orm-postgres/serverless`) both accept:
143
+ Every read terminal (`.all()`, and `db.query(plan)` for a SQL-builder plan) returns an `AsyncIterableResult`, so `for await` is always available. What it buys you depends on the `cursor` option, which `postgres()` and `postgresServerless()` (`@prisma/orm-postgres/serverless`) both accept:
131
144
 
132
145
  - **Default (cursors off), on a client and on a connection:** the full result set is fetched from the server before the first row is yielded; only *decoding* happens per row. `for await` therefore does not bound the memory held by the raw result. For very large sets, paginate (`.limit()` / `.offset()`, or `.orderBy(...).cursor(...)`) instead.
133
- - **`cursor` set in the options of `postgres()` or `postgresServerless()` (`{ batchSize: 100 }`; `{}` or `{ batchSize: undefined }` for batches of 100; a `batchSize` that is not a positive integer fails the factory call; there is no flag that turns cursors off):** the driver reads through a server-side cursor in batches of that size, so `for await` over `db.orm...all()` or `db.runtime().query(plan)` really does stream, and an early `break` stops reading. In a Worker, put the option only on a second serverless client that the streaming paths open their connections from, and keep the serverless client every other path uses without it. On a connection with cursors on, finish or `break` the `for await` loop before sending another query through `db`: the cursor holds the connection's only database connection until the loop ends, so a query inside the loop waits forever. On a client, the same query takes another database connection from the pool. Behind Cloudflare Hyperdrive, reads with cursors on hang, so the streaming paths hang there and the other paths do not.
146
+ - **`cursor` set in the options of `postgres()` or `postgresServerless()` (`{ batchSize: 100 }`; `{}` or `{ batchSize: undefined }` for batches of 100; a `batchSize` that is not a positive integer fails the factory call; there is no flag that turns cursors off):** the driver reads through a server-side cursor in batches of that size, so `for await` over `db.orm...all()` or `db.query(plan)` really does stream, and an early `break` stops reading. In a Worker, put the option only on a second serverless client that the streaming paths open their connections from, and keep the serverless client every other path uses without it. On a connection with cursors on, finish or `break` the `for await` loop before sending another query through `db`: the cursor holds the connection's only database connection until the loop ends, so a query inside the loop waits forever. On a client, the same query takes another database connection from the pool. Behind Cloudflare Hyperdrive, reads with cursors on hang, so the streaming paths hang there and the other paths do not.
134
147
 
135
148
  There is no `.stream()` method on a client or on a connection.
136
149
 
@@ -214,7 +227,7 @@ Target-specific pitfalls live in the per-target guides.
214
227
  - **Many-to-many relations work through the junction.** `.include('tags', (tag) => tag.select(...))` traverses an N:M relation's `through` table, and nested `create` / `connect` / `disconnect` on an N:M relation write the junction rows for you (`examples/prisma-8-demo/src/orm-client/get-post-tags.ts`, `create-post-with-tags.ts`). The one refusal: a junction with required payload columns the relation API cannot populate throws `ORM.RELATION_MUTATION_UNSUPPORTED` — write that junction directly or use the SQL builder.
215
228
  - **Ordering grouped aggregates by an aggregate alias (Postgres).** `db.orm.<ns>.<Model>.groupBy(...)` supports `.orderBy(...)` on group keys plus `.limit(...)` / `.offset(...)`, but the grouped collection cannot order by an aggregate alias such as `SUM(amount)`. A "top-N groups by SUM" query therefore falls back to JS-side sort + slice over the full grouped result, which is fine at small cardinalities and bad at scale. Workarounds: (a) drop to `db.sql.<ns>.<table>` and write the `GROUP BY` + `ORDER BY` + `LIMIT` against the aggregated table directly; (b) live with the JS-side sort/slice if the grouped cardinality is bounded. File a feature request via `references/feedback.md` if this is hitting you in production.
216
229
  - **A raw-SQL lane.** This one exists. Write whole-query raw SQL through the client's raw lane: ``db.raw.sql`SELECT ...`.returnsRow({ ... }).build()`` for rows, or `.affectedCount()` for a mutation's row count. Each declared column names the codec that decodes it, so the row stays typed. For an expression fragment inside a builder query, use `fns.raw` in a `.select(...)` callback instead.
217
- - **TypedSQL (`.sql` files compiled into typed callables).** Not implemented. For a repeated query, use `db.prepare(...)` (see *Prepared statements* above) or a function that returns the built plan and `db.runtime().query(plan)` at the call site. If you want a `.sql`-file compile path, file a feature request via `references/feedback.md`.
230
+ - **TypedSQL (`.sql` files compiled into typed callables).** Not implemented. For a repeated query, use `db.prepare(...)` (see *Prepared statements* above) or a function that returns the built plan and `db.query(plan)` at the call site. If you want a `.sql`-file compile path, file a feature request via `references/feedback.md`.
218
231
  - **`EXPLAIN` / query-plan inspection.** Prisma 8 does not expose an `.explain()` method. Workaround: connect a `pg.Pool` you control via the runtime's `pg:` binding (see `references/runtime.md`) and issue `EXPLAIN ANALYZE` through it. If you want a first-class plan-inspection surface, file a feature request via `references/feedback.md`.
219
232
  - **Multi-statement batching (Prisma-7-style `db.$transaction([call1, call2])`).** Prisma 8 runs each call sequentially. Workaround: wrap atomically-related work in `db.transaction(async (tx) => { ... })` on Postgres. If you want batch-as-array semantics, file a feature request via `references/feedback.md`.
220
233
  - **Mongo façade transactions.** `@internal/mongo/runtime` does not expose `db.transaction(...)`. Multi-document atomicity is not yet wrapped in the Prisma 8 Mongo façade. Workaround: use the MongoDB driver's session API directly if you control the client binding (`mongoClient:` option). File a feature request via `references/feedback.md` if you need a first-class façade surface.
@@ -132,7 +132,7 @@ Servers (HTTP handlers, workers in a request loop) **do not call `db.close()`**
132
132
 
133
133
  - **`close()` is idempotent.** Calling it twice is a no-op.
134
134
  - **`close()` is terminal.** There is no reconnect on a closed `db` — construct a new client if you need to reach the database again. After close, `db.runtime()`, `db.connect(...)`, `db.transaction(...)`, and `db.prepare(...)` reject with `Error('<target> client is closed')` (e.g. `'Postgres client is closed'`, `'SQLite client is closed'`, `'Mongo client is closed'`).
135
- - **`close()` waits for work already running and refuses new work.** On a Postgres client built from `{ url }`, `close()` refuses every new call at once with `DRIVER.NOT_CONNECTED` ("Postgres client is closed"), and a runtime captured with `db.runtime()` before `close()` is refused at once with "Runtime is closed"; it waits for the queries, transactions and ORM calls already in flight, then ends the pool. An ORM call that resolves to one value, such as `first()`, `create()` or a nested create with its reload, starts when it is called, so `close()` waits for it and it completes. On a serverless connection, `close()` waits until the runtime has been idle for one turn of the event loop, so a chain of queries that keeps it busy from the close onward completes, then ends the `pg.Client`; work that starts after that rejects with `DRIVER.NOT_CONNECTED` ("Runtime is closed"). A lazy result such as `db.orm...all()` or `db.runtime().query(plan)` starts when it is awaited or iterated, not when it is built; awaited after `close()`, an ORM `all()` is refused with "Postgres client is closed". A Postgres client given a caller's `pg.Pool` or `pg.Client` does not close its runtime, so work through a runtime taken before `close()` keeps running on the caller's pool. `await` outstanding work before calling `close()`.
135
+ - **`close()` waits for work already running and refuses new work.** On a Postgres client built from `{ url }`, `close()` refuses every new call at once with `DRIVER.NOT_CONNECTED` ("Postgres client is closed"), and a runtime captured with `db.runtime()` before `close()` is refused at once with "Runtime is closed"; it waits for the queries, transactions and ORM calls already in flight, then ends the pool. An ORM call that resolves to one value, such as `first()`, `create()` or a nested create with its reload, starts when it is called, so `close()` waits for it and it completes. On a serverless connection, `close()` waits until the runtime has been idle for one turn of the event loop, so a chain of queries that keeps it busy from the close onward completes, then ends the `pg.Client`; work that starts after that rejects with `DRIVER.NOT_CONNECTED` ("Runtime is closed"). A lazy result such as `db.orm...all()` or `db.query(plan)` starts when it is awaited or iterated, not when it is built; awaited after `close()`, an ORM `all()` is refused with "Postgres client is closed". A Postgres client given a caller's `pg.Pool` or `pg.Client` does not close its runtime, so work through a runtime taken before `close()` keeps running on the caller's pool. `await` outstanding work before calling `close()`.
136
136
  - **Ownership.** `close()` releases only what the façade constructed (`pg.Pool` from `{ url }`, `MongoClient` from `{ url }` / `{ uri, dbName }`, SQLite handle from `{ path }`). If you supplied your own `pg.Pool` / `pg.Client` (Postgres `pg:` option), `mongodb.MongoClient` (Mongo `mongoClient:` option), or a pre-built `binding`, `db.close()` does **not** touch those — you own their lifecycle.
137
137
 
138
138
  **`db.end()` does not exist.** The universal `node-postgres` name is `pool.end()` on a `pg.Pool`; the Prisma 8 runtime client is not a `pg.Pool`. The right call is `await db.close()`.
@@ -163,13 +163,13 @@ export default {
163
163
  };
164
164
  ```
165
165
 
166
- The rule to remember: inside a request, `db` does everything the `db` from `postgres()` does, so any documented `db.orm...`, `db.sql...`, `db.raw...`, `db.transaction(...)`, `db.prepare(...)` or `db.runtime().query(...)` snippet works unchanged. Await every query before the `await using` scope ends. The connection's `close()` waits until the runtime has been idle for one turn of the event loop (a `setTimeout(0)`), then refuses new work. A lazy ORM read such as `db.orm.public.User.all()`, or `db.runtime().query(plan)`, returned from the scope without `await` starts only when the caller awaits it, after the scope has closed, so it rejects with `DRIVER.NOT_CONNECTED` ("Runtime is closed"), whose `fix` names the missing `await`. Work that keeps the runtime busy from the close onward completes: a `first()`, `execute()` or `transaction()`, an ORM write and its reload, including `include(...).create()` and a nested `create()`, and an async helper whose steps go through `db.orm`, `db.transaction()` or `db.prepare()`; a transaction commits. Such work is never refused because of the close; if it fails for its own reason, it rejects like any unawaited promise. A helper that calls `db.runtime()` after the scope has ended throws "Postgres connection is closed" at that call. Work that starts after the runtime was idle for a turn is refused. Whether a query sent after waiting on something other than the database counts as idle depends on when that callback runs relative to the timer, so do not rely on it. An unawaited promise that fails then, or fails for its own reason, rejects like any unawaited promise, and Node reports it as unhandled. Write `return await db.orm...`, not `return db.orm...`.
166
+ The rule to remember: inside a request, `db` does everything the `db` from `postgres()` does, so any documented `db.orm...`, `db.sql...`, `db.raw...`, `db.transaction(...)`, `db.prepare(...)` or `db.query(...)` snippet works unchanged. Await every query before the `await using` scope ends. The connection's `close()` waits until the runtime has been idle for one turn of the event loop (a `setTimeout(0)`), then refuses new work. A lazy ORM read such as `db.orm.public.User.all()`, or `db.query(plan)`, returned from the scope without `await` starts only when the caller awaits it, after the scope has closed, so it rejects with `DRIVER.NOT_CONNECTED` ("Runtime is closed"), whose `fix` names the missing `await`. Work that keeps the runtime busy from the close onward completes: a `first()`, `execute()` or `transaction()`, an ORM write and its reload, including `include(...).create()` and a nested `create()`, and an async helper whose steps go through `db.orm`, `db.transaction()` or `db.prepare()`; a transaction commits. Such work is never refused because of the close; if it fails for its own reason, it rejects like any unawaited promise. A helper that calls `db.runtime()` after the scope has ended throws "Postgres connection is closed" at that call. Work that starts after the runtime was idle for a turn is refused. Whether a query sent after waiting on something other than the database counts as idle depends on when that callback runs relative to the timer, so do not rely on it. An unawaited promise that fails then, or fails for its own reason, rejects like any unawaited promise, and Node reports it as unhandled. Write `return await db.orm...`, not `return db.orm...`.
167
167
 
168
168
  - **`connect` connects before it returns.** When the database refuses the connection, rejects the credentials, or does not answer within 20 seconds, `postgres.connect({ url })` rejects with `DRIVER.CONNECTION_FAILED` and leaves nothing open; an empty URL, a string that is not a URL, or a scheme other than `postgres://` or `postgresql://` rejects with `RUNTIME.BINDING_INVALID`. Handle an unreachable database at the `connect` call, not at the first query. Answer a request that needs no query, such as an unknown route, before `connect`, because `connect` opens a database connection whether or not a query follows.
169
169
  - **Never call `connect` at module scope.** A connection opened there is shared by every request in the isolate, and fails in four ways: its database connection goes stale after the isolate idles, concurrent requests queue behind each other on one `pg.Client`, nothing closes it when a request ends, and Cloudflare Workers reject a socket used across requests.
170
170
  - **`db.orm` is the way to use the ORM.** For custom collection classes, pass `collections` to `postgresServerless({ contract, collections })` at module scope; every connection's `db.orm` and `tx.orm` then returns the classes. See *Workflow — Custom collection classes* in [`queries-postgres.md`](queries-postgres.md).
171
171
  - **Anything that takes a runtime gets `db.runtime()`.** That includes `withTransaction(runtime, fn)` and a prepared statement's `query(runtime, params)`. Do not pass `db` itself.
172
- - **Inside `db.transaction(async (tx) => ...)`, run every query through `tx`.** A connection has one database connection, so inside `db.transaction(async (tx) => ...)` a query through `db` is not independent of the transaction; run every query through `tx`. A query that uses the connection's database connection directly, such as a `db.orm` read, a `db.orm` create of one row, an `updateAll(...)` or `deleteAll()`, or `db.runtime().query(...)`, runs inside the open transaction without saying so. An operation that asks for a database connection of its own, such as a `db.orm` `update(...)` or `delete()` of one row, `db.runtime().connection()`, a `db.orm` create that also writes related rows, or a nested `db.transaction(...)`, waits for the database connection the transaction holds, and the request hangs.
172
+ - **Inside `db.transaction(async (tx) => ...)`, run every query through `tx`.** A connection has one database connection, so inside `db.transaction(async (tx) => ...)` a query through `db` is not independent of the transaction; run every query through `tx`. A query that uses the connection's database connection directly, such as a `db.orm` read, a `db.orm` create of one row, an `updateAll(...)` or `deleteAll()`, or `db.query(...)`, runs inside the open transaction without saying so. An operation that asks for a database connection of its own, such as a `db.orm` `update(...)` or `delete()` of one row, `db.runtime().connection()`, a `db.orm` create that also writes related rows, or a nested `db.transaction(...)`, waits for the database connection the transaction holds, and the request hangs.
173
173
  - **After `db.close()`** (or the end of the `await using` scope), `db.runtime()` throws `DRIVER.NOT_CONNECTED` ("Postgres connection is closed"), and ORM queries, `db.transaction(...)` and prepared statements that start after the runtime was idle for a turn reject with `DRIVER.NOT_CONNECTED` ("Runtime is closed"). Call `postgres.connect({ url })` again for a new connection.
174
174
 
175
175
  How connections read rows, and the `cursor` option on the serverless client (with the Hyperdrive caveat), is in `references/queries.md` § *Streaming*.
@@ -250,6 +250,8 @@ export const db = postgres({
250
250
  });
251
251
  ```
252
252
 
253
+ `mode` decides what a budget violation does. It is `'strict'` by default, and every `budgets()` violation throws. Pass `mode: 'permissive'` to `postgres()`, `postgresServerless()`, `sqlite()` or `supabase()`, and a violation whose severity is `'warn'` goes to `log.warn` instead, and the query runs; a violation whose severity is `'error'` still throws. `budgets()` gives latency `'warn'` and the row count `'error'` by default, so a row-count limit warns only with `severities: { rowCount: 'warn' }`.
254
+
253
255
  For the full option surface, read the source: `packages/2-sql/5-runtime/src/middleware/lints.ts` and `.../budgets.ts`. The `severities` keys (`selectStar`, `noLimit`, `deleteWithoutWhere`, `updateWithoutWhere`, `readOnlyMutation` for lints; `rowCount`, `latency` for budgets) are the source of truth; do not extrapolate to a key that is not in those two files. `lints()` with no argument uses the default severities.
254
256
 
255
257
  ## Workflow — Cache middleware
@@ -307,7 +309,7 @@ Order matters: `beforeEncode` runs in registration order for every middleware be
307
309
 
308
310
  ## Workflow — Configure the connection
309
311
 
310
- The concept: the runtime takes one of three binding shapes — `url`, `pg` (a pre-constructed `pg.Pool` or `pg.Client`), or `binding` (an explicit kind tag). They're mutually exclusive. The `pg` form is for projects that already manage their own pool (e.g. a Lambda layer); `url` is the default. Pool tuning is `poolOptions.connectionTimeoutMillis` / `poolOptions.idleTimeoutMillis` — *not* `driverOptions`. Reads are buffered by default; setting `cursor` (`{ batchSize: 100 }`; `{}` or `{ batchSize: undefined }` for batches of 100; a `batchSize` that is not a positive integer fails the factory call) makes them stream through a server-side cursor, and there is no flag that turns cursors off (see `references/queries.md` § *Streaming*). `postgresServerless()` takes the same `cursor` option. Pass `log` (an object with `info`, `warn`, `error` and an optional `debug`; `console` works, and the type is `Log` from `@prisma/orm-postgres/family-runtime`) to receive what the runtime logs: the marker-verification warnings `CONTRACT.MARKER_MISSING` and `CONTRACT.MARKER_MISMATCH` from the first query, the warnings `lints()` emits for rules whose severity is `warn`, and the errors a middleware's `activityEnded` or `activityFinalized` hook throws, which the runtime logs and swallows. If `log` has a `debug` method, it also receives debug events, for example when a middleware intercepts a statement. `budgets()` violations never reach `log`: the client runs its runtime in strict mode, so a violation throws, until the client exposes `mode` (TML-3567). Without `log`, the runtime drops these events. `postgresServerless()`, `sqlite()` and `supabase()` take the same option.
312
+ The concept: the runtime takes one of three binding shapes — `url`, `pg` (a pre-constructed `pg.Pool` or `pg.Client`), or `binding` (an explicit kind tag). They're mutually exclusive. The `pg` form is for projects that already manage their own pool (e.g. a Lambda layer); `url` is the default. Pool tuning is `poolOptions.connectionTimeoutMillis` / `poolOptions.idleTimeoutMillis` — *not* `driverOptions`. Reads are buffered by default; setting `cursor` (`{ batchSize: 100 }`; `{}` or `{ batchSize: undefined }` for batches of 100; a `batchSize` that is not a positive integer fails the factory call) makes them stream through a server-side cursor, and there is no flag that turns cursors off (see `references/queries.md` § *Streaming*). `postgresServerless()` takes the same `cursor` option. Pass `log` (an object with `info`, `warn`, `error` and an optional `debug`; `console` works, and the type is `Log` from `@prisma/orm-postgres/family-runtime`) to receive what the runtime logs: the marker-verification warnings `CONTRACT.MARKER_MISSING` and `CONTRACT.MARKER_MISMATCH` from the first query, the warnings `lints()` emits for rules whose severity is `warn`, and the errors a middleware's `activityEnded` or `activityFinalized` hook throws, which the runtime logs and swallows. If `log` has a `debug` method, it also receives debug events, for example when a middleware intercepts a statement. `budgets()` violations reach `log` only in `mode: 'permissive'` (see *Lints and budgets middleware*). Without `log`, the runtime drops these events. `postgresServerless()`, `sqlite()` and `supabase()` take the same option.
311
313
 
312
314
  ```typescript
313
315
  // Default — URL string, factory constructs the pool.
@@ -355,7 +357,7 @@ export const db = postgres({
355
357
 
356
358
  ## Workflow — Transactions
357
359
 
358
- The concept applies to **Postgres, SQLite and Supabase**. `db.transaction(fn)` opens a transaction, passes the callback a `tx`, commits when the callback returns and rolls back when it throws. `tx` offers the client's query members with the same types: `sql`, `orm` (with the client's custom collection classes), `raw`, `prepare`, `query` (rows) and `execute` (affected count). Postgres and serverless-connection transactions also have `enums` and `nativeEnums`; SQLite's has `enums`. `tx` has no `close`, `[Symbol.asyncDispose]`, `transaction` or `runtime()`. Inside the callback, send every query through `tx`, not `db`, so it runs inside the transaction. A Supabase role-bound client (`asUser`, `asAnon`, `asServiceRole`) has `transaction(fn)` too, and its `tx` runs every statement under the bound role. The Mongo façade does not expose `db.transaction(...)`.
360
+ The concept applies to **Postgres, SQLite and Supabase**. `db.transaction(fn)` opens a transaction, passes the callback a `tx`, commits when the callback returns and rolls back when it throws. `tx` offers the client's query members with the same types: `sql`, `orm` (with the client's custom collection classes), `raw`, `prepare`, `query` (rows), `execute` (affected count) and `toSql`. Postgres and serverless-connection transactions also have `enums` and `nativeEnums`; SQLite's has `enums`. `tx` has no `close`, `[Symbol.asyncDispose]`, `transaction` or `runtime()`. Inside the callback, send every query through `tx`, not `db`, so it runs inside the transaction. A Supabase role-bound client (`asUser`, `asAnon`, `asServiceRole`) has `transaction(fn)` too, and its `tx` runs every statement under the bound role. The Mongo façade does not expose `db.transaction(...)`.
359
361
 
360
362
  ```typescript
361
363
  await db.transaction(async (tx) => {