Skip to content
Merged
Show file tree
Hide file tree
Changes from 106 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
45fb5b6
TML-3537: plan for value objects in storage, and the first two dispat…
wmadden-electric Oct 23, 2026
5656914
TML-3537: refuse only an actual value-set clash, not dotted enum names
wmadden-electric Oct 23, 2026
e4cf4d2
TML-3537: list the storage entities that differ between two contracts
wmadden-electric Oct 23, 2026
a009fad
TML-3537: migration plan writes a migration with no operations when t…
wmadden-electric Oct 23, 2026
d607bde
TML-3537: a domain field refers to its value object by a storage coor…
wmadden-electric Oct 23, 2026
1792de2
TML-3537: SQL contracts store value objects under storage entries.val…
wmadden-electric Oct 23, 2026
965c0cf
TML-3537: Mongo contracts store value objects under storage entries.v…
wmadden-electric Oct 23, 2026
4f7338e
TML-3537: SQL authoring writes value objects and discriminator value …
wmadden-electric Oct 23, 2026
669f4b9
TML-3537: Mongo authoring writes value objects into storage
wmadden-electric Oct 23, 2026
d362ce9
TML-3537: test-utils createContract writes value objects into storage
wmadden-electric Oct 23, 2026
46322ba
TML-3537: a plan with no operations keeps its summary and adds what c…
wmadden-electric Oct 23, 2026
ba44c87
TML-3537: changedStorageEntities leaves out the unbound namespace id
wmadden-electric Oct 23, 2026
2de7579
TML-3537: a plan with no operations names the storage keys that chang…
wmadden-electric Oct 23, 2026
9f82c81
TML-3537: docs no longer describe the removed refusal of a plan with …
wmadden-electric Oct 23, 2026
299a8ca
TML-3537: a value object reference by name says the contract must be …
wmadden-electric Oct 23, 2026
6279851
TML-3537: valueObjectAt reads only own namespaces and tolerates a nam…
wmadden-electric Oct 23, 2026
649758e
TML-3537: a value object member's value set is typed as a storage val…
wmadden-electric Oct 23, 2026
b8916a3
TML-3537: a value object member's value set must exist in storage
wmadden-electric Oct 23, 2026
2286fe4
TML-3537: dispatch briefs for authoring and emit, and the column valu…
wmadden-electric Oct 23, 2026
d196e48
TML-3537: field types find a value object in the storage namespace it…
wmadden-electric Oct 23, 2026
0195e97
TML-3537: contract.d.ts describes value objects in the storage plane
wmadden-electric Oct 23, 2026
bbd50ff
TML-3537: a discriminator value set holds its values sorted, so decla…
wmadden-electric Oct 23, 2026
983929c
TML-3537: a discriminator value set is refused only when its namespac…
wmadden-electric Oct 23, 2026
3f08cce
TML-3537: two composite types with the same name in different PSL nam…
wmadden-electric Oct 23, 2026
207b0b6
TML-3537: test-utils writes value objects into storage without a cast
wmadden-electric Oct 23, 2026
9fe305d
TML-3537: a plan with no operations names the changed storage keys wh…
wmadden-electric Oct 23, 2026
90611d5
TML-3537: dispatch briefs for runtimes and Postgres checks, and the c…
wmadden-electric Oct 23, 2026
7f4890e
TML-3537: the Mongo ORM and query builder find a value object through…
wmadden-electric Oct 23, 2026
7d40131
TML-3537: contract.d.ts has no blank line between meta and profileHash
wmadden-electric Oct 23, 2026
4b69faf
TML-3537: rename statements find value objects in storage
wmadden-electric Oct 23, 2026
a2ef81b
TML-3537: contract print writes type blocks from the value objects in…
wmadden-electric Oct 23, 2026
ac7d924
TML-3537: the SQL ORM type test reads its value object from storage
wmadden-electric Oct 23, 2026
ab83996
TML-3537: deferred note on one value object alias per name
wmadden-electric Oct 23, 2026
cbf398e
TML-3537: Postgres derives a check for each value object column and e…
wmadden-electric Oct 23, 2026
613a5ca
TML-3537: contract print leaves out the derived value object and disc…
wmadden-electric Oct 23, 2026
a934fa1
TML-3537: docs describe the value object check and the discriminator …
wmadden-electric Oct 23, 2026
6c28383
TML-3537: validating a Mongo contract leaves its storage value object…
wmadden-electric Oct 23, 2026
c2b4f23
TML-3537: a print test reaches the refusal of a value object member w…
wmadden-electric Oct 23, 2026
0579aea
TML-3537: dot paths into a Mongo value object end at a value object a…
wmadden-electric Oct 23, 2026
2533092
TML-3537: a Mongo ORM filter encodes its value through a list index i…
wmadden-electric Oct 23, 2026
4aaa36d
Merge remote-tracking branch 'origin/main' into tml-3537-value-object…
wmadden-electric Oct 23, 2026
cf19f77
TML-3537: the MySQL and SQLite packages export the shared check expre…
wmadden-electric Oct 23, 2026
9692d3f
TML-3537: dispatch brief for re-emit, example migrations, the upgrade…
wmadden-electric Oct 23, 2026
0b3eba9
TML-3537: the Mongo ORM list-index filter test reads with first(), wh…
wmadden-electric Oct 23, 2026
1f3fbf9
TML-3537: contract print takes a value object column's nullability fr…
wmadden-electric Oct 23, 2026
04c2925
TML-3537: the Postgres value object check refuses JSON null for a req…
wmadden-electric Oct 23, 2026
06e5a73
TML-3537: the Postgres value object check requires a Decimal member t…
wmadden-electric Oct 23, 2026
7572360
TML-3537: the table lowering context names its storage storage, as re…
wmadden-electric Oct 23, 2026
3b17e63
TML-3537: hand-written test contracts and fixture generators write va…
wmadden-electric Oct 23, 2026
a37accd
TML-3537: re-emit every contract, fixture and example migration snaps…
wmadden-electric Oct 23, 2026
f8f564e
TML-3537: the prisma-8-demo initial migration creates the value objec…
wmadden-electric Oct 23, 2026
9d25b3a
TML-3537: a SQL storage value object read from JSON fills many as fal…
wmadden-electric Oct 23, 2026
58657b0
TML-3537: a prepared polymorphic select types the discriminator as it…
wmadden-electric Oct 23, 2026
ec32042
TML-3537: an upgrade script moves the value objects of a project's co…
wmadden-electric Oct 23, 2026
d4acafa
TML-3537: upgrade instructions for value objects in storage, for apps…
wmadden-electric Oct 23, 2026
0bee219
TML-3537: docs describe value objects as storage entities and the SQL…
wmadden-electric Oct 23, 2026
ed4d6b0
TML-3537: dispatch brief for journeys, the ADR number and the PR text
wmadden-electric Oct 23, 2026
9755284
TML-3537: the value objects ADR is ADR 309, since main has an ADR 278
wmadden-electric Oct 23, 2026
58e2d89
TML-3537: journeys show the value object and discriminator checks on …
wmadden-electric Oct 23, 2026
ac65eca
TML-3537: the SQL ORM fixture no longer patches a value object into i…
wmadden-electric Oct 23, 2026
b4d1c86
TML-3537: the SQL ORM value object type tests read an emitted PSL fix…
wmadden-electric Oct 23, 2026
13e112d
TML-3537: the skill and the older ADRs say value objects are storage …
wmadden-electric Oct 23, 2026
47d1e4d
TML-3537: the app upgrade guide says how to sign a database behind th…
wmadden-electric Oct 23, 2026
0e8628b
TML-3537: the extension upgrade guide covers ValueObjectTypesFromStor…
wmadden-electric Oct 23, 2026
8f59742
TML-3537: the Mongo family migration fixture's storage hash is the on…
wmadden-electric Oct 23, 2026
4c488d5
TML-3537: a Mongo ORM test builds its update with an undefined field …
wmadden-electric Oct 23, 2026
bc28697
TML-3537: the upgrade script stops with one line, not a stack trace, …
wmadden-electric Oct 23, 2026
5f48de9
TML-3537: deferred note on the SQL TypeScript builder having no value…
wmadden-electric Oct 23, 2026
07a8522
Merge remote-tracking branch 'origin/main' into tml-3537-value-object…
wmadden-electric Oct 23, 2026
059a3e6
TML-3537: the upgrade test fixture keeps the snapshot from before the…
wmadden-electric Oct 23, 2026
c6a92e7
TML-3537: dispatch brief for the fixes from the whole-branch review
wmadden-electric Oct 23, 2026
548feb2
TML-3537: both families validate a value object against one framework…
wmadden-electric Oct 23, 2026
d0e16fc
TML-3537: SQL contract validation refuses a value object member that …
wmadden-electric Oct 23, 2026
e544bbf
TML-3537: ContractWithDomain carries the storage namespaces, replacin…
wmadden-electric Oct 23, 2026
1878d5b
TML-3537: one framework walker, valueObjectsWithCoordinates, lists st…
wmadden-electric Oct 23, 2026
697b4bb
TML-3537: FieldTypesFromDomain requires the storage namespaces, the e…
wmadden-electric Oct 23, 2026
dd13414
TML-3537: re-emit every contract.d.ts with the storage namespaces pas…
wmadden-electric Oct 23, 2026
b33fa79
TML-3537: the check input types a value object column as ResolvedColu…
wmadden-electric Oct 23, 2026
bd01650
TML-3537: the Mongo validator reads each value object at the storage …
wmadden-electric Oct 23, 2026
d1f9c28
TML-3537: each Postgres codec declares the JSON type the value object…
wmadden-electric Oct 23, 2026
e1bf672
TML-3537: the codec authoring guide and the error reference describe …
wmadden-electric Oct 23, 2026
efd9ad7
TML-3537: the value object check's kind is shape, and its constraint …
wmadden-electric Oct 23, 2026
f015cac
TML-3537: the truncated shape prefix in the naming test
wmadden-electric Oct 23, 2026
708aaea
TML-3537: re-emit contracts and the prisma-8-demo migrations with the…
wmadden-electric Oct 23, 2026
bb6b0be
TML-3537: the upgrade guide and the Data Contract doc say adding a ch…
wmadden-electric Oct 23, 2026
4138620
TML-3537: migration plan reports changedElementCoordinates for every …
wmadden-electric Oct 23, 2026
89861e6
TML-3537: a storage validator beside the domain validator checks the …
wmadden-electric Oct 23, 2026
683d2c0
TML-3537: the refusal of a contract with value objects in the old sha…
wmadden-electric Oct 23, 2026
6a8e655
TML-3537: ADR 309 says why a value object has one definition, where i…
wmadden-electric Oct 23, 2026
57d70fd
TML-3537: the value object check's doc comment sits on its function, …
wmadden-electric Oct 23, 2026
3143a66
TML-3537: dispatch brief for the fixes from the second whole-branch r…
wmadden-electric Oct 23, 2026
8e27971
TML-3537: a codec declares jsonType, the JSON type its value is writt…
wmadden-electric Oct 23, 2026
8d8fddd
TML-3537: functions that read only storage take Pick<StorageBase, 'na…
wmadden-electric Oct 23, 2026
ba6d0ea
TML-3537: one framework schema validates a field's type for domain fi…
wmadden-electric Oct 23, 2026
b7c1bf1
TML-3537: regenerate the SQL contract JSON schema, which now refuses …
wmadden-electric Oct 23, 2026
63d5788
TML-3537: migration plan --json lists the changed storage entities as…
wmadden-electric Oct 23, 2026
e21fb97
TML-3537: the upgrade script writes nullable false where an old Mongo…
wmadden-electric Oct 23, 2026
3f510c4
TML-3537: ADR 221 and ADR 309 say the framework defines valueObject a…
wmadden-electric Oct 23, 2026
22fd7fb
TML-3537: the print refusal tests expect the value object named in th…
wmadden-electric Oct 23, 2026
4d902bc
TML-3537: the manual QA report for PR 3, and the brief for its fixes
wmadden-electric Oct 23, 2026
08c5d5e
TML-3537: a registered Postgres codec descriptor may lack jsonType, t…
wmadden-electric Oct 23, 2026
c8c8edf
TML-3537: the no-operations summary writes the entity kind in words, …
wmadden-electric Oct 23, 2026
cbf923e
TML-3537: when existing rows fail a check the apply adds, the failure…
wmadden-electric Oct 23, 2026
7db1126
TML-3537: the upgrade steps upgrade the packages before the script an…
wmadden-electric Oct 23, 2026
d846707
TML-3537: the demo migrations sort their snapshot imports
wmadden-electric Oct 23, 2026
1ad91b6
Merge branch 'main' of https://github.com/prisma/prisma into tml-3537…
wmadden-electric Oct 27, 2026
40fe413
Merge branch 'main' of https://github.com/prisma/prisma into tml-3537…
wmadden-electric Oct 28, 2026
b8bc677
TML-3537: the value object journeys load only workspace packages, so …
wmadden-electric Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 4 additions & 3 deletions apps/telemetry-backend/src/prisma/contract.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions docs/architecture docs/ADR-INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Open this list before you propose a new feature or surface, or judge a feature r
| 273 | A column of a type no data type claims is a raw column | A column whose database type no data type claims has data type `sql/raw`, whose parameter `sql` is the type exactly as the catalog prints it, and codec `sql/raw@1`, which passes values through typed `unknown`; migrations write the text into DDL and `db verify` compares it exactly; a Prisma 8 field declares one with ``Raw(sql`...`)``, and its default is a `sql` expression; the Prisma 7 reader reads `Unsupported("...")` as a raw column with no field | [ADR 273 - A column of a type no data type claims is a raw column.md](adrs/ADR%20273%20-%20A%20column%20of%20a%20type%20no%20data%20type%20claims%20is%20a%20raw%20column.md) |
| 275 | Client generators are field attributes, and a type alias is expanded into each column | **Implemented.** `@onCreate(fn())` and `@onUpdate(fn())` set the client's generators, resolved from the column's codec through a generator function registry the stack assembles, with params from the column's type parameters; `@default` means a database default only; a `types {}` alias may carry `@default`, `@onCreate` and `@onUpdate`, is expanded into each column, and is never stored, so `storage.types` keeps only types a contract space registers; field presets are removed from SQL and Mongo, PSL and the TypeScript builder, and targets contribute aliases such as `temporal.UpdatedAt` | [ADR 275 - Client generators are field attributes, and a type alias is expanded into each column.md](adrs/ADR%20275%20-%20Client%20generators%20are%20field%20attributes%2C%20and%20a%20type%20alias%20is%20expanded%20into%20each%20column.md) |
| 279 | Convenience types choose an explicit type from their arguments | A target can declare convenience types, named for what a field means, whose `as:` and `storage:` arguments pick one of its explicit, database-named types, with defaults that need no setup; the contract stores only the explicit type, and the tools write the convenience form. PostgreSQL's `DateTime`, `Date`, `Time` and `Duration` are the first | [ADR 279 - Convenience types choose an explicit type from their arguments.md](adrs/ADR%20279%20-%20Convenience%20types%20choose%20an%20explicit%20type%20from%20their%20arguments.md) |
| 309 | Value objects are storage entities, and a discriminator column names a value set | **Accepted.** A value object lives at `storage.namespaces.<ns>.entries.valueObject.<Name>` in both families, and a domain field refers to it by storage coordinate; a SQL discriminator column refers to a value set keyed `<Base>.<field>`; on a managed Postgres table both derive a check; a change to either changes the storage hash, and a plan with no operations is written and applied. Partially supersedes ADR 178. | [ADR 309 - Value objects are storage entities, and a discriminator column names a value set.md](adrs/ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md) |

