@prisma/orm-mongo 8.0.0-rc.14-dev.30 → 8.0.0-rc.14-dev.31
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.
|
|
3
|
+
"version": "8.0.0-rc.14-dev.31",
|
|
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.
|
|
14
|
-
"@prisma/orm-framework": "8.0.0-rc.14-dev.
|
|
15
|
-
"@prisma/orm-target-mongo": "8.0.0-rc.14-dev.
|
|
16
|
-
"@prisma/orm-toolchain": "8.0.0-rc.14-dev.
|
|
13
|
+
"@prisma/orm-family-mongo": "8.0.0-rc.14-dev.31",
|
|
14
|
+
"@prisma/orm-framework": "8.0.0-rc.14-dev.31",
|
|
15
|
+
"@prisma/orm-target-mongo": "8.0.0-rc.14-dev.31",
|
|
16
|
+
"@prisma/orm-toolchain": "8.0.0-rc.14-dev.31",
|
|
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.
|
|
23
|
-
"@repo/tsconfig": "8.0.0-rc.14-dev.
|
|
24
|
-
"@repo/tsdown": "8.0.0-rc.14-dev.
|
|
22
|
+
"@internal/mongo": "8.0.0-rc.14-dev.31",
|
|
23
|
+
"@repo/tsconfig": "8.0.0-rc.14-dev.31",
|
|
24
|
+
"@repo/tsdown": "8.0.0-rc.14-dev.31",
|
|
25
25
|
"tsdown": "0.22.14",
|
|
26
26
|
"typescript": "5.9.3"
|
|
27
27
|
},
|
package/skills/prisma-8/SKILL.md
CHANGED
|
@@ -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.
|
|
18
|
+
library_version: '8.0.0-rc.14-dev.31'
|
|
19
19
|
version: '2026-09-12'
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -62,7 +62,7 @@ Open the reference whose triggers match the task. If more than one matches, open
|
|
|
62
62
|
| Author migrations | [`references/migrations.md`](references/migrations.md) | `db update` vs `migration plan`, `db migrate`, `migration new`, `migration show`, `db update --dry-run`, `db verify`, `db sign`, data migration, `dataTransform`, placeholder sentinels in framework-rendered `migration.ts`, `MIGRATION.HASH_MISMATCH`, `MIGRATION.UNFILLED_PLACEHOLDER`, `MIGRATION.DESTRUCTIVE_CHANGES` / `--confirm <database>`, schema drift |
|
|
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
|
-
| 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), 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) |
|
|
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`), `apply` and scopes (`Scope`, `Filtered`, `Ordered`), 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
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 `afterQuery` 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 |
|
|
@@ -160,7 +160,7 @@ await db.orm.public.Post
|
|
|
160
160
|
.all();
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
**Cursor pagination.** Call `.cursor({ field: lastValue })` after `.orderBy(...)` to resume from a known position.
|
|
163
|
+
**Cursor pagination.** Call `.cursor({ field: lastValue })` after `.orderBy(...)` to resume from a known position. `.cursor(...)` and `.distinctOn(...)` require a prior `orderBy` — the type system enforces this on the collection they are called on, so a cast on the argument does not get past it. Direction (forward or backward) follows the sort: ascending order means "greater than the cursor value", descending means "less than".
|
|
164
164
|
|
|
165
165
|
```typescript
|
|
166
166
|
const page1 = await db.orm.public.Post
|
|
@@ -285,6 +285,77 @@ await db.orm.public.User
|
|
|
285
285
|
|
|
286
286
|
The ORM returns inserted / updated rows by default. The `.returning(...)` selector lives on the SQL builder (next section), where you build a plan and execute it explicitly.
|
|
287
287
|
|
|
288
|
+
**A write needs a filter on every code path.** `update`, `updateAll`, `updateAndCount`, `delete`, `deleteAll` and `deleteAndCount` compile only on a collection that is known to be filtered. A collection that is filtered on one path and not on another is not:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
const posts = search ? db.orm.public.Post.where({ title: search }) : db.orm.public.Post;
|
|
292
|
+
await posts.deleteAll(); // error: The 'this' context of type '...' is not assignable to method's 'this' of type 'HasWhere'
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Make the write only where the filter was applied, or filter on every path:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
if (search) {
|
|
299
|
+
await db.orm.public.Post.where({ title: search }).deleteAll();
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The same holds for an `if` with an early return, a `switch`, a loop and a reassigned `let`.
|
|
304
|
+
|
|
305
|
+
## Workflow — Custom collection classes
|
|
306
|
+
|
|
307
|
+
A custom collection class gives a model its own named queries. Extend `Collection`, register the class with `orm({ collections })`, and build that client inside the request from `db.runtime()` and `db.context`:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { Collection, type Filtered, type Ordered, orm, type Scope } from '@prisma/orm-postgres/orm-client';
|
|
311
|
+
import type { Contract } from './prisma/contract.d';
|
|
312
|
+
|
|
313
|
+
class PostCollection extends Collection<Contract, 'Post'> {
|
|
314
|
+
byAuthor(userId: string) {
|
|
315
|
+
return this.where({ userId });
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
newestFirst() {
|
|
319
|
+
return this.orderBy((p) => p.createdAt.desc());
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const { Post } = orm({
|
|
324
|
+
runtime: db.runtime(),
|
|
325
|
+
context: db.context,
|
|
326
|
+
collections: { Post: PostCollection },
|
|
327
|
+
}).public;
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Class methods chain with each other and with the built-in methods, in any order, and after `.include(...)`:
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
await Post.byAuthor(userId).newestFirst().limit(20).all();
|
|
334
|
+
await Post.where({ title }).byAuthor(userId).all();
|
|
335
|
+
await Post.include('user').newestFirst().all();
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
After `.select(...)` or `.variant(...)` the class methods are gone: those return the base `Collection` type. Call class methods before them. Inside an include refinement, the related collection is the base `Collection` type, not its registered class.
|
|
339
|
+
|
|
340
|
+
Inside a class body, a class method called on the result of another call loses what that call established. So a class method whose body chains two class methods loses the first call's facts for every caller: with `latest() { return this.byAuthor(id).newestFirst(); }`, `Post.latest()` is known to be ordered but not filtered. The same holds for `.prepared` after `.include(...)` inside the class: it describes the class's row without the included relation. Inside the class, follow a class method with built-in methods (`this.byAuthor(id).orderBy(...)`), or chain the class methods from outside the class, where they keep every fact.
|
|
341
|
+
|
|
342
|
+
`apply(fn)` calls a function with the collection and returns its result. A function from a collection to a collection is a scope, of type `Scope<In, Out>`, so a query can be written once and applied to any collection of that class:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
const newest: Scope<PostCollection, Ordered<PostCollection>> = (posts) => posts.newestFirst();
|
|
346
|
+
await Post.apply(newest).limit(20).all();
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
What a chain has established is part of its type. Write a filtered collection as `Filtered<C>` and an ordered one as `Ordered<C>`; `Filtered<C>` is `C & HasWhere`, the name error messages print. A function that takes `Filtered<PostCollection>` accepts only a collection that is filtered:
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
function deleteMatching(posts: Filtered<PostCollection>) {
|
|
353
|
+
return posts.deleteAll();
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
await deleteMatching(Post.byAuthor(userId)).toArray();
|
|
357
|
+
```
|
|
358
|
+
|
|
288
359
|
## Workflow — Aggregates
|
|
289
360
|
|
|
290
361
|
```typescript
|
|
@@ -163,7 +163,7 @@ The rule to remember: inside a request, `db` does everything the `db` from `post
|
|
|
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
|
-
- **`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.
|
|
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. See *Workflow — Custom collection classes* in [`queries-postgres.md`](queries-postgres.md).
|
|
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
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.
|