@prisma/orm-mongo 8.0.0-rc.14-dev.10 → 8.0.0-rc.14-dev.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/orm-mongo",
3
- "version": "8.0.0-rc.14-dev.10",
3
+ "version": "8.0.0-rc.14-dev.11",
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.14-dev.10",
14
- "@prisma/orm-framework": "8.0.0-rc.14-dev.10",
15
- "@prisma/orm-target-mongo": "8.0.0-rc.14-dev.10",
16
- "@prisma/orm-toolchain": "8.0.0-rc.14-dev.10",
13
+ "@prisma/orm-family-mongo": "8.0.0-rc.14-dev.11",
14
+ "@prisma/orm-framework": "8.0.0-rc.14-dev.11",
15
+ "@prisma/orm-target-mongo": "8.0.0-rc.14-dev.11",
16
+ "@prisma/orm-toolchain": "8.0.0-rc.14-dev.11",
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.14-dev.10",
23
- "@repo/tsconfig": "8.0.0-rc.14-dev.10",
24
- "@repo/tsdown": "8.0.0-rc.14-dev.10",
22
+ "@internal/mongo": "8.0.0-rc.14-dev.11",
23
+ "@repo/tsconfig": "8.0.0-rc.14-dev.11",
24
+ "@repo/tsdown": "8.0.0-rc.14-dev.11",
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.14-dev.10'
18
+ library_version: '8.0.0-rc.14-dev.11'
19
19
  version: '2026-09-12'
20
20
  ---
21
21
 
@@ -98,6 +98,8 @@ The single source of truth: read the envelope, find the row by `code`, follow th
98
98
  | `MIGRATION.RUNNER_FAILED` | `db migrate`, `db update`, `db init` | Wrapper for an unclassified apply failure; `why` and `meta` carry the detail. Reconcile the reported failure, then re-run. Previously applied migrations are preserved. |
99
99
  | `MIGRATION.DESTRUCTIVE_CHANGES` | `db update` when run with nobody to ask (`--no-interactive`, CI) | Consent is the database name: interactively you type it; non-interactively pass `--confirm <database>`. `--yes` does **not** grant it. `--dry-run` previews. **Only `db update` has this flow** — `db migrate` does not gate destructive ops on a flag. |
100
100
  | `MIGRATION.NO_INVARIANT_PATH` / `MIGRATION.UNKNOWN_INVARIANT` | `db migrate` | Concurrent-migration and invariant flows — `references/migration-review.md`. |
101
+ | `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*. |
102
+ | `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. |
101
103
  | `MIGRATION.PATH_UNREACHABLE` / `MIGRATION.MARKER_MISMATCH` | `db migrate` | Run `db migrate --show --db $URL` to inspect the path, then `migration plan --from <from> --to <target>` or `migration list` to audit the graph — see `references/migration-review.md`. |
102
104
  | `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*. |
103
105
  | `MIGRATION.MISSING_INVARIANTS` | `migration status` `warn` diagnostic (exit 0) | The live marker reached the destination hash structurally but doesn't carry all invariants the target ref requires. Run `db migrate --to <name> --db $URL` to take a path that covers the missing invariants. See `references/migration-review.md`. |
@@ -130,7 +130,7 @@ Servers (HTTP handlers, workers in a request loop) **do not call `db.close()`**
130
130
 
131
131
  - **`close()` is idempotent.** Calling it twice is a no-op.
132
132
  - **`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'`).
133
- - **`close()` does not abort in-flight queries.** `await` outstanding work before calling `close()`. Async iterators from `db.runtime().query(plan)` and `PreparedStatement` handles held after `close()` fail on their next call.
133
+ - **`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 and transactions already in flight, then ends the pool. Await an ORM write such as `include(...).create()` or a nested create before `close()`, because its reload is a new call. 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. 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()`.
134
134
  - **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.
135
135
 
136
136
  **`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()`.
@@ -159,14 +159,14 @@ export default {
159
159
  };
160
160
  ```
161
161
 
162
- 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 closes when the scope ends, so a query returned from the scope without `await` (`return db.orm...` instead of `return await db.orm...`) fails when its rows are read, with `CONTRACT.MARKER_READ_FAILED` (whose cause is `DRIVER.NOT_CONNECTED`) under the default options, or `DRIVER.NOT_CONNECTED` after an earlier awaited query or with `verifyMarker: false`.
162
+ 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...`.
163
163
 