## Query System

Expand Down Expand Up @@ -263,6 +264,7 @@ Requests answered with a no, with what to use instead. Every Accepted row is on
- **ADR 157** is partially superseded by its own October 12, 2026 amendment: the idea stands, and the amendment replaces how the contract realizes it
- **ADR 170** is partially superseded by ADR 275: its field-preset half; type constructors and namespacing stand
- **ADR 246** is superseded by ADR 275, except its two omission rules for `executionDefaults` and `typeParams`, which the Data Contract subsystem doc now states
- **ADR 178** is partially superseded by ADR 309: value objects are storage entities, not a domain section
- Field presets were removed on 2026-10-22 (ADR 275); ADRs that show them carry a dated amendment note
- **ADRs 104-118** form the core extension system architecture (decorators, attributes, capabilities, packs)
- **ADRs 126-127** introduce PSL top-level blocks and views as composable extensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ The contract has three levels, each serving a different consumer:
2. **Model storage bridge** (`model.storage`) — how domain fields connect to persistence. Sits on the model to preserve co-location. SQL carries field-to-column mappings because field names and column names can differ; Mongo carries the collection name and, in `model.storage.fields`, the key each field is stored under (`{ "field": "<stored name>" }`, an entry for every field), because field names and stored names can differ too (`id` → `_id`, `createdAt` → `_created_at`).
3. **Top-level storage** (`storage`) — the database schema itself. SQL: every table, every column with its native type, nullability constraint, default, plus indexes and foreign keys. Mongo: collection metadata (indexes, validators). Consumed by migration tooling, schema introspection, and DDL generation.

