@prisma/orm-mongo 8.0.0-rc.15-dev.3 → 8.0.0-rc.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/orm-mongo",
3
- "version": "8.0.0-rc.15-dev.3",
3
+ "version": "8.0.0-rc.16",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -10,18 +10,18 @@
10
10
  "skills"
11
11
  ],
12
12
  "dependencies": {
13
- "@prisma/orm-family-mongo": "8.0.0-rc.15-dev.3",
14
- "@prisma/orm-framework": "8.0.0-rc.15-dev.3",
15
- "@prisma/orm-target-mongo": "8.0.0-rc.15-dev.3",
16
- "@prisma/orm-toolchain": "8.0.0-rc.15-dev.3",
13
+ "@prisma/orm-family-mongo": "8.0.0-rc.16",
14
+ "@prisma/orm-framework": "8.0.0-rc.16",
15
+ "@prisma/orm-target-mongo": "8.0.0-rc.16",
16
+ "@prisma/orm-toolchain": "8.0.0-rc.16",
17
17
  "mongodb-connection-string-url": "^7.0.1",
18
18
  "pathe": "^2.0.3",
19
19
  "tinyglobby": "^0.2.17"
20
20
  },
21
21
  "devDependencies": {
22
- "@internal/mongo": "8.0.0-rc.15-dev.3",
23
- "@repo/tsconfig": "8.0.0-rc.15-dev.3",
24
- "@repo/tsdown": "8.0.0-rc.15-dev.3",
22
+ "@internal/mongo": "8.0.0-rc.16",
23
+ "@repo/tsconfig": "8.0.0-rc.16",
24
+ "@repo/tsdown": "8.0.0-rc.16",
25
25
  "tsdown": "0.22.14",
26
26
  "typescript": "5.9.3"
27
27
  },
@@ -15,7 +15,7 @@ description: >-
15
15
  ORM 7 or earlier (schema.prisma + @prisma/client).
16
16
  metadata:
17
17
  library: '@prisma/orm-mongo'
18
- library_version: '8.0.0-rc.15-dev.3'
18
+ library_version: '8.0.0-rc.16'
19
19
  version: '2026-09-12'
20
20
  ---
21
21
 
