@prisma/orm-mongo 8.0.0-rc.1-dev.45 → 8.0.0-rc.10
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/README.md +5 -9
- package/dist/contract-builder.d.mts +1 -0
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/utils__suppress-idle-connection-errors.d.mts +1 -0
- package/dist/utils__suppress-idle-connection-errors.mjs +2 -0
- package/package.json +14 -16
- package/skills/prisma-8/SKILL.md +96 -0
- package/skills/prisma-8/references/build.md +142 -0
- package/skills/prisma-8/references/contract.md +446 -0
- package/skills/prisma-8/references/debug.md +144 -0
- package/skills/prisma-8/references/feedback.md +251 -0
- package/skills/prisma-8/references/migration-model.md +175 -0
- package/skills/prisma-8/references/migration-review.md +241 -0
- package/skills/prisma-8/references/migrations.md +538 -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 +237 -0
- package/skills/prisma-8/references/quickstart.md +317 -0
- package/skills/prisma-8/references/runtime.md +366 -0
- package/skills/prisma-8/references/supabase.md +231 -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/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md +157 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md +33 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md +36 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.8-to-8.0.0-rc.9/instructions.md +63 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.9-to-8.0.0-rc.10/instructions.md +84 -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
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md +102 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md +33 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md +35 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.8-to-8.0.0-rc.9/instructions.md +86 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.9-to-8.0.0-rc.10/instructions.md +63 -0
- package/dist/bin__prisma-next.mjs +0 -3
|
@@ -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@latest`
|
|
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.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.5"
|
|
3
|
+
to: "8.0.0-rc.6"
|
|
4
|
+
changes:
|
|
5
|
+
- id: postgres-temporal-codec-ids-retired
|
|
6
|
+
summary: |
|
|
7
|
+
Five PostgreSQL temporal codec ids were removed with no compatibility aliases. Each
|
|
8
|
+
native type now has two representation-explicit codecs — one whose application value is a
|
|
9
|
+
`Temporal.*`, one that passes PostgreSQL's own text through unchanged:
|
|
10
|
+
|
|
11
|
+
| Retired | Temporal replacement | Text replacement |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `pg/date@1` | `pg/date-temporal@1` (`Temporal.PlainDate`) | `pg/date-string@1` |
|
|
14
|
+
| `pg/timestamp@1` | `pg/timestamp-temporal@1` (`Temporal.PlainDateTime`) | `pg/timestamp-string@1` |
|
|
15
|
+
| `pg/timestamptz@1` | `pg/timestamptz-temporal@1` (`Temporal.Instant`) | `pg/timestamptz-string@1` |
|
|
16
|
+
| `pg/time@1` | `pg/time-temporal@1` (`Temporal.PlainTime`) | `pg/time-string@1` |
|
|
17
|
+
| `sql/timestamp@1` | `pg/timestamptz-temporal@1` | `pg/timestamptz-string@1` |
|
|
18
|
+
|
|
19
|
+
An extension names these ids in more places than a user does. Sweep all of them:
|
|
20
|
+
|
|
21
|
+
1. **Column descriptors in an extension contract.** A pack that declares its own tables
|
|
22
|
+
(`extensionModel(...)` with `{ codecId, nativeType }` column literals) picks the
|
|
23
|
+
representation on its consumers' behalf. Choose the Temporal id where application code
|
|
24
|
+
reads the column as a value, and the `*String` id where it should stay text — the
|
|
25
|
+
Supabase pack's `auth` tables took the Temporal id for exactly that reason.
|
|
26
|
+
2. **`descriptor-meta` registrations, control-plane hooks and aggregate matrices.** Any
|
|
27
|
+
table keyed by codec id gains two entries where it had one, or moves its single entry.
|
|
28
|
+
A parity or coverage table that enumerates ids needs the four new `*-string@1` ids as
|
|
29
|
+
well as the four `*-temporal@1` ones.
|
|
30
|
+
3. **Hand-built contracts and test doubles.** Deserializing a contract literal that names
|
|
31
|
+
a retired id now fails validation rather than resolving to something plausible.
|
|
32
|
+
4. **Introspection maps.** `date`, `timestamp`, `timestamptz` and `time` map to the bare
|
|
33
|
+
PSL names (`Date`, `Timestamp(p)`, `Timestamptz(p)`, `Time(p)`), which resolve to the
|
|
34
|
+
Temporal codecs. The `*String` names are authoring-only and must claim no
|
|
35
|
+
`targetTypes`, or they compete for introspection ownership.
|
|
36
|
+
5. **Re-emit any contract your package commits.** `build:contract-space` (or
|
|
37
|
+
`prisma contract emit`) rewrites `contract.json` and `contract.d.ts`; commit both.
|
|
38
|
+
detection:
|
|
39
|
+
glob: "**/*.{ts,mts,cts,json}"
|
|
40
|
+
regex:
|
|
41
|
+
- "pg/(date|timestamp|timestamptz|time)@1"
|
|
42
|
+
- "sql/timestamp@1"
|
|
43
|
+
anyMatch: true
|
|
44
|
+
- id: temporal-codecs-require-a-global-and-refuse-a-date
|
|
45
|
+
summary: |
|
|
46
|
+
A Temporal-backed codec reads the application's global `Temporal` implementation. Prisma
|
|
47
|
+
neither bundles nor imports a polyfill, and the check is lazy: registering a pack,
|
|
48
|
+
validating a contract, resolving a descriptor and constructing a codec instance all
|
|
49
|
+
succeed with no `Temporal` in scope. Only invoking one fails, with
|
|
50
|
+
`RUNTIME.TEMPORAL_UNAVAILABLE`.
|
|
51
|
+
|
|
52
|
+
Two consequences for an extension:
|
|
53
|
+
|
|
54
|
+
1. **Your test suites need the global.** If your package exercises a Temporal-backed
|
|
55
|
+
column, install a polyfill in a vitest `setupFiles` entry
|
|
56
|
+
(`import 'temporal-polyfill/full/global';`) and add `temporal-polyfill` as a
|
|
57
|
+
devDependency. For TypeScript to see the same global, add a `.d.ts` under your test
|
|
58
|
+
directory containing `/// <reference types="temporal-polyfill/types/global" />` — the
|
|
59
|
+
package's own `temporal-polyfill/global` types resolve to `export {}` and declare
|
|
60
|
+
nothing.
|
|
61
|
+
2. **Encode is nominally typed now.** These codecs check `Symbol.toStringTag` and refuse
|
|
62
|
+
anything that is not their own Temporal type, including a `Date`, with
|
|
63
|
+
`RUNTIME.ENCODE_FAILED` naming the codec. If your pack contributes a mutation-default
|
|
64
|
+
generator or any other value that lands in a Temporal-backed column, it must produce
|
|
65
|
+
the matching `Temporal.*` value — a `Date` no longer slips through to be serialized as
|
|
66
|
+
`Date.prototype.toString()`.
|
|
67
|
+
detection:
|
|
68
|
+
glob: "**/*.{ts,mts,cts}"
|
|
69
|
+
regex:
|
|
70
|
+
- "pg/(date|timestamp|timestamptz|time)-temporal@1"
|
|
71
|
+
anyMatch: true
|
|
72
|
+
- id: contract-space-restamp
|
|
73
|
+
summary: |
|
|
74
|
+
The emitted contract artifacts embed the toolchain version, which moves to 8.0.0-rc.6.
|
|
75
|
+
Rebuild the extension's contract space (the package's `build:contract-space` script)
|
|
76
|
+
once after upgrading so the emitted artifacts match the installed toolchain. The
|
|
77
|
+
toolchain also re-released against `@prisma/cli-engine@0.2.2` (a CLI-side fix with no
|
|
78
|
+
extension-facing surface).
|
|
79
|
+
detection:
|
|
80
|
+
glob: "**/contract.json"
|
|
81
|
+
contains:
|
|
82
|
+
- '"version": "8.0.0-rc.5"'
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
# 8.0.0-rc.5 → 8.0.0-rc.6 — Extension author upgrade instructions
|
|
86
|
+
|
|
87
|
+
# PostgreSQL temporal representations, for extension authors
|
|
88
|
+
|
|
89
|
+
There is no codemod: the retired ids map to *two* replacements each, and which one an extension
|
|
90
|
+
should name is a judgement about what its consumers do with the column. Sweep by id, decide per
|
|
91
|
+
site, then re-emit any committed contract artifact.
|
|
92
|
+
|
|
93
|
+
Four behaviours bear on an extension's own codecs. Writes serialize at full precision and let
|
|
94
|
+
PostgreSQL round to the column's declared precision, carries included. A Temporal codec rejects
|
|
95
|
+
`infinity`, years beyond roughly ±271821, and non-ISO `DateStyle` output, naming the `*String` type
|
|
96
|
+
that reads them losslessly. The driver hands temporal OIDs through as server text rather than
|
|
97
|
+
building a `Date`. And temporal expressions are cast to `text` before PostgreSQL builds JSON, so a
|
|
98
|
+
nested read returns the same text a flat one does.
|
|
99
|
+
|
|
100
|
+
## `contract-space-restamp`
|
|
101
|
+
|
|
102
|
+
For every `contract.json` matched by `detection`, run the extension package's `build:contract-space` script (or its emit command) once after upgrading. Beyond the temporal changes above, the only expected diff is the embedded `version` moving to `8.0.0-rc.6`. The toolchain also re-released against `@prisma/cli-engine@0.2.2`; that change has no extension-facing surface.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.6"
|
|
3
|
+
to: "8.0.0-rc.7"
|
|
4
|
+
changes:
|
|
5
|
+
- id: rename-orm-pagination-methods
|
|
6
|
+
summary: |
|
|
7
|
+
Rename ORM collection pagination calls from `.take(n)` to `.limit(n)` and from `.skip(n)` to `.offset(n)`. This applies to SQL and Mongo ORM collections, including relation refinements and grouped SQL collections. Do not rename Mongo query-builder `.skip(n)` calls: that lower-level API continues to mirror the `$skip` pipeline stage.
|
|
8
|
+
- id: contract-space-restamp
|
|
9
|
+
summary: |
|
|
10
|
+
The emitted `contract.json` / `contract.d.ts` embed the toolchain version, which moves
|
|
11
|
+
to 8.0.0-rc.7. Rebuild the extension's contract space (the package's `build:contract-space`
|
|
12
|
+
script) once after upgrading so the emitted artifacts match the installed toolchain. The toolchain also re-released against
|
|
13
|
+
`@prisma/cli-engine@0.2.3` (a CLI-side change with no ORM-facing surface).
|
|
14
|
+
detection:
|
|
15
|
+
glob: "**/contract.json"
|
|
16
|
+
contains:
|
|
17
|
+
- '"version": "8.0.0-rc.6"'
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# 8.0.0-rc.6 → 8.0.0-rc.7 — Extension author upgrade instructions
|
|
21
|
+
|
|
22
|
+
## `rename-orm-pagination-methods`
|
|
23
|
+
|
|
24
|
+
Find calls on Prisma 8 ORM collections in extension source and tests, then apply these translations:
|
|
25
|
+
|
|
26
|
+
- `.take(n)` → `.limit(n)`
|
|
27
|
+
- `.skip(n)` → `.offset(n)`
|
|
28
|
+
|
|
29
|
+
Apply the same translation inside `include(...)` refinement callbacks, `combine(...)` branches, and after SQL ORM `groupBy(...)`. Leave Mongo query-builder chains that start from `mongoQuery(...).from(...)` or an equivalent query-builder factory unchanged: their `.limit(...)` and `.skip(...)` methods name Mongo aggregation pipeline stages rather than the ORM collection API.
|
|
30
|
+
|
|
31
|
+
## `contract-space-restamp`
|
|
32
|
+
|
|
33
|
+
For every `contract.json` matched by `detection`, run the extension package's `build:contract-space` script (or its emit command) once after upgrading. The only expected diff beyond the pagination rename is the embedded `version` moving to `8.0.0-rc.7`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.7"
|
|
3
|
+
to: "8.0.0-rc.8"
|
|
4
|
+
changes:
|
|
5
|
+
- id: engine-pin-moves-to-0-3-0
|
|
6
|
+
summary: |
|
|
7
|
+
The toolchain now peers `@prisma/cli-engine@0.3.0` (up from 0.2.3). An extension that
|
|
8
|
+
pins `@prisma/cli-engine` in its own manifests must move the pin to `0.3.0`. The engine
|
|
9
|
+
now declares `@prisma/management-api-sdk` as a peer dependency (`^1.55.0`) instead of a
|
|
10
|
+
regular dependency; the `prisma` CLI shell supplies it at runtime, so only tooling that
|
|
11
|
+
runs the engine outside the CLI shell needs to install the SDK itself.
|
|
12
|
+
detection:
|
|
13
|
+
glob: "**/package.json"
|
|
14
|
+
contains:
|
|
15
|
+
- '"@prisma/cli-engine": "0.2.3"'
|
|
16
|
+
- id: contract-space-restamp
|
|
17
|
+
summary: |
|
|
18
|
+
The emitted `contract.json` / `contract.d.ts` embed the toolchain version, which moves
|
|
19
|
+
to 8.0.0-rc.8. Rebuild the extension's contract space (the package's `build:contract-space`
|
|
20
|
+
script) once after upgrading so the emitted artifacts match the installed toolchain.
|
|
21
|
+
detection:
|
|
22
|
+
glob: "**/contract.json"
|
|
23
|
+
contains:
|
|
24
|
+
- '"version": "8.0.0-rc.7"'
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# 8.0.0-rc.7 → 8.0.0-rc.8 — Extension author upgrade instructions
|
|
28
|
+
|
|
29
|
+
## `engine-pin-moves-to-0-3-0`
|
|
30
|
+
|
|
31
|
+
For every `package.json` matched by `detection`, change the `@prisma/cli-engine` version from `0.2.3` to `0.3.0` and reinstall. If the extension's tooling runs the engine outside the unified `prisma` CLI shell (rare), also install `@prisma/management-api-sdk` at a version satisfying `^1.55.0` — the engine now declares it as a peer dependency and no longer bundles it.
|
|
32
|
+
|
|
33
|
+
## `contract-space-restamp`
|
|
34
|
+
|
|
35
|
+
For every `contract.json` matched by `detection`, run the extension package's `build:contract-space` script (or its emit command) once after upgrading. The only expected diff is the embedded `version` moving to `8.0.0-rc.8`.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.8"
|
|
3
|
+
to: "8.0.0-rc.9"
|
|
4
|
+
changes:
|
|
5
|
+
- id: remove-nested-relations-from-sql-orm-upsert-and-batch-create
|
|
6
|
+
summary: |
|
|
7
|
+
SQL ORM `upsert({ create })`, `createAll()`, and `createAndCount()` payloads no longer accept nested relation mutation callbacks, which these operations cannot execute. Remove the callbacks and create related records separately, or use ordinary `create()` when the records must be created as one nested relation operation.
|
|
8
|
+
- id: namespace-qualify-sql-orm-filter-types
|
|
9
|
+
summary: |
|
|
10
|
+
SQL ORM reusable filter types now require the domain namespace before the model name: `<Contract, Namespace, Model>`.
|
|
11
|
+
- id: add-attributes-to-psl-extension-block-literals
|
|
12
|
+
summary: |
|
|
13
|
+
`PslExtensionBlock` gained a required `attributes` record (attribute name → `{ args, span }`, the kit-parsed values of the block's `@@` attributes). Every hand-built block node — synthesised blocks in scripts, inference builders, and test fixtures — must set `attributes` next to `blockAttributes` (`{}` when the block carries no attributes).
|
|
14
|
+
detection:
|
|
15
|
+
glob: "**/*.{ts,tsx}"
|
|
16
|
+
contains:
|
|
17
|
+
- "blockAttributes:"
|
|
18
|
+
anyMatch: true
|
|
19
|
+
- id: read-native-enum-map-failures-from-the-kit
|
|
20
|
+
summary: |
|
|
21
|
+
`PSL_NATIVE_ENUM_INVALID_MAP` no longer exists. A malformed `@@map` on a `native_enum` block — and every other malformed block attribute — is reported at symbol-table time as `PSL_INVALID_ATTRIBUTE_SYNTAX`; only the policy `@@map("")` empty-name rule keeps its own code (`PSL_POLICY_INVALID_MAP`). Replace references to the removed code and assert those diagnostics on the `buildSymbolTable` result rather than on the interpretation result.
|
|
22
|
+
detection:
|
|
23
|
+
glob: "**/*.{ts,tsx}"
|
|
24
|
+
contains:
|
|
25
|
+
- "PSL_NATIVE_ENUM_INVALID_MAP"
|
|
26
|
+
anyMatch: true
|
|
27
|
+
- id: arg-type-parse-is-a-property
|
|
28
|
+
summary: |
|
|
29
|
+
`ArgType.parse` is now a property function type carrying a `Ctx` parameter, so the ctx an argument type needs is checked contravariantly. A class that implements `ArgType` with a `parse(...)` method, or an object typed against `ArgType<T>` and used inside `blockAttribute()`, must declare `parse` as a function-typed property over the ctx it actually reads.
|
|
30
|
+
detection:
|
|
31
|
+
glob: "**/*.{ts,tsx}"
|
|
32
|
+
contains:
|
|
33
|
+
- "implements ArgType"
|
|
34
|
+
- "ArgType<"
|
|
35
|
+
anyMatch: true
|
|
36
|
+
- id: state-attribute-spec-contexts-explicitly
|
|
37
|
+
summary: |
|
|
38
|
+
The attribute-spec interpret contexts were reshaped. `BlockInterpretCtx` and `InterpretCtx` are gone, replaced by `AttributeCtx` (`sourceId` + `sourceFile`), `ModelAttributeCtx` (adds `selfModel`), and `FieldAttributeCtx` (adds a required `field` and `resolveReferencedModel()`). Contexts no longer carry `level`. `ArgType`, `OptionalArgType`, `Param`, `PositionalParam`, and `AttributeSpec` lost their default type arguments, so every use site must name its context. `fieldRef('self')` / `fieldRef('referenced')` became `fieldRef()` / `referencedFieldRef()`, and `FieldRefScope`, `FieldRefArgType`, and the `scope` property are removed. `oneOf` is one generic signature over a single context shared by every alternative, so a mixed alternation must be given that context by an annotation or a contextual type.
|
|
39
|
+
detection:
|
|
40
|
+
glob: "**/*.{ts,tsx}"
|
|
41
|
+
contains:
|
|
42
|
+
- "InterpretCtx"
|
|
43
|
+
- "fieldRef("
|
|
44
|
+
- "FieldRefScope"
|
|
45
|
+
- "FieldRefArgType"
|
|
46
|
+
- "ArgType<"
|
|
47
|
+
- "AttributeSpec<"
|
|
48
|
+
- "PositionalParam"
|
|
49
|
+
anyMatch: true
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
# 8.0.0-rc.8 → 8.0.0-rc.9 — Extension author upgrade instructions
|
|
53
|
+
|
|
54
|
+
## `remove-nested-relations-from-sql-orm-upsert-and-batch-create`
|
|
55
|
+
|
|
56
|
+
Find SQL ORM calls to `upsert()`, `createAll()`, and `createAndCount()` whose create payloads contain relation fields assigned callback functions. Remove those callbacks and create the related records separately. When the operation requires nested relation creation, replace it with ordinary `create()`, which continues to accept and execute relation mutation callbacks.
|
|
57
|
+
|
|
58
|
+
## `namespace-qualify-sql-orm-filter-types`
|
|
59
|
+
|
|
60
|
+
Find TypeScript references to `ShorthandWhereFilter`, `RelationPredicate`, `RelationPredicateInput`, and `RelationFilterAccessor`. Add the model's domain namespace as the second generic argument and place the model name third. Rewrite `ShorthandWhereFilter<Contract, Model>` as `ShorthandWhereFilter<Contract, Namespace, Model>` and `ShorthandWhereFilter<Contract, Model, Namespace>` as `ShorthandWhereFilter<Contract, Namespace, Model>`. Rewrite the relation types from `<Contract, Model>` to `<Contract, Namespace, Model>`. For predicates targeting a relation, use the namespace declared by that relation's `to.namespace` coordinate.
|
|
61
|
+
|
|
62
|
+
## `add-attributes-to-psl-extension-block-literals`
|
|
63
|
+
|
|
64
|
+
Find every object literal typed as `PslExtensionBlock` (they carry `kind`, `keyword`, `name`, `parameters`, `blockAttributes`, `span`). Add `attributes` beside `blockAttributes`. A block with no `@@` attributes takes `attributes: {}`. A block synthesised with a `blockAttributes` entry takes the parsed shape of that entry, keyed by attribute name with the spec's positional keys as `args` — for example a synthesised `@@map("x")` on a `policy_*` or `native_enum` block becomes `attributes: { map: { args: { name: 'x' }, span } }`. Consumers that read a block attribute read `block.attributes[name]?.args`, never `block.blockAttributes`.
|
|
65
|
+
|
|
66
|
+
## `read-native-enum-map-failures-from-the-kit`
|
|
67
|
+
|
|
68
|
+
Delete every reference to `PSL_NATIVE_ENUM_INVALID_MAP`. Where a test asserted that code after interpreting a document, parse the document and assert `PSL_INVALID_ATTRIBUTE_SYNTAX` on the diagnostics `buildSymbolTable` returns instead; interpretation no longer sees a malformed block attribute. A `@@map(foo)` argument reports `Expected a string literal`; a missing argument reports `Attribute "map" is missing required argument "name"`.
|
|
69
|
+
|
|
70
|
+
## `arg-type-parse-is-a-property`
|
|
71
|
+
|
|
72
|
+
Find classes declaring `implements ArgType<…>` with a `parse(arg, ctx)` method and object literals typed against `ArgType<T>`. Declare `parse` as a property whose type is `(arg: ExpressionAst, ctx: Ctx) => Result<T, readonly PslDiagnostic[]>`. Pick the narrowest `Ctx` the implementation actually reads, as the next entry describes. Dispatch on the syntax node with `XAst.cast(arg.syntax)` rather than `arg instanceof XAst` so the argument type keeps working when the spec and the parser come from different module copies.
|
|
73
|
+
|
|
74
|
+
## `state-attribute-spec-contexts-explicitly`
|
|
75
|
+
|
|
76
|
+
**Rename the context types.** `BlockInterpretCtx` becomes `AttributeCtx`. `InterpretCtx` splits: use `ModelAttributeCtx` where the code reads `selfModel` and nothing else, and `FieldAttributeCtx` where it reads `field` or `resolveReferencedModel()`. Both are exported from `@internal/psl-parser`.
|
|
77
|
+
|
|
78
|
+
**Drop `level` from every context value.** A hand-built ctx object that set `level: 'field' | 'model' | 'block'` must delete that property; contexts no longer declare it. `AttributeSpec.level` is a different field and is unchanged — keep setting and reading it.
|
|
79
|
+
|
|
80
|
+
**Move `resolveReferencedModel` down to the field level.** A model-level ctx must no longer supply it. The `resolveReferencedModel: () => undefined` stub that model-level ctx builders carried is now a type error; delete it. A field-level ctx must supply both `field` (previously optional, now required) and `resolveReferencedModel()`.
|
|
81
|
+
|
|
82
|
+
**Name a context at every use site.** `ArgType<T>`, `OptionalArgType<T>`, `Param<T>`, `PositionalParam<T>`, and `AttributeSpec<Out>` no longer default their second type argument. Rewrite each as `ArgType<T, AttributeCtx>` when the combinator reads only `sourceId` / `sourceFile`, `ArgType<T, ModelAttributeCtx>` when it reads `selfModel`, and `ArgType<T, FieldAttributeCtx>` when it reads `field` or `resolveReferencedModel()`; the same choice applies to the other four. `PositionalParam` also lost its `T = unknown` default, so a bare `PositionalParam` becomes `PositionalParam<unknown, Ctx>`. Prefer the widest context that still typechecks: a spec parameter over `AttributeCtx` is usable inside `blockAttribute()`, `modelAttribute()`, and `fieldAttribute()` alike.
|
|
83
|
+
|
|
84
|
+
**Split the field reference combinator.** Replace `fieldRef('self')` with `fieldRef()` and `fieldRef('referenced')` with `referencedFieldRef()` (imported from `@internal/psl-parser`). `fieldRef()` is typed over `ModelAttributeCtx` and stays usable in model attributes such as `@@index`; `referencedFieldRef()` is typed over `FieldAttributeCtx` and is accepted only in field attributes. The `FieldRefScope` and `FieldRefArgType` types and the `scope` property on the returned combinator are removed — a test asserting `fieldRef('self').scope` has no replacement; assert on the parse behaviour or on `label` instead.
|
|
85
|
+
|
|
86
|
+
**Give `oneOf` one context for all of its alternatives.** `oneOf` is now a single generic signature: the output is the union of the alternatives' outputs, and every alternative parses over the same context. An alternation whose alternatives all read only `sourceId` / `sourceFile` — `str()`, `num()`, `bool()`, `identifier()`, `json()`, `entityRef()`, `funcCall()` — needs nothing; its context is `AttributeCtx` and it stays usable at every level. An alternation that mixes those with a model-scoped or field-scoped alternative such as `fieldRef()` must be told which context it parses over, because `oneOf` no longer computes one from the alternatives. Supply it from the surrounding code: annotate the result (`const arm: ArgType<string, ModelAttributeCtx> = oneOf(str(), fieldRef())`), annotate the alternatives tuple before spreading it into `oneOf(...arms)`, or let the enclosing function's return type provide it. Such an alternation remains rejected inside `blockAttribute()`.
|
package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.9-to-8.0.0-rc.10/instructions.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
from: "8.0.0-rc.9"
|
|
3
|
+
to: "8.0.0-rc.10"
|
|
4
|
+
# sql-orm-client doc-comment sweep: reviewed, no entry required
|
|
5
|
+
# postgres shell dependency ownership: reviewed, no extension-author action required; bundled packages now declare the catalog Node/pg type dependencies that public shell manifests mirror
|
|
6
|
+
changes:
|
|
7
|
+
- id: schema-header-use-prisma-8
|
|
8
|
+
summary: |
|
|
9
|
+
The schema header that marks a Prisma 8 schema is now `// use prisma-8`. The language server
|
|
10
|
+
still serves the old header and its Format action rewrites it; new schemas and the
|
|
11
|
+
inferred-schema printer write the new form. Replace `// use prisma-next`
|
|
12
|
+
at the top of every `.prisma` file the extension ships or tests against.
|
|
13
|
+
detection:
|
|
14
|
+
glob: "**/*.prisma"
|
|
15
|
+
contains:
|
|
16
|
+
- "// use prisma-next"
|
|
17
|
+
- id: env-vars-drop-next-infix
|
|
18
|
+
summary: |
|
|
19
|
+
The CLI environment variables lost their `NEXT_` infix: `PRISMA_NEXT_DISABLE_TELEMETRY`,
|
|
20
|
+
`PRISMA_NEXT_TELEMETRY_ENDPOINT`, `PRISMA_NEXT_DEBUG`, and the rest are now
|
|
21
|
+
`PRISMA_DISABLE_TELEMETRY`, `PRISMA_TELEMETRY_ENDPOINT`, `PRISMA_DEBUG`, and so on. The old
|
|
22
|
+
`PRISMA_NEXT_DISABLE_TELEMETRY` opt-out is still honoured; the others are not. Rename them
|
|
23
|
+
in the extension's test setup and CI configuration.
|
|
24
|
+
detection:
|
|
25
|
+
glob: "**/*"
|
|
26
|
+
contains:
|
|
27
|
+
- "PRISMA_NEXT_"
|
|
28
|
+
- id: to-one-relations-record-nullable
|
|
29
|
+
summary: |
|
|
30
|
+
`ContractNonJunctionRelation`'s `'1:1'` and `'N:1'` members now require `nullable: boolean`,
|
|
31
|
+
and contract validation rejects a `contract.json` whose to-one relations lack it. Set
|
|
32
|
+
`nullable` on every to-one relation the extension constructs, and rebuild the extension's
|
|
33
|
+
contract space so its emitted `contract.json` / `contract.d.ts` carry the flag.
|
|
34
|
+
detection:
|
|
35
|
+
glob: "**/*.ts"
|
|
36
|
+
matches:
|
|
37
|
+
- '(?<!\bnullable\b(?:[^{}]|\{[^{}]*\})*)(?:(?<=\bon\s*:(?:[^{}]|\{[^{}]*\})*)|(?=(?:[^{}]|\{[^{}]*\})*\bon\s*:))\bcardinality:\s*[''"](?:N:1|1:1)[''"](?!(?:[^{}]|\{[^{}]*\})*\bnullable\b)'
|
|
38
|
+
- id: contract-space-re-emit-nullable
|
|
39
|
+
summary: |
|
|
40
|
+
The extension's emitted `contract.json` must carry `nullable` on every `1:1` and `N:1`
|
|
41
|
+
relation. Rebuild the contract space (the package's `build:contract-space` script) once
|
|
42
|
+
after upgrading.
|
|
43
|
+
detection:
|
|
44
|
+
glob: "**/contract.json"
|
|
45
|
+
matches:
|
|
46
|
+
- '"cardinality":\s*"(?:N:1|1:1)",\s*"on":'
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## `to-one-relations-record-nullable`
|
|
50
|
+
|
|
51
|
+
For every TypeScript file matched by `detection`, find each object literal that builds a to-one contract relation (`cardinality: 'N:1'` or `'1:1'` together with an `on` join) and add `nullable: <boolean>` to it: `true` when the relation field is optional (the local foreign-key columns are nullable), `false` when it is required. The side of a one-to-one relation that does not own the foreign key is always `nullable: true`. Contract builders and PSL authoring set the flag from the field's `?`, so only code that assembles `ContractRelation` values by hand needs the edit.
|
|
52
|
+
|
|
53
|
+
## `contract-space-re-emit-nullable`
|
|
54
|
+
|
|
55
|
+
For every `contract.json` matched by `detection`, run the extension package's `build:contract-space` script (or its emit command) once after upgrading. The expected diff is one `"nullable"` boolean per to-one relation in `contract.json`, plus the `Models` namespace, `models` constant, and `RelationKeys` import in `contract.d.ts`.
|
|
56
|
+
|
|
57
|
+
## `schema-header-use-prisma-8`
|
|
58
|
+
|
|
59
|
+
For every `.prisma` file matched by `detection`, replace the first-line header `// use prisma-next` with `// use prisma-8`. Nothing else in the file changes.
|
|
60
|
+
|
|
61
|
+
## `env-vars-drop-next-infix`
|
|
62
|
+
|
|
63
|
+
For every file matched by `detection`, replace the `PRISMA_NEXT_` prefix with `PRISMA_` on each environment variable name.
|