**Note:** value objects are not at the domain level. They live in storage, at `storage.namespaces.<ns>.entries.valueObject`, and a domain field that holds one refers to it by its storage coordinate, because their fields are the keys every row stores ([ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md)).

`model.storage` sits on the model (not in a separate section) to preserve co-location. In SQL, field-to-column mappings like `"name": { "column": "display_name" }` need their table context nearby — separating them would leave column references dangling. For a consumer that only cares about the domain, `model.storage` is a clearly scoped block to skip. The separation is logical, not physical.

### Redundancy between levels
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ These are independent properties. This composability is why we rejected labeled

### Value objects use the same mechanism

> **Note:** value objects are now storage entities, at `storage.namespaces.<ns>.entries.valueObject`, not a domain `valueObjects` section ([ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md)). On SQL, a base model's discriminator column also refers to a value set of its variants' values.

The `discriminator`/`variants`/`base` pattern applies identically to value objects in the `valueObjects` section ([ADR 178](ADR%20178%20-%20Value%20objects%20in%20the%20contract.md)). A base value object declares a discriminator and variants; each variant declares its base and adds type-specific fields:

```json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## At a glance

> **Note:** this ADR describes value objects in the domain plane, where they first lived. They are now storage entities ([ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md)); the shapes of their members below are unchanged, and a field now refers to its value object by storage coordinate rather than by name.

A User model with scalar fields and value object fields. Value objects are defined in a separate `valueObjects` section — they share the same field descriptor shape (`{ nullable, codecId }`) as models, but the framework makes fundamentally different promises about them.

```json
Expand Down Expand Up @@ -103,6 +105,8 @@ This extends the framework commitment hierarchy:

