@prisma/orm-mongo 8.0.0-rc.4-dev.17 → 8.0.0-rc.5-dev.1
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 +11 -10
- package/skills/prisma-8/SKILL.md +84 -0
- package/skills/prisma-8/references/build.md +142 -0
- package/skills/prisma-8/references/contract.md +417 -0
- package/skills/prisma-8/references/debug.md +141 -0
- package/skills/prisma-8/references/feedback.md +251 -0
- package/skills/prisma-8/references/migration-review.md +224 -0
- package/skills/prisma-8/references/migrations.md +519 -0
- package/skills/prisma-8/references/queries-mongo.md +236 -0
- package/skills/prisma-8/references/queries-postgres.md +415 -0
- package/skills/prisma-8/references/queries.md +168 -0
- package/skills/prisma-8/references/quickstart.md +326 -0
- package/skills/prisma-8/references/runtime.md +344 -0
- package/skills/prisma-8/references/supabase.md +244 -0
- package/skills/prisma-8/references/upgrade-app.md +101 -0
- package/skills/prisma-8/references/upgrade-extension.md +105 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.10-to-0.11/instructions.md +56 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md +381 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts +202 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts +201 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts +198 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/instructions.md +339 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts +229 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md +543 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.14-to-0.15/instructions.md +359 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.15-to-0.16/instructions.md +173 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/instructions.md +805 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md +72 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md +8 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md +36 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md +86 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +588 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +158 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +42 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.10-to-0.11/instructions.md +276 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md +738 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts +97 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts +223 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.12-to-0.13/instructions.md +266 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md +522 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.14-to-0.15/instructions.md +803 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.15-to-0.16/instructions.md +219 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/instructions.md +731 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md +194 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md +8 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md +57 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/instructions.md +150 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +746 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +137 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +129 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.3"
|
|
3
|
+
to: "8.0.0-rc.4"
|
|
4
|
+
changes:
|
|
5
|
+
- id: prisma-config-hard-cut-and-top-level-commands
|
|
6
|
+
summary: |
|
|
7
|
+
The deprecated fallbacks are gone: the CLI no longer reads
|
|
8
|
+
`prisma-next.config.ts`, no longer accepts the flat (un-nested) config shape, and the
|
|
9
|
+
`prisma-next` command no longer exists. The unified CLI (`@prisma/cli`, installed from
|
|
10
|
+
the `next` dist-tag; its binary is currently `prisma-cli`) runs the ORM commands at the
|
|
11
|
+
top level — `contract emit`, `db init`, `migration plan`, `migrate` — with only `init`
|
|
12
|
+
under the `orm` group (`orm init`), and the only config it reads is `prisma.config.ts`
|
|
13
|
+
in the engine envelope shape.
|
|
14
|
+
|
|
15
|
+
1. Rename `prisma-next.config.ts` to `prisma.config.ts` if you have not already.
|
|
16
|
+
2. Rewrite the export to the envelope shape. Old flat shape:
|
|
17
|
+
`import { defineConfig } from '@prisma/orm-postgres/config';`
|
|
18
|
+
`export default defineConfig({ contract: '…', db: { connection: … } });`
|
|
19
|
+
New shape:
|
|
20
|
+
`import { definePrismaConfig } from '@prisma/cli-engine';`
|
|
21
|
+
`import { defineConfig as ormConfig } from '@prisma/orm-postgres/config';`
|
|
22
|
+
`export default definePrismaConfig({ orm: ormConfig({ contract: '…', db: { connection: … } }) });`
|
|
23
|
+
The options object moves into the target helper unchanged. The same pattern applies
|
|
24
|
+
to `@prisma/orm-sqlite/config` and `@prisma/orm-mongo/config`.
|
|
25
|
+
3. If the config reads `process.env`, keep (or add) `import 'dotenv/config';` as the
|
|
26
|
+
first import — the loader does not read `.env` for you.
|
|
27
|
+
4. In `package.json`, replace the `prisma-next` devDependency with `@prisma/cli@next`
|
|
28
|
+
plus `@prisma/cli-engine` at the exact version that `@prisma/cli` names in its own
|
|
29
|
+
dependencies, and update your extension's contract-space
|
|
30
|
+
build and emit scripts from `prisma-next contract emit` to `prisma-cli contract emit`.
|
|
31
|
+
5. Run `prisma-cli contract emit` to confirm the config loads and to regenerate the
|
|
32
|
+
artifacts (their generated-file headers change with this release).
|
|
33
|
+
detection:
|
|
34
|
+
glob: "**/prisma-next.config.ts"
|
|
35
|
+
- id: facades-compose-the-raw-lane
|
|
36
|
+
summary: |
|
|
37
|
+
A facade no longer gets the whole-query raw tag from the builder. `Db<C>` is a pure
|
|
38
|
+
namespace map now, so the `raw` key it used to answer is gone, and the tag is composed at
|
|
39
|
+
client build instead.
|
|
40
|
+
|
|
41
|
+
Build it with `createRawLane({ context, rawCodecInferer })` from
|
|
42
|
+
`@internal/sql-builder/runtime`, typed `RawLane<TContract>` from
|
|
43
|
+
`@internal/sql-builder/types`, and expose it as your client's `raw`. Callers then write
|
|
44
|
+
``client.raw.sql`SELECT ...` ``. A client that binds per role or per scope builds one lane
|
|
45
|
+
per bound context, the way it already builds one `sql` per context. A static context —
|
|
46
|
+
the no-runtime shape that returns `context`, `contract` and `sql` — builds one too and
|
|
47
|
+
returns it as `raw`.
|
|
48
|
+
|
|
49
|
+
If your `raw` property was the contract-free expression tag (`createRawSql(inferer)`), it
|
|
50
|
+
changes shape from a callable to `{ sql }`. That breaks your own surface, so note it in
|
|
51
|
+
your release.
|
|
52
|
+
detection:
|
|
53
|
+
glob: "**/*.{ts,mts,cts}"
|
|
54
|
+
regex:
|
|
55
|
+
- 'createRawSql\('
|
|
56
|
+
- 'RawSqlTag'
|
|
57
|
+
# `fns.raw` is a fragment call site and is deliberately excluded:
|
|
58
|
+
# fragments are unchanged by this release.
|
|
59
|
+
- '(?<!(?<![\w$])fns)\.raw`'
|
|
60
|
+
anyMatch: true
|
|
61
|
+
- id: reserved-raw-namespace-check-removed
|
|
62
|
+
summary: |
|
|
63
|
+
`sql()` no longer refuses a contract whose storage declares a namespace named `raw`, and
|
|
64
|
+
`ORM.NAMESPACE_RESERVED` leaves the error catalogue. Nothing raises the code now, so drop
|
|
65
|
+
any branch that matched it: a test asserting the refusal, a doc listing the code, an
|
|
66
|
+
error mapping of your own.
|
|
67
|
+
detection:
|
|
68
|
+
glob: "**/*.{ts,mts,cts,md}"
|
|
69
|
+
contains:
|
|
70
|
+
- "ORM.NAMESPACE_RESERVED"
|
|
71
|
+
anyMatch: true
|
|
72
|
+
- id: contract-fixture-restamp
|
|
73
|
+
summary: |
|
|
74
|
+
Committed contract artifacts (`contract.json` / `contract.d.ts`, including test
|
|
75
|
+
fixtures) embed the toolchain version, which moves to 8.0.0-rc.4. Regenerate them
|
|
76
|
+
with your emit script (`build:contract-space` or equivalent) after upgrading, or
|
|
77
|
+
fixture comparisons fail on the version stamp alone.
|
|
78
|
+
detection:
|
|
79
|
+
glob: "**/contract.json"
|
|
80
|
+
contains:
|
|
81
|
+
- '"version": "8.0.0-rc.3"'
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
# 8.0.0-rc.3 → 8.0.0-rc.4 — Extension-author upgrade instructions
|
|
85
|
+
|
|
86
|
+
## `facades-compose-the-raw-lane`
|
|
87
|
+
|
|
88
|
+
`Db<C>` is a namespace map and nothing else, so a facade composes the whole-query raw tag itself
|
|
89
|
+
and exposes it as the raw lane:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { createRawLane, sql } from '@internal/sql-builder/runtime';
|
|
93
|
+
import type { Db, RawLane } from '@internal/sql-builder/types';
|
|
94
|
+
|
|
95
|
+
const sqlDb: Db<TContract> = sql<TContract>({ context, rawCodecInferer });
|
|
96
|
+
const raw: RawLane<TContract> = createRawLane<TContract>({ context, rawCodecInferer });
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Callers reach the tag at `client.raw.sql`. A client that binds per role or per scope builds one
|
|
100
|
+
lane per bound context, exactly as it already builds one `sql` per context.
|
|
101
|
+
|
|
102
|
+
A static context does the same. If your facade ships a no-runtime surface — the shape that
|
|
103
|
+
returns `context`, `contract`, `sql` and friends without opening a connection — build the lane
|
|
104
|
+
there too and return it as `raw`:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
export interface YourStaticContext<TContract extends Contract<SqlStorage>> {
|
|
108
|
+
readonly sql: Db<TContract>;
|
|
109
|
+
readonly raw: RawLane<TContract>;
|
|
110
|
+
// …context, contract, enums
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const raw: RawLane<TContract> = createRawLane<TContract>({ context, rawCodecInferer });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Its `raw` property changes type from the contract-free tag to `RawLane<TContract>`, the same
|
|
117
|
+
change the connected client makes, so a consumer reads both surfaces the same way.
|
|
118
|
+
|
|
119
|
+
Two shapes change for your consumers. Anyone who wrote ``client.sql.raw`...` `` writes
|
|
120
|
+
``client.raw.sql`...` ``. Anyone who called `client.raw` as an expression tag calls
|
|
121
|
+
`client.raw.sql`...`.returns(codecId)` instead, or `fns.raw` inside a builder callback. Both are
|
|
122
|
+
breaking changes to your own surface, so note them in your release.
|
|
123
|
+
|
|
124
|
+
The detector looks for `createRawSql(`, `RawSqlTag`, and `raw` used as a tag. It skips the
|
|
125
|
+
receiver `fns` exactly, including `x.fns.raw`, because that is a fragment call site and needs no
|
|
126
|
+
change. A receiver that merely ends in those letters, such as `myfns.raw`, still matches, as
|
|
127
|
+
does a functions object aliased to another name.
|
|
128
|
+
|
|
129
|
+
## `reserved-raw-namespace-check-removed`
|
|
130
|
+
|
|
131
|
+
`sql()` used to refuse a contract whose storage declared a namespace named `raw`, raising
|
|
132
|
+
`ORM.NAMESPACE_RESERVED` at client construction. The check is gone with the constraint it
|
|
133
|
+
enforced: the lane is composed by the client, not answered by the namespace map, so no contract
|
|
134
|
+
can shadow it.
|
|
135
|
+
|
|
136
|
+
Drop any branch that matched the code — a test asserting the refusal, an error mapping, a doc
|
|
137
|
+
that lists it. The code no longer exists in the catalogue, and nothing raises it.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.4"
|
|
3
|
+
to: "8.0.0-rc.5"
|
|
4
|
+
changes:
|
|
5
|
+
- id: wrap-pg-constructions-with-suppress-idle-connection-errors
|
|
6
|
+
summary: |
|
|
7
|
+
Wrap every pg `Pool` or `Client` your extension constructs with `suppressIdleConnectionErrors`, newly exported from `@internal/driver-postgres/runtime` (canonical home `@internal/utils/suppress-idle-connection-errors`). node-postgres emits 'error' on the pool or client when an idle connection drops; with no listener Node kills the host process. The helper attaches a no-op listener, is idempotent per emitter, and returns the same instance. Bindings handed to the driver (`pgPool`/`pgClient`/`url`) are wrapped by the driver itself since rc.5, so this applies to pg handles your extension uses outside a driver binding.
|
|
8
|
+
detection:
|
|
9
|
+
glob: "**/*.ts"
|
|
10
|
+
contains:
|
|
11
|
+
- "new Pool("
|
|
12
|
+
- "new Client("
|
|
13
|
+
- "new pg.Pool("
|
|
14
|
+
- "new pg.Client("
|
|
15
|
+
anyMatch: true
|
|
16
|
+
- id: distinct-on-requires-postgres-capability
|
|
17
|
+
summary: |
|
|
18
|
+
`Collection#distinctOn(...)` now requires the contract to declare the `postgres.distinctOn`
|
|
19
|
+
capability, mirroring the sql-builder lane's existing gate. A contract without it (e.g.
|
|
20
|
+
SQLite-only) makes the call a compile error — the parameter type narrows to `never` — where
|
|
21
|
+
it used to compile and silently produce undeduped rows at runtime, since the target's
|
|
22
|
+
renderer never rendered `DISTINCT ON` for a target that cannot express it.
|
|
23
|
+
|
|
24
|
+
Every `.distinctOn(...)` call your code makes on a `Collection` was already wrong on any
|
|
25
|
+
target lacking `postgres.distinctOn`; the type error is the fix surfacing at compile time
|
|
26
|
+
instead of a silently wrong result set at runtime. Move the call to a contract that
|
|
27
|
+
declares `postgres.distinctOn`, or remove it — there is no runtime opt-out.
|
|
28
|
+
detection:
|
|
29
|
+
glob: "**/*.{ts,mts,cts}"
|
|
30
|
+
regex:
|
|
31
|
+
- '\.distinctOn\('
|
|
32
|
+
anyMatch: true
|
|
33
|
+
- id: groupby-pre-group-pagination-now-scopes-rows
|
|
34
|
+
summary: |
|
|
35
|
+
`take()`, `skip()`, `cursor()`, `distinct()`, `distinctOn()`, and `orderBy()` written before
|
|
36
|
+
`.groupBy(...)` on a `Collection` now scope the rows that get grouped, instead of being
|
|
37
|
+
silently dropped. `db.orm.<Model>.take(10).groupBy('x').aggregate(...)` used to group every
|
|
38
|
+
matching row; it now groups only the first 10 (by whatever `orderBy()` is active).
|
|
39
|
+
|
|
40
|
+
There is no reliable static pattern that separates a call site whose answer just became
|
|
41
|
+
correct from one whose answer is now different from before — both look identical in source.
|
|
42
|
+
Any test asserting values on a `.groupBy(...)` chain with a pre-group pagination clause
|
|
43
|
+
needs re-checking against the new (correct) numbers by hand.
|
|
44
|
+
- id: groupby-post-group-pagination-requires-order-by
|
|
45
|
+
summary: |
|
|
46
|
+
`GroupedCollection` gained its own `take()` / `skip()` / `orderBy()`, which page the grouped
|
|
47
|
+
rows themselves when written *after* `.groupBy(...)`. Post-group `take()` / `skip()` require
|
|
48
|
+
a prior post-group `orderBy()` — without one they are a compile error, the parameter type
|
|
49
|
+
narrows to `never`, because a database may return groups in any order and "the first n
|
|
50
|
+
groups" is undefined without one.
|
|
51
|
+
|
|
52
|
+
This is not a rote find-and-replace: `db.orm.<Model>.groupBy('x').take(10)` needs a caller
|
|
53
|
+
to pick what "first" means for their groups, which is a decision only they can make. Add an
|
|
54
|
+
`.orderBy(...)` naming one of the fields passed to `groupBy(...)` before the `take()` /
|
|
55
|
+
`skip()` call.
|
|
56
|
+
detection:
|
|
57
|
+
glob: "**/*.{ts,mts,cts}"
|
|
58
|
+
regex:
|
|
59
|
+
- '\.groupBy\('
|
|
60
|
+
anyMatch: true
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
# 8.0.0-rc.4 → 8.0.0-rc.5 — Extension author upgrade instructions
|
|
64
|
+
|
|
65
|
+
## `wrap-pg-constructions-with-suppress-idle-connection-errors`
|
|
66
|
+
|
|
67
|
+
Walk every file matched by `detection.glob`. For each pg `Pool` or `Client` the extension constructs, wrap the construction:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { suppressIdleConnectionErrors } from '@internal/driver-postgres/runtime';
|
|
71
|
+
|
|
72
|
+
const pool = suppressIdleConnectionErrors(
|
|
73
|
+
new Pool({ connectionString: options.url }),
|
|
74
|
+
);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This is the same translation applied to the in-repo `@internal/postgres` and `@internal/extension-supabase` runtimes in this transition. The helper only attaches a no-op `'error'` listener (connect/query failures still reject their own promises), so behavior is otherwise unchanged; without it, a dropped idle connection crashes the process that hosts the extension.
|
|
78
|
+
|
|
79
|
+
If your extension's test suite fakes the `pg` module, the fakes need an `on` method (`on = vi.fn().mockReturnThis()` on a class fake, or `on: vi.fn()` on an object literal) — the runtime now calls `.on('error', ...)` on every pool, client, and checked-out pool client.
|
|
80
|
+
## `distinct-on-requires-postgres-capability`
|
|
81
|
+
|
|
82
|
+
`Collection#distinctOn(...)` used to compile and run on any target, but only Postgres ever
|
|
83
|
+
rendered its `DISTINCT ON` clause — a call on any other target (SQLite) compiled clean and
|
|
84
|
+
silently returned undeduped rows at runtime. The method now carries the same capability gate the
|
|
85
|
+
sql-builder lane already enforces: its parameter type narrows to `never` unless the contract
|
|
86
|
+
declares `postgres.distinctOn`, so the same call is a compile error on a contract that lacks it,
|
|
87
|
+
and a runtime error carrying `ORM.CAPABILITY_MISSING` if reached dynamically (e.g. through a
|
|
88
|
+
hand-built `CollectionState`).
|
|
89
|
+
|
|
90
|
+
Find every `.distinctOn(...)` call your code makes on a `Collection` and check whether the
|
|
91
|
+
contract it runs against declares `postgres.distinctOn`. If it does, nothing changes — the call
|
|
92
|
+
already worked correctly and keeps compiling. If it does not, the call was already producing the
|
|
93
|
+
wrong result set; either move the collection onto a Postgres-capable contract, or remove the
|
|
94
|
+
`.distinctOn(...)` call and accept the undeduped rows it was silently returning before.
|
|
95
|
+
|
|
96
|
+
`Collection#distinct(...)` is unaffected — it lowers to a portable `ROW_NUMBER` dedup and needs
|
|
97
|
+
no capability, on any target.
|
|
98
|
+
|
|
99
|
+
## `groupby-pre-group-pagination-now-scopes-rows`
|
|
100
|
+
|
|
101
|
+
Any `.take(...)`, `.skip(...)`, `.cursor(...)`, `.distinct(...)`, `.distinctOn(...)`, or
|
|
102
|
+
`.orderBy(...)` your extension calls *before* `.groupBy(...)` on a `Collection` used to be
|
|
103
|
+
silently dropped once `.groupBy(...)` joined the chain — the aggregate reduced over every
|
|
104
|
+
matching row, ignoring the pagination clause entirely. It now scopes the rows that get grouped,
|
|
105
|
+
the same way root `.aggregate()` scopes its rows (see the sibling entry for that fix, already
|
|
106
|
+
shipped in `8.0.0-rc.4` → `8.0.0-rc.5`'s predecessor window).
|
|
107
|
+
|
|
108
|
+
There is no detection regex for this one worth writing: the call sites that need re-checking
|
|
109
|
+
look identical, in source, to the call sites that already worked correctly (a chain built with
|
|
110
|
+
this scoping in mind, versus one that assumed the pagination clause was a no-op). Grep for
|
|
111
|
+
`.groupBy(` and read every match with a pre-group pagination clause; if the test asserting its
|
|
112
|
+
result seeds fewer distinct groups than pagination scope allows, or asserts totals computed over
|
|
113
|
+
every row rather than the paginated window, the expected values need updating to match the now-
|
|
114
|
+
correct behavior.
|
|
115
|
+
|
|
116
|
+
## `groupby-post-group-pagination-requires-order-by`
|
|
117
|
+
|
|
118
|
+
`GroupedCollection` (what `.groupBy(...)` returns) gained `take()`, `skip()`, and `orderBy()`,
|
|
119
|
+
which page the *grouped* rows when written after `.groupBy(...)` — previously `.groupBy(...)` had
|
|
120
|
+
no chain of its own past `.having(...)`. Calling post-group `take()` or `skip()` without a prior
|
|
121
|
+
post-group `orderBy()` is a compile error: the parameter type narrows to `never`, because a
|
|
122
|
+
database may return groups in any order and "the first n groups" has no defined meaning without
|
|
123
|
+
one.
|
|
124
|
+
|
|
125
|
+
If your extension's own code (or its test suite) calls `.groupBy(...).take(...)` or
|
|
126
|
+
`.groupBy(...).skip(...)` with no `.orderBy(...)` between them, it will fail to compile after this
|
|
127
|
+
upgrade. There is no default ordering to insert automatically — add an `.orderBy(...)` naming one
|
|
128
|
+
of the fields you passed to `groupBy(...)` (ascending or descending is your call; whichever
|
|
129
|
+
matches what "the first n groups" should mean for that query) before the `take()` / `skip()` call.
|