@prisma/orm-mongo 8.0.0-rc.16-dev.1 → 8.0.0-rc.16-dev.2
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.16-dev.
|
|
3
|
+
"version": "8.0.0-rc.16-dev.2",
|
|
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.16-dev.
|
|
14
|
-
"@prisma/orm-framework": "8.0.0-rc.16-dev.
|
|
15
|
-
"@prisma/orm-target-mongo": "8.0.0-rc.16-dev.
|
|
16
|
-
"@prisma/orm-toolchain": "8.0.0-rc.16-dev.
|
|
13
|
+
"@prisma/orm-family-mongo": "8.0.0-rc.16-dev.2",
|
|
14
|
+
"@prisma/orm-framework": "8.0.0-rc.16-dev.2",
|
|
15
|
+
"@prisma/orm-target-mongo": "8.0.0-rc.16-dev.2",
|
|
16
|
+
"@prisma/orm-toolchain": "8.0.0-rc.16-dev.2",
|
|
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.16-dev.
|
|
23
|
-
"@repo/tsconfig": "8.0.0-rc.16-dev.
|
|
24
|
-
"@repo/tsdown": "8.0.0-rc.16-dev.
|
|
22
|
+
"@internal/mongo": "8.0.0-rc.16-dev.2",
|
|
23
|
+
"@repo/tsconfig": "8.0.0-rc.16-dev.2",
|
|
24
|
+
"@repo/tsdown": "8.0.0-rc.16-dev.2",
|
|
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.16-dev.
|
|
18
|
+
library_version: '8.0.0-rc.16-dev.2'
|
|
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), custom collection class (`extends Collection`), `
|
|
65
|
+
| Write queries | [`references/queries.md`](references/queries.md) | query, where, select, project, orderBy, limit, offset, take, skip, include, lookup, first, all, count, aggregate, groupBy, create, update, delete, upsert, returning, transaction, `db.orm`, `db.sql`, `runtime.query(plan)` vs `runtime.execute(plan)`, `db.prepare` / prepared statements, streaming / `for await`, many-to-many `include` and nested `connect`, `and` / `or` / `not` from `@prisma/orm-postgres/orm-client`, `db.query.from(...)` (Mongo pipeline), namespace-aware accessors, `.all()` Thenable, single-use iterators (`RUNTIME.ITERATOR_CONSUMED`), target-declared aggregate types (`count`, integer `sum`, and integer `avg` are `number`; `count` and integer `sum` throw outside ±(2^53 − 1) rather than round, while `avg` is a fraction already and carries no guard; `countBigInt` / `sumBigInt` / `avgDecimal` are the lossless forms, `avgDecimal` on PostgreSQL only), custom collection class (`extends Collection`), `with` and scopes (`Scope`, `Filtered`, `Ordered`), shared query fragments (`db.orm.scope(fields, body)` for a filter on every model with given fields, `CodecField`, `db.orm.public.Post.scope(...)` for a shared `select` / `include`, `orderByField` for an order or sort parameter from a request), drizzle-style, kysely-style. Naming types (§ *Naming model and result types*): "type of my model", "return type of a query", `ResultType`, `Scalars`, `Shape`, `models` / `Models` namespace in `contract.d.ts`, `Models.public_User`, Prisma 7 `Prisma.User` / `GetPayload` / `UserGetPayload` equivalents. Postgres/SQLite specifics: [`references/queries-postgres.md`](references/queries-postgres.md); Mongo specifics: [`references/queries-mongo.md`](references/queries-mongo.md) |
|
|
66
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 |
|
|
@@ -341,11 +341,11 @@ After `.select(...)` or `.variant(...)` the class methods are gone: those return
|
|
|
341
341
|
|
|
342
342
|
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.
|
|
343
343
|
|
|
344
|
-
`
|
|
344
|
+
`with(fn)` calls a function with the collection and returns its result. A pure filter is `where(rowFragment)`; `with` is for what `where` cannot express, such as a shared `select` and `include`, an order, a limit or offset, or a variant. 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:
|
|
345
345
|
|
|
346
346
|
```typescript
|
|
347
347
|
const newest: Scope<PostCollection, Ordered<PostCollection>> = (posts) => posts.newestFirst();
|
|
348
|
-
await Post.
|
|
348
|
+
await Post.with(newest).limit(20).all();
|
|
349
349
|
```
|
|
350
350
|
|
|
351
351
|
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:
|
|
@@ -360,7 +360,7 @@ await deleteMatching(Post.byAuthor(userId)).toArray();
|
|
|
360
360
|
|
|
361
361
|
## Workflow — Scopes
|
|
362
362
|
|
|
363
|
-
A piece of a query used in several places is a function. Do not build a filter object and spread it into each query; write a function and pass it to `.where(...)`, `.orderBy(...)` or `.
|
|
363
|
+
A piece of a query used in several places is a function. Do not build a filter object and spread it into each query; write a function and pass it to `.where(...)`, `.orderBy(...)` or `.with(...)`. A function from a collection to a collection is a **scope**, and `.with(...)` runs it. A pure filter is `where(rowFragment)`; `with` is for what `where` cannot express, such as a shared `select` and `include`, an order, a limit or offset, or a variant.
|
|
364
364
|
|
|
365
365
|
**The same filter on several models.** Define a scope with `db.orm.scope(fields, body)`. Declare each field the scope needs with the same builder the schema uses, from the `field` that `@prisma/orm-postgres/contract-builder` exports, adding `.optional()` for a field that may be null. The body sees only those fields:
|
|
366
366
|
|
|
@@ -372,8 +372,8 @@ const createdSince = (since: Temporal.Instant) =>
|
|
|
372
372
|
rows.where((r) => r.createdAt.gte(since)),
|
|
373
373
|
);
|
|
374
374
|
|
|
375
|
-
await db.orm.public.User.
|
|
376
|
-
await db.orm.public.Post.
|
|
375
|
+
await db.orm.public.User.with(createdSince(since)).all();
|
|
376
|
+
await db.orm.public.Post.with(createdSince(since)).deleteAll();
|
|
377
377
|
```
|
|
378
378
|
|
|
379
379
|
Pick the builder whose codec matches the field's codec in `contract.d.ts`: a PSL `DateTime` is `field.temporal.timestamptz()` (`pg/timestamptz-temporal@1`), a `String` is `field.text()` (`pg/text@1`), a `Uuid` is `field.uuidNative()` (`pg/uuid@1`). `field.column(columnType)` is the explicit form. A package that offers a scope and does not import the facade writes `{ codecId: 'pg/text@1', nullable: false }`, with a codec of the contract. For a list field such as `String[]`, add `.many()` to the builder or `many: { elementNullable: false }` to the object; for a `String?[]`, whose elements may be null, add `.many({ elementsNullable: true })` or `many: { elementNullable: true }`. Without it the declaration does not match a list field, and with it the element nullability must match too. A list of value objects such as `Address[]` is stored as one `jsonb` value and is still a list: `field.column(jsonbColumn).many()`. The body may call `where`, `orderBy`, `limit` and `offset`. The result keeps the collection's class and records the filter, so `update` and `delete` are allowed after a scope that filters. `updateAll`, `deleteAll` and their `AndCount` forms change every matching row and throw `ORM.ARGUMENT_INVALID` when the chain has a `limit`, `offset`, `cursor`, `distinct` or `distinctOn`, so do not put a limit in a scope that will be followed by one of them. `update` and `delete` change the one row `first()` returns, so the order, offset, cursor, `distinct` and `distinctOn` choose it, and after `limit(0)` they change nothing and return `null`; `update` with a relation callback throws on an order, a limit, an offset, a cursor, `distinct` or `distinctOn`, because it finds its row by the filter alone. A model without the field, or with the field under another codec or nullability, is a compile error, and a run-time `ORM.FIELD_UNKNOWN`. A custom collection class carries no namespace in its type, so at compile time it matches only a field that every model of that name has, with the same codec and nullability, and its real namespace is checked at run time. The codec, the nullability, whether the field is a list and the nullability of its elements are compared; the column type's parameters are not, so `field.uuidString()` (`char(36)`) also matches a `char(10)` field.
|
|
@@ -391,7 +391,7 @@ await db.orm.public.Post.where((p) => and(created(since)(p), p.title.ilike('%orm
|
|
|
391
391
|
|
|
392
392
|
Both forms check values against the codec's type, not the field's. For a field that narrows its codec's values, such as an enum stored as `pg/text@1`, they accept values the field would refuse: `row.kind.eq('superuser')` compiles even when `kind` has no such member. Write a filter on such a field inline, on the model, where the field's own type checks the value.
|
|
393
393
|
|
|
394
|
-
**The same `select` and `include` in several queries.** Define it once with `.scope(...)` on a collection of the model, run it with `.
|
|
394
|
+
**The same `select` and `include` in several queries.** Define it once with `.scope(...)` on a collection of the model, run it with `.with(...)`, and name its row with `CollectionRowOf`:
|
|
395
395
|
|
|
396
396
|
```typescript
|
|
397
397
|
import type { CollectionRowOf } from '@prisma/orm-postgres/orm-client';
|
|
@@ -401,8 +401,8 @@ const postSummary = db.orm.public.Post.scope((posts) =>
|
|
|
401
401
|
);
|
|
402
402
|
type PostSummary = CollectionRowOf<ReturnType<typeof postSummary>>;
|
|
403
403
|
|
|
404
|
-
await db.orm.public.Post.where({ userId }).
|
|
405
|
-
await db.orm.public.User.include('posts', (posts) => posts.
|
|
404
|
+
await db.orm.public.Post.where({ userId }).with(postSummary).limit(20).all();
|
|
405
|
+
await db.orm.public.User.include('posts', (posts) => posts.with(postSummary)).all();
|
|
406
406
|
```
|
|
407
407
|
|
|
408
408
|
The body receives the plain collection of the model, without a custom class's methods. Apply the scope before `.select(...)` or `.variant(...)`: it is refused on a collection they narrowed. Its result is always typed as the plain collection, even when the body keeps the row, so a custom class's methods are gone after it, and `update`, `delete` and `cursor` are refused, although an earlier `.where(...)` still runs; it is for reads. For a filter on one model, use a class method or `db.orm.scope`. A scope for one model refuses a collection of another model or namespace at run time with `ORM.ARGUMENT_INVALID`.
|
|
@@ -624,7 +624,7 @@ Cross-namespace relations (e.g. `public.Profile` → `auth.User`) follow the sam
|
|
|
624
624
|
- [ ] Expressed ranges as chained `.where(...)` clauses or a single `and(...)` clause — did NOT reach for a non-existent `.between(...)` operator.
|
|
625
625
|
- [ ] 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.
|
|
626
626
|
- [ ] For ORM combinators, imported `and` / `or` / `not` from `@prisma/orm-postgres/orm-client`.
|
|
627
|
-
- [ ] Wrote a query piece shared between places as a function: a scope from `db.orm.scope(fields, body)` or `collection.scope(body)` run with `.
|
|
627
|
+
- [ ] Wrote a query piece shared between places as a function: a scope from `db.orm.scope(fields, body)` or `collection.scope(body)` run with `.with(...)`, a `where` callback typed with `CodecField`, or `orderByField` for an order parameter from a request.
|
|
628
628
|
- [ ] 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.
|
|
629
629
|
- [ ] Wrapped multi-statement work in `db.transaction(async (tx) => { ... })` where atomicity matters.
|
|
630
630
|
- [ ] For top-N grouped aggregates at meaningful scale, dropped to `db.sql.<ns>.<table>` rather than JS-side sort + slice over `groupBy(...).aggregate(...)`.
|