164
164
  - **`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.
165
165
  - **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.
166
166
  - **`db.orm` is the default way to use the ORM.** Build `orm({ runtime: db.runtime(), context: db.context, collections })` only for custom collection classes, and build it inside the request.
167
167
  - **Anything that takes a runtime gets `db.runtime()`.** That includes `orm({ runtime, ... })`, `withTransaction(runtime, fn)` and a prepared statement's `query(runtime, params)`. Do not pass `db` itself to `orm()`.
168
168
  - **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.
169
- - **After `db.close()`** (or the end of the `await using` scope), `db.runtime()`, ORM queries, `db.transaction(...)` and `db.prepare(...)` fail with `DRIVER.NOT_CONNECTED`. Call `postgres.connect({ url })` again for a new connection.
169
+ - **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.
170
170
 
171
171
  How connections read rows, and the `cursor` option on the serverless client (with the Hyperdrive caveat), is in `references/queries.md` § *Streaming*.
172
172
 
@@ -167,7 +167,7 @@ The **serverless client** returned by `postgresServerless(...)` still holds no d
167
167
 
168
168
  In each file that imports `@prisma/orm-postgres/serverless`, or that uses the result of its `connect()`:
169
169
 
170
- 1. Name the serverless client `postgres` and the connection that `connect()` returns `db`. With these names, code written for a `postgres()` client (`db.orm...`, `db.transaction(...)`, `db.runtime().query(...)`) works unchanged inside a request, as long as every query is awaited before the `await using` scope ends: the connection closes when the scope ends, so a query returned from the scope without `await` fails when its rows are read, with `CONTRACT.MARKER_READ_FAILED` (whose cause is `DRIVER.NOT_CONNECTED`) under the default options, or `DRIVER.NOT_CONNECTED` after an earlier awaited query or with `verifyMarker: false`. Update every import of the serverless client to the new name.
170
+ 1. Name the serverless client `postgres` and the connection that `connect()` returns `db`. With these names, code written for a `postgres()` client (`db.orm...`, `db.transaction(...)`, `db.runtime().query(...)`) works unchanged inside a request, as long as every query is awaited before the `await using` scope ends: the connection closes when the scope ends, so a lazy ORM read or `db.runtime().query(plan)` returned from the scope without `await` starts after the close and rejects with `DRIVER.NOT_CONNECTED` ("Runtime is closed"), whose `fix` names the missing `await`; a `first()`, `execute()` or `transaction()` returned without `await` had already started, so the close waits for it and it completes. Update every import of the serverless client to the new name.
171
171
  2. Replace `runtime.query(plan)` with `db.runtime().query(plan)`, and `runtime.execute(plan)` with `db.runtime().execute(plan)`. The old `connect()` result was a full `Runtime`, so the same applies to its other methods: `runtime.connection()`, `runtime.telemetry()` and `runtime.prepare(...)` become `db.runtime().connection()`, `db.runtime().telemetry()` and `db.runtime().prepare(...)`. `db.prepare(...)` also exists and accepts ORM queries as well as SQL plans. `db.sql` is the same object as `postgres.sql`, so `postgres.sql...` inside a request may be written `db.sql...`.
172
172
  3. Anything that took the `connect()` result as a runtime takes `db.runtime()` instead: `withTransaction(runtime, fn)`, `orm({ runtime, context })`, `preparedStatement.query(runtime, params)`, and your own functions whose parameter is typed `Runtime`. A function that needs both the runtime and the context can take the connection, typed with `PostgresServerlessConnection<Contract>` from `@prisma/orm-postgres/serverless`, and read `db.runtime()` and `db.context`. That removes any cast of the serverless client's `context` to `ExecutionContext<Contract>`, and the `Runtime`, `ExecutionContext` and serverless client imports that only served it.
173
173
  4. Update comments that describe the old shape. A comment that names the old variable or says the runtime is acquired through `db.connect(...)` now names `postgres.connect({ url })` and the connection `db`. A comment that calls the serverless client a facade, or calls a connection a per-request client or a runtime, now says serverless client or connection. For example, the doc comment on the serverless client says that it is built once per isolate, holds no database connection, and that each request opens its own connection with `postgres.connect({ url })`; it sits directly above the `postgresServerless(...)` declaration, so move it there if it sits above another declaration. Update any README that describes the old shape in the same way.