@@ -0,0 +1,108 @@
1
+ ---
2
+ from: "8.0.0-rc.15"
3
+ to: "8.0.0-rc.16"
4
+ changes:
5
+ - id: engine-pin-moves-to-0-6-3
6
+ summary: |
7
+ The toolchain now requires `@prisma/cli-engine@0.6.3` (up from 0.6.2). A project that pins `@prisma/cli-engine` itself must move the pin to `0.6.3`. The engine's only change is that it accepts any ArkType `^2.2.7`, so it shares one ArkType copy with the Prisma ORM packages.
8
+ detection:
9
+ glob: "**/package.json"
10
+ contains:
11
+ - '"@prisma/cli-engine": "0.6.2"'
12
+ - id: default-refusals-point-at-the-written-value
13
+ summary: |
14
+ `@default` reports `PSL_VALUE_TYPE_INCOMPATIBLE` and `PSL_INVALID_LITERAL` at the written value, or at the list element they are about, not at the whole attribute. The `@default` list no longer offers `sql` as an element.
15
+ detection:
16
+ glob: "**/*.{ts,mts,cts,js,mjs}"
17
+ matches:
18
+ - '\bPSL_VALUE_TYPE_INCOMPATIBLE\b'
19
+ - '\bPSL_INVALID_LITERAL\b'
20
+ - 'list of \([^)]*\bsql`\.\.\.`'
21
+ - id: default-refusals-say-what-to-write
22
+ summary: |
23
+ A `@default` refusal from the cast rule starts with what to write instead, as in `Expected a number`, not the list of types the column casts from. It names the column's type and the value's type only when a value of an admitted form is still refused, such as a number too large for the column. `Unknown literal tag` in a `@default` starts with the field it is about, and `this target has no data type for` comes after what to write.
24
+ detection:
25
+ glob: "**/*.{ts,mts,cts,js,mjs,json}"
26
+ matches:
27
+ - '; it casts from '
28
+ - '(: |[''"`])this target has no data type for a (string|boolean|number) value[''"`]'
29
+ - '[''"`]Unknown literal tag '
30
+ - id: function-call-arguments-keep-their-diagnostics
31
+ summary: |
32
+ A call to a function that exactly one alternative of an attribute argument names, such as `@default(uuid(5))`, reports what is wrong with its arguments instead of `Expected one of: …`.
33
+ detection:
34
+ glob: "**/*.{ts,mts,cts,js,mjs}"
35
+ matches:
36
+ - 'Expected one of: string \| number \| boolean \| autoincrement\(\)'
37
+ - id: contract-artifacts-restamp
38
+ summary: |
39
+ An extension that writes its own package version into the contracts it emits, such as the
40
+ Supabase extension, now writes 8.0.0-rc.16. Run `contract emit` once after upgrading so the
41
+ emitted `contract.json` and `contract.d.ts` match the installed extension.
42
+ detection:
43
+ glob: "**/contract.json"
44
+ contains:
45
+ - '"version": "8.0.0-rc.15"'
46
+ ---
47
+
48
+ # 8.0.0-rc.15 → 8.0.0-rc.16 — User upgrade instructions
49
+
50
+ ## `engine-pin-moves-to-0-6-3`
51
+
52
+ For every `package.json` matched by `detection`, change the `@prisma/cli-engine` version from `0.6.2` to `0.6.3` and reinstall. Projects assembled by the `prisma` CLI resolve the engine automatically.
53
+
54
+ Engine 0.6.2 required ArkType `2.2.3` exactly, while the Prisma ORM packages accept any `^2.2.2`. A package manager could then install two ArkType copies, and with Bun `prisma contract emit` failed on a valid contract with `CONTRACT.VALIDATION_FAILED`. Engine 0.6.3 accepts `^2.2.7`, so one copy serves both. Nothing in the engine's commands or output changes.
55
+
56
+ ## `default-refusals-point-at-the-written-value`
57
+
58
+ This entry, `default-refusals-say-what-to-write` and `function-call-arguments-keep-their-diagnostics` matter only to code that reads the location of a PSL diagnostic, or the text of a diagnostic message, such as a test that asserts one. Schemas and contracts do not change.
59
+
60
+ `PSL_VALUE_TYPE_INCOMPATIBLE` and `PSL_INVALID_LITERAL` from `@default` used to point at the whole `@default(...)` attribute. They now point at the written value. When the message names a list element (`at element 2`), they point at that element. The codes are unchanged; the next section describes the new wording. `PSL_DEFAULT_LIST_EXPECTED` and `PSL_INVALID_DEFAULT_LITERAL` still point at the attribute.
61
+
62
+ For `tags Int[] @default([1, "x"])`, the diagnostic `Field "Post.tags" at element 2: Expected a number` now spans `"x"`.
63
+
64
+ When a tagged literal has both an unknown tag and a NUL character or more text than the limit, `@default` now reports the canonicalization code, `PSL_TAGGED_LITERAL_NUL` or `PSL_TAGGED_LITERAL_TOO_LARGE`, where it used to report `PSL_UNKNOWN_LITERAL_TAG`.
65
+
66
+ This supersedes the last row of the table in `default-diagnostic-codes-changed` in the 8.0.0-rc.14 to 8.0.0-rc.15 guide: a `sql` literal inside a list literal is reported with `PSL_VALUE_TYPE_INCOMPATIBLE` at the element, not at the `@default` attribute.
67
+
68
+ Update an assertion on the span or range of one of these diagnostics to the written value.
69
+
70
+ ### `sql` is no longer offered as a list element
71
+
72
+ A `sql` literal is never a list element, so the list arm of `@default` no longer lists it. The editor stops offering `sql` inside `@default([`, and an `Expected one of` message for `@default` ends with `list of (string | number | boolean | json`...`)` instead of `list of (string | number | boolean | sql`...` | json`...`)`. A `sql` literal written inside a list is still refused by the cast rule, as before.
73
+
74
+ Update an assertion on that message to the new text.
75
+
76
+ ## `default-refusals-say-what-to-write`
77
+
78
+ `@default` and every other position that takes a value of a data type now word a refusal of the cast rule the same way. A refusal starts with what to write instead, the forms the column's type admits, as in `Expected a number`, not the list of types it casts from. It names the column's type and the value's type only when the value has an admitted form and is still refused, such as a number too large for the column. A quoted string on a column whose type has a tag also gets that string as a tagged literal to write, when the column's type takes it, as the `Jsonb` row shows. An element of a list written on a column whose type has a list cast, such as a vector, is refused with the forms of the list cast's element types. The two other refusals change as the table shows. The codes do not change.
79
+
80
+ | Written | Message before | Message now |
81
+ | --- | --- | --- |
82
+ | `count Int @default(100000000000000099)` | `Field "N.count": pg/int4 has no cast from pg/int8; it casts from pg/int2` | `Field "N.count": Expected a number that pg/int4 can hold; got pg/int8` |
83
+ | `meta Jsonb @default("{}")` | `Field "N.meta": pg/jsonb has no cast from pg/text; it casts from pg/json` | ``Field "N.meta": Expected json`...`; write json`{}` `` |
84
+ | `count Int @default([1])` | `Field "N.count": pg/int4 has no cast from a list; it casts from pg/int2` | `Field "N.count": Expected a number; got a list` |
85
+ | `embed pgvector.Vector(3) @default([1, "x", 3])` | `Field "N.embed" at element 2: pgvector/vector has no cast from pg/text; it casts from pg/int2, pg/int4, pg/int8, pg/numeric` | `Field "N.embed" at element 2: Expected a number` |
86
+ | `active Int @default(true)` on SQLite | `Field "N.active": this target has no data type for a boolean value` | `Field "N.active": Expected a number; this target has no data type for a boolean value` |
87
+ | ``v String @default(pg.sql`x`)`` | `Unknown literal tag "pg.sql". Known tags: sql, json.` | `Field "N.v": Unknown literal tag "pg.sql". Known tags: sql, json.` |
88
+ | ``tags String[] @default([sql`'a'`])`` | `Field "Post.tags" at element 1: pg/text has no cast from sql/expression; it casts from nothing` | `Field "Post.tags" at element 1: Expected a quoted string` |
89
+ | `enum P { @@type("pg/text@1") Low = 1 }` | `enum "P" member "Low": pg/text has no cast from pg/int2; it casts from nothing` | `enum "P" member "Low": Expected a quoted string` |
90
+ | `enum P { Low = 3000000000 }`, an enum without `@@type` | `enum "P" member "Low": pg/int4 has no cast from pg/int8; it casts from pg/int2` | `enum "P" member "Low": Expected a number that pg/int4 can hold; got pg/int8` |
91
+
92
+ Update an assertion on one of these messages to the new text.
93
+
94
+ ## `function-call-arguments-keep-their-diagnostics`
95
+
96
+ A call to a default function with wrong arguments used to report `PSL_INVALID_ATTRIBUTE_SYNTAX` with `Expected one of: string | number | boolean | autoincrement() | …` at the whole `@default` value. When exactly one alternative names the called function, the diagnostic now comes from that function, at the argument it is about. The code is still `PSL_INVALID_ATTRIBUTE_SYNTAX`. The same holds for any attribute argument that offers several functions, such as the field functions of a MongoDB `@@index`.
97
+
98
+ | Written | Message before | Message now |
99
+ | --- | --- | --- |
100
+ | `@default(uuid(5))` | `Expected one of: string \| number \| …`, at `uuid(5)` | `Expected one of: 4 \| 7`, at `5` |
101
+ | `@default(nanoid(1))` | `Expected one of: string \| number \| …`, at `nanoid(1)` | `Expected an integer between 2 and 255`, at `1` |
102
+ | `@default(cuid())` | `Expected one of: string \| number \| …`, at `cuid()` | `Attribute "cuid" is missing required argument "version"`, at `cuid()` |
103
+
104
+ A call to a function no alternative names, such as `@default(other(1))`, still reports `Expected one of: …`. Schemas and contracts do not change. Update an assertion on the old message or span to the new one.
105
+
106
+ ## `contract-artifacts-restamp`
107
+
108
+ For every `contract.json` matched by `detection`, run the project's emit command (`prisma contract emit`, or the project's `contract:emit` script) once after upgrading. This entry accounts for the extension's embedded `version` moving to `8.0.0-rc.16`; any other difference in the emitted files comes from an earlier entry in this guide.
@@ -0,0 +1,223 @@
1
+ ---
2
+ from: "8.0.0-rc.15"
3
+ to: "8.0.0-rc.16"
4
+ changes:
5
+ - id: engine-pin-moves-to-0-6-3
6
+ summary: |
7
+ The toolchain now peers `@prisma/cli-engine@0.6.3` (up from 0.6.2). An extension package that pins `@prisma/cli-engine` for its tests or tooling must move the pin to `0.6.3`. The engine's only change is that it accepts any ArkType `^2.2.7`, so it shares one ArkType copy with the Prisma ORM packages.
8
+ detection:
9
+ glob: "**/package.json"
10
+ contains:
11
+ - '"@prisma/cli-engine": "0.6.2"'
12
+ - id: spec-contexts-carry-data-types
13
+ summary: |
14
+ `ControlDefaultRegistries` loses `dataTypeEntries`. An attribute spec context carries the stack's data types as `dataTypes: DataTypeSupport`, and `createBinder` and the Mongo PSL interpreter take them as `dataTypes`.
15
+ detection:
16
+ glob: "**/*.{ts,mts,cts}"
17
+ matches:
18
+ - '\bcontrolMutationDefaults\s*:\s*\{[^}]*\bdataTypeEntries\s*:'
19
+ - '\b(AttributeSpecContext|FieldAttributeSpecContext|ControlDefaultRegistries)\b'
20
+ - '\bcreateBinder\s*\('
21
+ - '\binterpretPslDocumentToMongoContract\s*\('
22
+ - id: stack-and-source-context-carry-data-types
23
+ summary: |
24
+ `ControlStack` replaces `dataTypeLookup` with `dataTypes: DataTypeSupport`. `ContractSourceContext`, `InterpretPslDocumentToSqlContractInput` and `InterpretPrisma7DocumentsInput` replace `dataTypeLookup` with `dataTypes: DataTypeSupport`.
25
+ detection:
26
+ glob: "**/*.{ts,mts,cts}"
27
+ matches:
28
+ - '\bdataTypeLookup\s*:'
29
+ - '\b(context|stack)\.dataTypeLookup\b'
30
+ - id: print-path-carries-data-types
31
+ summary: |
32
+ `SqlPslBuildContext` replaces `dataTypeLookup` and `authoringContributions.dataTypes` with `dataTypes: DataTypeSupport`. `DefaultMappingOptions` replaces `dataTypeEntries` and `dataTypeLookup` with `dataTypes: DataTypeSupport`.
33
+ detection:
34
+ glob: "**/*.{ts,mts,cts}"
35
+ matches:
36
+ - '\b(SqlPslBuildContext|DefaultMappingOptions)\b'
37
+ - '\bdataTypeEntries\s*:'
38
+ - '\bcontext\.authoringContributions\.dataTypes\b'
39
+ - id: cast-rule-moves-to-the-framework
40
+ summary: |
41
+ `entryForTag`, `WrittenValue` and `DataTypeSupport` are no longer exported from `@internal/sql-contract-psl/resolution`. Import them from `@internal/framework-components/authoring`, which also exports the cast rule for one written value. `DefaultRefusal` is the framework's refusals plus the default-only ones: its `no-cast` arm names `receivingType`, not `columnType`, and `readDataTypeDefault` takes `dataTypes`, not `support`.
42
+ detection:
43
+ glob: "**/*.{ts,mts,cts}"
44
+ matches:
45
+ - 'import\s*(type\s*)?\{[^}]*\b(entryForTag|WrittenValue|DataTypeSupport)\b[^}]*\}\s*from\s*[''"]@internal/sql-contract-psl/resolution[''"]'
46
+ - '\b(readDataTypeDefault|DefaultRefusal)\b'
47
+ - id: tagged-literal-text-renames
48
+ summary: |
49
+ The canonical value of a tagged literal is its text: `TaggedLiteralCanonicalization` carries `text`, not `body`; `TaggedLiteralExprAst.body()` is `text()`; `parseJsonBody` and `printJsonBody` are `parseJsonText` and `printJsonText`; `checkSqlDefaultBody` and `reservedSqlDefaultBody` are `checkSqlDefaultText` and `reservedSqlDefaultText`.
50
+ detection:
51
+ glob: "**/*.{ts,mts,cts}"
52
+ matches:
53
+ - '\b(parseJsonBody|printJsonBody)\b'
54
+ - '\b(canonicalizeTaggedLiteralBody|TaggedLiteralCanonicalization|TaggedLiteralExprAst)\b'
55
+ - '\b(checkSqlDefaultBody|reservedSqlDefaultBody)\b'
56
+ - id: one-of-returns-the-claiming-alternative
57
+ summary: |
58
+ An argument type may claim an argument whose shape is its own (`ArgType.claims`); `funcCall` claims a call to its name. When exactly one `oneOf` alternative claims the argument, `oneOf` returns its result, success or failure, and tries no other alternative.
59
+ detection:
60
+ glob: "**/*.{ts,mts,cts}"
61
+ matches:
62
+ - '\bfuncCall\s*\('
63
+ - id: default-refusals-point-at-the-written-value
64
+ summary: |
65
+ `@default` reports `PSL_VALUE_TYPE_INCOMPATIBLE` and `PSL_INVALID_LITERAL` at the written value, or at the list element they are about, not at the whole attribute. The `@default` list no longer offers `sql` as an element.
66
+ detection:
67
+ glob: "**/*.{ts,mts,cts,js,mjs}"
68
+ matches:
69
+ - '\bPSL_VALUE_TYPE_INCOMPATIBLE\b'
70
+ - '\bPSL_INVALID_LITERAL\b'
71
+ - 'list of \([^)]*\bsql`\.\.\.`'
72
+ - id: default-refusals-say-what-to-write
73
+ summary: |
74
+ A `@default` refusal from the cast rule starts with what to write instead, as in `Expected a number`, not the list of types the column casts from. It names the column's type and the value's type only when a value of an admitted form is still refused, such as a number too large for the column. `Unknown literal tag` in a `@default` starts with the field it is about, and `this target has no data type for` comes after what to write.
75
+ detection:
76
+ glob: "**/*.{ts,mts,cts,js,mjs,json}"
77
+ matches:
78
+ - '; it casts from '
79
+ - '(: |[''"`])this target has no data type for a (string|boolean|number) value[''"`]'
80
+ - '[''"`]Unknown literal tag '
81
+ ---
82
+
83
+ # 8.0.0-rc.15 → 8.0.0-rc.16 — Extension author upgrade instructions
84
+
85
+ ## `engine-pin-moves-to-0-6-3`
86
+
87
+ For every `package.json` matched by `detection`, change the `@prisma/cli-engine` version from `0.6.2` to `0.6.3` and reinstall.
88
+
89
+ Engine 0.6.2 required ArkType `2.2.3` exactly, while the Prisma ORM packages accept any `^2.2.2`. With two ArkType copies installed, a type your package exports from an ArkType schema can fail to build its declarations with `TS2742`, because the inferred type names the other copy's path. After moving the pin, make sure your lockfile resolves a single ArkType version, for example with `pnpm dedupe`. Nothing in the engine's commands or output changes.
90
+
91
+ ## `spec-contexts-carry-data-types`
92
+
93
+ `ControlDefaultRegistries` held the function registry and the stack's data type authoring entries. It now holds only `defaultFunctionRegistry`. The data types move to the attribute spec context, with their lookup:
94
+
95
+ ```ts
96
+ import type { DataTypeSupport } from '@internal/framework-components/authoring';
97
+
98
+ interface AttributeSpecContext {
99
+ readonly symbols: SymbolTable;
100
+ readonly model: ModelSymbol;
101
+ readonly controlMutationDefaults: ControlDefaultRegistries;
102
+ readonly dataTypes: DataTypeSupport; // { entries, lookup }
103
+ }
104
+ ```
105
+
106
+ Where code builds a spec context, a binder or a Mongo interpreter input, move the entries out of `controlMutationDefaults` and pass the stack's data types beside it:
107
+
108
+ ```diff
109
+ createBinder({
110
+ sources,
111
+ symbolTable,
112
+ typeConstructors,
113
+ attributeSpecs,
114
+ - controlMutationDefaults: { defaultFunctionRegistry, dataTypeEntries: context.authoringContributions.dataTypes },
115
+ + controlMutationDefaults: { defaultFunctionRegistry },
116
+ + dataTypes: context.dataTypes,
117
+ });
118
+ ```
119
+
120
+ - `createBinder` requires `dataTypes`.
121
+ - `createSqlBinder` and `createMongoBinder` require `dataTypes`.
122
+ - `interpretPslDocumentToMongoContract` and the Prisma 6 MongoDB contract source's `interpretPrisma6Documents` require `dataTypes`.
123
+ - A spec context literal (`{ symbols, model, controlMutationDefaults }`) adds `dataTypes`.
124
+ - A stack that registers no data types, and a test that needs none, passes `EMPTY_DATA_TYPES` from `@internal/psl-parser`.
125
+ - A spec factory that read `ctx.controlMutationDefaults.dataTypeEntries` reads `ctx.dataTypes.entries`.
126
+
127
+ ## `stack-and-source-context-carry-data-types`
128
+
129
+ `ControlStack` replaces `dataTypeLookup` with `dataTypes: DataTypeSupport`: its registered data types (`lookup`) with their authoring entries (`entries`, the same object as `authoringContributions.dataTypes`). Code that read `stack.dataTypeLookup` reads `stack.dataTypes.lookup`. `ContractSourceContext` replaces `dataTypeLookup` with the same `dataTypes`, and so do the inputs of the SQL and Prisma 7 interpreters. The SQL interpreter no longer reads entries from `authoringContributions.dataTypes`.
130
+
131
+ ```diff
132
+ const context: ContractSourceContext = {
133
+ authoringContributions: stack.authoringContributions,
134
+ - dataTypeLookup: stack.dataTypeLookup,
135
+ + dataTypes: stack.dataTypes,
136
+ ...
137
+ };
138
+
139
+ interpretPslDocumentToSqlContract({
140
+ - dataTypeLookup: lookup,
141
+ - authoringContributions: { ...contributions, dataTypes: entries },
142
+ + dataTypes: { entries, lookup },
143
+ + authoringContributions: contributions,
144
+ ...
145
+ });
146
+ ```
147
+
148
+ A test that passed a lookup without entries passes `{ entries: {}, lookup }`. Code that read `context.dataTypeLookup` reads `context.dataTypes.lookup`.
149
+
150
+ ## `print-path-carries-data-types`
151
+
152
+ `SqlPslBuildContext`, which a target's `buildPslContract` receives, carries `dataTypes: DataTypeSupport` from `stack.dataTypes` in place of `dataTypeLookup`, and its `authoringContributions` no longer includes `dataTypes`. `DefaultMappingOptions`, which `mapDefault` takes, had `dataTypeEntries` beside `dataTypeLookup`; it now has one `dataTypes: DataTypeSupport`.
153
+
154
+ ```diff
155
+ mapDefault(columnDefault, {
156
+ - dataTypeEntries: context.authoringContributions.dataTypes,
157
+ - dataTypeLookup: context.dataTypeLookup,
158
+ + dataTypes: context.dataTypes,
159
+ columnCodec,
160
+ });
161
+ ```
162
+
163
+ A hand-built `SqlPslBuildContext` or `DefaultMappingOptions` passes `dataTypes: { entries, lookup }`. Code that read `options.dataTypeLookup.get(...)` reads `options.dataTypes.lookup.get(...)`.
164
+
165
+ ## `one-of-returns-the-claiming-alternative`
166
+
167
+ `oneOf` used to try its alternatives in order and, when all failed, report `Expected one of: …` at the whole argument. Now an argument type may claim an argument whose shape is its own, through the optional `claims(arg)` on `ArgType`, and when exactly one alternative claims the argument, `oneOf` returns that alternative's result, success or failure. `funcCall` claims a call to its name whose callee is a plain identifier. A wrong argument is then reported inside the call, for example `Expected one of: 4 | 7` at the `5` of `uuid(5)`. A call to a dotted or colon-qualified name, a call no alternative names, and a call two alternatives name still try every alternative in order.
168
+
169
+ An alternative of your own that accepts call expressions, placed beside a `funcCall` of the same name, is no longer tried for that call. Give the function one alternative, or rename one of them. An argument type of your own may implement `claims` when a malformed argument of its shape should be reported with its own diagnostics. Update an assertion on an `Expected one of` message for such a call to the diagnostic of the function.
170
+
171
+ ## `cast-rule-moves-to-the-framework`
172
+
173
+ `@internal/framework-components/authoring` exports the ADR 254 cast rule for one written value: `WrittenValue`, `WrittenScalar`, `DataTypeSupport`, `TypedValue`, `ReadRefusal`, `CastRefusal`, `entryForTag`, `entryForPlain`, `knownTags`, `readWrittenValue`, `castTypedValue`, `admittedTags`, `admittedForms`, `tagForm` and `describeAdmittedForms`, and the wording of a refusal: `WrittenForm`, `RefusalGuidance`, `describeRefusal`, which words a refusal as a PSL code and message, `describeExpected`, `describeRefusedValueType` and `exactRewrite`. `@internal/sql-contract-psl/resolution` no longer exports `entryForTag`, `WrittenValue` or `DataTypeSupport`; change those imports to `@internal/framework-components/authoring`.
174
+
175
+ `readDataTypeDefault`, `DefaultRefusal` and `DefaultColumn` stay in `@internal/sql-contract-psl/resolution`. `readDataTypeDefault` takes the stack's data types as `dataTypes`, not `support`, and a refused result carries `suggestedTypes`, the types whose written forms a message suggests. `DefaultRefusal` is the framework's `ReadRefusal` and `CastRefusal` with `elementIndex`, plus `not-a-list`, `no-list-cast`, `no-element-cast` and `undecodable`. Code that read `refusal.columnType` on a `no-cast` refusal reads `refusal.receivingType`. A list written on a column whose type has no list cast is now `no-list-cast`, where it was a `no-cast` whose `valueType` was `'a list'`. An element of a written list that the column type's list cast does not take is now `no-element-cast`, with `receivingType`, `valueType` and the cast's `elementTypes`, where it was a `no-cast` whose `casts` were the list cast's element types.
176
+
177
+ `@internal/psl-parser` adds the argument type `dataTypeValue(dataType, support)`, which admits any literal the cast rule admits for `dataType`, and `readWrittenScalar`. No built-in attribute uses `dataTypeValue` yet. Its label is the type's tag, as in ``sql`...` ``, or the forms the type admits, as in `a number`.
178
+
179
+ ## `tagged-literal-text-renames`
180
+
181
+ The body is what is written between the quotes; the text is the canonical value. These names change:
182
+
183
+ | Old | New |
184
+ | --- | --- |
185
+ | `TaggedLiteralCanonicalization` `{ ok: true, body }`, from `canonicalizeTaggedLiteralBody` | `{ ok: true, text }` |
186
+ | `TaggedLiteralExprAst.body()` | `TaggedLiteralExprAst.text()` |
187
+ | `parseJsonBody`, `printJsonBody` from `@internal/sql-contract/data-type-support` | `parseJsonText`, `printJsonText` from `@internal/sql-contract/data-type-support` |
188
+ | `checkSqlDefaultBody`, `reservedSqlDefaultBody` from `@internal/sql-contract/validators` (and `checkSqlDefaultBody` from `@internal/family-sql/control`) | `checkSqlDefaultText`, `reservedSqlDefaultText` |
189
+
190
+ An entry that registers the `json` tag changes its imports:
191
+
192
+ ```diff
193
+ - written: { kind: 'tag', tag: 'json', parse: parseJsonBody },
194
+ - print: printJsonBody,
195
+ + written: { kind: 'tag', tag: 'json', parse: parseJsonText },
196
+ + print: printJsonText,
197
+ ```
198
+
199
+ The `why` of the `CONTRACT.INVALID_JSON_LITERAL` error `parseJsonText` throws reads `The text is not a JSON document.`
200
+
201
+ ## `default-refusals-point-at-the-written-value`
202
+
203
+ `PSL_VALUE_TYPE_INCOMPATIBLE` and `PSL_INVALID_LITERAL` from `@default` used to point at the whole `@default(...)` attribute. They now point at the written value, or at the list element the message names. The codes are unchanged; the messages change as the next section shows. `PSL_DEFAULT_LIST_EXPECTED` and `PSL_INVALID_DEFAULT_LITERAL` still point at the attribute. This supersedes the last row of the table in `default-diagnostic-codes-changed` in the 8.0.0-rc.14 to 8.0.0-rc.15 guide: a `sql` literal inside a list literal is reported at the element.
204
+
205
+ The list arm of `@default` no longer offers `sql` as an element, so its label is `list of (string | number | boolean | json`...`)`, and so is the end of the `Expected one of` message. Update an assertion on the span of one of these diagnostics, or on that message.
206
+
207
+ ## `default-refusals-say-what-to-write`
208
+
209
+ `@default` and every other position that takes a value of a data type now word a refusal of the cast rule the same way. A refusal starts with what to write instead, the forms the column's type admits, as in `Expected a number`, not the list of types it casts from. It names the column's type and the value's type only when the value has an admitted form and is still refused, such as a number too large for the column. A quoted string on a column whose type has a tag also gets that string as a tagged literal to write, when the column's type takes it, as the `Jsonb` row shows. An element of a list written on a column whose type has a list cast, such as a vector, is refused with the forms of the list cast's element types. The two other refusals change as the table shows. The codes do not change.
210
+
211
+ | Written | Message before | Message now |
212
+ | --- | --- | --- |
213
+ | `count Int @default(100000000000000099)` | `Field "N.count": pg/int4 has no cast from pg/int8; it casts from pg/int2` | `Field "N.count": Expected a number that pg/int4 can hold; got pg/int8` |
214
+ | `meta Jsonb @default("{}")` | `Field "N.meta": pg/jsonb has no cast from pg/text; it casts from pg/json` | ``Field "N.meta": Expected json`...`; write json`{}` `` |
215
+ | `count Int @default([1])` | `Field "N.count": pg/int4 has no cast from a list; it casts from pg/int2` | `Field "N.count": Expected a number; got a list` |
216
+ | `embed pgvector.Vector(3) @default([1, "x", 3])` | `Field "N.embed" at element 2: pgvector/vector has no cast from pg/text; it casts from pg/int2, pg/int4, pg/int8, pg/numeric` | `Field "N.embed" at element 2: Expected a number` |
217
+ | `active Int @default(true)` on SQLite | `Field "N.active": this target has no data type for a boolean value` | `Field "N.active": Expected a number; this target has no data type for a boolean value` |
218
+ | ``v String @default(pg.sql`x`)`` | `Unknown literal tag "pg.sql". Known tags: sql, json.` | `Field "N.v": Unknown literal tag "pg.sql". Known tags: sql, json.` |
219
+ | ``tags String[] @default([sql`'a'`])`` | `Field "Post.tags" at element 1: pg/text has no cast from sql/expression; it casts from nothing` | `Field "Post.tags" at element 1: Expected a quoted string` |
220
+ | `enum P { @@type("pg/text@1") Low = 1 }` | `enum "P" member "Low": pg/text has no cast from pg/int2; it casts from nothing` | `enum "P" member "Low": Expected a quoted string` |
221
+ | `enum P { Low = 3000000000 }`, an enum without `@@type` | `enum "P" member "Low": pg/int4 has no cast from pg/int8; it casts from pg/int2` | `enum "P" member "Low": Expected a number that pg/int4 can hold; got pg/int8` |
222
+
223
+ Update an assertion on one of these messages to the new text.