@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.
Files changed (81) hide show
  1. package/README.md +5 -9
  2. package/dist/contract-builder.d.mts +1 -0
  3. package/dist/contract-builder.d.mts.map +1 -1
  4. package/dist/utils__suppress-idle-connection-errors.d.mts +1 -0
  5. package/dist/utils__suppress-idle-connection-errors.mjs +2 -0
  6. package/package.json +14 -16
  7. package/skills/prisma-8/SKILL.md +96 -0
  8. package/skills/prisma-8/references/build.md +142 -0
  9. package/skills/prisma-8/references/contract.md +446 -0
  10. package/skills/prisma-8/references/debug.md +144 -0
  11. package/skills/prisma-8/references/feedback.md +251 -0
  12. package/skills/prisma-8/references/migration-model.md +175 -0
  13. package/skills/prisma-8/references/migration-review.md +241 -0
  14. package/skills/prisma-8/references/migrations.md +538 -0
  15. package/skills/prisma-8/references/queries-mongo.md +236 -0
  16. package/skills/prisma-8/references/queries-postgres.md +415 -0
  17. package/skills/prisma-8/references/queries.md +237 -0
  18. package/skills/prisma-8/references/quickstart.md +317 -0
  19. package/skills/prisma-8/references/runtime.md +366 -0
  20. package/skills/prisma-8/references/supabase.md +231 -0
  21. package/skills/prisma-8/references/upgrade-app.md +101 -0
  22. package/skills/prisma-8/references/upgrade-extension.md +105 -0
  23. package/skills/prisma-8/upgrading/app/upgrades/0.10-to-0.11/instructions.md +56 -0
  24. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md +381 -0
  25. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts +202 -0
  26. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts +201 -0
  27. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts +198 -0
  28. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
  29. package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/instructions.md +339 -0
  30. package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts +229 -0
  31. package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md +543 -0
  32. package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
  33. package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
  34. package/skills/prisma-8/upgrading/app/upgrades/0.14-to-0.15/instructions.md +359 -0
  35. package/skills/prisma-8/upgrading/app/upgrades/0.15-to-0.16/instructions.md +173 -0
  36. package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/instructions.md +805 -0
  37. package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
  38. package/skills/prisma-8/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md +72 -0
  39. package/skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md +8 -0
  40. package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md +36 -0
  41. package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
  42. package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md +86 -0
  43. package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
  44. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +588 -0
  45. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
  46. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +158 -0
  47. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +42 -0
  48. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md +157 -0
  49. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md +33 -0
  50. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md +36 -0
  51. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.8-to-8.0.0-rc.9/instructions.md +63 -0
  52. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.9-to-8.0.0-rc.10/instructions.md +84 -0
  53. package/skills/prisma-8/upgrading/extension/upgrades/0.10-to-0.11/instructions.md +276 -0
  54. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md +738 -0
  55. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts +97 -0
  56. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts +223 -0
  57. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
  58. package/skills/prisma-8/upgrading/extension/upgrades/0.12-to-0.13/instructions.md +266 -0
  59. package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md +522 -0
  60. package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
  61. package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
  62. package/skills/prisma-8/upgrading/extension/upgrades/0.14-to-0.15/instructions.md +803 -0
  63. package/skills/prisma-8/upgrading/extension/upgrades/0.15-to-0.16/instructions.md +219 -0
  64. package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/instructions.md +731 -0
  65. package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
  66. package/skills/prisma-8/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md +194 -0
  67. package/skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md +8 -0
  68. package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md +57 -0
  69. package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
  70. package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/instructions.md +150 -0
  71. package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
  72. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +746 -0
  73. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
  74. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +137 -0
  75. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +129 -0
  76. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md +102 -0
  77. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md +33 -0
  78. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md +35 -0
  79. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.8-to-8.0.0-rc.9/instructions.md +86 -0
  80. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.9-to-8.0.0-rc.10/instructions.md +63 -0
  81. package/dist/bin__prisma-next.mjs +0 -3
@@ -0,0 +1,5 @@
1
+ ---
2
+ from: "8.0.0-rc.2"
3
+ to: "8.0.0-rc.3"
4
+ changes: []
5
+ ---
@@ -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()`.
@@ -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.
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import "@prisma/orm-toolchain/bin/prisma-next";
3
- export {};