### Value objects are a top-level contract section

> **Superseded:** value objects now live in the storage plane, at `storage.namespaces.<ns>.entries.valueObject`, and a domain field refers to one by its storage coordinate. See [ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md).

Value objects live in a `valueObjects` section alongside `models`. They use the same field shape (`{ nullable, codecId }`) as model fields. Refer to the [At a glance](#at-a-glance) example for the complete structure.

**Why not inside `models`?** The `models` section carries an implicit promise: everything here is a full framework citizen. Mixing in value objects conflates two concepts with different guarantees. Consumers iterating `models` (the ORM building its graph, migration tooling planning DDL, validation checking integrity constraints) would need to filter by kind.
Expand Down Expand Up @@ -168,6 +172,8 @@ You say `boundingBox.topLeft`, not `boundingBox[0]`. Length constraints on homog

### Value objects need no special storage mapping

> **Superseded:** the value object's definition is now a storage entity, so a change to its fields changes the storage hash. See [ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md).

Value object fields use `storage.fields` like any other field. The storage layer maps domain field names to physical locations without knowing whether the field holds a scalar or a composite:

**Mongo:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
**Status:** Accepted
**Date:** 2026-05-20

> **Note:** value objects have since moved out of the domain plane. They are storage entities, at `storage.namespaces.<ns>.entries.valueObject`, and a domain field refers to one by coordinate ([ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md)). The domain `valueObjects` key shown below no longer exists.

---

## A concrete example
Expand Down Expand Up @@ -143,6 +145,8 @@ The built-in kinds (`tables`, `collections`) stay hardcoded inside their family

The mechanism's value is that it satisfies two requirements at once: a kind is contributed at the framework level (so authoring tools — the PSL interpreter, the TS DSL, the emitter — all see it) *without* any target-specific symbol appearing in the framework or in sibling-target packages. A cheaper-looking option — keep a kind hardcoded but move the hardcode from the framework into the pack — fails the second requirement, because the slot name still leaks into the framework's authoring-tool dispatch.

**Kinds the framework defines or reads.** One storage kind is not contributed but defined by the framework, because domain fields refer to it: `valueObject`. The framework reads it by slot key, validates a value object's fields against one schema that both families use, and types it in `contract.d.ts`. Where a value object member names a value set, the framework also reads the `valueSet` slot by key, to check that the reference resolves; the families define the value set entity. Each family still registers a descriptor and an IR class for both kinds. See [ADR 309](ADR%20309%20-%20Value%20objects%20are%20storage%20entities%2C%20and%20a%20discriminator%20column%20names%20a%20value%20set.md).

## The `Namespace` interface

The framework's `Namespace` interface declares only `{ id, kind }`. Family-specific slots live on family-shaped namespace types — `SqlNamespace = Namespace & { tables: …, [...packContributedSlots] }`, `MongoNamespace = Namespace & { collections: … }`. The framework type is honest about what the framework actually knows.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ The Prisma 7 reader builds the contract directly and writes no aliases. It reads

- **Breaking for schemas.** Every preset call and every `@default(<client function>())` must be rewritten. `@updatedAt` keeps being refused in Prisma 8 PSL, with a hint that names `@onCreate(now()) @onUpdate(now())` and `temporal.UpdatedAt`.
- **Hashes.** Rewriting a preset or `@default(uuid())` as attributes changes no hash when the column and generators are the same. A contract with a `types {}` block or TypeScript `types` gets a new storage hash, because its columns lose `typeRef` and gain inline params. Supabase's space contract gets a new hash. pgvector's and PostGIS's do not.
- **Upgrade.** The upgrade instructions ship a script that rewrites stored contracts and migration snapshots into the expanded form and refreshes their hashes, as the removal of `@noCheck` did. Users then re-emit and run `db sign` against every database. `migration plan` alone cannot record the new hash, because the change has no operations. The instructions also give the PSL and TypeScript rewrites for presets.
- **Upgrade.** The upgrade instructions ship a script that rewrites stored contracts and migration snapshots into the expanded form and refreshes their hashes, as the removal of `@noCheck` did. Users then re-emit and run `db sign` against every database. The change has no operations; since ADR 309, `migration plan` writes such a migration with no operations, and `db migrate` applies it by moving the marker to the new hash. The instructions also give the PSL and TypeScript rewrites for presets.
- **Breaking for extension authors.** A default function can no longer lower to a client generator: `ControlMutationDefaultEntry.lower` returns a database default only. An extension that generated a value through a default function, such as `slugid()`, contributes a generator function with a binding for each codec it fills instead. `printArguments` and `applicableCodecIds` are removed; a binding declares the codecs it fills and how `contract print` writes each generator.
- **Diagnostics.** The `PSL_PRESET_*` diagnostics and the refusal of preset-only generators in `@default` are removed. `@default(uuid())` gets a refusal that names `@onCreate(uuid())`. (Amended 2026-10-22.) A preset call is `PSL_UNRESOLVED_REFERENCE` with its rewrite. Mongo's `PSL_PRESET_ON_VARIANT_FIELD` and `PSL_PRESET_CONFLICT`, which also fire for `@onCreate` and `@onUpdate`, are renamed `PSL_GENERATOR_ON_VARIANT_FIELD` and `PSL_GENERATOR_CONFLICT`.
- **Less code.** The `fieldPreset` descriptor kind, `instantiateAuthoringFieldPreset`, the `authoring.field` namespace, the `option`, `number` and `object` argument kinds, the `select` template node, the `path` and `default` of an argument reference, the PSL text parsers only those kinds used, the temporal preset builders, `field.generated(...)` with the `@internal/ids` spec helpers, and the preset print search are removed (amended 2026-10-22). Only the `value` argument kind is left. The language server loses its field-preset completion and hover branches.
Expand Down
Loading
Loading